diff --git a/MaxNifPlugins_Readme.txt b/MaxNifPlugins_Readme.txt index 856575961a891c5f729f1d6cc9226b3371eff47a..f6b2a49d058fc408a191e43b2dd487e756938f7c 100644 --- a/MaxNifPlugins_Readme.txt +++ b/MaxNifPlugins_Readme.txt @@ -37,7 +37,24 @@ ----- o Importer/Exporter - Improved Bridge Commander support. - - Added more Collision support (bhkRigidBodyModifier, bhkCollisionShape) + - Added more Collision support + + Modifiers + * bhkRigidBody - Modifier + This is a modifier which converts a mesh into a collision mesh + and is a replacement for the Utility. + + + Helper Objects (Find under Create | Helper | NifTools) + * bhkRigidBody + Rigid Body reference object. Place all havok objects in this object. + * bhkBox + Primitive for a Havok Box + * bhkSphere + Primitive for a Havok Sphere + * bhkCapsule + Primitive for a Havok Capsule + * bhkCollProxy + Makes a collision object from an existing set of objects but does not make the root + objects collision objects. 0.2.12 ----- diff --git a/NifCommon/NifQHull.cpp b/NifCommon/NifQHull.cpp index 354fe195a58863de5ea07ed60caadc67d80a9b21..ff47ff9a9471b04d104ffdf9813aebe10165d456 100644 --- a/NifCommon/NifQHull.cpp +++ b/NifCommon/NifQHull.cpp @@ -156,6 +156,7 @@ void compute_convex_hull(Mesh& mesh, Mesh& outmesh) delete[] points; mn.MakeConvex(); + mn.FillInMesh(); mn.EliminateBadVerts(0); mn.Triangulate(); mn.OutToTri(outmesh); diff --git a/NifCommon/niutils.cpp b/NifCommon/niutils.cpp index 7326a6961bed3dcd9e46c2db51873ad44170d70c..ff3669fed663afc4137b295cf9a0c540eae0d8e0 100644 --- a/NifCommon/niutils.cpp +++ b/NifCommon/niutils.cpp @@ -1168,4 +1168,20 @@ Modifier *CreatebhkCollisionModifier(INode* node, int type, HavokMaterial materi TSTR GetNodeName(INode* node) { return node->GetName(); +} + +Matrix3 GetLocalTM(INode *node) +{ + if (INode *parent = node->GetParentNode()) + { + Matrix3 parentTM, nodeTM; + nodeTM = node->GetNodeTM(0); + parent = node->GetParentNode(); + parentTM = parent->GetNodeTM(0); + return nodeTM*Inverse(parentTM); + } + else + { + return node->GetNodeTM(0); + } } \ No newline at end of file diff --git a/NifCommon/niutils.h b/NifCommon/niutils.h index f9b4e2754e9c0d1cdd240bb67f84903c2c858080..93e53bc2f7f4f16237cf1687babbfaae11a4fb97 100644 --- a/NifCommon/niutils.h +++ b/NifCommon/niutils.h @@ -428,4 +428,6 @@ Modifier *CreatebhkCollisionModifier(INode* node, int type, Niflib::HavokMateria void GetIniFileName(char *iniName); +Matrix3 GetLocalTM(INode *node); + #endif // _NIUTILS_H_ \ No newline at end of file diff --git a/NifExport/Coll.cpp b/NifExport/Coll.cpp index e007f43e6c5aa572242a359f2c8b35fe79358a41..fab3f73afcb41556763d933f94c40e6ac8713679 100755 --- a/NifExport/Coll.cpp +++ b/NifExport/Coll.cpp @@ -2,6 +2,11 @@ #include "../NifProps/bhkRigidBodyInterface.h" #include "obj/bhkListShape.h" #include "obj/bhkConvexVerticesShape.h" +#include "obj/bhkTransformShape.h" +#include "obj/bhkSphereShape.h" +#include "obj/bhkBoxShape.h" +#include "obj/bhkCapsuleShape.h" + #include "..\NifProps\bhkHelperFuncs.h" #include "..\NifProps\bhkHelperInterface.h" @@ -427,10 +432,12 @@ bhkShapeRef Exporter::makeBoxShape(INode *node, Object *obj, Matrix3& tm) float length = 0; float height = 0; float width = 0; - IParamArray *params = obj->GetParamBlock(); - params->GetValue(obj->GetParamBlockIndex(BOXOBJ_LENGTH), 0, length, FOREVER); - params->GetValue(obj->GetParamBlockIndex(BOXOBJ_HEIGHT), 0, height, FOREVER); - params->GetValue(obj->GetParamBlockIndex(BOXOBJ_WIDTH), 0, width, FOREVER); + if (IParamBlock2* pblock2 = obj->GetParamBlockByID(0)) + { + pblock2->GetValue(BOXOBJ_LENGTH, 0, length, FOREVER); + pblock2->GetValue(BOXOBJ_HEIGHT, 0, height, FOREVER); + pblock2->GetValue(BOXOBJ_WIDTH, 0, width, FOREVER); + } bhkBoxShapeRef box = new bhkBoxShape(); Vector3 dim(width * scale[0], length * scale[1], height * scale[2]); @@ -454,8 +461,10 @@ bhkShapeRef Exporter::makeSphereShape(INode *node, Object *obj, Matrix3& tm) float s = (scale[0] + scale[1] + scale[2]) / 3.0; float radius = 0; - IParamArray *params = obj->GetParamBlock(); - params->GetValue(obj->GetParamBlockIndex(SPHERE_RADIUS), 0, radius, FOREVER); + if (IParamBlock2* pblock2 = obj->GetParamBlockByID(0)) + { + pblock2->GetValue(SPHERE_RADIUS, 0, radius, FOREVER); + } bhkSphereShapeRef sphere = new bhkSphereShape(); sphere->SetRadius(radius * s); @@ -504,24 +513,38 @@ bhkShapeRef Exporter::makebhkBoxShape(INode *node, Object *obj, Matrix3& tm) Point3 scale = GetScale(tm); float s = (scale[0] + scale[1] + scale[2]) / 3.0; - int mtl = 0, length = 0, width = 0, height = 0; + int mtl = 0; + float length = 0, width = 0, height = 0; pblock2->GetValue(PB_MATERIAL, 0, mtl, FOREVER, 0); pblock2->GetValue(PB_LENGTH, 0, length, FOREVER, 0); pblock2->GetValue(PB_WIDTH, 0, width, FOREVER, 0); pblock2->GetValue(PB_HEIGHT, 0, height, FOREVER, 0); - bhkBoxShapeRef box = new bhkBoxShape(); + Vector3 dim(width * scale[0], length * scale[1], height * scale[2]); // Adjust translation for center of z axis in box tm.Translate(Point3(0.0, 0.0, dim.z / 2.0)); - dim /= (Exporter::bhkScaleFactor * 2); + //dim /= (Exporter::bhkScaleFactor * 2); box->SetDimensions(dim); box->SetMaterial(HavokMaterial(mtl)); - retval = StaticCast<bhkShape>(box); + + Matrix3 tm = GetLocalTM(node); + if (tm.IsIdentity()) + { + retval = StaticCast<bhkShape>(box); + } + else + { + bhkTransformShapeRef transform = new bhkTransformShape(); + transform->SetTransform(TOMATRIX4(tm).Transpose()); + transform->SetShape(box); + transform->SetMaterial(HavokMaterial(mtl)); + retval = StaticCast<bhkShape>(transform); + } } return retval; @@ -531,6 +554,34 @@ bhkShapeRef Exporter::makebhkSphereShape(INode *node, Object *obj, Matrix3& tm) { bhkShapeRef retval; + enum { sphere_params, }; + enum { PB_MATERIAL, PB_RADIUS, PB_SEGS, PB_SMOOTH, }; + + if (IParamBlock2* pblock2 = obj->GetParamBlockByID(sphere_params)) + { + float radius = 0.0f; + int mtl = NP_DEFAULT_HVK_MATERIAL; + pblock2->GetValue(PB_RADIUS, 0, radius, FOREVER, 0); + pblock2->GetValue(PB_MATERIAL, 0, mtl, FOREVER, 0); + + bhkSphereShapeRef shape = new bhkSphereShape(); + shape->SetRadius(radius); + shape->SetMaterial(HavokMaterial(mtl)); + + Matrix3 tm = GetLocalTM(node); + if (tm.IsIdentity()) + { + retval = StaticCast<bhkShape>(shape); + } + else + { + bhkTransformShapeRef transform = new bhkTransformShape(); + transform->SetTransform(TOMATRIX4(tm).Transpose()); + transform->SetShape(shape); + transform->SetMaterial(HavokMaterial(mtl)); + retval = StaticCast<bhkShape>(transform); + } + } return retval; } @@ -538,6 +589,40 @@ bhkShapeRef Exporter::makebhkCapsuleShape(INode *node, Object *obj, Matrix3& tm) { bhkShapeRef retval; + enum { cap_params, }; + enum { PB_MATERIAL, PB_RADIUS1, PB_RADIUS2, PB_LENGTH, }; + + if (IParamBlock2* pblock2 = obj->GetParamBlockByID(cap_params)) + { + float radius1 = 0.0f, radius2 = 0.0f, len = 0.0f; + int mtl = NP_DEFAULT_HVK_MATERIAL; + 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); + + bhkCapsuleShapeRef shape = new bhkCapsuleShape(); + shape->SetRadius((radius1 + radius2)/2.0f); + shape->SetRadius1(radius1); + shape->SetRadius2(radius2); + shape->SetMaterial(HavokMaterial(mtl)); + + Matrix3 tm = GetLocalTM(node); + Point3 center = tm.GetTrans(); + + Matrix3 rot = tm; + rot.NoTrans(); + rot.NoScale(); + + float distFromCenter = len*Exporter::bhkScaleFactor/2.0f; + + Point3 pt1 = ((TransMatrix(Point3(0.0f, 0.0f, +distFromCenter)) * rot).GetTrans() + center) / Exporter::bhkScaleFactor; + Point3 pt2 = ((TransMatrix(Point3(0.0f, 0.0f, -distFromCenter)) * rot).GetTrans() + center) / Exporter::bhkScaleFactor; + shape->SetFirstPoint(TOVECTOR3(pt1)); + shape->SetSecondPoint(TOVECTOR3(pt2)); + + retval = StaticCast<bhkShape>(shape); + } return retval; } @@ -754,20 +839,20 @@ bhkShapeRef Exporter::makeProxyShape(INode *node, Object *obj, Matrix3& tm) switch (bvType) { case bv_type_box: + shape = makeProxyBoxShape(node, obj, mesh, tm); break; + //case bv_type_sphere: + // shape = makeProxySphereShape(node, obj, mesh, tm); + // break; + case bv_type_shapes: case bv_type_packed: + shape = makeProxyTriStripShape(node, obj, mesh, tm); break; case bv_type_convex: - Matrix3 tm(true); - if (bhkConvexVerticesShapeRef convShape = makeConvexShape(mesh, tm)) - { - int mtl = pblock2->GetInt(PB_MATERIAL, 0, 0); - convShape->SetMaterial(HavokMaterial(mtl)); - shape = StaticCast<bhkShape>(convShape); - } + shape = makeProxyConvexShape(node, obj, mesh, tm); break; } } @@ -776,6 +861,121 @@ bhkShapeRef Exporter::makeProxyShape(INode *node, Object *obj, Matrix3& tm) return shape; } +bhkShapeRef Exporter::makeProxyBoxShape(INode *node, Object *obj, Mesh& mesh, Matrix3& tm) +{ + enum { list_params, bv_mesh, }; // pblock2 ID + enum { PB_MATERIAL, PB_MESHLIST, PB_BOUND_TYPE, PB_CENTER, }; + enum { bv_type_none, bv_type_box, bv_type_shapes, bv_type_packed, bv_type_convex, }; // pblock ID + + bhkShapeRef retval; + if (IParamBlock2* pblock2 = obj->GetParamBlockByID(list_params)) + { + Box3 box; box.Init(); + CalcAxisAlignedBox(mesh, box, NULL); + + int mtl = 0; + float length = 0, width = 0, height = 0; + pblock2->GetValue(PB_MATERIAL, 0, mtl, FOREVER, 0); + + 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->SetDimensions(dim); + + Matrix3 tm = /*GetLocalTM(node) * */TransMatrix(box.Center()/Exporter::bhkScaleFactor); + if (tm.IsIdentity()) + { + retval = StaticCast<bhkShape>(shape); + } + else + { + bhkTransformShapeRef transform = new bhkTransformShape(); + transform->SetTransform(TOMATRIX4(tm).Transpose()); + transform->SetShape(shape); + transform->SetMaterial(HavokMaterial(mtl)); + retval = StaticCast<bhkShape>(transform); + } + } + return retval; +} + +bhkShapeRef Exporter::makeProxySphereShape(INode *node, Object *obj, Mesh& mesh, Matrix3& tm) +{ + enum { list_params, bv_mesh, }; // pblock2 ID + enum { PB_MATERIAL, PB_MESHLIST, PB_BOUND_TYPE, PB_CENTER, }; + enum { bv_type_none, bv_type_box, bv_type_shapes, bv_type_packed, bv_type_convex, }; // pblock ID + + bhkShapeRef shape; + if (IParamBlock2* pblock2 = obj->GetParamBlockByID(list_params)) + { + //Matrix3 tm = GetLocalTM(node) * TransMatrix(box.Center()); + + } + return shape; +} + +bhkShapeRef Exporter::makeProxyConvexShape(INode *node, Object *obj, Mesh& mesh, Matrix3& tm) +{ + enum { list_params, bv_mesh, }; // pblock2 ID + enum { PB_MATERIAL, PB_MESHLIST, PB_BOUND_TYPE, PB_CENTER, }; + enum { bv_type_none, bv_type_box, bv_type_shapes, bv_type_packed, bv_type_convex, }; // pblock ID + + bhkShapeRef shape; + if (IParamBlock2* pblock2 = obj->GetParamBlockByID(list_params)) + { + Matrix3 tm(true); + if (bhkConvexVerticesShapeRef convShape = makeConvexShape(mesh, tm)) + { + int mtl = pblock2->GetInt(PB_MATERIAL, 0, 0); + convShape->SetMaterial(HavokMaterial(mtl)); + shape = StaticCast<bhkShape>(convShape); + } + } + return shape; +} + +bhkShapeRef Exporter::makeProxyTriStripShape(INode *node, Object *obj, Mesh& mesh, Matrix3& tm) +{ + enum { list_params, bv_mesh, }; // pblock2 ID + enum { PB_MATERIAL, PB_MESHLIST, PB_BOUND_TYPE, PB_CENTER, }; + enum { bv_type_none, bv_type_box, bv_type_shapes, bv_type_packed, bv_type_convex, }; // pblock ID + + bhkShapeRef shape; + if (IParamBlock2* pblock2 = obj->GetParamBlockByID(list_params)) + { + int mtl = pblock2->GetInt(PB_MATERIAL, 0, 0); + + Matrix3 ident(true); + bhkNiTriStripsShapeRef trishape = makeTriStripsShape(mesh, ident); + trishape->SetMaterial(HavokMaterial(mtl)); + + shape = StaticCast<bhkShape>(trishape); + } + return shape; +} + +bhkShapeRef Exporter::makeProxyPackedTriStripShape(INode *node, Object *obj, Mesh& mesh, Matrix3& tm) +{ + enum { list_params, bv_mesh, }; // pblock2 ID + enum { PB_MATERIAL, PB_MESHLIST, PB_BOUND_TYPE, PB_CENTER, }; + enum { bv_type_none, bv_type_box, bv_type_shapes, bv_type_packed, bv_type_convex, }; // pblock ID + + bhkShapeRef shape; + if (IParamBlock2* pblock2 = obj->GetParamBlockByID(list_params)) + { + int mtl = pblock2->GetInt(PB_MATERIAL, 0, 0); + + Matrix3 ident(true); + bhkNiTriStripsShapeRef trishape = makeTriStripsShape(mesh, ident); + trishape->SetMaterial(HavokMaterial(mtl)); + + shape = StaticCast<bhkShape>(trishape); + } + return shape; +} + bhkShapeRef Exporter::makeModifierShape(INode *node, Object* obj, Modifier* mod, Matrix3& tm) { enum { havok_params }; @@ -811,32 +1011,193 @@ bhkShapeRef Exporter::makeModifierShape(INode *node, Object* obj, Modifier* mod, break; case bv_type_box: - shape = makeBoxShape(node, obj, tm); + shape = makeModBoxShape(node, mod, const_cast<Mesh&>(*mesh), tm); break; case bv_type_sphere: - shape = makeSphereShape(node, obj, tm); + shape = makeModSphereShape(node, mod, const_cast<Mesh&>(*mesh), tm); break; case bv_type_capsule: - shape = makeCapsuleShape(node, obj, tm); + shape = makeModCapsuleShape(node, mod, const_cast<Mesh&>(*mesh), tm); break; case bv_type_shapes: - if (bhkNiTriStripsShapeRef trishape = makeTriStripsShape(const_cast<Mesh&>(*mesh), tm)) - { - trishape->SetMaterial(HavokMaterial(material)); - shape = StaticCast<bhkShape>(trishape); - } + shape = makeModTriStripShape(node, mod, const_cast<Mesh&>(*mesh), tm); break; case bv_type_convex: - if (bhkConvexVerticesShapeRef convShape = makeConvexShape(const_cast<Mesh&>(*mesh), tm)) + shape = makeModConvexShape(node, mod, const_cast<Mesh&>(*mesh), tm); + break; + } + return shape; +} + +bhkShapeRef Exporter::makeModBoxShape(INode *node, Modifier* mod, Mesh& mesh, Matrix3& tm) +{ + 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, }; // pblock ID + int material = NP_DEFAULT_HVK_MATERIAL; + + if (IParamBlock2* pblock2 = mod->GetParamBlockByID(havok_params)) + { + pblock2->GetValue(PB_MATERIAL, 0, material, FOREVER, 0); + } + + bhkShapeRef retval; + if (bhkBoxShapeRef shape = new bhkBoxShape()) + { + Box3 box; box.Init(); + CalcAxisAlignedBox(mesh, box, NULL); + + 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)); + + Matrix3 tm = /*GetLocalTM(node) * */TransMatrix(box.Center()/Exporter::bhkScaleFactor); + if (tm.IsIdentity()) { - convShape->SetMaterial(HavokMaterial(material)); - shape = StaticCast<bhkShape>(convShape); + retval = StaticCast<bhkShape>(shape); + } + else + { + bhkTransformShapeRef transform = new bhkTransformShape(); + transform->SetTransform(TOMATRIX4(tm).Transpose()); + transform->SetShape(shape); + transform->SetMaterial(HavokMaterial(material)); + retval = StaticCast<bhkShape>(transform); + } + } + return retval; +} + +bhkShapeRef Exporter::makeModSphereShape(INode *node, Modifier* mod, Mesh& mesh, Matrix3& tm) +{ + 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, }; // pblock ID + int material = NP_DEFAULT_HVK_MATERIAL; + + if (IParamBlock2* pblock2 = mod->GetParamBlockByID(havok_params)) + { + pblock2->GetValue(PB_MATERIAL, 0, material, FOREVER, 0); + } + + bhkShapeRef retval; + + Point3 center = Point3::Origin; + float radius = 0.0f; + CalcCenteredSphere(mesh, center, radius); + + if (bhkSphereShapeRef shape = new bhkSphereShape()) + { + shape->SetRadius(radius / Exporter::bhkScaleFactor); + shape->SetMaterial(HavokMaterial(material)); + + Matrix3 tm = /*GetLocalTM(node) * */TransMatrix(center/Exporter::bhkScaleFactor); + if (tm.IsIdentity()) + { + retval = StaticCast<bhkShape>(shape); + } + else + { + bhkTransformShapeRef transform = new bhkTransformShape(); + transform->SetTransform(TOMATRIX4(tm).Transpose()); + transform->SetShape(shape); + transform->SetMaterial(HavokMaterial(material)); + retval = StaticCast<bhkShape>(transform); } - break; + } + return retval; +} + +bhkShapeRef Exporter::makeModCapsuleShape(INode *node, Modifier* mod, Mesh& mesh, Matrix3& tm) +{ + 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, }; // pblock ID + int material = NP_DEFAULT_HVK_MATERIAL; + + if (IParamBlock2* pblock2 = mod->GetParamBlockByID(havok_params)) + { + pblock2->GetValue(PB_MATERIAL, 0, material, FOREVER, 0); + } + + bhkShapeRef retval; + + Point3 center = Point3::Origin; + float radius = 0.0f; + CalcCenteredSphere(mesh, center, radius); + + if (bhkCapsuleShapeRef shape = new bhkCapsuleShape()) + { + shape->SetRadius(radius / Exporter::bhkScaleFactor); + shape->SetRadius1(radius / Exporter::bhkScaleFactor); + shape->SetRadius2(radius / Exporter::bhkScaleFactor); + shape->SetFirstPoint(TOVECTOR3(center/Exporter::bhkScaleFactor)); + shape->SetSecondPoint(TOVECTOR3(center/Exporter::bhkScaleFactor)); + shape->SetMaterial(HavokMaterial(material)); + + Matrix3 tm = /*GetLocalTM(node) * */TransMatrix(center/Exporter::bhkScaleFactor); + if (tm.IsIdentity()) + { + retval = StaticCast<bhkShape>(shape); + } + else + { + bhkTransformShapeRef transform = new bhkTransformShape(); + transform->SetTransform(TOMATRIX4(tm).Transpose()); + transform->SetShape(shape); + transform->SetMaterial(HavokMaterial(material)); + retval = StaticCast<bhkShape>(transform); + } + } + return retval; +} + +bhkShapeRef Exporter::makeModConvexShape(INode *node, Modifier* mod, Mesh& mesh, Matrix3& tm) +{ + 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, }; // pblock ID + int material = NP_DEFAULT_HVK_MATERIAL; + + bhkShapeRef shape; + if (bhkConvexVerticesShapeRef convShape = makeConvexShape(mesh, tm)) + { + if (IParamBlock2* pblock2 = mod->GetParamBlockByID(havok_params)) + { + pblock2->GetValue(PB_MATERIAL, 0, material, FOREVER, 0); + } + convShape->SetMaterial(HavokMaterial(material)); + shape = StaticCast<bhkShape>(convShape); + } + return shape; +} + +bhkShapeRef Exporter::makeModTriStripShape(INode *node, Modifier* mod, Mesh& mesh, Matrix3& tm) +{ + 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, }; // pblock ID + int material = NP_DEFAULT_HVK_MATERIAL; + + bhkShapeRef shape; + if (bhkNiTriStripsShapeRef trishape = makeTriStripsShape(mesh, tm)) + { + 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; -} \ No newline at end of file +} + +bhkShapeRef Exporter::makeModPackedTriStripShape(INode *node, Modifier* mod, Mesh& mesh, Matrix3& tm) +{ + return makeModTriStripShape(node, mod, mesh, tm); +} diff --git a/NifExport/Exporter.h b/NifExport/Exporter.h index 1f2c12d6984d72766c7cd3a0360c19c2c52f4008..7b103da49b0d8f881ecd048430aabce20c99f38c 100755 --- a/NifExport/Exporter.h +++ b/NifExport/Exporter.h @@ -238,13 +238,26 @@ public: 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 makeProxyShape(INode *node, Object *obj, Matrix3& tm); bhkShapeRef makeConvexShape(INode *node, Object* obj, Matrix3& tm); - bhkShapeRef makeModifierShape(INode *node, Object* obj, Modifier* mod, Matrix3& tm); Ref<bhkConvexVerticesShape> makeConvexShape(Mesh& mesh, Matrix3& tm); Ref<bhkNiTriStripsShape> makeTriStripsShape(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); + /* skin export */ bool makeSkin(NiTriBasedGeomRef shape, INode *node, FaceGroup &grp, TimeValue t); bool exportSkin(); diff --git a/NifImport/ImportCollision.cpp b/NifImport/ImportCollision.cpp index f6078597613a7702083d1f177c045c7764b575cf..d36cc4d10ff97a5593a3393f230446e6e5fb5386 100644 --- a/NifImport/ImportCollision.cpp +++ b/NifImport/ImportCollision.cpp @@ -23,6 +23,7 @@ HISTORY: #include "obj\bhkPackedNiTriStripsShape.h" #include "obj\hkPackedNiTriStripsData.h" #include "obj\bhkListShape.h" +#include "obj\bhkTransformShape.h" #include "..\NifProps\bhkRigidBodyInterface.h" #include "NifPlugins.h" @@ -30,6 +31,9 @@ using namespace Niflib; extern Class_ID BHKLISTOBJECT_CLASS_ID; extern Class_ID BHKRIGIDBODYMODIFIER_CLASS_ID; +extern Class_ID bhkBoxObject_CLASS_ID; +extern Class_ID BHKCAPSULEOBJECT_CLASS_ID; +extern Class_ID bhkSphereObject_CLASS_ID; static Class_ID SCUBA_CLASS_ID(0x6d3d77ac, 0x79c939a9); enum @@ -50,16 +54,17 @@ struct CollisionImport bool ImportRigidBody(bhkRigidBodyRef rb, INode* node); INode *CreateRigidBody(bhkRigidBodyRef body, INode* parent); - bool ImportBase(bhkRigidBodyRef body, bhkShapeRef shape, INode* parent, INode *shapeNode); - bool ImportShape(INode *rbody, bhkRigidBodyRef body, bhkShapeRef shape, INode* parent); - bool ImportBox(INode *rbody, bhkRigidBodyRef body, bhkBoxShapeRef shape, INode *parent); - bool ImportSphere(INode *rbody, bhkRigidBodyRef body, bhkSphereShapeRef shape, INode *parent); - bool ImportCapsule(INode *rbody, bhkRigidBodyRef body, bhkCapsuleShapeRef shape, INode *parent); - bool ImportConvexVertices(INode *rbody, bhkRigidBodyRef body, bhkConvexVerticesShapeRef shape, INode *parent); - bool ImportTriStripsShape(INode *rbody, bhkRigidBodyRef body, bhkNiTriStripsShapeRef shape, INode *parent); - bool ImportMoppBvTreeShape(INode *rbody, bhkRigidBodyRef body, bhkMoppBvTreeShapeRef shape, INode *parent); - bool ImportPackedNiTriStripsShape(INode *rbody, bhkRigidBodyRef body, bhkPackedNiTriStripsShapeRef shape, INode *parent); - bool ImportListShape(INode *rbody, bhkRigidBodyRef body, bhkListShapeRef shape, INode *parent); + bool ImportBase(bhkRigidBodyRef body, bhkShapeRef shape, INode* parent, INode *shapeNode, Matrix3& tm); + bool ImportShape(INode *rbody, bhkRigidBodyRef body, bhkShapeRef shape, INode* parent, Matrix3& tm); + bool ImportBox(INode *rbody, bhkRigidBodyRef body, bhkBoxShapeRef shape, INode *parent, Matrix3& tm); + bool ImportSphere(INode *rbody, bhkRigidBodyRef body, bhkSphereShapeRef shape, INode *parent, Matrix3& tm); + bool ImportCapsule(INode *rbody, bhkRigidBodyRef body, bhkCapsuleShapeRef shape, INode *parent, Matrix3& tm); + bool ImportConvexVertices(INode *rbody, bhkRigidBodyRef body, bhkConvexVerticesShapeRef shape, INode *parent, Matrix3& tm); + bool ImportTriStripsShape(INode *rbody, bhkRigidBodyRef body, bhkNiTriStripsShapeRef shape, INode *parent, Matrix3& tm); + bool ImportMoppBvTreeShape(INode *rbody, bhkRigidBodyRef body, bhkMoppBvTreeShapeRef shape, INode *parent, Matrix3& tm); + bool ImportPackedNiTriStripsShape(INode *rbody, bhkRigidBodyRef body, bhkPackedNiTriStripsShapeRef shape, INode *parent, Matrix3& tm); + bool ImportListShape(INode *rbody, bhkRigidBodyRef body, bhkListShapeRef shape, INode *parent, Matrix3& tm); + bool ImportTransform(INode *rbody, bhkRigidBodyRef body, bhkTransformShapeRef shape, INode *parent, Matrix3& tm); INode* ImportCollisionMesh( const vector<Vector3>& verts, @@ -89,15 +94,19 @@ bool NifImporter::ImportCollision(NiNodeRef node) if (bhkShapeRef shape = rbody->GetShape()) { INode *node = NULL; NiNodeRef target = collObj->GetTarget(); - if (strmatch(target->GetName(), "Scene Root")) + if (mergeNonAccum && target && wildmatch("* NonAccum", target->GetName()) ) { + node = FindNode(target->GetParent()); + } else if (target && strmatch(target->GetName(), "Scene Root")) { node = gi->GetRootNode(); - else + } else { node = FindNode(target); + } CollisionImport ci(*this); if (INode *body = ci.CreateRigidBody(rbody, node)) { - if (!ci.ImportShape(body, rbody, shape, node)) + Matrix3 tm(true); + if (!ci.ImportShape(body, rbody, shape, node, tm)) { body->Delete(0, 1); } @@ -214,7 +223,7 @@ void CollisionImport::AddShape(INode *rbody, INode *shapeNode) } } -bool CollisionImport::ImportBase(bhkRigidBodyRef body, bhkShapeRef shape, INode* parent, INode *shapeNode) +bool CollisionImport::ImportBase(bhkRigidBodyRef body, bhkShapeRef shape, INode* parent, INode *shapeNode, Matrix3& tm) { // Now do common post processing for the node if (shapeNode != NULL) @@ -227,6 +236,12 @@ bool CollisionImport::ImportBase(bhkRigidBodyRef body, bhkShapeRef shape, INode* //Quat rot = TOQUAT(body->GetRotation()); //PosRotScaleNode(shapeNode, pos, rot, 1.0, prsDefault); + if (!tm.IsIdentity()) + { + Point3 pos = tm.GetTrans(); + Quat rot(tm); + PosRotScaleNode(shapeNode, pos, rot, 1.0, prsDefault); + } // Wireframe Red color StdMat2 *collMat = NewDefaultStdMat(); @@ -242,46 +257,51 @@ bool CollisionImport::ImportBase(bhkRigidBodyRef body, bhkShapeRef shape, INode* shapeNode->SetRenderable(FALSE); //shapeNode->XRayMtl(TRUE); shapeNode->SetWireColor( RGB(255,0,0) ); - parent->AttachChild(shapeNode); + if (parent) + parent->AttachChild(shapeNode); return true; } return false; } -bool CollisionImport::ImportShape(INode *rbody, bhkRigidBodyRef body, bhkShapeRef shape, INode* parent) +bool CollisionImport::ImportShape(INode *rbody, bhkRigidBodyRef body, bhkShapeRef shape, INode* parent, Matrix3& tm) { bool ok = false; if (shape->IsDerivedType(bhkBoxShape::TYPE)) { - ok |= ImportBox(rbody, body, bhkBoxShapeRef(shape), parent); + ok |= ImportBox(rbody, body, bhkBoxShapeRef(shape), parent, tm); } else if (shape->IsDerivedType(bhkCapsuleShape::TYPE)) { - ok |= ImportCapsule(rbody, body, bhkCapsuleShapeRef(shape), parent); + ok |= ImportCapsule(rbody, body, bhkCapsuleShapeRef(shape), parent, tm); } else if (shape->IsDerivedType(bhkSphereShape::TYPE)) { - ok |= ImportSphere(rbody, body, bhkSphereShapeRef(shape), parent); + ok |= ImportSphere(rbody, body, bhkSphereShapeRef(shape), parent, tm); } else if (shape->IsDerivedType(bhkConvexVerticesShape::TYPE)) { - ok |= ImportConvexVertices(rbody, body, bhkConvexVerticesShapeRef(shape), parent); + ok |= ImportConvexVertices(rbody, body, bhkConvexVerticesShapeRef(shape), parent, tm); } else if (shape->IsDerivedType(bhkNiTriStripsShape::TYPE)) { - ok |= ImportTriStripsShape(rbody, body, bhkNiTriStripsShapeRef(shape), parent); + ok |= ImportTriStripsShape(rbody, body, bhkNiTriStripsShapeRef(shape), parent, tm); } else if (shape->IsDerivedType(bhkMoppBvTreeShape::TYPE)) { - ok |= ImportMoppBvTreeShape(rbody, body, bhkMoppBvTreeShapeRef(shape), parent); + ok |= ImportMoppBvTreeShape(rbody, body, bhkMoppBvTreeShapeRef(shape), parent, tm); } else if (shape->IsDerivedType(bhkPackedNiTriStripsShape::TYPE)) { - ok |= ImportPackedNiTriStripsShape(rbody, body, bhkPackedNiTriStripsShapeRef(shape), parent); + ok |= ImportPackedNiTriStripsShape(rbody, body, bhkPackedNiTriStripsShapeRef(shape), parent, tm); } else if (shape->IsDerivedType(bhkListShape::TYPE)) { - ok |= ImportListShape(rbody, body, bhkListShapeRef(shape), parent); + ok |= ImportListShape(rbody, body, bhkListShapeRef(shape), parent, tm); + } + else if (shape->IsDerivedType(bhkTransformShape::TYPE)) + { + ok |= ImportTransform(rbody, body, bhkTransformShapeRef(shape), parent, tm); } return ok; } @@ -333,8 +353,32 @@ INode *CollisionImport::ImportCollisionMesh( return returnNode; } -bool CollisionImport::ImportSphere(INode *rbody, bhkRigidBodyRef body, bhkSphereShapeRef shape, INode *parent) +bool CollisionImport::ImportSphere(INode *rbody, bhkRigidBodyRef body, bhkSphereShapeRef shape, INode *parent, Matrix3& tm) { + bhkShapeRef retval; + + enum { sphere_params, }; + enum { PB_MATERIAL, PB_RADIUS, PB_SEGS, PB_SMOOTH, }; + + if (SimpleObject *obj = (SimpleObject *)ni.gi->CreateInstance(HELPER_CLASS_ID, bhkSphereObject_CLASS_ID)) { + + if (IParamBlock2* pblock2 = obj->GetParamBlockByID(sphere_params)) + { + float radius = shape->GetRadius(); + int mtl = shape->GetMaterial(); + + pblock2->SetValue(PB_RADIUS, 0, radius, 0); + pblock2->SetValue(PB_MATERIAL, 0, mtl, 0); + + if (INode *n = ni.CreateImportNode(shape->GetType().GetTypeName().c_str(), obj, parent)) { + ImportBase(body, shape, parent, n, tm); + AddShape(rbody, n); + return true; + } + } + } + +#if 0 if (SimpleObject *ob = (SimpleObject *)ni.gi->CreateInstance(GEOMOBJECT_CLASS_ID, Class_ID(SPHERE_CLASS_ID, 0))) { float radius = shape->GetRadius(); @@ -348,22 +392,82 @@ bool CollisionImport::ImportSphere(INode *rbody, bhkRigidBodyRef body, bhkSphere #endif CreatebhkCollisionModifier(n, bv_type_sphere, shape->GetMaterial()); - ImportBase(body, shape, parent, n); + ImportBase(body, shape, parent, n, tm); AddShape(rbody, n); return true; } } +#endif return false; } -bool CollisionImport::ImportBox(INode *rbody, bhkRigidBodyRef body, bhkBoxShapeRef shape, INode *parent) +bool CollisionImport::ImportBox(INode *rbody, bhkRigidBodyRef body, bhkBoxShapeRef shape, INode *parent, Matrix3& tm) { - //CreatebhkCollisionModifier(inode, bv_type_box, shape->GetMaterial()); + enum { box_params, }; + enum { PB_MATERIAL, PB_LENGTH, PB_WIDTH, PB_HEIGHT, }; + + bhkShapeRef retval; + if (SimpleObject *obj = (SimpleObject *)ni.gi->CreateInstance(HELPER_CLASS_ID, bhkBoxObject_CLASS_ID)) { + + if (IParamBlock2* pblock2 = obj->GetParamBlockByID(box_params)) + { + float radius = shape->GetRadius(); + int mtl = shape->GetMaterial(); + Vector3 dim = shape->GetDimensions(); + + pblock2->SetValue(PB_MATERIAL, 0, mtl, 0); + pblock2->SetValue(PB_WIDTH, 0, dim.x, 0); + pblock2->SetValue(PB_LENGTH, 0, dim.y, 0); + pblock2->SetValue(PB_HEIGHT, 0, dim.z, 0); + + if (INode *n = ni.CreateImportNode(shape->GetType().GetTypeName().c_str(), obj, parent)) { + ImportBase(body, shape, parent, n, tm); + AddShape(rbody, n); + return true; + } + } + } return false; } -bool CollisionImport::ImportCapsule(INode *rbody, bhkRigidBodyRef body, bhkCapsuleShapeRef shape, INode *parent) +bool CollisionImport::ImportCapsule(INode *rbody, bhkRigidBodyRef body, bhkCapsuleShapeRef shape, INode *parent, Matrix3& tm) { + enum { cap_params, }; + enum { PB_MATERIAL, PB_RADIUS1, PB_RADIUS2, PB_LENGTH, }; + + bhkShapeRef retval; + if (SimpleObject *obj = (SimpleObject *)ni.gi->CreateInstance(HELPER_CLASS_ID, BHKCAPSULEOBJECT_CLASS_ID)) { + + if (IParamBlock2* pblock2 = obj->GetParamBlockByID(cap_params)) + { + float radius = shape->GetRadius(); + int mtl = shape->GetMaterial(); + float radius1 = shape->GetRadius1(); + float radius2 = shape->GetRadius2(); + Vector3 pt1 = shape->GetFirstPoint(); + Vector3 pt2 = shape->GetSecondPoint(); + float len = (pt2 - pt1).Magnitude(); + + Point3 center = (TOPOINT3(pt2 + pt1) / 2.0f) * ni.bhkScaleFactor; + Point3 norm = Normalize(TOPOINT3(pt2 - pt1)); + Matrix3 mat; + MatrixFromNormal(norm,mat); + Matrix3 newTM = tm * mat * TransMatrix(center); + + pblock2->SetValue(PB_MATERIAL, 0, mtl, 0); + pblock2->SetValue(PB_LENGTH, 0, len, 0); + pblock2->SetValue(PB_RADIUS1, 0, radius1, 0); + pblock2->SetValue(PB_RADIUS2, 0, radius2, 0); + + if (INode *n = ni.CreateImportNode(shape->GetType().GetTypeName().c_str(), obj, parent)) { + ImportBase(body, shape, parent, n, newTM); + AddShape(rbody, n); + return true; + } + } + } + return false; +#if 0 if (SimpleObject *ob = (SimpleObject *)ni.gi->CreateInstance(GEOMOBJECT_CLASS_ID, SCUBA_CLASS_ID)) { float radius = shape->GetRadius(); float radius1 = shape->GetRadius1(); @@ -374,10 +478,12 @@ bool CollisionImport::ImportCapsule(INode *rbody, bhkRigidBodyRef body, bhkCapsu int heighttype = 1; RefTargetHandle t = ob->GetReference(0); - IParamArray *params = ob->GetParamBlock(); - params->SetValue(ob->GetParamBlockIndex(CAPSULE_RADIUS), 0, radius); - params->SetValue(ob->GetParamBlockIndex(CAPSULE_HEIGHT), 0, height); - params->SetValue(ob->GetParamBlockIndex(CAPSULE_CENTERS), 0, heighttype); + if (IParamBlock2* pblock2 = ob->GetParamBlockByID(0)) + { + pblock2->SetValue(CAPSULE_RADIUS, 0, radius); + pblock2->SetValue(CAPSULE_HEIGHT, 0, height); + pblock2->SetValue(CAPSULE_CENTERS, 0, heighttype); + } if (INode *n = ni.CreateImportNode(shape->GetType().GetTypeName().c_str(), ob, parent)) { // Need to "Affect Pivot Only" and "Center to Object" first @@ -386,23 +492,20 @@ 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()); - ImportBase(body, shape, parent, n); + ImportBase(body, shape, parent, n, tm); AddShape(rbody, n); return true; } } return true; +#endif } extern vector<Triangle> compute_convex_hull(const vector<Vector3>& verts); -bool CollisionImport::ImportConvexVertices(INode *rbody, bhkRigidBodyRef body, bhkConvexVerticesShapeRef shape, INode *parent) +bool CollisionImport::ImportConvexVertices(INode *rbody, bhkRigidBodyRef body, bhkConvexVerticesShapeRef shape, INode *parent, Matrix3& tm) { INode *returnNode = NULL; - //Vector3 trans = body->GetTranslation(); - //QuaternionXYZW quat = body->GetRotation(); - //Matrix3 tm = TOMATRIX3(trans, quat, 1.0f); - Matrix3 tm(true); vector<Vector3> verts = shape->GetVertices(); //vector<Triangle> tris = shape->GetTriangles(); vector<Vector3> norms = shape->GetNormals(); @@ -410,12 +513,12 @@ bool CollisionImport::ImportConvexVertices(INode *rbody, bhkRigidBodyRef body, b returnNode = ImportCollisionMesh(verts, tris, norms, tm, parent); CreatebhkCollisionModifier(returnNode, bv_type_convex, shape->GetMaterial()); - ImportBase(body, shape, parent, returnNode); + ImportBase(body, shape, parent, returnNode, tm); AddShape(rbody, returnNode); return true; } -bool CollisionImport::ImportTriStripsShape(INode *rbody, bhkRigidBodyRef body, bhkNiTriStripsShapeRef shape, INode *parent) +bool CollisionImport::ImportTriStripsShape(INode *rbody, bhkRigidBodyRef body, bhkNiTriStripsShapeRef shape, INode *parent, Matrix3& tm) { if (shape->GetNumStripsData() != 1) return NULL; @@ -451,16 +554,16 @@ bool CollisionImport::ImportTriStripsShape(INode *rbody, bhkRigidBodyRef body, b ni.ImportMesh(node, triObject, triShape, triShapeData, tris); CreatebhkCollisionModifier(inode, bv_type_shapes, shape->GetMaterial()); - ImportBase(body, shape, parent, inode); + ImportBase(body, shape, parent, inode, tm); AddShape(rbody, inode); return true; } return false; } -bool CollisionImport::ImportMoppBvTreeShape(INode *rbody, bhkRigidBodyRef body, bhkMoppBvTreeShapeRef shape, INode *parent) +bool CollisionImport::ImportMoppBvTreeShape(INode *rbody, bhkRigidBodyRef body, bhkMoppBvTreeShapeRef shape, INode *parent, Matrix3& tm) { - bool retval = ImportShape(rbody, body, shape->GetShape(), parent); + bool retval = ImportShape(rbody, body, shape->GetShape(), parent, tm); //if (shapes.Count() > 0) { // for (int i=0, n=shapes.Count(); i<n; ++i) // { @@ -470,7 +573,7 @@ bool CollisionImport::ImportMoppBvTreeShape(INode *rbody, bhkRigidBodyRef body, return retval; } -bool CollisionImport::ImportPackedNiTriStripsShape(INode *rbody, bhkRigidBodyRef body, bhkPackedNiTriStripsShapeRef shape, INode *parent) +bool CollisionImport::ImportPackedNiTriStripsShape(INode *rbody, bhkRigidBodyRef body, bhkPackedNiTriStripsShapeRef shape, INode *parent, Matrix3& tm) { if (hkPackedNiTriStripsDataRef data = shape->GetData()) { @@ -485,7 +588,7 @@ bool CollisionImport::ImportPackedNiTriStripsShape(INode *rbody, bhkRigidBodyRef INode *inode = ImportCollisionMesh(verts, tris, norms, tm, parent); CreatebhkCollisionModifier(inode, bv_type_shapes, HavokMaterial(NP_DEFAULT_HVK_MATERIAL)); - ImportBase(body, shape, parent, inode); + ImportBase(body, shape, parent, inode, tm); AddShape(rbody, inode); return true; } @@ -493,7 +596,7 @@ bool CollisionImport::ImportPackedNiTriStripsShape(INode *rbody, bhkRigidBodyRef return false; } -bool CollisionImport::ImportListShape(INode *rbody, bhkRigidBodyRef body, bhkListShapeRef shape, INode *parent) +bool CollisionImport::ImportListShape(INode *rbody, bhkRigidBodyRef body, bhkListShapeRef shape, INode *parent, Matrix3& tm) { bool ok = false; HavokMaterial material = shape->GetMaterial(); @@ -506,7 +609,7 @@ bool CollisionImport::ImportListShape(INode *rbody, bhkRigidBodyRef body, bhkLis vector<Ref<bhkShape > > bhkshapes = shape->GetSubShapes(); for (int i = 0, n = bhkshapes.size(); i<n; ++i) { - ok |= ImportShape(rbody, body, bhkshapes[i], parent); + ok |= ImportShape(rbody, body, bhkshapes[i], parent, tm); //if (shapes.Count() > 0) { // for (int i=0, n=shapes.Count(); i<n; ++i) { // npSetProp(shapes[i], NP_HVK_MATERIAL, shape->GetMaterial()); @@ -514,4 +617,17 @@ bool CollisionImport::ImportListShape(INode *rbody, bhkRigidBodyRef body, bhkLis //} } return ok; +} + +bool CollisionImport::ImportTransform(INode *rbody, bhkRigidBodyRef body, bhkTransformShapeRef shape, INode *parent, Matrix3& tm) +{ + Matrix44 m4 = shape->GetTransform().Transpose(); + Vector3 trans; Matrix33 rot; float scale; + m4.Decompose(trans, rot, scale); + Matrix3 wm = tm + * TransMatrix(TOPOINT3(trans * ni.bhkScaleFactor)) + * TOMATRIX3(rot) + * ScaleMatrix(Point3(scale, scale, scale)) + ; + return ImportShape(rbody, body, shape->GetShape(), parent, wm); } \ No newline at end of file diff --git a/NifImport/ImportSkeleton.cpp b/NifImport/ImportSkeleton.cpp index 99c42fc0ba0efe40219dbbee2538ba6af85168c9..60d709156dfe77c368c5bbb8559a5e972eb1ebbf 100644 --- a/NifImport/ImportSkeleton.cpp +++ b/NifImport/ImportSkeleton.cpp @@ -227,21 +227,6 @@ static float CalcLength(NiNodeRef node, vector<NiAVObjectRef>& children) return len; } -Matrix3 GetLocalTM(INode *node) -{ - if (INode *parent = node->GetParentNode()) - { - Matrix3 parentTM, nodeTM; - nodeTM = node->GetNodeTM(0); - parent = node->GetParentNode(); - parentTM = parent->GetNodeTM(0); - return nodeTM*Inverse(parentTM); - } - else - { - return node->GetNodeTM(0); - } -} static float CalcLength(INode *bone) { @@ -527,7 +512,8 @@ INode *NifImporter::CreateCamera(const string& name) ob->Enable(1); ob->NewCamera(0); ob->SetFOV(0, TORAD(75.0f)); - if (INode *n = CreateImportNode(name.c_str(), ob, NULL)) { + if (INode *n = gi->CreateObjectNode(ob)) { + //if (INode *n = CreateImportNode(name.c_str(), ob, NULL)) { n->Hide(TRUE); n->BoneAsLine(1); return n; @@ -609,7 +595,7 @@ void NifImporter::ImportBones(NiNodeRef node, bool recurse) Matrix44 tm = parent->GetLocalTransform() * node->GetLocalTransform(); name = realname; len += tm.GetTranslation().Magnitude(); - parent = parent->GetParent(); + parent = parent->GetParent(); } } diff --git a/NifImport/MaxNifImport.h b/NifImport/MaxNifImport.h index 83fff4b18ff6d436ab41605acea6abdf43e31a52..01cafcd4e7892766a33c5d6c6baa03948c5eaad8 100644 --- a/NifImport/MaxNifImport.h +++ b/NifImport/MaxNifImport.h @@ -26,6 +26,7 @@ #ifdef USE_BIPED # include <cs/BipedApi.h> #endif +#include <meshadj.h> //#include <scenetraversal.h> #include <plugapi.h> #include <triobj.h> diff --git a/NifPlugins/DllEntry.cpp b/NifPlugins/DllEntry.cpp index 732cf6b80880b12b9c4e61857995d2945fc0660a..e7f01f370e66ef71145a468bb69a71a0dfe09140 100644 --- a/NifPlugins/DllEntry.cpp +++ b/NifPlugins/DllEntry.cpp @@ -90,12 +90,10 @@ void InitializeLibSettings() classDescriptions[nClasses++] = GetNifPropsDesc(); classDescriptions[nClasses++] = GetbhkListObjDesc(); classDescriptions[nClasses++] = GetbhkProxyObjDesc(); -#ifdef USE_UNSUPPORTED_CODE classDescriptions[nClasses++] = GetbhkRigidBodyModifierDesc(); classDescriptions[nClasses++] = GetbhkSphereDesc(); classDescriptions[nClasses++] = GetbhkCapsuleDesc(); classDescriptions[nClasses++] = GetbhkBoxDesc(); -#endif } if ( GetIniValue<bool>("NifFurniture", "Enable", true, iniName) ) { classDescEnabled[CD_Furniture] = true; diff --git a/NifProps/NifProps.rc b/NifProps/NifProps.rc index 270745a862eaf99f5227c7980a2dd52b3daff65d..cb2eeeeccd71add75a764c60353ed8a52df7858a 100755 --- a/NifProps/NifProps.rc +++ b/NifProps/NifProps.rc @@ -1158,10 +1158,10 @@ BEGIN IDS_RB_MOD_PANEL2 "Sphere" IDS_RB_MOD_PANEL3 "Capsule" IDS_RB_MOD_PANEL4 "Proxy Mesh" - IDS_RB_LIST "bhkListShape" - IDS_RB_LIST_CLASS "bhkListShape" - IDS_RB_PROXY "bhkCollisionProxy" - IDS_RB_PROXY_CLASS "bhkCollisionProxy" + IDS_RB_LIST "bhkRigidBody" + IDS_RB_LIST_CLASS "bhkRigidBody" + IDS_RB_PROXY "bhkCollProxy" + IDS_RB_PROXY_CLASS "bhkCollProxy" END STRINGTABLE diff --git a/NifProps/bhkBoxObj.cpp b/NifProps/bhkBoxObj.cpp index d7aff148374c4782eb7e25c957544a8893e6e8cc..2b5858534413e397ffa682cea0bbfca68d31210f 100644 --- a/NifProps/bhkBoxObj.cpp +++ b/NifProps/bhkBoxObj.cpp @@ -28,7 +28,7 @@ HISTORY: #ifndef _countof #define _countof(x) (sizeof(x)/sizeof((x)[0])) #endif - +const float bhkScaleFactor = 7.0f; Class_ID bhkBoxObject_CLASS_ID = Class_ID(0x86e19816, BHKRIGIDBODYCLASS_DESC.PartB()); static ParamBlockDesc2* GetbhkBoxParamBlockDesc(); @@ -294,7 +294,7 @@ void bhkBoxObject::BuildMesh(TimeValue t) pblock2->GetValue(PB_LENGTH,t,l,ivalid); pblock2->GetValue(PB_WIDTH,t,w,ivalid); pblock2->GetValue(PB_HEIGHT,t,h,ivalid); - BuildBox(mesh, l, w, h); + BuildBox(mesh, (l * bhkScaleFactor * 2), (w * bhkScaleFactor * 2), (h * bhkScaleFactor * 2)); } @@ -373,9 +373,9 @@ int BoxObjCreateCallBack::proc(ViewExp *vpt,int msg, int point, int flags, IPoin square = TRUE; } - ob->pblock2->SetValue(PB_WIDTH,0,float(fabs(d.x))); - ob->pblock2->SetValue(PB_LENGTH,0,float(fabs(d.y))); - ob->pblock2->SetValue(PB_HEIGHT,0,float(fabs(d.z))); + ob->pblock2->SetValue(PB_WIDTH,0,float(fabs(d.x / bhkScaleFactor / 2.0f))); + ob->pblock2->SetValue(PB_LENGTH,0,float(fabs(d.y / bhkScaleFactor / 2.0f))); + ob->pblock2->SetValue(PB_HEIGHT,0,float(fabs(d.z / bhkScaleFactor / 2.0f))); ob->pmapParam->Invalidate(); if (msg==MOUSE_POINT && (Length(sp1-sp0)<3 || Length(d)<0.1f)) { @@ -401,9 +401,9 @@ int BoxObjCreateCallBack::proc(ViewExp *vpt,int msg, int point, int flags, IPoin d.x = d.y = 2.0f * len; } - ob->pblock2->SetValue(PB_WIDTH,0,float(fabs(d.x))); - ob->pblock2->SetValue(PB_LENGTH,0,float(fabs(d.y))); - ob->pblock2->SetValue(PB_HEIGHT,0,float(d.z)); + ob->pblock2->SetValue(PB_WIDTH,0,float(fabs(d.x / bhkScaleFactor / 2.0f))); + ob->pblock2->SetValue(PB_LENGTH,0,float(fabs(d.y / bhkScaleFactor / 2.0f))); + ob->pblock2->SetValue(PB_HEIGHT,0,float(d.z / bhkScaleFactor / 2.0f)); ob->pmapParam->Invalidate(); if (msg==MOUSE_POINT) diff --git a/NifProps/bhkCapsuleObj.cpp b/NifProps/bhkCapsuleObj.cpp index 3e90a355def0c02092f5f21ae2590f79e9da5bf9..236334fcf8610043813fb47c575c81f9a22dbbed 100644 --- a/NifProps/bhkCapsuleObj.cpp +++ b/NifProps/bhkCapsuleObj.cpp @@ -29,7 +29,7 @@ HISTORY: #ifndef _countof #define _countof(x) (sizeof(x)/sizeof((x)[0])) #endif - +const float bhkScaleFactor = 7.0f; Class_ID BHKCAPSULEOBJECT_CLASS_ID = Class_ID(0x7f8f629a, BHKRIGIDBODYCLASS_DESC.PartB()); class bhkCapsuleObject : public SimpleObject2 @@ -291,7 +291,7 @@ void bhkCapsuleObject::BuildMesh(TimeValue t) } else { - BuildScubaMesh(mesh, segs, smooth, hsegs, radius2, radius1, length); + BuildScubaMesh(mesh, segs, smooth, hsegs, radius2*bhkScaleFactor, radius1*bhkScaleFactor, length*bhkScaleFactor); } } diff --git a/NifProps/bhkHelperFuncs.cpp b/NifProps/bhkHelperFuncs.cpp index 1233c680d8ad44676c46f66a96b2b87cc5d49e94..883fd0d2119942faf2a9e9bb07fa8090349c1d4d 100644 --- a/NifProps/bhkHelperFuncs.cpp +++ b/NifProps/bhkHelperFuncs.cpp @@ -131,7 +131,7 @@ void CalcAxisAlignedSphere(Mesh& mesh, Point3& center, float& radius) void CalcCenteredSphere(Mesh& mesh, Point3& center, float& radius) { int nv = mesh.getNumVerts(); - Point3 sum; + Point3 sum(0.0f, 0.0f, 0.0f); for (int i=0; i<nv; ++i) sum += mesh.getVert(i); center = sum / float(nv); @@ -753,4 +753,4 @@ void BuildScubaMesh(Mesh &mesh, int segs, int smooth, int llsegs, assert(fc==mesh.numFaces); // assert(nv==mesh.numVerts); mesh.InvalidateTopologyCache(); -} \ No newline at end of file +} diff --git a/NifProps/bhkListObj.cpp b/NifProps/bhkListObj.cpp index 10c583519d8485591d86847938ad4c6c536175f7..56c7cdc4e5ffdf48f85b257acd4809501d20acde 100644 --- a/NifProps/bhkListObj.cpp +++ b/NifProps/bhkListObj.cpp @@ -552,7 +552,7 @@ int bhkListObject::Display(TimeValue t, INode* inode, ViewExp *vpt, int flags) Matrix3 m3(true); - float size = 20.0f; + float size = 5.0f; Point3 pts[5]; // X pts[0] = Point3(-size, 0.0f, 0.0f); pts[1] = Point3(size, 0.0f, 0.0f); diff --git a/NifProps/bhkSphereObj.cpp b/NifProps/bhkSphereObj.cpp index 7a6c48cbcb0c642b413c4d795ded2954f6104b41..f2a5d1e08804cf4342d9f1804456271db9ebfe90 100644 --- a/NifProps/bhkSphereObj.cpp +++ b/NifProps/bhkSphereObj.cpp @@ -152,7 +152,7 @@ static ParamBlockDesc2 param_blk ( end, PB_SEGS, _T("segments"), TYPE_INT, P_ANIMATABLE, IDS_RB_SEGS, - p_default, 32, + p_default, 16, p_range, MIN_SEGMENTS, MAX_SEGMENTS, p_ui, TYPE_SPINNER, EDITTYPE_POS_INT, IDC_SEGMENTS, IDC_SEGSPINNER, 1.0f, end, @@ -304,7 +304,7 @@ void bhkSphereObject::BuildMesh(TimeValue t) pblock2->GetValue(PB_RADIUS, t, radius, ivalid); pblock2->GetValue(PB_SEGS, t, segs, ivalid); pblock2->GetValue(PB_SMOOTH, t, smooth, ivalid); - BuildSphere(mesh, radius, segs, smooth, startAng); + BuildSphere(mesh, (radius * 7.0f), segs, smooth, startAng); } @@ -358,7 +358,7 @@ int SphereObjCreateCallBack::proc(ViewExp *vpt,int msg, int point, int flags, IP mat.IdentityMatrix(); //mat.PreRotateZ(HALFPI); p1 = vpt->SnapPoint(m,m,NULL,SNAP_IN_3D); - r = Length(p1-p0); + r = Length(p1-p0) / 7.0f; mat.SetTrans(p0); ob->pblock2->SetValue(PB_RADIUS,0,r);