diff --git a/Build/NifPlugins_VC2008.vcproj b/Build/NifPlugins_VC2008.vcproj index 32b491a451665ceee5c2de9374bbb591926ac05c..27f7d179cea54d57bf40546b11e2bc5a7b5168de 100644 --- a/Build/NifPlugins_VC2008.vcproj +++ b/Build/NifPlugins_VC2008.vcproj @@ -4495,15 +4495,15 @@ > </File> <File - RelativePath="..\NifCommon\niutils.h" + RelativePath="..\NifCommon\niutils.cpp" > </File> <File - RelativePath="..\NifCommon\objectParams.h" + RelativePath="..\NifCommon\niutils.h" > </File> <File - RelativePath="..\NifCommon\pch.h" + RelativePath="..\NifCommon\objectParams.h" > </File> </Filter> @@ -4538,10 +4538,6 @@ RelativePath="..\NifCommon\nimorph.cpp" > </File> - <File - RelativePath="..\NifCommon\niutils.cpp" - > - </File> </Filter> <Filter Name="Resource Files" @@ -6942,6 +6938,10 @@ RelativePath="..\NifCommon\qhull\merge.h" > </File> + <File + RelativePath="..\NifCommon\pch.h" + > + </File> <File RelativePath="..\NifCommon\qhull\poly.c" > diff --git a/CHANGELOG.TXT b/CHANGELOG.TXT index 3a464fd378f6b41bfd9545dc824b5d30bf8071ef..571a70aa87a456345c644968cf949bcda9a5a85f 100644 --- a/CHANGELOG.TXT +++ b/CHANGELOG.TXT @@ -8,11 +8,11 @@ NifTools MaxPlugin o All - Correct project so Max 2008 is properly supported. - Update license to reflect that its a BSD license + - Update to latest version of niflib o Importer - Add initial support for Freedom Force animation import - Add support for importing Collision as Packed TriStrip as appropriate - - Remove code which was causing collision to be imported twice in some models o Exporter - Fix Binormal and Tangent export calculations @@ -21,6 +21,10 @@ NifTools MaxPlugin bhkMoppBvTreeShape uses the Havok SDK to generate efficient collision models which is supperior to bhkNiTriStripsShape. This feature will not be available for max x64 builds. + - Add more support for grouped nodes referenced in a bhkRigidBody + + o Props + - Add additional settings on bhkRigidBodyModifier for bhkPacked 0.2.16 ----- diff --git a/MaxNifTools.iss b/MaxNifTools.iss index cb3921dc6968ea205aba4b992a2d210378a1a8ed..4b1ede10c5aad5fe716e85a61e2504c75611eca1 100644 --- a/MaxNifTools.iss +++ b/MaxNifTools.iss @@ -6,7 +6,7 @@ AppName=NIF Utilities for 3ds Max AppVerName=NIF Utilities {code:CurVer} for 3ds Max AppPublisher=NIF File Format Library and Tools AppCopyright=Copyright © 2008, NIF File Format Library and Tools -OutputBaseFilename=niftools-max-plugins-0.2.17.0 +OutputBaseFilename=niftools-max-plugins-0.2.17.2 DisableProgramGroupPage=yes Compression=lzma SolidCompression=yes @@ -18,7 +18,7 @@ UninstallFilesDir={win}{\}Installer\NifTools Uninstallable=yes DisableDirPage=yes ArchitecturesInstallIn64BitMode=x64 -VersionInfoVersion=0.2.17.0 +VersionInfoVersion=0.2.17.2 SourceDir=. ;UninstallDisplayIcon={app}{\}..\Oblivion.exe @@ -44,7 +44,11 @@ Name: "max11x64"; Description: "3ds Max 2009 (x64)"; Types: custom; ;Name: "src"; Description: "Program Source"; [Files] -Source: "Staging\Release - gmax\Readme.txt"; DestName: "NifPlugins_Readme.txt"; DestDir: "{code:InstallPath|gmax12}"; Components: "gmax12"; Flags: isreadme ignoreversion; +Source: "License.txt"; DestDir: "{app}"; Flags: isreadme ignoreversion; +Source: "ChangeLog.txt"; DestDir: "{app}"; Flags: isreadme ignoreversion; +Source: "Readme.txt"; DestDir: "{app}"; Flags: isreadme ignoreversion; + +;Source: "Staging\Release - gmax\Readme.txt"; DestName: "NifPlugins_Readme.txt"; DestDir: "{code:InstallPath|gmax12}"; Components: "gmax12"; Flags: isreadme ignoreversion; Source: "Staging\Release - gmax\nifgmax.exe"; DestDir: "{code:InstallPath|gmax12}"; Components: "gmax12"; Flags: ignoreversion; Source: "Staging\Release - gmax\NifPlugins.dlu"; DestDir: "{code:InstallPath|gmax12}{\}plugins"; Components: "gmax12"; Flags: ignoreversion; Source: "Staging\Release - gmax\MaxNifTools.ini"; DestDir: "{code:InstallPath|gmax12}{\}plugcfg"; Components: "gmax12"; Flags: ignoreversion; @@ -59,55 +63,55 @@ Source: "Staging\NifMopp.dll"; DestDir: "{code:InstallPath|gmax12}{\}plugins"; C ;Source: "Staging\Release - Max 4.2\MaxNifTools.ini"; DestDir: "{code:InstallPath|max42}{\}plugcfg"; Components: "max42"; Flags: ignoreversion; ;Source: "Staging\NifMopp.dll" DestDir: "{code:InstallPath|max42}{\}plugins"; Components: "gmax12"; Flags: ignoreversion; -Source: "Staging\Release - Max 5\Readme.txt"; DestName: "NifPlugins_Readme.txt"; DestDir: "{code:InstallPath|max5}"; Components: "max5"; Flags: isreadme ignoreversion; +;Source: "Staging\Release - Max 5\Readme.txt"; DestName: "NifPlugins_Readme.txt"; DestDir: "{code:InstallPath|max5}"; Components: "max5"; Flags: isreadme ignoreversion; Source: "Staging\Release - Max 5\NifPlugins.dlu"; DestDir: "{code:InstallPath|max5}{\}plugins"; Components: "max5"; Flags: ignoreversion; Source: "Staging\Release - Max 5\MaxNifTools.ini"; DestDir: "{code:InstallPath|max5}{\}plugcfg"; Components: "max5"; Flags: ignoreversion; Source: "Staging\NifMopp.dll"; DestDir: "{code:InstallPath|max5}{\}plugins"; Components: "max5"; Flags: ignoreversion; -Source: "Staging\Release - Max 6\Readme.txt"; DestName: "NifPlugins_Readme.txt"; DestDir: "{code:InstallPath|max6}"; Components: "max6"; Flags: isreadme ignoreversion; +;Source: "Staging\Release - Max 6\Readme.txt"; DestName: "NifPlugins_Readme.txt"; DestDir: "{code:InstallPath|max6}"; Components: "max6"; Flags: isreadme ignoreversion; Source: "Staging\Release - Max 6\NifPlugins.dlu"; DestDir: "{code:InstallPath|max6}{\}plugins"; Components: "max6"; Flags: ignoreversion; Source: "Staging\Release - Max 6\MaxNifTools.ini"; DestDir: "{code:InstallPath|max6}{\}plugcfg"; Components: "max6"; Flags: ignoreversion; Source: "Staging\NifMopp.dll"; DestDir: "{code:InstallPath|max6}{\}plugins"; Components: "max6"; Flags: ignoreversion; -Source: "Staging\Release - Max 7\Readme.txt"; DestName: "NifPlugins_Readme.txt"; DestDir: "{code:InstallPath|max7}"; Components: "max7"; Flags: isreadme ignoreversion; +;Source: "Staging\Release - Max 7\Readme.txt"; DestName: "NifPlugins_Readme.txt"; DestDir: "{code:InstallPath|max7}"; Components: "max7"; Flags: isreadme ignoreversion; Source: "Staging\Release - Max 7\NifPlugins.dlu"; DestDir: "{code:InstallPath|max7}{\}plugins"; Components: "max7"; Flags: ignoreversion; Source: "Staging\Release - Max 7\MaxNifTools.ini"; DestDir: "{code:InstallPath|max7}{\}plugcfg"; Components: "max7"; Flags: ignoreversion; Source: "Staging\NifMopp.dll"; DestDir: "{code:InstallPath|max7}{\}plugins"; Components: "max7"; Flags: ignoreversion; -Source: "Staging\Release - Max 8\Readme.txt"; DestName: "NifPlugins_Readme.txt"; DestDir: "{code:InstallPath|max8}"; Components: "max8"; Flags: isreadme ignoreversion; +;Source: "Staging\Release - Max 8\Readme.txt"; DestName: "NifPlugins_Readme.txt"; DestDir: "{code:InstallPath|max8}"; Components: "max8"; Flags: isreadme ignoreversion; Source: "Staging\Release - Max 8\NifPlugins.dlu"; DestDir: "{code:InstallPath|max8}{\}plugins"; Components: "max8"; Flags: ignoreversion; Source: "Staging\Release - Max 8\MaxNifTools.ini"; DestDir: "{code:InstallPath|max8}{\}plugcfg"; Components: "max8"; Flags: ignoreversion; Source: "Staging\NifMopp.dll"; DestDir: "{code:InstallPath|max8}{\}plugins"; Components: "max8"; Flags: ignoreversion; -Source: "Staging\Release - Max 9\Readme.txt"; DestName: "NifPlugins_Readme.txt"; DestDir: "{code:InstallPath|max9}"; Components: "max9"; Flags: isreadme ignoreversion; +;Source: "Staging\Release - Max 9\Readme.txt"; DestName: "NifPlugins_Readme.txt"; DestDir: "{code:InstallPath|max9}"; Components: "max9"; Flags: isreadme ignoreversion; Source: "Staging\Release - Max 9\NifPlugins.dlu"; DestDir: "{code:InstallPath|max9}{\}plugins"; Components: "max9"; Flags: ignoreversion; Source: "Staging\Release - Max 9\MaxNifTools.ini"; DestDir: "{code:InstallPath|max9}{\}plugcfg"; Components: "max9"; Flags: ignoreversion; Source: "Staging\Release - Max 9\MaxNifTools.ini"; DestDir: "{localappdata}{\}Autodesk\3dsmax\9 - 32bit\enu\plugcfg"; Components: "max9"; Flags: ignoreversion; Source: "Staging\NifMopp.dll"; DestDir: "{code:InstallPath|max9}{\}plugins"; Components: "max9"; Flags: ignoreversion; -Source: "Staging\Release - Max 9 - x64\Readme.txt"; DestName: "NifPlugins_Readme.txt"; DestDir: "{code:InstallPath|max9x64}"; Components: "max9x64"; Flags: isreadme ignoreversion; +;Source: "Staging\Release - Max 9 - x64\Readme.txt"; DestName: "NifPlugins_Readme.txt"; DestDir: "{code:InstallPath|max9x64}"; Components: "max9x64"; Flags: isreadme ignoreversion; Source: "Staging\Release - Max 9 - x64\NifPlugins.dlu"; DestDir: "{code:InstallPath|max9x64}{\}plugins"; Components: "max9x64"; Flags: ignoreversion; Source: "Staging\Release - Max 9 - x64\MaxNifTools.ini"; DestDir: "{code:InstallPath|max9x64}{\}plugcfg"; Components: "max9x64"; Flags: ignoreversion; Source: "Staging\Release - Max 9 - x64\MaxNifTools.ini"; DestDir: "{localappdata}{\}Autodesk\3dsmax\9 - 64bit\enu\plugcfg"; Components: "max9x64"; Flags: ignoreversion; -Source: "Staging\Release - Max 2008\Readme.txt"; DestName: "NifPlugins_Readme.txt"; DestDir: "{code:InstallPath|max10}"; Components: "max10"; Flags: isreadme ignoreversion; +;Source: "Staging\Release - Max 2008\Readme.txt"; DestName: "NifPlugins_Readme.txt"; DestDir: "{code:InstallPath|max10}"; Components: "max10"; Flags: isreadme ignoreversion; Source: "Staging\Release - Max 2008\NifPlugins.dlu"; DestDir: "{code:InstallPath|max10}{\}plugins"; Components: "max10"; Flags: ignoreversion; Source: "Staging\Release - Max 2008\MaxNifTools.ini"; DestDir: "{code:InstallPath|max10}{\}plugcfg"; Components: "max10"; Flags: ignoreversion; Source: "Staging\Release - Max 2008\MaxNifTools.ini"; DestDir: "{localappdata}{\}Autodesk\3dsmax\2008 - 32bit\enu\plugcfg"; Components: "max10"; Flags: ignoreversion; Source: "Staging\NifMopp.dll"; DestDir: "{code:InstallPath|max10}{\}plugins"; Components: "max10"; Flags: ignoreversion; -Source: "Staging\Release - Max 2008 - x64\Readme.txt"; DestName: "NifPlugins_Readme.txt"; DestDir: "{code:InstallPath|max10x64}"; Components: "max10x64"; Flags: isreadme ignoreversion; +;Source: "Staging\Release - Max 2008 - x64\Readme.txt"; DestName: "NifPlugins_Readme.txt"; DestDir: "{code:InstallPath|max10x64}"; Components: "max10x64"; Flags: isreadme ignoreversion; Source: "Staging\Release - Max 2008 - x64\NifPlugins.dlu"; DestDir: "{code:InstallPath|max10x64}{\}plugins"; Components: "max10x64"; Flags: ignoreversion; Source: "Staging\Release - Max 2008 - x64\MaxNifTools.ini"; DestDir: "{code:InstallPath|max10x64}{\}plugcfg"; Components: "max10x64"; Flags: ignoreversion; Source: "Staging\Release - Max 2008 - x64\MaxNifTools.ini"; DestDir: "{localappdata}{\}Autodesk\3dsmax\10 - 64bit\enu\plugcfg"; Components: "max10x64"; Flags: ignoreversion; -Source: "Staging\Release - Max 2009\Readme.txt"; DestName: "NifPlugins_Readme.txt"; DestDir: "{code:InstallPath|max11}"; Components: "max11"; Flags: isreadme ignoreversion; +;Source: "Staging\Release - Max 2009\Readme.txt"; DestName: "NifPlugins_Readme.txt"; DestDir: "{code:InstallPath|max11}"; Components: "max11"; Flags: isreadme ignoreversion; Source: "Staging\Release - Max 2009\NifPlugins.dlu"; DestDir: "{code:InstallPath|max11}{\}plugins"; Components: "max11"; Flags: ignoreversion; Source: "Staging\Release - Max 2009\MaxNifTools.ini"; DestDir: "{code:InstallPath|max11}{\}plugcfg"; Components: "max11"; Flags: ignoreversion; Source: "Staging\Release - Max 2009\MaxNifTools.ini"; DestDir: "{localappdata}{\}Autodesk\3dsmax\2009 - 32bit\enu\plugcfg"; Components: "max11"; Flags: ignoreversion; Source: "Staging\NifMopp.dll"; DestDir: "{code:InstallPath|max11}{\}plugins"; Components: "max11"; Flags: ignoreversion; -Source: "Staging\Release - Max 2009 - x64\Readme.txt"; DestName: "NifPlugins_Readme.txt"; DestDir: "{code:InstallPath|max11x64}"; Components: "max11x64"; Flags: isreadme ignoreversion; +;Source: "Staging\Release - Max 2009 - x64\Readme.txt"; DestName: "NifPlugins_Readme.txt"; DestDir: "{code:InstallPath|max11x64}"; Components: "max11x64"; Flags: isreadme ignoreversion; Source: "Staging\Release - Max 2009 - x64\NifPlugins.dlu"; DestDir: "{code:InstallPath|max11x64}{\}plugins"; Components: "max11x64"; Flags: ignoreversion; Source: "Staging\Release - Max 2009 - x64\MaxNifTools.ini"; DestDir: "{code:InstallPath|max11x64}{\}plugcfg"; Components: "max11x64"; Flags: ignoreversion; Source: "Staging\Release - Max 2009 - x64\MaxNifTools.ini"; DestDir: "{localappdata}{\}Autodesk\3dsmax\11 - 64bit\enu\plugcfg"; Components: "max11x64"; Flags: ignoreversion; diff --git a/NifCommon/NifPlugins.h b/NifCommon/NifPlugins.h index 5c8f4c1d7b1d44c8c1de987cb04e032064b817da..ef2e088de284d75ebd51eadae3a86f1bf5afeac8 100644 --- a/NifCommon/NifPlugins.h +++ b/NifCommon/NifPlugins.h @@ -44,7 +44,7 @@ using Niflib::Vector3; #define NP_ANM_PRI _T("np_anm_pri") /* default values */ -#define NP_DEFAULT_HVK_MATERIAL 9 +#define NP_DEFAULT_HVK_MATERIAL 0 #define NP_DEFAULT_HVK_LAYER 1 #define NP_DEFAULT_HVK_LINEAR_DAMPING 0.1f #define NP_DEFAULT_HVK_ANGULAR_DAMPING 0.05f @@ -53,6 +53,7 @@ using Niflib::Vector3; #define NP_DEFAULT_HVK_PENETRATION_DEPTH 0.15f #define NP_DEFAULT_HVK_MOTION_SYSTEM 7 #define NP_DEFAULT_HVK_QUALITY_TYPE 1 +#define NP_DEFAULT_HVK_FILTER 0 #define NP_DEFAULT_ANM_PRI 0.0f diff --git a/NifCommon/NifVersion.h b/NifCommon/NifVersion.h index cd367ecad82275b9fcbbf2306440535c93943489..c20287fa6a52a9b652f4829ced694731cf4459d4 100644 --- a/NifCommon/NifVersion.h +++ b/NifCommon/NifVersion.h @@ -19,9 +19,9 @@ HISTORY: #define VERSION_MAJOR_INT 0 #define VERSION_MINOR_INT 2 #define VERSION_BUILD_INT 17 -#define VERSION_PATCH_INT 0 +#define VERSION_PATCH_INT 2 -#define VERSION_STRING "0, 2, 17, 0" +#define VERSION_STRING "0, 2, 17, 2" //#define DEF_VERSION_STRING(a,b,c,d) #a ", " #b ", " #c ", " #d //#define VERSION_STRING DEF_VERSION_STRING(a,b,c,d) diff --git a/NifCommon/niutils.cpp b/NifCommon/niutils.cpp index 33da10f9ddc2f19dd1c812f7d547f944c016bd51..7bc7911d9cbf3ac50c4d466c849e405fd578be8a 100644 --- a/NifCommon/niutils.cpp +++ b/NifCommon/niutils.cpp @@ -1147,10 +1147,16 @@ Modifier *GetbhkCollisionModifier(INode* node) return NULL; } -Modifier *CreatebhkCollisionModifier(INode* node, int type, HavokMaterial material) +Modifier *CreatebhkCollisionModifier( + INode* node + , int type + , HavokMaterial material /*= HAV_MAT_STONE*/ + , OblivionLayer layer /*= OL_UNIDENTIFIED */ + , unsigned char filter /*= 0*/ + ) { enum { havok_params }; - enum { PB_BOUND_TYPE, PB_MATERIAL, }; + enum { PB_BOUND_TYPE, PB_MATERIAL, PB_OPT_ENABLE, PB_MAXEDGE, PB_FACETHRESH, PB_EDGETHRESH, PB_BIAS, PB_LAYER, PB_FILTER, }; extern Class_ID BHKRIGIDBODYMODIFIER_CLASS_ID; Modifier *rbMod = GetbhkCollisionModifier(node); @@ -1168,6 +1174,8 @@ Modifier *CreatebhkCollisionModifier(INode* node, int type, HavokMaterial materi { pblock2->SetValue(PB_BOUND_TYPE, 0, type, 0); pblock2->SetValue(PB_MATERIAL, 0, material, 0); + pblock2->SetValue(PB_LAYER, 0, layer, 0); + pblock2->SetValue(PB_FILTER, 0, filter, 0); } return rbMod; } diff --git a/NifCommon/niutils.h b/NifCommon/niutils.h index a8c37cbbd8cc7d5f51d086f47d4f1879cc203c7b..f8cee40c6dabd671c8c3944484c0866f518dbc49 100644 --- a/NifCommon/niutils.h +++ b/NifCommon/niutils.h @@ -294,10 +294,23 @@ static inline Point3 TOPOINT3(const Niflib::Vector3& v){ return Point3(v.x, v.y, v.z); } +static inline Point3 TOPOINT3(const Niflib::Vector4& v){ + return Point3(v.x, v.y, v.z); +} + static inline Niflib::Vector3 TOVECTOR3(const Point3& v){ return Niflib::Vector3(v.x, v.y, v.z); } +static inline Niflib::Vector3 TOVECTOR3(const Niflib::Vector4& v){ + return Niflib::Vector3(v.x, v.y, v.z); +} + +static inline Niflib::Vector4 TOVECTOR4(const Point3& v, float w = 0.0){ + return Niflib::Vector4(v.x, v.y, v.z, w); +} + + static inline Quat TOQUAT(const Niflib::Quaternion& q, bool inverse = false){ Quat qt(q.x, q.y, q.z, q.w); return (inverse && q.w != FloatNegINF) ? qt.Inverse() : qt; @@ -424,7 +437,13 @@ void CollapseGeomTransforms(std::vector<Niflib::NiTriBasedGeomRef>& shapes); void FixNormals(std::vector<Niflib::Triangle>& tris, std::vector<Niflib::Vector3>& verts, std::vector<Niflib::Vector3>& norms); Modifier *GetbhkCollisionModifier(INode* node); -Modifier *CreatebhkCollisionModifier(INode* node, int type, Niflib::HavokMaterial material); +Modifier *CreatebhkCollisionModifier( + INode* node + , int type + , Niflib::HavokMaterial material + , Niflib::OblivionLayer layer + , byte filter + ); void GetIniFileName(char *iniName); diff --git a/NifExport/Coll.cpp b/NifExport/Coll.cpp index 3a836af323e0f3bcb7419d20dc9c4bb9b5bbe635..17ecc418a547ab53e18cc222e822b293661cb516 100755 --- a/NifExport/Coll.cpp +++ b/NifExport/Coll.cpp @@ -516,7 +516,7 @@ bhkPackedNiTriStripsShapeRef Exporter::makePackedTriStripsShape(Mesh& mesh, Matr OblivionSubShape subshape; subshape.layer = OL_STATIC; - subshape.material = HAV_MAT_WOOD; + subshape.material = HAV_MAT_STONE; subshape.numVertices = verts.size(); vector<OblivionSubShape> subshapes; @@ -537,7 +537,7 @@ bhkConvexVerticesShapeRef Exporter::makeConvexShape(Mesh& mesh, Matrix3& tm) radius /= Exporter::bhkScaleFactor; shape->SetRadius(radius); vector<Vector3> verts; - vector<Float4> norms; + vector<Vector4> norms; int nvert = mesh.getNumVerts(); int nface = mesh.getNumFaces(); mesh.checkNormals(FALSE); @@ -552,7 +552,7 @@ bhkConvexVerticesShapeRef Exporter::makeConvexShape(Mesh& mesh, Matrix3& tm) } for (int i=0; i<nface; ++i) { - Float4 &value = norms[i]; + Vector4 &value = norms[i]; Point3 &pt = mesh.getFaceNormal(i); value[0] = pt.x; value[1] = pt.y; @@ -560,7 +560,7 @@ bhkConvexVerticesShapeRef Exporter::makeConvexShape(Mesh& mesh, Matrix3& tm) value[3] = -(mesh.FaceCenter(i) * tm).Length() / Exporter::bhkScaleFactor; } sortVector3(verts); - sortFloat4(norms); + sortVector4(norms); shape->SetVertices(verts); shape->SetNormalsAndDist(norms); return shape; @@ -573,7 +573,9 @@ bhkShapeRef Exporter::makeCollisionShape(INode *node, Matrix3& tm, bhkRigidBodyR TimeValue t = 0; ObjectState os = node->EvalWorldState(t); - if (os.obj->ClassID() == SCUBA_CLASS_ID) + if (node->IsGroupHead()) + shape = makeModPackedTriStripShape(node, tm); + else if (os.obj->ClassID() == SCUBA_CLASS_ID) shape = makeCapsuleShape(node, os.obj, tm); else if (os.obj->ClassID() == Class_ID(BOXOBJ_CLASS_ID, 0)) shape = makeBoxShape(node, os.obj, tm); @@ -845,23 +847,38 @@ bhkShapeRef Exporter::makeConvexShape(INode *node, Object* obj, Matrix3& tm) return shape; } +static void AccumulateNodesFromGroup(INode *node, INodeTab& map) +{ + map.Append(1, &node); + if (node->IsGroupHead()) { + for (int i=0; i<node->NumberOfChildren(); i++) + AccumulateNodesFromGroup( node->GetChildNode(i), map ); + } +} + Exporter::Result Exporter::scanForCollision(INode *node) { if (node == NULL || (node->IsHidden() && !mExportHidden)) return Exporter::Skip; // Get the bhk RigidBody modifier if available and then get the picked node. + + TSTR nodeName = node->GetName(); if (Modifier * mod = GetbhkCollisionModifier(node)){ if (IParamBlock2* pblock = (IParamBlock2*)mod->GetReference(0)) { if (INode *collMesh = pblock->GetINode(0, 0)) { mCollisionNodes.insert(collMesh); } else { - if (mSceneCollisionNode != NULL) { - if (mExportCollision) { - throw runtime_error("There are more than one Collision mesh found at the Scene Level."); - } - } else { - mSceneCollisionNode = node; - } + if ( node->IsGroupMember() ){ + // skip groups ??? + } else { + if (mSceneCollisionNode != NULL) { + if (mExportCollision) { + throw runtime_error("There are more than one Collision mesh found at the Scene Level."); + } + } else { + mSceneCollisionNode = node; + } + } } } } @@ -872,6 +889,8 @@ Exporter::Result Exporter::scanForCollision(INode *node) { mCollisionNodes.insert(node); + // process all children of groups as collision + INodeTab map; const int PB_MESHLIST = 1; IParamBlock2* pblock2 = obj->GetParamBlockByID(0); int nBlocks = pblock2->Count(PB_MESHLIST); @@ -879,10 +898,15 @@ Exporter::Result Exporter::scanForCollision(INode *node) INode *tnode = NULL; pblock2->GetValue(PB_MESHLIST,0,tnode,FOREVER,i); if (tnode != NULL && (!tnode->IsHidden() || mExportHidden)) { - mCollisionNodes.insert(tnode); - markAsHandled(tnode); // dont process collision since the list will + AccumulateNodesFromGroup(tnode, map); } } + for (int i=0; i<map.Count(); i++) { + INode *cnode = map[i]; + if (!node->IsGroupHead()) + mCollisionNodes.insert(cnode); + markAsHandled(cnode); // dont process collision since the list will + } } else if (obj->SuperClassID() == HELPER_CLASS_ID && obj->ClassID().PartB() == BHKRIGIDBODYCLASS_DESC.PartB()) @@ -898,6 +922,7 @@ Exporter::Result Exporter::scanForCollision(INode *node) } } } + // process legacy collision if (npIsCollision(node)) { mCollisionNodes.insert(node); @@ -973,7 +998,15 @@ bhkShapeRef Exporter::makeListShape(INode *node, Matrix3& tm, bhkRigidBodyRef bo { bhkShapeRef subshape = makeCollisionShape(tnode, tm, body); if (subshape) + { + // set the material of the tree to same as list + if (subshape->IsDerivedType(bhkMoppBvTreeShape::TYPE)) + { + bhkMoppBvTreeShapeRef tree = DynamicCast<bhkMoppBvTreeShape>(subshape); + tree->SetMaterial( shape->GetMaterial() ); + } shapes.push_back(subshape); + } } } shape->SetSubShapes(shapes); @@ -1404,6 +1437,118 @@ bhkShapeRef Exporter::makeModTriStripShape(INode *node, Modifier* mod, Mesh& mes return shape; } +bhkShapeRef Exporter::makeModPackedTriStripShape(INode *tnode, Matrix3& tm) +{ + INodeTab map; + AccumulateNodesFromGroup(tnode, map); + + // Need to separate the vertices based on material. + typedef vector<Triangle> Triangles; + + // setup shape data + vector<Vector3> verts; + vector<Vector3> norms; + Triangles tris; + int voff = 0; + + int material = NP_DEFAULT_HVK_MATERIAL; + + vector<OblivionSubShape> subshapes; + + for (int i=0; i<map.Count(); ++i) { + + INode *node = map[i]; + + // skip group heads + if (node->IsGroupHead()) + continue; + + + ObjectState os = node->EvalWorldState(0); + + enum { havok_params, opt_params, clone_params, subshape_params }; // pblock ID + enum { PB_BOUND_TYPE, PB_MATERIAL, PB_OPT_ENABLE, PB_MAXEDGE, PB_FACETHRESH, PB_EDGETHRESH, PB_BIAS, PB_LAYER, PB_FILTER, }; + enum { bv_type_none, bv_type_box, bv_type_sphere, bv_type_capsule, bv_type_shapes, bv_type_convex, bv_type_packed, }; // pblock ID + + int layer = NP_DEFAULT_HVK_LAYER; + int filter = NP_DEFAULT_HVK_FILTER; + Mesh *mesh = NULL; + + if ( Modifier* mod = GetbhkCollisionModifier(node) ) + { + if (IParamBlock2* pblock2 = mod->GetParamBlockByID(havok_params)) { + pblock2->GetValue(PB_MATERIAL, 0, material, FOREVER, 0); + pblock2->GetValue(PB_FILTER, 0, filter, FOREVER, 0); + pblock2->GetValue(PB_LAYER, 0, layer, FOREVER, 0); + } + + if (bhkHelperInterface* bhkHelp = (bhkHelperInterface*)mod->GetInterface(BHKHELPERINTERFACE_DESC)) + mesh = const_cast<Mesh*>(bhkHelp->GetMesh()); + } + else + { + if (TriObject *tri = (TriObject *)os.obj->ConvertToType(0, Class_ID(TRIOBJ_CLASS_ID, 0))) + mesh = const_cast<Mesh*>(&tri->GetMesh()); + } + if (mesh == NULL) + continue; + + Matrix3 ltm = node->GetObjTMAfterWSM(0) * tm; + int vi[3]; + if (TMNegParity(ltm)) { + vi[0] = 2; vi[1] = 1; vi[2] = 0; + } else { + vi[0] = 0; vi[1] = 1; vi[2] = 2; + } + + int nvert = mesh->getNumVerts(); + int nface = mesh->getNumFaces(); + mesh->buildNormals(); + + for (int i=0; i<nvert; ++i) + { + Point3 vert = (mesh->getVert(i) * tm) / Exporter::bhkScaleFactor; + verts.push_back( TOVECTOR3(vert) ); + } + for (int i=0; i<nface; ++i) + { + norms.push_back( TOVECTOR3(mesh->getFaceNormal(i)) ); + + Triangle tri; + Face& face = mesh->faces[i]; + tri[0] = (USHORT)face.getVert(0) + voff; + tri[1] = (USHORT)face.getVert(1) + voff; + tri[2] = (USHORT)face.getVert(2) + voff; + tris.push_back(tri); + } + voff += nvert; + + + OblivionSubShape subshape; + subshape.layer = OblivionLayer(layer); + subshape.material = HavokMaterial(material); + subshape.colFilter = filter; + subshape.numVertices = nvert; + subshapes.push_back(subshape); + } + + hkPackedNiTriStripsDataRef data = new hkPackedNiTriStripsData(); + data->SetNumFaces( tris.size() ); + data->SetVertices(verts); + data->SetTriangles(tris); + data->SetNormals(norms); + + // setup shape + bhkPackedNiTriStripsShapeRef shape = new bhkPackedNiTriStripsShape(); + shape->SetData(data); + + shape->SetSubShapes( subshapes ); + + if ( TheHavokCode.Initialize() ) + return StaticCast<bhkShape>( makeTreeShape(shape, (Niflib::HavokMaterial)material) ); + return shape; +} + bhkShapeRef Exporter::makeModPackedTriStripShape(INode *node, Modifier* mod, Mesh& mesh, Matrix3& tm) { enum { havok_params }; diff --git a/NifExport/Exporter.h b/NifExport/Exporter.h index da95e886298fb09b3630494d57c128cbedb212e8..55db2a06c62cf0e3b5f5a171da1a7aa59bf473b7 100755 --- a/NifExport/Exporter.h +++ b/NifExport/Exporter.h @@ -273,6 +273,7 @@ public: bhkShapeRef makeModConvexShape(INode *node, Modifier* mod, Mesh& mesh, Matrix3& tm); bhkShapeRef makeModTriStripShape(INode *node, Modifier* mod, Mesh& mesh, Matrix3& tm); bhkShapeRef makeModPackedTriStripShape(INode *node, Modifier* mod, Mesh& mesh, Matrix3& tm); + bhkShapeRef makeModPackedTriStripShape(INode *tnode, Matrix3& tm); /* skin export */ bool makeSkin(NiTriBasedGeomRef shape, INode *node, FaceGroup &grp, TimeValue t); @@ -300,7 +301,7 @@ public: bool isSkeletonRoot(INode *node); void ApplyAllSkinOffsets( NiAVObjectRef & root ); void sortVector3(vector<Vector3>& vector); - void sortFloat4(vector<Float4>& vector); + void sortVector4(vector<Vector4>& vector); /* Progress Bar stuff */ enum ProgressSection diff --git a/NifExport/Mesh.cpp b/NifExport/Mesh.cpp index 15d3605dd3e0ebe08c431c7ecbc8b78b3ab8a565..c413d633e264082301c3f74794aba856f3cd4576 100755 --- a/NifExport/Mesh.cpp +++ b/NifExport/Mesh.cpp @@ -560,7 +560,7 @@ void InitializeRigidBody(bhkRigidBodyRef body, INode *node) Matrix3 tm = node->GetObjTMAfterWSM(0); body->SetRotation( TOQUATXYZW(Quat(tm)) ); - body->SetTranslation( TOVECTOR3(tm.GetTrans() / 7.0f) ); + body->SetTranslation( TOVECTOR4(tm.GetTrans() / 7.0f) ); } NiNodeRef Exporter::exportBone(NiNodeRef parent, INode *node) diff --git a/NifExport/Util.cpp b/NifExport/Util.cpp index ce72984bb79544cac0f737cbb2eaea060194a43d..68b680b3883fe659b47d3c6b3def2e67658825bc 100755 --- a/NifExport/Util.cpp +++ b/NifExport/Util.cpp @@ -605,7 +605,7 @@ void Exporter::sortVector3(vector<Vector3>& vector) std::stable_sort(vector.begin(), vector.end(), SortVectorEquivalence()); } -void Exporter::sortFloat4(vector<Float4>& vector) +void Exporter::sortVector4(vector<Vector4>& vector) { std::stable_sort(vector.begin(), vector.end(), SortVectorEquivalence()); } diff --git a/NifImport/ImportCollision.cpp b/NifImport/ImportCollision.cpp index 48900c6b152b21524da8bc1c79fb0190abc0ad88..04a9210df87bcccb258c8ba48e659e323703e2cf 100644 --- a/NifImport/ImportCollision.cpp +++ b/NifImport/ImportCollision.cpp @@ -135,7 +135,7 @@ bool CollisionImport::ImportRigidBody(bhkRigidBodyRef body, INode* node) float maxlinvel = body->GetMaxLinearVelocity(); float maxangvel = body->GetMaxAngularVelocity(); float pendepth = body->GetPenetrationDepth(); - Vector3 center = body->GetCenter(); + Vector3 center = TOVECTOR3(body->GetCenter()); // Update node npSetProp(node, NP_HVK_LAYER, lyr); @@ -174,7 +174,7 @@ INode* CollisionImport::CreateRigidBody(bhkRigidBodyRef body, INode *parent, Mat float maxlinvel = body->GetMaxLinearVelocity(); float maxangvel = body->GetMaxAngularVelocity(); float pendepth = body->GetPenetrationDepth(); - Vector3 center = body->GetCenter(); + Vector4 center = body->GetCenter(); SimpleObject2* listObj = (SimpleObject2*)ni.gi->CreateInstance(HELPER_CLASS_ID, BHKLISTOBJECT_CLASS_ID); if (listObj != NULL) @@ -393,7 +393,7 @@ bool CollisionImport::ImportSphere(INode *rbody, bhkRigidBodyRef body, bhkSphere // Need to "Affect Pivot Only" and "Center to Object" first n->CenterPivot(0, FALSE); #endif - CreatebhkCollisionModifier(n, bv_type_sphere, shape->GetMaterial()); + CreatebhkCollisionModifier(n, bv_type_sphere, shape->GetMaterial(), OL_UNIDENTIFIED, 0); ImportBase(body, shape, parent, n, tm); AddShape(rbody, n); @@ -494,7 +494,7 @@ bool CollisionImport::ImportCapsule(INode *rbody, bhkRigidBodyRef body, bhkCapsu // Need to reposition the Capsule so that caps are rotated correctly for pts given - CreatebhkCollisionModifier(n, bv_type_capsule, shape->GetMaterial()); + CreatebhkCollisionModifier(n, bv_type_capsule, shape->GetMaterial(), OL_UNIDENTIFIED, 0); ImportBase(body, shape, parent, n, tm); AddShape(rbody, n); return true; @@ -515,7 +515,7 @@ bool CollisionImport::ImportConvexVertices(INode *rbody, bhkRigidBodyRef body, b vector<Triangle> tris = compute_convex_hull(verts); returnNode = ImportCollisionMesh(verts, tris, norms, ltm, parent); - CreatebhkCollisionModifier(returnNode, bv_type_convex, shape->GetMaterial()); + CreatebhkCollisionModifier(returnNode, bv_type_convex, shape->GetMaterial(), OL_UNIDENTIFIED, 0); ImportBase(body, shape, parent, returnNode, tm); AddShape(rbody, returnNode); return true; @@ -543,7 +543,7 @@ bool CollisionImport::ImportTriStripsShape(INode *rbody, bhkRigidBodyRef body, b NiTriStripsRef triShape = new NiTriStrips(); vector<Triangle> tris = triShapeData->GetTriangles(); ni.ImportMesh(node, triObject, triShape, triShapeData, tris); - CreatebhkCollisionModifier(inode, bv_type_shapes, shape->GetMaterial()); + CreatebhkCollisionModifier(inode, bv_type_shapes, shape->GetMaterial(), OL_UNIDENTIFIED, 0); ImportBase(body, shape, parent, inode, tm); AddShape(rbody, inode); return true; @@ -566,10 +566,73 @@ bool CollisionImport::ImportPackedNiTriStripsShape(INode *rbody, bhkRigidBodyRef vector<Triangle> tris = data->GetTriangles(); vector<Vector3> norms = data->GetNormals(); - INode *inode = ImportCollisionMesh(verts, tris, norms, tm, parent); - CreatebhkCollisionModifier(inode, bv_type_packed, HavokMaterial(NP_DEFAULT_HVK_MATERIAL)); - ImportBase(body, shape, parent, inode, ltm); - AddShape(rbody, inode); + vector<Niflib::OblivionSubShape> subshapes = shape->GetSubShapes(); + if (subshapes.size() == 0) + { + // Is this possible? + INode *inode = ImportCollisionMesh(verts, tris, norms, tm, parent); + CreatebhkCollisionModifier(inode, bv_type_packed, HavokMaterial(NP_DEFAULT_HVK_MATERIAL), OL_UNIDENTIFIED, 0); + ImportBase(body, shape, parent, inode, ltm); + AddShape(rbody, inode); + } + else + { + unsigned int voff = 0; + unsigned int toff = 0; + + INodeTab nodes; + for (int i = 0, n = subshapes.size(); i<n; ++i) { + Niflib::OblivionSubShape& s = subshapes[i]; + + vector<Vector3> subverts; + vector<Triangle> subtris; + vector<Vector3> subnorms; + + subverts.reserve(s.numVertices); + for (unsigned int v=voff; v < (voff + s.numVertices); ++v) { + subverts.push_back( verts[v] ); + } + unsigned int vend = (voff + s.numVertices ); + + // TODO: Fix algorithm. I do not know how to split the triangles here + // Basically, greedily take all triangles until next subshape + // This is not correct but seems to work with most meshes tested. + subtris.reserve( s.numVertices / 2 ); + subnorms.reserve( s.numVertices / 2 ); + while ( toff < tris.size() ){ + Triangle t = tris[toff]; + if ( t.v1 >= vend || t.v2 >= vend || t.v3 >= vend ) + break; + // remove offset for mesh + t.v1 -= voff; t.v2 -= voff; t.v3 -= voff; + subtris.push_back( t ); + subnorms.push_back( norms[toff] ); + ++toff; + } + voff += s.numVertices; + + INode *inode = ImportCollisionMesh(subverts, subtris, subnorms, tm, parent); + + CreatebhkCollisionModifier(inode, bv_type_packed, HavokMaterial(s.material), s.layer, s.colFilter); + ImportBase(body, shape, parent, inode, ltm); + + if (n > 1) + inode->SetName( FormatText("%s:%d", "OblivionSubShape", i).data() ); + + nodes.Append(1, &inode); + } + // TODO: Group nodes on import + if ( nodes.Count() > 1 ) + { + TSTR shapeName = "bhkPackedNiTriStripsShape"; + INode *group = ni.gi->GroupNodes(&nodes, &shapeName, 0); + AddShape(rbody, group); + } + else if ( nodes.Count() == 1 ) + { + AddShape(rbody, nodes[0]); + } + } return true; } diff --git a/NifImport/ImportSkeleton.cpp b/NifImport/ImportSkeleton.cpp index 7fcf1c16b8a5c993e62ff9fa5767fafa3c361923..e5d15f5a7cdfc5fbbc2bec4028b9adcc0a93c3ec 100644 --- a/NifImport/ImportSkeleton.cpp +++ b/NifImport/ImportSkeleton.cpp @@ -93,12 +93,14 @@ bool NifImporter::HasSkeleton() bool NifImporter::IsBiped() { - if (hasSkeleton){ + if (HasSkeleton()){ NiNodeRef rootNode = root; if (rootNode){ list<NiExtraDataRef> extraData = rootNode->GetExtraData(); if (!extraData.empty()) { - return ( SelectFirstObjectOfType<BSBound>(extraData) != NULL ); + if ( BSXFlagsRef flags = SelectFirstObjectOfType<BSXFlags>(extraData) ) { + return (flags->GetData() & 0x4); + } } } } @@ -685,9 +687,9 @@ void NifImporter::ImportBones(NiNodeRef node, bool recurse) // Import Havok Collision Data surrounding node, // unfortunately this causes double import of collision so I'm disabling it for now. - // if (ImportCollision) { - //ImportCollision(node); - // } + if (enableCollision && node->GetParent()) { + ImportCollision(node); + } if (bone && recurse) { diff --git a/NifImport/MaxNifImport.cpp b/NifImport/MaxNifImport.cpp index 55ab585d29a4dbe7bbc15eea42364299e4402e75..05427334f337dc726c40c07b5936bb6066e06e72 100644 --- a/NifImport/MaxNifImport.cpp +++ b/NifImport/MaxNifImport.cpp @@ -204,23 +204,23 @@ int MaxNifImport::DoImport(const TCHAR *filename,ImpInterface *i, Interface *gi, return FALSE; ok = importer.DoImport(); } - } - catch (exception &e) - { - MessageBox(NULL, e.what(), "Import Error", MB_OK); - return TRUE; } - catch (RuntimeError &e) - { -#if VERSION_3DSMAX > ((5000<<16)+(15<<8)+0) // Version 6+ - MessageBox(NULL, e.desc1, "Import Error", MB_OK); -#endif - return TRUE; + catch (exception &e) + { + MessageBox(NULL, e.what(), "Import Error", MB_OK); + return TRUE; + } + catch (RuntimeError &e) + { +#if VERSION_3DSMAX > ((5000<<16)+(15<<8)+0) // Version 6+ + MessageBox(NULL, e.desc1, "Import Error", MB_OK); +#endif + return TRUE; } catch (...) { - MessageBox(NULL, "Unknown error.", "Import Error", MB_OK); - return TRUE; + MessageBox(NULL, "Unknown error.", "Import Error", MB_OK); + return TRUE; } return ok ? TRUE : FALSE; } diff --git a/NifImport/NIFImport.cpp b/NifImport/NIFImport.cpp index ea64549a7e9d7081a254cee43a57602329cfcba9..e6b49bfb77f760ddf140110288d75e26ac97608d 100644 --- a/NifImport/NIFImport.cpp +++ b/NifImport/NIFImport.cpp @@ -93,6 +93,7 @@ void NifImporter::Initialize() skeleton = GetSkeleton(appSettings); importSkeleton = (appSettings != NULL) ? appSettings->useSkeleton : false; importSkeleton &= hasSkeleton; + importSkeleton &= !isBiped; // Guess that the skeleton is the same one in the current directory if (importSkeleton && !defaultSkeletonName.empty()) { diff --git a/NifProps/NifProps.rc b/NifProps/NifProps.rc index 3e6d8f5445c6b13cf7c8d508ca44022d389d53fa..08abe009dd85c6a40b0dbde1f2099ba26b572f37 100755 --- a/NifProps/NifProps.rc +++ b/NifProps/NifProps.rc @@ -13,8 +13,7 @@ #define DLLNAME "NifProps.dlu" // DLL Name #define DLLDESCRIPTION "3ds Max Nif Reactor Properites Plugin" #include "..\nifcommon\nifversion.rc" -#endif - +#endif ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS @@ -53,7 +52,6 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) #endif //_WIN32 - #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // @@ -317,6 +315,17 @@ BEGIN CONTROL "Capsule",IDC_RDO_CAPSULE,"Button",BS_AUTORADIOBUTTON,8,99,80,10 END +IDD_RB_MOD_PANEL5 DIALOGEX 0, 0, 107, 42 +STYLE DS_SETFONT | DS_3DLOOK | WS_CHILD | WS_VISIBLE +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + CONTROL "Layer:",IDC_LBL_MATERIAL,"Static",SS_LEFTNOWORDWRAP | SS_CENTERIMAGE | WS_GROUP,3,4,83,8 + COMBOBOX IDC_CB_LAYER,1,15,103,157,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + LTEXT "Filter:",IDC_STATIC,4,30,18,8 + CONTROL "",IDC_ED_FILTER,"CustEdit",WS_DISABLED | WS_TABSTOP,33,29,43,10 + CONTROL "",IDC_SP_FILTER,"SpinnerControl",WS_DISABLED,76,29,7,10 +END + ///////////////////////////////////////////////////////////////////////////// // @@ -1040,76 +1049,6 @@ BEGIN 0 END -IDD_RB_MOD_PANEL DLGINIT -BEGIN - IDC_CB_MATERIAL, 0x403, 6, 0 -0x7453, 0x6e6f, 0x0065, - IDC_CB_MATERIAL, 0x403, 6, 0 -0x6c43, 0x746f, 0x0068, - IDC_CB_MATERIAL, 0x403, 5, 0 -0x6944, 0x7472, "\000" - IDC_CB_MATERIAL, 0x403, 6, 0 -0x6c47, 0x7361, 0x0073, - IDC_CB_MATERIAL, 0x403, 6, 0 -0x7247, 0x7361, 0x0073, - IDC_CB_MATERIAL, 0x403, 6, 0 -0x654d, 0x6174, 0x006c, - IDC_CB_MATERIAL, 0x403, 8, 0 -0x724f, 0x6167, 0x696e, 0x0063, - IDC_CB_MATERIAL, 0x403, 5, 0 -0x6b53, 0x6e69, "\000" - IDC_CB_MATERIAL, 0x403, 6, 0 -0x6157, 0x6574, 0x0072, - IDC_CB_MATERIAL, 0x403, 5, 0 -0x6f57, 0x646f, "\000" - IDC_CB_MATERIAL, 0x403, 12, 0 -0x6548, 0x7661, 0x2079, 0x7453, 0x6e6f, 0x0065, - IDC_CB_MATERIAL, 0x403, 12, 0 -0x6548, 0x7661, 0x2079, 0x654d, 0x6174, 0x006c, - IDC_CB_MATERIAL, 0x403, 11, 0 -0x6548, 0x7661, 0x2079, 0x6f57, 0x646f, "\000" - IDC_CB_MATERIAL, 0x403, 6, 0 -0x6843, 0x6961, 0x006e, - IDC_CB_MATERIAL, 0x403, 5, 0 -0x6e53, 0x776f, "\000" - IDC_CB_MATERIAL, 0x403, 13, 0 -0x7453, 0x6e6f, 0x2065, 0x7453, 0x6961, 0x7372, "\000" - IDC_CB_MATERIAL, 0x403, 13, 0 -0x6c43, 0x746f, 0x2068, 0x7453, 0x6961, 0x7372, "\000" - IDC_CB_MATERIAL, 0x403, 12, 0 -0x6944, 0x7472, 0x5320, 0x6174, 0x7269, 0x0073, - IDC_CB_MATERIAL, 0x403, 13, 0 -0x6c47, 0x7361, 0x2073, 0x7453, 0x6961, 0x7372, "\000" - IDC_CB_MATERIAL, 0x403, 13, 0 -0x7247, 0x7361, 0x2073, 0x7453, 0x6961, 0x7372, "\000" - IDC_CB_MATERIAL, 0x403, 13, 0 -0x654d, 0x6174, 0x206c, 0x7453, 0x6961, 0x7372, "\000" - IDC_CB_MATERIAL, 0x403, 15, 0 -0x724f, 0x6167, 0x696e, 0x2063, 0x7453, 0x6961, 0x7372, "\000" - IDC_CB_MATERIAL, 0x403, 12, 0 -0x6b53, 0x6e69, 0x5320, 0x6174, 0x7269, 0x0073, - IDC_CB_MATERIAL, 0x403, 13, 0 -0x6157, 0x6574, 0x2072, 0x7453, 0x6961, 0x7372, "\000" - IDC_CB_MATERIAL, 0x403, 12, 0 -0x6f57, 0x646f, 0x5320, 0x6174, 0x7269, 0x0073, - IDC_CB_MATERIAL, 0x403, 19, 0 -0x6548, 0x7661, 0x2079, 0x7453, 0x6e6f, 0x2065, 0x7453, 0x6961, 0x7372, -"\000" - IDC_CB_MATERIAL, 0x403, 19, 0 -0x6548, 0x7661, 0x2079, 0x654d, 0x6174, 0x206c, 0x7453, 0x6961, 0x7372, -"\000" - IDC_CB_MATERIAL, 0x403, 18, 0 -0x6548, 0x7661, 0x2079, 0x6f57, 0x646f, 0x5320, 0x6174, 0x7269, 0x0073, - - IDC_CB_MATERIAL, 0x403, 13, 0 -0x6843, 0x6961, 0x206e, 0x7453, 0x6961, 0x7372, "\000" - IDC_CB_MATERIAL, 0x403, 12, 0 -0x6e53, 0x776f, 0x5320, 0x6174, 0x7269, 0x0073, - IDC_CB_MATERIAL, 0x403, 9, 0 -0x6c45, 0x7665, 0x7461, 0x726f, "\000" - 0 -END - ///////////////////////////////////////////////////////////////////////////// // @@ -1198,6 +1137,8 @@ BEGIN IDS_OPT_ENABLE "Enable" IDS_TRANS_ENABLE "Enable Transform" IDS_CLONE_PARAMS "Clone Parameters" + IDS_DS_FILTER "Filter" + IDS_LIST_SUBSHAPEPROPS "Subshape Properties" END #endif // English (U.S.) resources @@ -1210,8 +1151,7 @@ END // // Generated from the TEXTINCLUDE 3 resource. // - - + ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED diff --git a/NifProps/bhkRigidBodyModifer.cpp b/NifProps/bhkRigidBodyModifer.cpp index e3837013987439ecc3c8f696e3a33ad96889a54f..6fb29aba82e494e09cbb8a4b93c676f9de5676be 100644 --- a/NifProps/bhkRigidBodyModifer.cpp +++ b/NifProps/bhkRigidBodyModifer.cpp @@ -171,8 +171,8 @@ class bhkRigidBodyModifierClassDesc : public ClassDesc2 // Parameter and ParamBlock IDs -enum { havok_params, opt_params, clone_params}; // pblock ID -enum { PB_BOUND_TYPE, PB_MATERIAL, PB_OPT_ENABLE, PB_MAXEDGE, PB_FACETHRESH, PB_EDGETHRESH, PB_BIAS, }; +enum { havok_params, opt_params, clone_params, subshape_params }; // pblock ID +enum { PB_BOUND_TYPE, PB_MATERIAL, PB_OPT_ENABLE, PB_MAXEDGE, PB_FACETHRESH, PB_EDGETHRESH, PB_BIAS, PB_LAYER, PB_FILTER, }; enum { havok_params_panel, }; @@ -181,10 +181,11 @@ enum { bv_type_none, bv_type_box, bv_type_sphere, bv_type_capsule, bv_type_shape static ParamBlockDesc2 havok_param_blk ( havok_params, _T("BoundingVolumes"), 0, NULL, P_AUTO_CONSTRUCT + P_AUTO_UI + P_MULTIMAP, PBLOCK_REF, //rollout - 3, + 4, havok_params, IDD_RB_MOD_PANEL, IDS_PARAMS, 0, 0, NULL, opt_params, IDD_RB_MOD_PANEL1, IDS_OPT_PARAMS, 0, 0, NULL, clone_params, IDD_CLONE_PANEL, IDS_CLONE_PARAMS, 0, 0, NULL, + subshape_params, IDD_RB_MOD_PANEL5, IDS_LIST_SUBSHAPEPROPS, 0, 0, NULL, PB_MATERIAL, _T("material"), TYPE_INT, P_ANIMATABLE, IDS_DS_MATERIAL, p_default, NP_DEFAULT_HVK_MATERIAL, @@ -222,6 +223,18 @@ static ParamBlockDesc2 havok_param_blk ( p_uix, opt_params, end, + PB_LAYER, _T("layer"), TYPE_INT, P_ANIMATABLE, IDS_DS_LAYER, + p_default, NP_DEFAULT_HVK_LAYER, + end, + + PB_FILTER, _T("filter"), TYPE_INT, P_ANIMATABLE, IDS_DS_FILTER, + p_default, NP_DEFAULT_HVK_FILTER, + p_range, 0, 255, + p_ui, subshape_params, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_ED_FILTER, IDC_SP_FILTER, 0.01f, + p_uix, subshape_params, + end, + + end, end ); @@ -256,8 +269,10 @@ INT_PTR bhkRigidBodyModifierDlgProc::DlgProc (TimeValue t,IParamMap2 *map,HWND h Interval valid; mod->pblock->GetValue( PB_MATERIAL, 0, sel, valid); mCbMaterial.select( sel ); - EnableWindow(GetDlgItem(hWnd, IDC_RDO_CAPSULE), FALSE); +#if defined(USES_WILDMAGIC) && !defined(_M_X64) + EnableWindow(GetDlgItem(hWnd, IDC_RDO_CAPSULE), FALSE); +#endif Update(t); break; } @@ -312,6 +327,58 @@ namespace } return FALSE; } + + + // Controller for subshape properies: layer and filter + class SubShapeDlgProc : public ParamMap2UserDlgProc { + public: + bhkRigidBodyModifier *mod; + NpComboBox mCbLayer; + SubShapeDlgProc(bhkRigidBodyModifier* m) {mod = m;} + INT_PTR DlgProc(TimeValue t,IParamMap2 *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam); + void DeleteThis() {delete this;} + }; + + INT_PTR SubShapeDlgProc::DlgProc (TimeValue t,IParamMap2 *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) + { + switch (msg) + { + case WM_INITDIALOG: + { + mCbLayer.init(GetDlgItem(hWnd, IDC_CB_LAYER)); + for (const char **str = NpHvkLayerNames; *str; ++str) + mCbLayer.add(*str); + + int sel = NP_DEFAULT_HVK_LAYER; + Interval valid; + mod->pblock->GetValue( PB_LAYER, 0, sel, valid); + mCbLayer.select( sel ); + + + + Update(t); + break; + } + + case WM_DESTROY: + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_CB_LAYER: + if (HIWORD(wParam)==CBN_SELCHANGE) { + mod->pblock->SetValue( PB_MATERIAL, 0, mCbLayer.selection() ); + } + break; + + default: + return FALSE; + } + } + return FALSE; + } + } //--- bhkRigidBodyModifier ------------------------------------------------------- @@ -524,6 +591,7 @@ void bhkRigidBodyModifier::BeginEditParams(IObjParam *ip, ULONG flags,Animatabl bhkRigidBodyModifierDesc.BeginEditParams(ip,this,flags,prev); havok_param_blk.SetUserDlgProc(havok_params, new bhkRigidBodyModifierDlgProc(this)); havok_param_blk.SetUserDlgProc(clone_params, new CloneMeshDlgProc(this)); + havok_param_blk.SetUserDlgProc(subshape_params, new SubShapeDlgProc(this)); //pmapParam = pblock->GetMap(havok_params); //UpdateBVDialogs(); diff --git a/NifProps/resource.h b/NifProps/resource.h index 42afffe225ead29e7ab02daaa284655bf9daaca0..95e1c3acba7d5ab79a5cbb1f6e8fc350d1d960e2 100755 --- a/NifProps/resource.h +++ b/NifProps/resource.h @@ -48,6 +48,8 @@ #define IDC_RDO_CONVEX 1718 #define IDC_TRANS_ENABLE 1719 #define IDC_BTN_CLONE 1720 +#define IDC_ED_FILTER 1721 +#define IDC_SP_FILTER 1722 #define IDC_LENGTHEDIT 3009 #define IDC_WIDTHEDIT 3010 #define IDC_OPT_BIAS 6007 @@ -97,6 +99,7 @@ #define IDS_DS_FRICTION 11013 #define IDD_PROXYPARAM1 11013 #define IDS_DS_RESTITUTION 11014 +#define IDD_RB_MOD_PANEL5 11014 #define IDS_DS_LINEAR_DAMPING 11015 #define IDS_DS_ANGULAR_DAMPING 11016 #define IDS_DS_MAX_LINEAR_VELOCITY 11017 @@ -147,6 +150,8 @@ #define IDS_OPT_ENABLE 11062 #define IDS_TRANS_ENABLE 11063 #define IDS_CLONE_PARAMS 11064 +#define IDS_DS_FILTER 11065 +#define IDS_LIST_SUBSHAPEPROPS 11066 #define IDC_ED_CENTER_X 11490 #define IDC_SP_CENTER_X 11491 #define IDC_ED_CENTER_Y 11492 @@ -192,9 +197,9 @@ // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 106 +#define _APS_NEXT_RESOURCE_VALUE 108 #define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1721 +#define _APS_NEXT_CONTROL_VALUE 1723 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif