From 2a280179c2f4f4d9c63e36401a2c6642bf3fb625 Mon Sep 17 00:00:00 2001 From: Tazpn <tazpn@users.sourceforge.net> Date: Sun, 16 Jul 2006 18:39:09 +0000 Subject: [PATCH] Fixed UV values when flipping so they align properly in UVW window Fixed rotation issue with animation import Added biped "support" for max 7 (still cannot test properly but it compiles.) --- MaxNifPlugins_Readme.txt | 14 ++++++++--- NifImport/BaseImporter.h | 16 +++++++++---- NifImport/ImportAnimation.cpp | 19 +++++++++++++++ NifImport/ImportMeshAndSkin.cpp | 2 +- NifImport/ImportSkeleton.cpp | 41 ++++++++++++++++++++------------- NifImport/MaxNifImport.h | 2 +- NifImport/MaxNifImport.rc | 8 +++---- NifImport/MaxNifImport.vcproj | 4 ++-- NifImport/NIFImport.cpp | 3 ++- NifImport/niutils.cpp | 34 ++++++++++++++++++--------- NifImport/niutils.h | 6 +++++ 11 files changed, 106 insertions(+), 43 deletions(-) diff --git a/MaxNifPlugins_Readme.txt b/MaxNifPlugins_Readme.txt index be0812c..9b799a4 100644 --- a/MaxNifPlugins_Readme.txt +++ b/MaxNifPlugins_Readme.txt @@ -1,4 +1,4 @@ - MaxPlugins 0.1.3 + MaxPlugins 0.1.4 ================ @@ -28,12 +28,20 @@ Change log ---------- + 0.1.4 + ----- + + o Importer + - Fixed UV values when flipping so they align properly in UVW window + - Fixed issues with DAoC mesh import (in NifLib) + - Fixed rotation issue with animation import + 0.1.3 ----- o Importer - - Fixed alignment issues when importing Morrowind Armor nifs - - Added initial animation support (only for animations internal to nif, no kf file support yet) + - Fixed alignment issues when importing Morrowind Armor nifs + - Added initial animation support (only for animations internal to nif, no kf file support yet) - Fixed numerous issues with bone system (biped is still broken) - Fixed issues with skin and doac nifs diff --git a/NifImport/BaseImporter.h b/NifImport/BaseImporter.h index abedf9f..d6c3b7d 100644 --- a/NifImport/BaseImporter.h +++ b/NifImport/BaseImporter.h @@ -16,6 +16,7 @@ HISTORY: class IBipMaster; extern IBipMaster * (_cdecl * Max8CreateNewBiped)(float,float,class Point3 const &,int,int,int,int,int,int,int,int,int,int,int,int,float,int,int,int,int,int,int,int,int); +extern IBipMaster * (_cdecl * Max7CreateNewBiped)(float,float,class Point3 const &,int,int,int,int,int,int,int,int,int,int,int,int,float,int,int,int,int); // Importer Base class BaseImporter @@ -47,11 +48,18 @@ public: path = buffer; iniFileValid = false; - LPCTSTR Max8CreateNewBipedName = TEXT("?CreateNewBiped@@YAPAVIBipMaster@@MMABVPoint3@@HHHHHHHHHHHHMHHHHHHHH@Z"); HMODULE hBiped = GetModuleHandle("biped.dlc"); - if (NULL != hBiped && 0 == Max8CreateNewBiped) - *(FARPROC*)&Max8CreateNewBiped = GetProcAddress(hBiped, Max8CreateNewBipedName); - + if (NULL != hBiped) + { + if (0 == Max8CreateNewBiped && 0 == Max7CreateNewBiped){ + LPCTSTR Max8CreateNewBipedName = TEXT("?CreateNewBiped@@YAPAVIBipMaster@@MMABVPoint3@@HHHHHHHHHHHHMHHHHHHHH@Z"); + *(FARPROC*)&Max8CreateNewBiped = GetProcAddress(hBiped, Max8CreateNewBipedName); + } + if (0 == Max8CreateNewBiped && 0 == Max7CreateNewBiped) { + LPCTSTR Max7CreateNewBipedName = TEXT("?CreateNewBiped@@YAPAVIBipMaster@@MMABVPoint3@@HHHHHHHHHHHHMHHHH@Z"); + *(FARPROC*)&Max7CreateNewBiped = GetProcAddress(hBiped, Max7CreateNewBipedName); + } + } // Load ini settings iniFileValid = false; LoadIniSettings(); diff --git a/NifImport/ImportAnimation.cpp b/NifImport/ImportAnimation.cpp index 80cf840..c126177 100644 --- a/NifImport/ImportAnimation.cpp +++ b/NifImport/ImportAnimation.cpp @@ -307,6 +307,13 @@ bool KFMImporter::ImportAnimation() float total = (stop - start); if ((*lnk).interpolator){ if (NiTransformInterpolatorRef interp = (*lnk).interpolator) { + + // Set initial conditions + Point3 p = TOPOINT3(interp->GetTranslation()); + Quat q = TOQUAT(interp->GetRotation()); + float s = interp->GetScale(); + PosRotScaleNode(c, p, q, s, prsDefault, 0); + if (NiTransformDataRef data = interp->GetData()){ if (ai.AddValues(c, data, time)) { minTime = min(minTime, start); @@ -317,6 +324,12 @@ bool KFMImporter::ImportAnimation() } else if (NiBSplineCompTransformInterpolatorRef interp = (*lnk).interpolator) { int npoints = total * 60.0f; + // Set initial conditions + Point3 p = TOPOINT3(interp->GetTranslation()); + Quat q = TOQUAT(interp->GetRotation()); + float s = interp->GetScale(); + PosRotScaleNode(c, p, q, s, prsDefault, 0); + NiKeyframeDataRef data = CreateBlock("NiKeyframeData"); data->SetRotateType(QUADRATIC_KEY); data->SetTranslateType(QUADRATIC_KEY); @@ -334,6 +347,12 @@ bool KFMImporter::ImportAnimation() } else if ((*lnk).controller) { if (NiTransformControllerRef tc = DynamicCast<NiTransformController>((*lnk).controller)) { if (NiTransformInterpolatorRef interp = tc->GetInterpolator()) { + // Set initial conditions + Point3 p = TOPOINT3(interp->GetTranslation()); + Quat q = TOQUAT(interp->GetRotation()); + float s = interp->GetScale(); + PosRotScaleNode(c, p, q, s, prsDefault, 0); + if (NiTransformDataRef data = interp->GetData()){ if (ai.AddValues(c, data, time)) { minTime = min(minTime, start); diff --git a/NifImport/ImportMeshAndSkin.cpp b/NifImport/ImportMeshAndSkin.cpp index 0b311ec..ef7e435 100644 --- a/NifImport/ImportMeshAndSkin.cpp +++ b/NifImport/ImportMeshAndSkin.cpp @@ -128,7 +128,7 @@ bool NifImporter::ImportMesh(ImpNode *node, TriObject *o, NiTriBasedGeomRef triG mesh.setNumTVerts(n, FALSE); for (int i=0; i<n; ++i) { TexCoord& texCoord = texCoords[i]; - mesh.tVerts[i].Set(texCoord.u, (flipUVTextures) ? -texCoord.v : texCoord.v, 0); + mesh.tVerts[i].Set(texCoord.u, (flipUVTextures) ? 1.0f-texCoord.v : texCoord.v, 0); } } } diff --git a/NifImport/ImportSkeleton.cpp b/NifImport/ImportSkeleton.cpp index 9cc6b8c..799771b 100644 --- a/NifImport/ImportSkeleton.cpp +++ b/NifImport/ImportSkeleton.cpp @@ -12,7 +12,7 @@ HISTORY: **********************************************************************/ #include "stdafx.h" #include "MaxNifImport.h" -//#include <cs/Biped8Api.h> +#include <cs/BipedApi.h> #include <obj/NiTriBasedGeom.h> #include <obj/NiTriBasedGeomData.h> #include <obj/NiTimeController.h> @@ -152,11 +152,20 @@ void NifImporter::ImportBipeds(vector<NiNodeRef>& nodes) int horseTwistLinks = CountNodesByName(bipedNodes, FormatText("%s L Horse*Twist*", bipname.c_str())); NiNodeRef root = nodes[0]; - IBipMaster* master = Max8CreateNewBiped(height, angle, wpos, arms, triPelvis, - nnecklinks, nspinelinks, nleglinks, ntaillinks, npony1links, npony2links, - numfingers, nfinglinks, numtoes, ntoelinks, bipedAnkleAttach, prop1exists, - prop2exists, prop3exists, forearmTwistLinks, upperarmTwistLinks, thighTwistLinks, - calfTwistLinks, horseTwistLinks); + IBipMaster* master = NULL; + if (Max8CreateNewBiped) { + master = Max8CreateNewBiped(height, angle, wpos, arms, triPelvis, + nnecklinks, nspinelinks, nleglinks, ntaillinks, npony1links, npony2links, + numfingers, nfinglinks, numtoes, ntoelinks, bipedAnkleAttach, prop1exists, + prop2exists, prop3exists, forearmTwistLinks, upperarmTwistLinks, thighTwistLinks, + calfTwistLinks, horseTwistLinks); + } else if (Max7CreateNewBiped) { + master = Max7CreateNewBiped(height, angle, wpos, arms, triPelvis, + nnecklinks, nspinelinks, nleglinks, ntaillinks, npony1links, npony2links, + numfingers, nfinglinks, numtoes, ntoelinks, bipedAnkleAttach, prop1exists, + prop2exists, prop3exists, forearmTwistLinks); + } + if (master) { master->SetRootName(const_cast<TCHAR*>(bipname.c_str())); @@ -328,15 +337,15 @@ Matrix3 GenerateRotMatrix(AngAxis a) float w = a.axis.z; float rcos = cos(a.angle); float rsin = sin(a.angle); - m[0][0] = rcos + u*u*(1-rcos); - m[1][0] = w * rsin + v*u*(1-rcos); - m[2][0] = -v * rsin + w*u*(1-rcos); - m[0][1] = -w * rsin + u*v*(1-rcos); - m[1][1] = rcos + v*v*(1-rcos); - m[2][1] = u * rsin + w*v*(1-rcos); - m[0][2] = v * rsin + u*w*(1-rcos); - m[1][2] = -u * rsin + v*w*(1-rcos); - m[2][2] = rcos + w*w*(1-rcos); + m.GetRow(0)[0] = rcos + u*u*(1-rcos); + m.GetRow(1)[0] = w * rsin + v*u*(1-rcos); + m.GetRow(2)[0] = -v * rsin + w*u*(1-rcos); + m.GetRow(0)[1] = -w * rsin + u*v*(1-rcos); + m.GetRow(1)[1] = rcos + v*v*(1-rcos); + m.GetRow(2)[1] = u * rsin + w*v*(1-rcos); + m.GetRow(0)[2] = v * rsin + u*w*(1-rcos); + m.GetRow(1)[2] = -u * rsin + v*w*(1-rcos); + m.GetRow(2)[2] = rcos + w*w*(1-rcos); return m; } @@ -560,7 +569,7 @@ void NifImporter::ImportBones(NiNodeRef node, bool recurse) Quat q(im); //q.Normalize(); Vector3 ppos; - Point3 zAxis(0,1,0); + Point3 zAxis(0,0,0); bool hasChildren = !children.empty(); if (hasChildren) { float len = 0.0f; diff --git a/NifImport/MaxNifImport.h b/NifImport/MaxNifImport.h index 19ff556..30ff9e2 100644 --- a/NifImport/MaxNifImport.h +++ b/NifImport/MaxNifImport.h @@ -24,7 +24,7 @@ #include <iparamb2.h> #include <iparamm2.h> #ifdef USE_BIPED -# include <cs/Biped8Api.h> +# include <cs/BipedApi.h> #endif #include <scenetraversal.h> #include <plugapi.h> diff --git a/NifImport/MaxNifImport.rc b/NifImport/MaxNifImport.rc index 51d8121..d343520 100644 --- a/NifImport/MaxNifImport.rc +++ b/NifImport/MaxNifImport.rc @@ -88,8 +88,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,1,3,4 - PRODUCTVERSION 0,1,3,0 + FILEVERSION 0,1,4,6 + PRODUCTVERSION 0,1,4,0 FILEFLAGSMASK 0x37L #ifdef _DEBUG FILEFLAGS 0x21L @@ -105,12 +105,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "3ds Max Nif Importer" - VALUE "FileVersion", "0, 1, 3, 4" + VALUE "FileVersion", "0, 1, 4, 6" VALUE "InternalName", "MaxNifImport.dli" VALUE "LegalCopyright", "Copyright (c) 2006, NIF File Format Library and Tools\r\nAll rights reserved." VALUE "OriginalFilename", "MaxNifImport.dli" VALUE "ProductName", "3ds Max Nif Importer" - VALUE "ProductVersion", "0, 1, 3, 0" + VALUE "ProductVersion", "0, 1, 4, 0" VALUE "SpecialBuild", "Alpha" END END diff --git a/NifImport/MaxNifImport.vcproj b/NifImport/MaxNifImport.vcproj index 3c93bcd..cbd0c7b 100644 --- a/NifImport/MaxNifImport.vcproj +++ b/NifImport/MaxNifImport.vcproj @@ -50,7 +50,7 @@ AdditionalOptions="/LD " InlineFunctionExpansion="1" AdditionalIncludeDirectories="C:\3dsmax7\maxsdk\include" - PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES" + PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;USE_BIPED" StringPooling="true" ExceptionHandling="2" RuntimeLibrary="0" @@ -154,7 +154,7 @@ AdditionalOptions="/LD " Optimization="0" AdditionalIncludeDirectories="C:\3dsmax7\maxsdk\include" - PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;USE_UNSUPPORTED_CODE" + PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;USE_UNSUPPORTED_CODE;USE_BIPED" GeneratePreprocessedFile="0" ExceptionHandling="2" RuntimeLibrary="1" diff --git a/NifImport/NIFImport.cpp b/NifImport/NIFImport.cpp index 16b1047..c59900b 100644 --- a/NifImport/NIFImport.cpp +++ b/NifImport/NIFImport.cpp @@ -23,6 +23,7 @@ LPCTSTR AnimImportSection = TEXT("AnimationImport"); class IBipMaster; IBipMaster * (_cdecl * Max8CreateNewBiped)(float,float,class Point3 const &,int,int,int,int,int,int,int,int,int,int,int,int,float,int,int,int,int,int,int,int,int) = 0; +IBipMaster * (_cdecl * Max7CreateNewBiped)(float,float,class Point3 const &,int,int,int,int,int,int,int,int,int,int,int,int,float,int,int,int,int) = 0; NifImporter::NifImporter(const TCHAR *Name,ImpInterface *I,Interface *GI, BOOL SuppressPrompts) : BaseImporter() @@ -66,7 +67,7 @@ void NifImporter::Initialize() GoToSkeletonBindPosition(nodes); // Only support biped if CreateNewBiped can be found. - useBiped &= (Max8CreateNewBiped != NULL); + useBiped &= (Max8CreateNewBiped != NULL || Max7CreateNewBiped != NULL); hasSkeleton = HasSkeleton(); isBiped = IsBiped(); diff --git a/NifImport/niutils.cpp b/NifImport/niutils.cpp index b49bc0c..449e445 100644 --- a/NifImport/niutils.cpp +++ b/NifImport/niutils.cpp @@ -20,7 +20,7 @@ HISTORY: #include <modstack.h> #include <iskin.h> #ifdef USE_BIPED -# include <cs/Biped8Api.h> +# include <cs/BipedApi.h> # include <cs/OurExp.h> #endif using namespace std; @@ -334,13 +334,13 @@ void PosRotScaleNode(INode *n, Matrix3& m3, PosRotScale prs, TimeValue t) void PosRotScaleNode(INode *n, Point3 p, Quat& q, float s, PosRotScale prs, TimeValue t) { if (Control *c = n->GetTMController()) { - ScaleValue sv(Point3(s,s,s)); #ifdef USE_BIPED // Bipeds are special. And will crash if you dont treat them with care if ( (c->ClassID() == BIPSLAVE_CONTROL_CLASS_ID) ||(c->ClassID() == BIPBODY_CONTROL_CLASS_ID) ||(c->ClassID() == FOOTPRINT_CLASS_ID)) { + ScaleValue sv(Point3(s,s,s)); // Get the Biped Export Interface from the controller //IBipedExport *BipIface = (IBipedExport *) c->GetInterface(I_BIPINTERFACE); IOurBipExport *BipIface = (IOurBipExport *) c->GetInterface(I_OURINTERFACE); @@ -354,19 +354,31 @@ void PosRotScaleNode(INode *n, Point3 p, Quat& q, float s, PosRotScale prs, Time else #endif { - if (prs & prsScale) - if (Control *sclCtrl = c->GetScaleController()) - sclCtrl->SetValue(t, &sv, 1, CTRL_ABSOLUTE); - if (prs & prsRot) - if (Control *rotCtrl = c->GetRotationController()) - rotCtrl->SetValue(t, &q, 1, CTRL_ABSOLUTE); - if (prs & prsPos) - if (Control *posCtrl = c->GetPositionController()) - posCtrl->SetValue(t, &p, 1, CTRL_ABSOLUTE); + PosRotScaleNode(c, p, q, s, prs, t); } } } +void PosRotScaleNode(Control *c, Point3 p, Quat& q, float s, PosRotScale prs, TimeValue t) +{ + if (c) { + if (prs & prsRot && q.w == FloatNegINF) prs = PosRotScale(prs & ~prsRot); + if (prs & prsPos && p.x == FloatNegINF) prs = PosRotScale(prs & ~prsPos); + if (prs & prsScale && s == FloatNegINF) prs = PosRotScale(prs & ~prsScale); + + ScaleValue sv(Point3(s,s,s)); + if (prs & prsScale) + if (Control *sclCtrl = c->GetScaleController()) + sclCtrl->SetValue(t, &sv, 1, CTRL_ABSOLUTE); + if (prs & prsRot) + if (Control *rotCtrl = c->GetRotationController()) + rotCtrl->SetValue(t, &q, 1, CTRL_ABSOLUTE); + if (prs & prsPos) + if (Control *posCtrl = c->GetPositionController()) + posCtrl->SetValue(t, &p, 1, CTRL_ABSOLUTE); + } +} + // Search NiNode collection for a specific name NiNodeRef FindNodeByName( const vector<NiNodeRef>& blocks, const string& name ) { diff --git a/NifImport/niutils.h b/NifImport/niutils.h index 56685f3..fd8f5cb 100644 --- a/NifImport/niutils.h +++ b/NifImport/niutils.h @@ -41,6 +41,11 @@ INFO: See Implementation for minimalist comments #define _countof(x) (sizeof(x)/sizeof((x)[0])) #endif +const unsigned int IntegerInf = 0x7f7fffff; +const unsigned int IntegerNegInf = 0xff7fffff; +const float FloatINF = *(float*)&IntegerInf; +const float FloatNegINF = *(float*)&IntegerNegInf; + // Trim whitespace before and after a string inline TCHAR *Trim(TCHAR*&p) { while(_istspace(*p)) *p++ = 0; @@ -220,6 +225,7 @@ enum PosRotScale prsDefault = prsPos | prsRot | prsScale, }; extern void PosRotScaleNode(INode *n, Point3 p, Quat& q, float s, PosRotScale prs = prsDefault, TimeValue t = 0); +extern void PosRotScaleNode(Control *c, Point3 p, Quat& q, float s, PosRotScale prs = prsDefault, TimeValue t = 0); extern void PosRotScaleNode(INode *n, Matrix3& m3, PosRotScale prs = prsDefault, TimeValue t = 0); extern Niflib::NiNodeRef FindNodeByName( const vector<Niflib::NiNodeRef>& blocks, const string& name ); -- GitLab