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