From b4ce7dc3887aa1374172308be8d72e8549f8b7f3 Mon Sep 17 00:00:00 2001 From: Tazpn <tazpn@users.sourceforge.net> Date: Sat, 23 Aug 2008 22:35:58 +0000 Subject: [PATCH] Max: More work on collision. Add defaulting for materials. Fixing export cases for mopp trees. --- CHANGELOG.TXT | 2 +- MaxNifTools.iss | 4 +- NifCommon/NifPlugins.h | 5 +- NifCommon/NifVersion.h | 4 +- NifExport/Coll.cpp | 370 ++++++++++++++++++------------- NifExport/Exporter.cpp | 10 +- NifExport/Exporter.h | 63 +++--- NifProps/NifStrings.h | 38 ++-- NifProps/bhkBoxObj.cpp | 60 ++--- NifProps/bhkCapsuleObj.cpp | 16 +- NifProps/bhkListObj.cpp | 16 +- NifProps/bhkProxyObj.cpp | 18 +- NifProps/bhkRigidBodyModifer.cpp | 10 +- NifProps/bhkSphereObj.cpp | 18 +- 14 files changed, 354 insertions(+), 280 deletions(-) diff --git a/CHANGELOG.TXT b/CHANGELOG.TXT index 571a70a..204e825 100644 --- a/CHANGELOG.TXT +++ b/CHANGELOG.TXT @@ -24,7 +24,7 @@ NifTools MaxPlugin - Add more support for grouped nodes referenced in a bhkRigidBody o Props - - Add additional settings on bhkRigidBodyModifier for bhkPacked + - Add additional settings on bhkRigidBodyModifier for bhkPackedTriShapes (layer and colfilter) 0.2.16 ----- diff --git a/MaxNifTools.iss b/MaxNifTools.iss index 4b1ede1..01b3d79 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.2 +OutputBaseFilename=niftools-max-plugins-0.2.17.3 DisableProgramGroupPage=yes Compression=lzma SolidCompression=yes @@ -18,7 +18,7 @@ UninstallFilesDir={win}{\}Installer\NifTools Uninstallable=yes DisableDirPage=yes ArchitecturesInstallIn64BitMode=x64 -VersionInfoVersion=0.2.17.2 +VersionInfoVersion=0.2.17.3 SourceDir=. ;UninstallDisplayIcon={app}{\}..\Oblivion.exe diff --git a/NifCommon/NifPlugins.h b/NifCommon/NifPlugins.h index ef2e088..7a6559e 100644 --- a/NifCommon/NifPlugins.h +++ b/NifCommon/NifPlugins.h @@ -44,12 +44,13 @@ using Niflib::Vector3; #define NP_ANM_PRI _T("np_anm_pri") /* default values */ +#define NP_INVALID_HVK_MATERIAL -1 #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 -#define NP_DEFAULT_HVK_MAX_LINEAR_VELOCITY 250.0f -#define NP_DEFAULT_HVK_MAX_ANGULAR_VELOCITY 31.4159f +#define NP_DEFAULT_HVK_MAX_LINEAR_VELOCITY 200.0f +#define NP_DEFAULT_HVK_MAX_ANGULAR_VELOCITY 200.0f #define NP_DEFAULT_HVK_PENETRATION_DEPTH 0.15f #define NP_DEFAULT_HVK_MOTION_SYSTEM 7 #define NP_DEFAULT_HVK_QUALITY_TYPE 1 diff --git a/NifCommon/NifVersion.h b/NifCommon/NifVersion.h index c20287f..9822b2f 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 2 +#define VERSION_PATCH_INT 3 -#define VERSION_STRING "0, 2, 17, 2" +#define VERSION_STRING "0, 2, 17, 3" //#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/NifExport/Coll.cpp b/NifExport/Coll.cpp index 17ecc41..3f96727 100755 --- a/NifExport/Coll.cpp +++ b/NifExport/Coll.cpp @@ -286,7 +286,7 @@ Exporter::Result Exporter::exportCollision(NiNodeRef &parent, INode *node) //tm.IdentityMatrix(); } - bhkShapeRef shape = makeCollisionShape(node, tm, body); + bhkShapeRef shape = makeCollisionShape(node, tm, body, HavokMaterial(NP_DEFAULT_HVK_MATERIAL)); if (shape) { body->SetShape(DynamicCast<bhkShape>(shape)); @@ -412,7 +412,7 @@ bhkRigidBodyRef Exporter::makeCollisionBody(INode *node) return body; } -bhkNiTriStripsShapeRef Exporter::makeTriStripsShape(Mesh& mesh, Matrix3& sm) +bhkNiTriStripsShapeRef Exporter::makeTriStripsShape(Mesh& mesh, Matrix3& sm, HavokMaterial mtlDefault) { typedef vector<Triangle> Triangles; @@ -465,7 +465,7 @@ static bhkMoppBvTreeShapeRef makeTreeShape(bhkPackedNiTriStripsShapeRef mesh, Ni return mopp; } -bhkPackedNiTriStripsShapeRef Exporter::makePackedTriStripsShape(Mesh& mesh, Matrix3& sm) +bhkPackedNiTriStripsShapeRef Exporter::makePackedTriStripsShape(Mesh& mesh, Matrix3& sm, HavokMaterial mtlDefault, OblivionLayer layer, int colFilter) { // Need to separate the vertices based on material. typedef vector<Triangle> Triangles; @@ -515,20 +515,18 @@ bhkPackedNiTriStripsShapeRef Exporter::makePackedTriStripsShape(Mesh& mesh, Matr shape->SetData(data); OblivionSubShape subshape; - subshape.layer = OL_STATIC; - subshape.material = HAV_MAT_STONE; + subshape.layer = layer; + subshape.material = mtlDefault; + subshape.colFilter = colFilter; subshape.numVertices = verts.size(); vector<OblivionSubShape> subshapes; subshapes.push_back(subshape); shape->SetSubShapes( subshapes ); - //shape->SetStripsData(0, data); - //shape->SetNumDataLayers(1); - //shape->SetOblivionLayer(0, OL_STATIC); return shape; } -bhkConvexVerticesShapeRef Exporter::makeConvexShape(Mesh& mesh, Matrix3& tm) +bhkConvexVerticesShapeRef Exporter::makeConvexShape(Mesh& mesh, Matrix3& tm, HavokMaterial mtlDefault) { bhkConvexVerticesShapeRef shape = StaticCast<bhkConvexVerticesShape>(bhkConvexVerticesShape::Create()); Point3 center(0.0f, 0.0f, 0.0f); @@ -567,45 +565,45 @@ bhkConvexVerticesShapeRef Exporter::makeConvexShape(Mesh& mesh, Matrix3& tm) } -bhkShapeRef Exporter::makeCollisionShape(INode *node, Matrix3& tm, bhkRigidBodyRef body) +bhkShapeRef Exporter::makeCollisionShape(INode *node, Matrix3& tm, bhkRigidBodyRef body, HavokMaterial mtlDefault) { bhkShapeRef shape; TimeValue t = 0; ObjectState os = node->EvalWorldState(t); if (node->IsGroupHead()) - shape = makeModPackedTriStripShape(node, tm); + shape = makeModPackedTriStripShape(node, tm, mtlDefault); else if (os.obj->ClassID() == SCUBA_CLASS_ID) - shape = makeCapsuleShape(node, os.obj, tm); + shape = makeCapsuleShape(node, os.obj, tm, mtlDefault); else if (os.obj->ClassID() == Class_ID(BOXOBJ_CLASS_ID, 0)) - shape = makeBoxShape(node, os.obj, tm); + shape = makeBoxShape(node, os.obj, tm, mtlDefault); else if (os.obj->ClassID() == Class_ID(SPHERE_CLASS_ID, 0)) - shape = makeSphereShape(node, os.obj, tm); + shape = makeSphereShape(node, os.obj, tm, mtlDefault); else if (os.obj->ClassID() == bhkBoxObject_CLASS_ID) - shape = makebhkBoxShape(node, os.obj, tm); + shape = makebhkBoxShape(node, os.obj, tm, mtlDefault); else if (os.obj->ClassID() == bhkSphereObject_CLASS_ID) - shape = makebhkSphereShape(node, os.obj, tm); + shape = makebhkSphereShape(node, os.obj, tm, mtlDefault); else if (os.obj->ClassID() == BHKCAPSULEOBJECT_CLASS_ID) - shape = makebhkCapsuleShape(node, os.obj, tm); + shape = makebhkCapsuleShape(node, os.obj, tm, mtlDefault); else if (os.obj->ClassID() == BHKLISTOBJECT_CLASS_ID) - shape = makeListShape(node, tm, body); + shape = makeListShape(node, tm, body, mtlDefault); else if (os.obj->ClassID() == BHKPROXYOBJECT_CLASS_ID) - shape = makeProxyShape(node, os.obj, tm); + shape = makeProxyShape(node, os.obj, tm, mtlDefault); else if (os.obj->SuperClassID() == GEOMOBJECT_CLASS_ID) { if (Modifier* mod = GetbhkCollisionModifier(node)) { - shape = makeModifierShape(node, os.obj, mod, tm); + shape = makeModifierShape(node, os.obj, mod, tm, mtlDefault); } else { - shape = makeTriStripsShape(node, tm); + shape = makeTriStripsShape(node, tm, mtlDefault); } } return shape; } -bhkShapeRef Exporter::makeBoxShape(INode *node, Object *obj, Matrix3& tm) +bhkShapeRef Exporter::makeBoxShape(INode *node, Object *obj, Matrix3& tm, HavokMaterial mtlDefault) { Point3 scale = GetScale(tm); float length = 0; @@ -627,14 +625,14 @@ bhkShapeRef Exporter::makeBoxShape(INode *node, Object *obj, Matrix3& tm) dim /= (Exporter::bhkScaleFactor * 2); box->SetDimensions(dim); - int mtl = 0; - npGetProp(node, NP_HVK_MATERIAL, mtl, NP_DEFAULT_HVK_MATERIAL); + int mtl = mtlDefault; + npGetProp(node, NP_HVK_MATERIAL, mtl, mtlDefault); box->SetMaterial(HavokMaterial(mtl)); return bhkShapeRef(DynamicCast<bhkSphereRepShape>(box)); } -bhkShapeRef Exporter::makeSphereShape(INode *node, Object *obj, Matrix3& tm) +bhkShapeRef Exporter::makeSphereShape(INode *node, Object *obj, Matrix3& tm, HavokMaterial mtlDefault) { Point3 scale = GetScale(tm); float s = (scale[0] + scale[1] + scale[2]) / 3.0f; @@ -648,14 +646,14 @@ bhkShapeRef Exporter::makeSphereShape(INode *node, Object *obj, Matrix3& tm) bhkSphereShapeRef sphere = new bhkSphereShape(); sphere->SetRadius(radius * s); - int mtl = 0; - npGetProp(node, NP_HVK_MATERIAL, mtl, NP_DEFAULT_HVK_MATERIAL); + int mtl = mtlDefault; + npGetProp(node, NP_HVK_MATERIAL, mtl, mtlDefault); sphere->SetMaterial(HavokMaterial(mtl)); return bhkShapeRef(DynamicCast<bhkSphereRepShape>(sphere)); } -bhkShapeRef Exporter::makeCapsuleShape(INode *node, Object *obj, Matrix3& tm) +bhkShapeRef Exporter::makeCapsuleShape(INode *node, Object *obj, Matrix3& tm, HavokMaterial mtlDefault) { Point3 scale = GetScale(tm); float s = (scale[0] + scale[1] + scale[2]) / 3.0f; @@ -674,14 +672,14 @@ bhkShapeRef Exporter::makeCapsuleShape(INode *node, Object *obj, Matrix3& tm) capsule->SetRadius1(radius); capsule->SetRadius2(radius); - int mtl = 0; - npGetProp(node, NP_HVK_MATERIAL, mtl, NP_DEFAULT_HVK_MATERIAL); + int mtl = mtlDefault; + npGetProp(node, NP_HVK_MATERIAL, mtl, mtlDefault); capsule->SetMaterial(HavokMaterial(mtl)); return bhkShapeRef(DynamicCast<bhkSphereRepShape>(capsule)); } -bhkShapeRef Exporter::makebhkBoxShape(INode *node, Object *obj, Matrix3& tm) +bhkShapeRef Exporter::makebhkBoxShape(INode *node, Object *obj, Matrix3& tm, HavokMaterial mtlDefault) { enum { box_params, }; enum { PB_MATERIAL, PB_LENGTH, PB_WIDTH, PB_HEIGHT, }; @@ -692,9 +690,10 @@ bhkShapeRef Exporter::makebhkBoxShape(INode *node, Object *obj, Matrix3& tm) Point3 scale = GetScale(tm); float s = (scale[0] + scale[1] + scale[2]) / 3.0f; - int mtl = 0; + HavokMaterial mtl = mtlDefault; float length = 0, width = 0, height = 0; - pblock2->GetValue(PB_MATERIAL, 0, mtl, FOREVER, 0); + mtl = HavokMaterial(pblock2->GetInt(PB_MATERIAL, 0, 0)); + if ( mtl < 0 ) mtl = mtlDefault; pblock2->GetValue(PB_LENGTH, 0, length, FOREVER, 0); pblock2->GetValue(PB_WIDTH, 0, width, FOREVER, 0); pblock2->GetValue(PB_HEIGHT, 0, height, FOREVER, 0); @@ -709,7 +708,7 @@ bhkShapeRef Exporter::makebhkBoxShape(INode *node, Object *obj, Matrix3& tm) // Adjust translation for center of z axis in box tm.Translate(Point3(0.0, 0.0, dim.z / 2.0)); box->SetDimensions(dim); - box->SetMaterial(HavokMaterial(mtl)); + box->SetMaterial(mtl); Matrix3 ltm = node->GetNodeTM(0) * tm; if (ltm.IsIdentity()) @@ -723,7 +722,7 @@ bhkShapeRef Exporter::makebhkBoxShape(INode *node, Object *obj, Matrix3& tm) bhkTransformShapeRef transform = new bhkTransformShape(); transform->SetTransform(TOMATRIX4(ltm).Transpose()); transform->SetShape(box); - transform->SetMaterial(HavokMaterial(mtl)); + transform->SetMaterial(mtl); retval = StaticCast<bhkShape>(transform); } } @@ -731,7 +730,7 @@ bhkShapeRef Exporter::makebhkBoxShape(INode *node, Object *obj, Matrix3& tm) return retval; } -bhkShapeRef Exporter::makebhkSphereShape(INode *node, Object *obj, Matrix3& tm) +bhkShapeRef Exporter::makebhkSphereShape(INode *node, Object *obj, Matrix3& tm, HavokMaterial mtlDefault) { bhkShapeRef retval; @@ -741,13 +740,14 @@ bhkShapeRef Exporter::makebhkSphereShape(INode *node, Object *obj, Matrix3& tm) if (IParamBlock2* pblock2 = obj->GetParamBlockByID(sphere_params)) { float radius = 0.0f; - int mtl = NP_DEFAULT_HVK_MATERIAL; + HavokMaterial mtl = mtlDefault; pblock2->GetValue(PB_RADIUS, 0, radius, FOREVER, 0); - pblock2->GetValue(PB_MATERIAL, 0, mtl, FOREVER, 0); + mtl = HavokMaterial(pblock2->GetInt(PB_MATERIAL, 0, 0)); + if ( mtl < 0 ) mtl = mtlDefault; bhkSphereShapeRef shape = new bhkSphereShape(); shape->SetRadius(radius); - shape->SetMaterial(HavokMaterial(mtl)); + shape->SetMaterial(mtl); Matrix3 ltm = node->GetNodeTM(0) * tm; if (ltm.IsIdentity()) @@ -761,14 +761,14 @@ bhkShapeRef Exporter::makebhkSphereShape(INode *node, Object *obj, Matrix3& tm) bhkTransformShapeRef transform = new bhkTransformShape(); transform->SetTransform(TOMATRIX4(ltm).Transpose()); transform->SetShape(shape); - transform->SetMaterial(HavokMaterial(mtl)); + transform->SetMaterial(mtl); retval = StaticCast<bhkShape>(transform); } } return retval; } -bhkShapeRef Exporter::makebhkCapsuleShape(INode *node, Object *obj, Matrix3& tm) +bhkShapeRef Exporter::makebhkCapsuleShape(INode *node, Object *obj, Matrix3& tm, HavokMaterial mtlDefault) { bhkShapeRef retval; @@ -778,17 +778,18 @@ bhkShapeRef Exporter::makebhkCapsuleShape(INode *node, Object *obj, Matrix3& tm) if (IParamBlock2* pblock2 = obj->GetParamBlockByID(cap_params)) { float radius1 = 0.0f, radius2 = 0.0f, len = 0.0f; - int mtl = NP_DEFAULT_HVK_MATERIAL; + HavokMaterial mtl = mtlDefault; pblock2->GetValue(PB_RADIUS1, 0, radius1, FOREVER, 0); pblock2->GetValue(PB_RADIUS2, 0, radius2, FOREVER, 0); pblock2->GetValue(PB_LENGTH, 0, len, FOREVER, 0); - pblock2->GetValue(PB_MATERIAL, 0, mtl, FOREVER, 0); + mtl = HavokMaterial(pblock2->GetInt(PB_MATERIAL, 0, 0)); + if ( mtl < 0 ) mtl = mtlDefault; bhkCapsuleShapeRef shape = new bhkCapsuleShape(); shape->SetRadius((radius1 + radius2)/2.0f); shape->SetRadius1(radius1); shape->SetRadius2(radius2); - shape->SetMaterial(HavokMaterial(mtl)); + shape->SetMaterial(mtl); Matrix3 ltm = node->GetNodeTM(0) * tm; Point3 center = ltm.GetTrans(); @@ -810,7 +811,7 @@ bhkShapeRef Exporter::makebhkCapsuleShape(INode *node, Object *obj, Matrix3& tm) } -bhkShapeRef Exporter::makeTriStripsShape(INode *node, Matrix3& tm) +bhkShapeRef Exporter::makeTriStripsShape(INode *node, Matrix3& tm, HavokMaterial mtlDefault) { TimeValue t = 0; Matrix3 sm = ScaleMatrix( GetScale(tm) ); @@ -826,7 +827,7 @@ bhkShapeRef Exporter::makeTriStripsShape(INode *node, Matrix3& tm) Mesh &mesh = tri->GetMesh(); mesh.buildNormals(); - bhkNiTriStripsShapeRef shape = makeTriStripsShape(mesh, sm); + bhkNiTriStripsShapeRef shape = makeTriStripsShape(mesh, sm, mtlDefault); int lyr = OL_STATIC; npGetProp(node, NP_HVK_LAYER, lyr, NP_DEFAULT_HVK_LAYER); @@ -840,7 +841,7 @@ bhkShapeRef Exporter::makeTriStripsShape(INode *node, Matrix3& tm) return StaticCast<bhkShape>(shape); } -bhkShapeRef Exporter::makeConvexShape(INode *node, Object* obj, Matrix3& tm) +bhkShapeRef Exporter::makeConvexShape(INode *node, Object* obj, Matrix3& tm, HavokMaterial mtlDefault) { bhkShapeRef shape; @@ -868,17 +869,17 @@ Exporter::Result Exporter::scanForCollision(INode *node) if (INode *collMesh = pblock->GetINode(0, 0)) { mCollisionNodes.insert(collMesh); } else { - 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; - } - } + //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; + //} + //} } } } @@ -950,7 +951,49 @@ bool Exporter::isCollision(INode *node) return (mCollisionNodes.find(node) != mCollisionNodes.end()); } -bhkShapeRef Exporter::makeListShape(INode *node, Matrix3& tm, bhkRigidBodyRef body) +static void AccumulateSubShapesFromGroup(INode *node, INodeTab& packedShapes, INodeTab& otherShapes) +{ + enum { havok_params }; + enum { PB_BOUND_TYPE, PB_MATERIAL, }; + enum { bv_type_none, bv_type_box, bv_type_sphere, bv_type_capsule, bv_type_shapes, bv_type_convex, bv_type_packed, }; // pblock ID + + ObjectState os = node->EvalWorldState(0); + if (node->IsGroupHead()) { + for (int i=0; i<node->NumberOfChildren(); i++) + AccumulateSubShapesFromGroup( node->GetChildNode(i), packedShapes, otherShapes); + } + else if ( (os.obj->ClassID() == SCUBA_CLASS_ID) + || (os.obj->ClassID() == Class_ID(BOXOBJ_CLASS_ID, 0)) + || (os.obj->ClassID() == Class_ID(SPHERE_CLASS_ID, 0)) + || (os.obj->ClassID() == bhkBoxObject_CLASS_ID) + || (os.obj->ClassID() == bhkSphereObject_CLASS_ID) + || (os.obj->ClassID() == BHKCAPSULEOBJECT_CLASS_ID) + || (os.obj->ClassID() == BHKLISTOBJECT_CLASS_ID) + || (os.obj->ClassID() == BHKPROXYOBJECT_CLASS_ID) + ) + { + otherShapes.Append(1, &node); + } + else if (os.obj->SuperClassID() == GEOMOBJECT_CLASS_ID) + { + if (Modifier* mod = GetbhkCollisionModifier(node)) + { + int type = bv_type_none; + if (IParamBlock2* pblock2 = mod->GetParamBlockByID(havok_params)) + pblock2->GetValue(PB_BOUND_TYPE, 0, type, FOREVER, 0); + if (type == bv_type_packed) + packedShapes.Insert(0, 1, &node); + else + otherShapes.Insert(0, 1, &node); + } + else + { + packedShapes.Insert(0, 1, &node); + } + } +} + +bhkShapeRef Exporter::makeListShape(INode *node, Matrix3& tm, bhkRigidBodyRef body, HavokMaterial mtlDefault) { const int PB_MATERIAL = 0; const int PB_MESHLIST = 1; @@ -985,28 +1028,37 @@ bhkShapeRef Exporter::makeListShape(INode *node, Matrix3& tm, bhkRigidBodyRef bo body->SetMaxAngularVelocity(maxangvel); body->SetPenetrationDepth(pendepth); } + // Accumulate potential bhkPackedStripShapes bhkListShapeRef shape = new bhkListShape(); - int mtl = pblock2->GetInt(PB_MATERIAL, 0, 0); - shape->SetMaterial(HavokMaterial(mtl)); + HavokMaterial mtl = HavokMaterial(pblock2->GetInt(PB_MATERIAL, 0, 0)); + if (mtl < 0) mtl = mtlDefault; + shape->SetMaterial(mtl); - vector<bhkShapeRef> shapes; + // Locate all packed shapes for efficient mopp packing + INodeTab packedShapes, otherShapes; for (int i = 0; i < nBlocks; i++) { INode *tnode = NULL; pblock2->GetValue(PB_MESHLIST,0,tnode,FOREVER,i); + if (tnode != NULL) + AccumulateSubShapesFromGroup(tnode, packedShapes, otherShapes); + } + + vector<bhkShapeRef> shapes; + + if (packedShapes.Count() > 0) + { + if (bhkShapeRef subshape = makeModPackedTriStripShape(packedShapes, tm, HavokMaterial(mtl))) + shapes.push_back(subshape); + } + + for (int i = 0; i < otherShapes.Count(); i++) { + INode *tnode = otherShapes[i]; if (tnode != NULL && (!tnode->IsHidden() || mExportHidden)) { - bhkShapeRef subshape = makeCollisionShape(tnode, tm, body); + bhkShapeRef subshape = makeCollisionShape(tnode, tm, body, HavokMaterial(mtl)); 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); @@ -1023,7 +1075,7 @@ bhkShapeRef Exporter::makeListShape(INode *node, Matrix3& tm, bhkRigidBodyRef bo return bhkShapeRef(); } -bhkShapeRef Exporter::makeProxyShape(INode *node, Object *obj, Matrix3& tm) +bhkShapeRef Exporter::makeProxyShape(INode *node, Object *obj, Matrix3& tm, HavokMaterial mtlDefault) { enum { list_params, bv_mesh, }; // pblock2 ID enum { PB_MATERIAL, PB_MESHLIST, PB_BOUND_TYPE, PB_CENTER, }; @@ -1042,7 +1094,7 @@ bhkShapeRef Exporter::makeProxyShape(INode *node, Object *obj, Matrix3& tm) switch (bvType) { case bv_type_box: - shape = makeProxyBoxShape(node, obj, mesh, tm); + shape = makeProxyBoxShape(node, obj, mesh, tm, mtlDefault); break; //case bv_type_sphere: @@ -1050,15 +1102,15 @@ bhkShapeRef Exporter::makeProxyShape(INode *node, Object *obj, Matrix3& tm) // break; case bv_type_shapes: - shape = makeProxyTriStripShape(node, obj, mesh, tm); + shape = makeProxyTriStripShape(node, obj, mesh, tm, mtlDefault); break; case bv_type_packed: - shape = makeProxyPackedTriStripShape(node, obj, mesh, tm); + shape = makeProxyPackedTriStripShape(node, obj, mesh, tm, mtlDefault); break; case bv_type_convex: - shape = makeProxyConvexShape(node, obj, mesh, tm); + shape = makeProxyConvexShape(node, obj, mesh, tm, mtlDefault); break; } } @@ -1067,7 +1119,7 @@ bhkShapeRef Exporter::makeProxyShape(INode *node, Object *obj, Matrix3& tm) return shape; } -bhkShapeRef Exporter::makeProxyBoxShape(INode *node, Object *obj, Mesh& mesh, Matrix3& tm) +bhkShapeRef Exporter::makeProxyBoxShape(INode *node, Object *obj, Mesh& mesh, Matrix3& tm, HavokMaterial mtlDefault) { enum { list_params, bv_mesh, }; // pblock2 ID enum { PB_MATERIAL, PB_MESHLIST, PB_BOUND_TYPE, PB_CENTER, }; @@ -1079,15 +1131,16 @@ bhkShapeRef Exporter::makeProxyBoxShape(INode *node, Object *obj, Mesh& mesh, Ma Box3 box; box.Init(); CalcAxisAlignedBox(mesh, box, NULL); - int mtl = 0; + HavokMaterial mtl = mtlDefault; float length = 0, width = 0, height = 0; - pblock2->GetValue(PB_MATERIAL, 0, mtl, FOREVER, 0); + mtl = HavokMaterial(pblock2->GetInt(PB_MATERIAL, 0, 0)); + if ( mtl < 0 ) mtl = mtlDefault; bhkBoxShapeRef shape = new bhkBoxShape(); Vector3 dim(box.Max().x-box.Min().x, box.Max().y-box.Min().y, box.Max().z-box.Min().z); dim /= (Exporter::bhkScaleFactor * 2); - shape->SetMaterial(HavokMaterial(mtl)); + shape->SetMaterial(mtl); shape->SetDimensions(dim); Matrix3 ltm = /*GetLocalTM(node) * */TransMatrix(box.Center()) * tm; @@ -1102,14 +1155,14 @@ bhkShapeRef Exporter::makeProxyBoxShape(INode *node, Object *obj, Mesh& mesh, Ma bhkTransformShapeRef transform = new bhkTransformShape(); transform->SetTransform(TOMATRIX4(ltm).Transpose()); transform->SetShape(shape); - transform->SetMaterial(HavokMaterial(mtl)); + transform->SetMaterial(mtl); retval = StaticCast<bhkShape>(transform); } } return retval; } -bhkShapeRef Exporter::makeProxySphereShape(INode *node, Object *obj, Mesh& mesh, Matrix3& tm) +bhkShapeRef Exporter::makeProxySphereShape(INode *node, Object *obj, Mesh& mesh, Matrix3& tm, HavokMaterial mtlDefault) { enum { list_params, bv_mesh, }; // pblock2 ID enum { PB_MATERIAL, PB_MESHLIST, PB_BOUND_TYPE, PB_CENTER, }; @@ -1124,7 +1177,7 @@ bhkShapeRef Exporter::makeProxySphereShape(INode *node, Object *obj, Mesh& mesh, return shape; } -bhkShapeRef Exporter::makeProxyConvexShape(INode *node, Object *obj, Mesh& mesh, Matrix3& tm) +bhkShapeRef Exporter::makeProxyConvexShape(INode *node, Object *obj, Mesh& mesh, Matrix3& tm, HavokMaterial mtlDefault) { enum { list_params, bv_mesh, }; // pblock2 ID enum { PB_MATERIAL, PB_MESHLIST, PB_BOUND_TYPE, PB_CENTER, }; @@ -1133,17 +1186,18 @@ bhkShapeRef Exporter::makeProxyConvexShape(INode *node, Object *obj, Mesh& mesh, bhkShapeRef shape; if (IParamBlock2* pblock2 = obj->GetParamBlockByID(list_params)) { - if (bhkConvexVerticesShapeRef convShape = makeConvexShape(mesh, tm)) + if (bhkConvexVerticesShapeRef convShape = makeConvexShape(mesh, tm, mtlDefault)) { - int mtl = pblock2->GetInt(PB_MATERIAL, 0, 0); - convShape->SetMaterial(HavokMaterial(mtl)); + HavokMaterial mtl = HavokMaterial(pblock2->GetInt(PB_MATERIAL, 0, 0)); + if ( mtl < 0 ) mtl = mtlDefault; + convShape->SetMaterial(mtl); shape = StaticCast<bhkShape>(convShape); } } return shape; } -bhkShapeRef Exporter::makeProxyTriStripShape(INode *node, Object *obj, Mesh& mesh, Matrix3& tm) +bhkShapeRef Exporter::makeProxyTriStripShape(INode *node, Object *obj, Mesh& mesh, Matrix3& tm, HavokMaterial mtlDefault) { enum { list_params, bv_mesh, }; // pblock2 ID enum { PB_MATERIAL, PB_MESHLIST, PB_BOUND_TYPE, PB_CENTER, }; @@ -1152,7 +1206,8 @@ bhkShapeRef Exporter::makeProxyTriStripShape(INode *node, Object *obj, Mesh& mes bhkShapeRef shape; if (IParamBlock2* pblock2 = obj->GetParamBlockByID(list_params)) { - int mtl = pblock2->GetInt(PB_MATERIAL, 0, 0); + HavokMaterial mtl = HavokMaterial(pblock2->GetInt(PB_MATERIAL, 0, 0)); + if ( mtl < 0 ) mtl = mtlDefault; // Transform location Mesh localmesh(mesh); @@ -1163,15 +1218,15 @@ bhkShapeRef Exporter::makeProxyTriStripShape(INode *node, Object *obj, Mesh& mes localmesh.buildNormals(); Matrix3 ident(true); - bhkNiTriStripsShapeRef trishape = makeTriStripsShape(localmesh, ident); - trishape->SetMaterial(HavokMaterial(mtl)); + bhkNiTriStripsShapeRef trishape = makeTriStripsShape(localmesh, ident, mtl); + trishape->SetMaterial(mtl); shape = StaticCast<bhkShape>(trishape); } return shape; } -bhkShapeRef Exporter::makeProxyPackedTriStripShape(INode *node, Object *obj, Mesh& mesh, Matrix3& tm) +bhkShapeRef Exporter::makeProxyPackedTriStripShape(INode *node, Object *obj, Mesh& mesh, Matrix3& tm, HavokMaterial mtlDefault) { enum { list_params, bv_mesh, }; // pblock2 ID enum { PB_MATERIAL, PB_MESHLIST, PB_BOUND_TYPE, PB_CENTER, }; @@ -1180,7 +1235,10 @@ bhkShapeRef Exporter::makeProxyPackedTriStripShape(INode *node, Object *obj, Mes bhkShapeRef shape; if (IParamBlock2* pblock2 = obj->GetParamBlockByID(list_params)) { - int mtl = pblock2->GetInt(PB_MATERIAL, 0, 0); + HavokMaterial mtl = HavokMaterial(pblock2->GetInt(PB_MATERIAL, 0, 0)); + if ( mtl < 0 ) mtl = mtlDefault; + int layer = NP_DEFAULT_HVK_LAYER; + int filter = NP_DEFAULT_HVK_FILTER; // Transform location Mesh localmesh(mesh); @@ -1191,7 +1249,7 @@ bhkShapeRef Exporter::makeProxyPackedTriStripShape(INode *node, Object *obj, Mes localmesh.buildNormals(); Matrix3 ident(true); - bhkPackedNiTriStripsShapeRef trishape = makePackedTriStripsShape(localmesh, ident); + bhkPackedNiTriStripsShapeRef trishape = makePackedTriStripsShape(localmesh, ident, mtlDefault, OblivionLayer(layer), filter); if ( TheHavokCode.Initialize() ) shape = StaticCast<bhkShape>( makeTreeShape(trishape, (Niflib::HavokMaterial)mtl) ); else @@ -1200,7 +1258,7 @@ bhkShapeRef Exporter::makeProxyPackedTriStripShape(INode *node, Object *obj, Mes return shape; } -bhkShapeRef Exporter::makeModifierShape(INode *node, Object* obj, Modifier* mod, Matrix3& tm) +bhkShapeRef Exporter::makeModifierShape(INode *node, Object* obj, Modifier* mod, Matrix3& tm, HavokMaterial mtlDefault) { enum { havok_params }; enum { PB_BOUND_TYPE, PB_MATERIAL, }; @@ -1209,7 +1267,7 @@ bhkShapeRef Exporter::makeModifierShape(INode *node, Object* obj, Modifier* mod, bhkShapeRef shape; const Mesh* mesh = NULL; - int material = NP_DEFAULT_HVK_MATERIAL; + HavokMaterial material = mtlDefault; int type = bv_type_none; node->EvalWorldState(0); @@ -1227,7 +1285,8 @@ bhkShapeRef Exporter::makeModifierShape(INode *node, Object* obj, Modifier* mod, if (IParamBlock2* pblock2 = mod->GetParamBlockByID(havok_params)) { pblock2->GetValue(PB_BOUND_TYPE, 0, type, FOREVER, 0); - pblock2->GetValue(PB_MATERIAL, 0, material, FOREVER, 0); + material = HavokMaterial(pblock2->GetInt(PB_MATERIAL, 0, 0)); + if ( material < 0 ) material = mtlDefault; } switch (type) { @@ -1236,42 +1295,43 @@ bhkShapeRef Exporter::makeModifierShape(INode *node, Object* obj, Modifier* mod, break; case bv_type_box: - shape = makeModBoxShape(node, mod, const_cast<Mesh&>(*mesh), tm); + shape = makeModBoxShape(node, mod, const_cast<Mesh&>(*mesh), tm, material); break; case bv_type_sphere: - shape = makeModSphereShape(node, mod, const_cast<Mesh&>(*mesh), tm); + shape = makeModSphereShape(node, mod, const_cast<Mesh&>(*mesh), tm, material); break; case bv_type_capsule: - shape = makeModCapsuleShape(node, mod, const_cast<Mesh&>(*mesh), tm); + shape = makeModCapsuleShape(node, mod, const_cast<Mesh&>(*mesh), tm, material); break; case bv_type_shapes: - shape = makeModTriStripShape(node, mod, const_cast<Mesh&>(*mesh), tm); + shape = makeModTriStripShape(node, mod, const_cast<Mesh&>(*mesh), tm, material); break; case bv_type_convex: - shape = makeModConvexShape(node, mod, const_cast<Mesh&>(*mesh), tm); + shape = makeModConvexShape(node, mod, const_cast<Mesh&>(*mesh), tm, material); break; case bv_type_packed: - shape = makeModPackedTriStripShape(node, mod, const_cast<Mesh&>(*mesh), tm); + shape = makeModPackedTriStripShape(node, mod, const_cast<Mesh&>(*mesh), tm, material); break; } return shape; } -bhkShapeRef Exporter::makeModBoxShape(INode *node, Modifier* mod, Mesh& mesh, Matrix3& tm) +bhkShapeRef Exporter::makeModBoxShape(INode *node, Modifier* mod, Mesh& mesh, Matrix3& tm, HavokMaterial mtlDefault) { enum { havok_params }; enum { PB_BOUND_TYPE, PB_MATERIAL, }; 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 material = NP_DEFAULT_HVK_MATERIAL; + HavokMaterial material = mtlDefault; if (IParamBlock2* pblock2 = mod->GetParamBlockByID(havok_params)) { - pblock2->GetValue(PB_MATERIAL, 0, material, FOREVER, 0); + material = HavokMaterial(pblock2->GetInt(PB_MATERIAL, 0, 0)); + if ( material < 0 ) material = mtlDefault; } bhkShapeRef retval; @@ -1283,7 +1343,7 @@ bhkShapeRef Exporter::makeModBoxShape(INode *node, Modifier* mod, Mesh& mesh, Ma Vector3 dim(box.Max().x-box.Min().x, box.Max().y-box.Min().y, box.Max().z-box.Min().z); dim /= (Exporter::bhkScaleFactor * 2); shape->SetDimensions(dim); - shape->SetMaterial(HavokMaterial(material)); + shape->SetMaterial(material); Matrix3 ltm = TransMatrix(box.Center()) * node->GetNodeTM(0) * tm; if (ltm.IsIdentity()) @@ -1297,23 +1357,24 @@ bhkShapeRef Exporter::makeModBoxShape(INode *node, Modifier* mod, Mesh& mesh, Ma bhkTransformShapeRef transform = new bhkTransformShape(); transform->SetTransform(TOMATRIX4(ltm).Transpose()); transform->SetShape(shape); - transform->SetMaterial(HavokMaterial(material)); + transform->SetMaterial(material); retval = StaticCast<bhkShape>(transform); } } return retval; } -bhkShapeRef Exporter::makeModSphereShape(INode *node, Modifier* mod, Mesh& mesh, Matrix3& tm) +bhkShapeRef Exporter::makeModSphereShape(INode *node, Modifier* mod, Mesh& mesh, Matrix3& tm, HavokMaterial mtlDefault) { enum { havok_params }; enum { PB_BOUND_TYPE, PB_MATERIAL, }; 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 material = NP_DEFAULT_HVK_MATERIAL; + HavokMaterial material = mtlDefault; if (IParamBlock2* pblock2 = mod->GetParamBlockByID(havok_params)) { - pblock2->GetValue(PB_MATERIAL, 0, material, FOREVER, 0); + material = HavokMaterial(pblock2->GetInt(PB_MATERIAL, 0, 0)); + if ( material < 0 ) material = mtlDefault; } bhkShapeRef retval; @@ -1325,7 +1386,7 @@ bhkShapeRef Exporter::makeModSphereShape(INode *node, Modifier* mod, Mesh& mesh, if (bhkSphereShapeRef shape = new bhkSphereShape()) { shape->SetRadius(radius / Exporter::bhkScaleFactor); - shape->SetMaterial(HavokMaterial(material)); + shape->SetMaterial(material); Matrix3 ltm = TransMatrix(center) * node->GetObjTMAfterWSM(0) * tm; if (ltm.IsIdentity()) @@ -1339,24 +1400,25 @@ bhkShapeRef Exporter::makeModSphereShape(INode *node, Modifier* mod, Mesh& mesh, bhkTransformShapeRef transform = new bhkTransformShape(); transform->SetTransform(TOMATRIX4(ltm).Transpose()); transform->SetShape(shape); - transform->SetMaterial(HavokMaterial(material)); + transform->SetMaterial(material); retval = StaticCast<bhkShape>(transform); } } return retval; } -bhkShapeRef Exporter::makeModCapsuleShape(INode *node, Modifier* mod, Mesh& mesh, Matrix3& tm) +bhkShapeRef Exporter::makeModCapsuleShape(INode *node, Modifier* mod, Mesh& mesh, Matrix3& tm, HavokMaterial mtlDefault) { enum { havok_params }; enum { PB_BOUND_TYPE, PB_MATERIAL, }; 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 material = NP_DEFAULT_HVK_MATERIAL; + HavokMaterial material = mtlDefault; node->EvalWorldState(0); if (IParamBlock2* pblock2 = mod->GetParamBlockByID(havok_params)) { - pblock2->GetValue(PB_MATERIAL, 0, material, FOREVER, 0); + material = HavokMaterial(pblock2->GetInt(PB_MATERIAL, 0, 0)); + if ( material < 0 ) material = mtlDefault; } bhkShapeRef retval; @@ -1372,7 +1434,7 @@ bhkShapeRef Exporter::makeModCapsuleShape(INode *node, Modifier* mod, Mesh& mesh shape->SetRadius2(radius / Exporter::bhkScaleFactor); shape->SetFirstPoint(TOVECTOR3(center/Exporter::bhkScaleFactor)); shape->SetSecondPoint(TOVECTOR3(center/Exporter::bhkScaleFactor)); - shape->SetMaterial(HavokMaterial(material)); + shape->SetMaterial(material); Matrix3 ltm = TransMatrix(center) * node->GetObjTMAfterWSM(0) * tm; if (ltm.IsIdentity()) @@ -1386,62 +1448,67 @@ bhkShapeRef Exporter::makeModCapsuleShape(INode *node, Modifier* mod, Mesh& mesh bhkTransformShapeRef transform = new bhkTransformShape(); transform->SetTransform(TOMATRIX4(ltm).Transpose()); transform->SetShape(shape); - transform->SetMaterial(HavokMaterial(material)); + transform->SetMaterial(material); retval = StaticCast<bhkShape>(transform); } } return retval; } -bhkShapeRef Exporter::makeModConvexShape(INode *node, Modifier* mod, Mesh& mesh, Matrix3& tm) +bhkShapeRef Exporter::makeModConvexShape(INode *node, Modifier* mod, Mesh& mesh, Matrix3& tm, HavokMaterial mtlDefault) { enum { havok_params }; enum { PB_BOUND_TYPE, PB_MATERIAL, }; 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 material = NP_DEFAULT_HVK_MATERIAL; + HavokMaterial material = mtlDefault; + if (IParamBlock2* pblock2 = mod->GetParamBlockByID(havok_params)) + { + material = HavokMaterial(pblock2->GetInt(PB_MATERIAL, 0, 0)); + if ( material < 0 ) material = mtlDefault; + } Matrix3 ltm = node->GetObjTMAfterWSM(0) * tm; bhkShapeRef shape; - if (bhkConvexVerticesShapeRef convShape = makeConvexShape(mesh, ltm)) + if (bhkConvexVerticesShapeRef convShape = makeConvexShape(mesh, ltm, material)) { - if (IParamBlock2* pblock2 = mod->GetParamBlockByID(havok_params)) - { - pblock2->GetValue(PB_MATERIAL, 0, material, FOREVER, 0); - } - convShape->SetMaterial(HavokMaterial(material)); + convShape->SetMaterial(material); shape = StaticCast<bhkShape>(convShape); } return shape; } -bhkShapeRef Exporter::makeModTriStripShape(INode *node, Modifier* mod, Mesh& mesh, Matrix3& tm) +bhkShapeRef Exporter::makeModTriStripShape(INode *node, Modifier* mod, Mesh& mesh, Matrix3& tm, HavokMaterial mtlDefault) { enum { havok_params }; enum { PB_BOUND_TYPE, PB_MATERIAL, }; 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 material = NP_DEFAULT_HVK_MATERIAL; + HavokMaterial material = mtlDefault; + if (IParamBlock2* pblock2 = mod->GetParamBlockByID(havok_params)) + { + material = HavokMaterial(pblock2->GetInt(PB_MATERIAL, 0, 0)); + if ( material < 0 ) material = mtlDefault; + } Matrix3 ltm = node->GetObjTMAfterWSM(0) * tm; bhkShapeRef shape; - if (bhkNiTriStripsShapeRef trishape = makeTriStripsShape(mesh, ltm)) + if (bhkNiTriStripsShapeRef trishape = makeTriStripsShape(mesh, ltm, material)) { - trishape->SetMaterial(HavokMaterial(material)); - if (IParamBlock2* pblock2 = mod->GetParamBlockByID(havok_params)) - { - pblock2->GetValue(PB_MATERIAL, 0, material, FOREVER, 0); - } shape = StaticCast<bhkShape>(trishape); } return shape; } -bhkShapeRef Exporter::makeModPackedTriStripShape(INode *tnode, Matrix3& tm) +bhkShapeRef Exporter::makeModPackedTriStripShape(INode *tnode, Matrix3& tm, HavokMaterial mtlDefault) { INodeTab map; AccumulateNodesFromGroup(tnode, map); + return makeModPackedTriStripShape(map, tm, Niflib::HavokMaterial(NP_DEFAULT_HVK_MATERIAL)); +} +bhkShapeRef Exporter::makeModPackedTriStripShape(INodeTab &map, Matrix3& tm, Niflib::HavokMaterial mtlDefault) +{ // Need to separate the vertices based on material. typedef vector<Triangle> Triangles; @@ -1451,7 +1518,7 @@ bhkShapeRef Exporter::makeModPackedTriStripShape(INode *tnode, Matrix3& tm) Triangles tris; int voff = 0; - int material = NP_DEFAULT_HVK_MATERIAL; + HavokMaterial material = mtlDefault; vector<OblivionSubShape> subshapes; @@ -1463,7 +1530,6 @@ bhkShapeRef Exporter::makeModPackedTriStripShape(INode *tnode, Matrix3& tm) if (node->IsGroupHead()) continue; - ObjectState os = node->EvalWorldState(0); enum { havok_params, opt_params, clone_params, subshape_params }; // pblock ID @@ -1477,7 +1543,8 @@ bhkShapeRef Exporter::makeModPackedTriStripShape(INode *tnode, Matrix3& tm) if ( Modifier* mod = GetbhkCollisionModifier(node) ) { if (IParamBlock2* pblock2 = mod->GetParamBlockByID(havok_params)) { - pblock2->GetValue(PB_MATERIAL, 0, material, FOREVER, 0); + material = HavokMaterial(pblock2->GetInt(PB_MATERIAL, 0, 0)); + if ( material < 0 ) material = mtlDefault; pblock2->GetValue(PB_FILTER, 0, filter, FOREVER, 0); pblock2->GetValue(PB_LAYER, 0, layer, FOREVER, 0); } @@ -1526,7 +1593,7 @@ bhkShapeRef Exporter::makeModPackedTriStripShape(INode *tnode, Matrix3& tm) OblivionSubShape subshape; subshape.layer = OblivionLayer(layer); - subshape.material = HavokMaterial(material); + subshape.material = material < 0 ? mtlDefault : HavokMaterial(material); subshape.colFilter = filter; subshape.numVertices = nvert; subshapes.push_back(subshape); @@ -1545,28 +1612,31 @@ bhkShapeRef Exporter::makeModPackedTriStripShape(INode *tnode, Matrix3& tm) shape->SetSubShapes( subshapes ); if ( TheHavokCode.Initialize() ) - return StaticCast<bhkShape>( makeTreeShape(shape, (Niflib::HavokMaterial)material) ); + return StaticCast<bhkShape>( makeTreeShape(shape, (Niflib::HavokMaterial)mtlDefault) ); return shape; } -bhkShapeRef Exporter::makeModPackedTriStripShape(INode *node, Modifier* mod, Mesh& mesh, Matrix3& tm) +bhkShapeRef Exporter::makeModPackedTriStripShape(INode *node, Modifier* mod, Mesh& mesh, Matrix3& tm, HavokMaterial mtlDefault) { - enum { havok_params }; - enum { PB_BOUND_TYPE, PB_MATERIAL, }; + 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 material = NP_DEFAULT_HVK_MATERIAL; + HavokMaterial material = mtlDefault; + int layer = NP_DEFAULT_HVK_LAYER; + int filter = NP_DEFAULT_HVK_FILTER; + if (IParamBlock2* pblock2 = mod->GetParamBlockByID(havok_params)) + { + material = HavokMaterial(pblock2->GetInt(PB_MATERIAL, 0, 0)); + if ( material < 0 ) material = mtlDefault; + pblock2->GetValue(PB_FILTER, 0, filter, FOREVER, 0); + pblock2->GetValue(PB_LAYER, 0, layer, FOREVER, 0); + } Matrix3 ltm = node->GetObjTMAfterWSM(0) * tm; bhkShapeRef shape; - if (bhkPackedNiTriStripsShapeRef trishape = makePackedTriStripsShape(mesh, ltm)) + if (bhkPackedNiTriStripsShapeRef trishape = makePackedTriStripsShape(mesh, ltm, material, OblivionLayer(layer), filter)) { - //trishape->SetMaterial(HavokMaterial(material)); - if (IParamBlock2* pblock2 = mod->GetParamBlockByID(havok_params)) - { - pblock2->GetValue(PB_MATERIAL, 0, material, FOREVER, 0); - } - if ( TheHavokCode.Initialize() ) shape = StaticCast<bhkShape>( makeTreeShape(trishape, (Niflib::HavokMaterial)material) ); else diff --git a/NifExport/Exporter.cpp b/NifExport/Exporter.cpp index a3940e3..e9b5f77 100755 --- a/NifExport/Exporter.cpp +++ b/NifExport/Exporter.cpp @@ -145,11 +145,11 @@ Exporter::Result Exporter::doExport(NiNodeRef &root, INode *node) Result result = exportNodes(root, selectedRoots[i]); if (result != Ok && result != Skip) return result; - //if (mExportCollision) { - // result = exportCollision(root, selectedRoots[i]); - // if (result != Ok) - // return result; - //} + if (mExportCollision) { + result = exportCollision(root, selectedRoots[i]); + if (result != Ok) + return result; + } } // Always Zero out root transforms vector<NiAVObjectRef> children = root->GetChildren(); diff --git a/NifExport/Exporter.h b/NifExport/Exporter.h index 55db2a0..e4b82fd 100755 --- a/NifExport/Exporter.h +++ b/NifExport/Exporter.h @@ -243,37 +243,38 @@ public: /* creates a bhkRigidBody */ bhkRigidBodyRef makeCollisionBody(INode *node); /* creates a collision shape from a node */ - bhkShapeRef makeCollisionShape(INode *node, Matrix3& tm, bhkRigidBodyRef body); - - bhkShapeRef makeTriStripsShape(INode *node, Matrix3& tm); - bhkShapeRef makeBoxShape(INode *node, Object *obj, Matrix3& tm); - bhkShapeRef makeSphereShape(INode *node, Object *obj, Matrix3& tm); - bhkShapeRef makeCapsuleShape(INode *node, Object *obj, Matrix3& tm); - bhkShapeRef makeListShape(INode *node, Matrix3& tm, bhkRigidBodyRef body); - bhkShapeRef makebhkBoxShape(INode *node, Object *obj, Matrix3& tm); - bhkShapeRef makebhkSphereShape(INode *node, Object *obj, Matrix3& tm); - bhkShapeRef makebhkCapsuleShape(INode *node, Object *obj, Matrix3& tm); - bhkShapeRef makeConvexShape(INode *node, Object* obj, Matrix3& tm); - - Ref<bhkConvexVerticesShape> makeConvexShape(Mesh& mesh, Matrix3& tm); - Ref<bhkNiTriStripsShape> makeTriStripsShape(Mesh& mesh, Matrix3& sm); - Ref<bhkPackedNiTriStripsShape> makePackedTriStripsShape(Mesh& mesh, Matrix3& sm); - - bhkShapeRef makeProxyShape(INode *node, Object *obj, Matrix3& tm); - bhkShapeRef makeProxyBoxShape(INode *node, Object *obj, Mesh& mesh, Matrix3& tm); - bhkShapeRef makeProxySphereShape(INode *node, Object *obj, Mesh& mesh, Matrix3& tm); - bhkShapeRef makeProxyConvexShape(INode *node, Object *obj, Mesh& mesh, Matrix3& tm); - bhkShapeRef makeProxyTriStripShape(INode *node, Object *obj, Mesh& mesh, Matrix3& tm); - bhkShapeRef makeProxyPackedTriStripShape(INode *node, Object *obj, Mesh& mesh, Matrix3& tm); - - bhkShapeRef makeModifierShape(INode *node, Object* obj, Modifier* mod, Matrix3& tm); - bhkShapeRef makeModBoxShape(INode *node, Modifier* mod, Mesh& mesh, Matrix3& tm); - bhkShapeRef makeModSphereShape(INode *node, Modifier* mod, Mesh& mesh, Matrix3& tm); - bhkShapeRef makeModCapsuleShape(INode *node, Modifier* mod, Mesh& mesh, Matrix3& tm); - 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); + bhkShapeRef makeCollisionShape(INode *node, Matrix3& tm, bhkRigidBodyRef body, HavokMaterial mtlDefault); + + bhkShapeRef makeTriStripsShape(INode *node, Matrix3& tm, HavokMaterial mtlDefault); + bhkShapeRef makeBoxShape(INode *node, Object *obj, Matrix3& tm, HavokMaterial mtlDefault); + bhkShapeRef makeSphereShape(INode *node, Object *obj, Matrix3& tm, HavokMaterial mtlDefault); + bhkShapeRef makeCapsuleShape(INode *node, Object *obj, Matrix3& tm, HavokMaterial mtlDefault); + bhkShapeRef makeListShape(INode *node, Matrix3& tm, bhkRigidBodyRef body, HavokMaterial mtlDefault); + bhkShapeRef makebhkBoxShape(INode *node, Object *obj, Matrix3& tm, HavokMaterial mtlDefault); + bhkShapeRef makebhkSphereShape(INode *node, Object *obj, Matrix3& tm, HavokMaterial mtlDefault); + bhkShapeRef makebhkCapsuleShape(INode *node, Object *obj, Matrix3& tm, HavokMaterial mtlDefault); + bhkShapeRef makeConvexShape(INode *node, Object* obj, Matrix3& tm, HavokMaterial mtlDefault); + + Ref<bhkConvexVerticesShape> makeConvexShape(Mesh& mesh, Matrix3& tm, HavokMaterial mtlDefault); + Ref<bhkNiTriStripsShape> makeTriStripsShape(Mesh& mesh, Matrix3& sm, HavokMaterial mtlDefault); + Ref<bhkPackedNiTriStripsShape> makePackedTriStripsShape(Mesh& mesh, Matrix3& sm, HavokMaterial mtlDefault, OblivionLayer layer, int colFilter); + + bhkShapeRef makeProxyShape(INode *node, Object *obj, Matrix3& tm, HavokMaterial mtlDefault); + bhkShapeRef makeProxyBoxShape(INode *node, Object *obj, Mesh& mesh, Matrix3& tm, HavokMaterial mtlDefault); + bhkShapeRef makeProxySphereShape(INode *node, Object *obj, Mesh& mesh, Matrix3& tm, HavokMaterial mtlDefault); + bhkShapeRef makeProxyConvexShape(INode *node, Object *obj, Mesh& mesh, Matrix3& tm, HavokMaterial mtlDefault); + bhkShapeRef makeProxyTriStripShape(INode *node, Object *obj, Mesh& mesh, Matrix3& tm, HavokMaterial mtlDefault); + bhkShapeRef makeProxyPackedTriStripShape(INode *node, Object *obj, Mesh& mesh, Matrix3& tm, HavokMaterial mtlDefault); + + bhkShapeRef makeModifierShape(INode *node, Object* obj, Modifier* mod, Matrix3& tm, HavokMaterial mtlDefault); + bhkShapeRef makeModBoxShape(INode *node, Modifier* mod, Mesh& mesh, Matrix3& tm, HavokMaterial mtlDefault); + bhkShapeRef makeModSphereShape(INode *node, Modifier* mod, Mesh& mesh, Matrix3& tm, HavokMaterial mtlDefault); + bhkShapeRef makeModCapsuleShape(INode *node, Modifier* mod, Mesh& mesh, Matrix3& tm, HavokMaterial mtlDefault); + bhkShapeRef makeModConvexShape(INode *node, Modifier* mod, Mesh& mesh, Matrix3& tm, HavokMaterial mtlDefault); + bhkShapeRef makeModTriStripShape(INode *node, Modifier* mod, Mesh& mesh, Matrix3& tm, HavokMaterial mtlDefault); + bhkShapeRef makeModPackedTriStripShape(INode *node, Modifier* mod, Mesh& mesh, Matrix3& tm, HavokMaterial mtlDefault); + bhkShapeRef makeModPackedTriStripShape(INode *tnode, Matrix3& tm, HavokMaterial mtlDefault); + bhkShapeRef makeModPackedTriStripShape(INodeTab &map, Matrix3& tm, HavokMaterial mtlDefault); /* skin export */ bool makeSkin(NiTriBasedGeomRef shape, INode *node, FaceGroup &grp, TimeValue t); diff --git a/NifProps/NifStrings.h b/NifProps/NifStrings.h index a3e5cd4..af25ab8 100755 --- a/NifProps/NifStrings.h +++ b/NifProps/NifStrings.h @@ -98,28 +98,30 @@ static const char *NpHvkLayerNames[] = static const char *NpHvkMotionSystems[] = { - "Keyframed", - "Box (2)", - "Sphere (2)", - "Sphere (3)", - "Box (4)", - "Box (5)", - "Keyframed (6)", - "Keyframed (7)", - "Box", - "Keyframed?", + "0: Invalid", + "1: Dynamic", + "2: Sphere", + "3: Sphere Inertia", + "4: Box", + "5: Box Stabilized", + "6: Keyframed", + "7: Fixed", + "8: Thin Box", + "9: Character", NULL }; static const char *NpHvkQualityTypes[] = { - "Moving", - "Fixed", - "Keyframed", - "Moving(?)", - "Critical", - "Bullet", - "User", - "Null", + "0: Invalid", + "1: Fixed", + "2: Keyframed", + "3: Debris", + "4: Moving" + "5: Critical", + "6: Bullet", + "7: User", + "8: Character", + "9: Keyframed Report", NULL }; diff --git a/NifProps/bhkBoxObj.cpp b/NifProps/bhkBoxObj.cpp index 2b58585..cced893 100644 --- a/NifProps/bhkBoxObj.cpp +++ b/NifProps/bhkBoxObj.cpp @@ -123,7 +123,7 @@ static ParamBlockDesc2 param_blk ( // params PB_MATERIAL, _T("material"), TYPE_INT, P_ANIMATABLE, IDS_DS_MATERIAL, - p_default, NP_DEFAULT_HVK_MATERIAL, + p_default, NP_INVALID_HVK_MATERIAL, end, PB_LENGTH, _T("length"), TYPE_FLOAT, P_ANIMATABLE, IDS_DS_LENGTH, @@ -183,35 +183,35 @@ void BoxParamDlgProc::Update(TimeValue t) INT_PTR BoxParamDlgProc::DlgProc(TimeValue t,IParamMap2 *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) { - thishWnd=hWnd; - switch (msg) - { - case WM_INITDIALOG: - { - mCbMaterial.init(GetDlgItem(hWnd, IDC_CB_MATERIAL)); - for (const char **str = NpHvkMaterialNames; *str; ++str) - mCbMaterial.add(*str); - - int sel = NP_DEFAULT_HVK_MATERIAL; - Interval valid; - so->pblock2->GetValue( PB_MATERIAL, 0, sel, valid); - mCbMaterial.select( sel ); - - Update(t); - break; - } - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDC_CB_MATERIAL: - if (HIWORD(wParam)==CBN_SELCHANGE) { - so->pblock2->SetValue( PB_MATERIAL, 0, mCbMaterial.selection() ); - } - break; - } - break; - } - return FALSE; + thishWnd=hWnd; + switch (msg) + { + case WM_INITDIALOG: + { + mCbMaterial.init(GetDlgItem(hWnd, IDC_CB_MATERIAL)); + mCbMaterial.add("<Default>"); + for (const char **str = NpHvkMaterialNames; *str; ++str) + mCbMaterial.add(*str); + Interval valid; + int sel = NP_INVALID_HVK_MATERIAL; + so->pblock2->GetValue( PB_MATERIAL, 0, sel, valid); + mCbMaterial.select( sel + 1 ); + + Update(t); + break; + } + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_CB_MATERIAL: + if (HIWORD(wParam)==CBN_SELCHANGE) { + so->pblock2->SetValue( PB_MATERIAL, 0, mCbMaterial.selection() ); + } + break; + } + break; + } + return FALSE; } //--- Box methods ------------------------------- diff --git a/NifProps/bhkCapsuleObj.cpp b/NifProps/bhkCapsuleObj.cpp index 236334f..3c60eaf 100644 --- a/NifProps/bhkCapsuleObj.cpp +++ b/NifProps/bhkCapsuleObj.cpp @@ -199,14 +199,14 @@ INT_PTR CapsuleParamDlgProc::DlgProc(TimeValue t,IParamMap2 *map,HWND hWnd,UINT { case WM_INITDIALOG: { - mCbMaterial.init(GetDlgItem(hWnd, IDC_CB_MATERIAL)); - for (const char **str = NpHvkMaterialNames; *str; ++str) - mCbMaterial.add(*str); - - int sel = NP_DEFAULT_HVK_MATERIAL; - Interval valid; - so->pblock2->GetValue( PB_MATERIAL, 0, sel, valid); - mCbMaterial.select( sel ); + mCbMaterial.init(GetDlgItem(hWnd, IDC_CB_MATERIAL)); + mCbMaterial.add("<Default>"); + for (const char **str = NpHvkMaterialNames; *str; ++str) + mCbMaterial.add(*str); + Interval valid; + int sel = NP_INVALID_HVK_MATERIAL; + so->pblock2->GetValue( PB_MATERIAL, 0, sel, valid); + mCbMaterial.select( sel + 1 ); Update(t); break; diff --git a/NifProps/bhkListObj.cpp b/NifProps/bhkListObj.cpp index e0fa4cb..3933a65 100644 --- a/NifProps/bhkListObj.cpp +++ b/NifProps/bhkListObj.cpp @@ -294,14 +294,14 @@ INT_PTR ListParamDlgProc::DlgProc(TimeValue t,IParamMap2 *map,HWND hWnd,UINT msg { case WM_INITDIALOG: { - mCbMaterial.init(GetDlgItem(hWnd, IDC_CB_MATERIAL)); - for (const char **str = NpHvkMaterialNames; *str; ++str) - mCbMaterial.add(*str); - - int sel = NP_DEFAULT_HVK_MATERIAL; - Interval valid; - so->pblock2->GetValue( PB_MATERIAL, 0, sel, valid); - mCbMaterial.select( sel ); + mCbMaterial.init(GetDlgItem(hWnd, IDC_CB_MATERIAL)); + mCbMaterial.add("<Default>"); + for (const char **str = NpHvkMaterialNames; *str; ++str) + mCbMaterial.add(*str); + Interval valid; + int sel = NP_INVALID_HVK_MATERIAL; + so->pblock2->GetValue( PB_MATERIAL, 0, sel, valid); + mCbMaterial.select( sel + 1 ); Update(t); break; diff --git a/NifProps/bhkProxyObj.cpp b/NifProps/bhkProxyObj.cpp index 7243af2..6416bde 100644 --- a/NifProps/bhkProxyObj.cpp +++ b/NifProps/bhkProxyObj.cpp @@ -164,7 +164,7 @@ static ParamBlockDesc2 param_blk ( // params PB_MATERIAL, _T("material"), TYPE_INT, P_ANIMATABLE, IDS_DS_MATERIAL, - p_default, NP_DEFAULT_HVK_MATERIAL, + p_default, NP_INVALID_HVK_MATERIAL, end, PB_BOUND_TYPE, _T("boundType"), TYPE_INT, 0, IDS_BV_BOUNDING_TYPE, @@ -342,14 +342,14 @@ INT_PTR ProxyParamDlgProc::DlgProc(TimeValue t,IParamMap2 *map,HWND hWnd,UINT ms { case WM_INITDIALOG: { - mCbMaterial.init(GetDlgItem(hWnd, IDC_CB_MATERIAL)); - for (const char **str = NpHvkMaterialNames; *str; ++str) - mCbMaterial.add(*str); - - int sel = NP_DEFAULT_HVK_MATERIAL; - Interval valid; - so->pblock2->GetValue( PB_MATERIAL, 0, sel, valid); - mCbMaterial.select( sel ); + mCbMaterial.init(GetDlgItem(hWnd, IDC_CB_MATERIAL)); + mCbMaterial.add("<Default>"); + for (const char **str = NpHvkMaterialNames; *str; ++str) + mCbMaterial.add(*str); + Interval valid; + int sel = NP_INVALID_HVK_MATERIAL; + so->pblock2->GetValue( PB_MATERIAL, 0, sel, valid); + mCbMaterial.select( sel + 1 ); // Disable all types not currently implemented EnableWindow(GetDlgItem(hWnd, IDC_RDO_CAPSULE), FALSE); EnableWindow(GetDlgItem(hWnd, IDC_RDO_PACKED_STRIPS), FALSE); diff --git a/NifProps/bhkRigidBodyModifer.cpp b/NifProps/bhkRigidBodyModifer.cpp index 6fb29ab..80f5cd3 100644 --- a/NifProps/bhkRigidBodyModifer.cpp +++ b/NifProps/bhkRigidBodyModifer.cpp @@ -188,7 +188,7 @@ static ParamBlockDesc2 havok_param_blk ( 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, + p_default, NP_INVALID_HVK_MATERIAL, end, PB_BOUND_TYPE, _T("boundType"), TYPE_INT, 0, IDS_BV_BOUNDING_TYPE, @@ -262,13 +262,13 @@ INT_PTR bhkRigidBodyModifierDlgProc::DlgProc (TimeValue t,IParamMap2 *map,HWND h case WM_INITDIALOG: { mCbMaterial.init(GetDlgItem(hWnd, IDC_CB_MATERIAL)); + mCbMaterial.add("<Default>"); for (const char **str = NpHvkMaterialNames; *str; ++str) mCbMaterial.add(*str); - - int sel = NP_DEFAULT_HVK_MATERIAL; Interval valid; + int sel = NP_INVALID_HVK_MATERIAL; mod->pblock->GetValue( PB_MATERIAL, 0, sel, valid); - mCbMaterial.select( sel ); + mCbMaterial.select( sel + 1 ); #if defined(USES_WILDMAGIC) && !defined(_M_X64) EnableWindow(GetDlgItem(hWnd, IDC_RDO_CAPSULE), FALSE); @@ -285,7 +285,7 @@ INT_PTR bhkRigidBodyModifierDlgProc::DlgProc (TimeValue t,IParamMap2 *map,HWND h { case IDC_CB_MATERIAL: if (HIWORD(wParam)==CBN_SELCHANGE) { - mod->pblock->SetValue( PB_MATERIAL, 0, mCbMaterial.selection() ); + mod->pblock->SetValue( PB_MATERIAL, 0, mCbMaterial.selection() - 1 ); } break; diff --git a/NifProps/bhkSphereObj.cpp b/NifProps/bhkSphereObj.cpp index f2a5d1e..2a1c6ca 100644 --- a/NifProps/bhkSphereObj.cpp +++ b/NifProps/bhkSphereObj.cpp @@ -142,7 +142,7 @@ static ParamBlockDesc2 param_blk ( // params PB_MATERIAL, _T("material"), TYPE_INT, P_ANIMATABLE, IDS_DS_MATERIAL, - p_default, NP_DEFAULT_HVK_MATERIAL, + p_default, NP_INVALID_HVK_MATERIAL, end, PB_RADIUS, _T("radius"), TYPE_FLOAT, P_ANIMATABLE, IDS_RB_RADIUS, @@ -207,14 +207,14 @@ INT_PTR SphereParamDlgProc::DlgProc(TimeValue t,IParamMap2 *map,HWND hWnd,UINT m { case WM_INITDIALOG: { - mCbMaterial.init(GetDlgItem(hWnd, IDC_CB_MATERIAL)); - for (const char **str = NpHvkMaterialNames; *str; ++str) - mCbMaterial.add(*str); - - int sel = NP_DEFAULT_HVK_MATERIAL; - Interval valid; - so->pblock2->GetValue( PB_MATERIAL, 0, sel, valid); - mCbMaterial.select( sel ); + mCbMaterial.init(GetDlgItem(hWnd, IDC_CB_MATERIAL)); + mCbMaterial.add("<Default>"); + for (const char **str = NpHvkMaterialNames; *str; ++str) + mCbMaterial.add(*str); + Interval valid; + int sel = NP_INVALID_HVK_MATERIAL; + so->pblock2->GetValue( PB_MATERIAL, 0, sel, valid); + mCbMaterial.select( sel + 1 ); Update(t); break; -- GitLab