From 48c5581db9cf82ac8e8ceeb3ed14a175ff0f998e Mon Sep 17 00:00:00 2001 From: Tazpn <tazpn@users.sourceforge.net> Date: Tue, 11 Sep 2007 02:17:56 +0000 Subject: [PATCH] Add misc. collision fixes. And a capsule skeleton code with wildmagic disabled by default. --- NifExport/Coll.cpp | 5 ++- NifExport/Exporter.cpp | 2 +- NifProps/NifProps.rc | 15 +++---- NifProps/bhkHelperFuncs.cpp | 70 ++++++++++++++++++++++++++++++++ NifProps/bhkHelperFuncs.h | 2 + NifProps/bhkProxyObj.cpp | 47 ++++++++++++++++++--- NifProps/bhkRigidBodyModifer.cpp | 21 +++++----- 7 files changed, 137 insertions(+), 25 deletions(-) diff --git a/NifExport/Coll.cpp b/NifExport/Coll.cpp index 548a50b..709d8ba 100755 --- a/NifExport/Coll.cpp +++ b/NifExport/Coll.cpp @@ -421,7 +421,8 @@ bhkConvexVerticesShapeRef Exporter::makeConvexShape(Mesh& mesh, Matrix3& tm) bhkConvexVerticesShapeRef shape = StaticCast<bhkConvexVerticesShape>(bhkConvexVerticesShape::Create()); Point3 center(0.0f, 0.0f, 0.0f); float radius = 0.10f; - //CalcAxisAlignedSphere(mesh, center, radius); + CalcCenteredSphere(mesh, center, radius); + radius /= Exporter::bhkScaleFactor; shape->SetRadius(radius); vector<Vector3> verts; vector<Float4> norms; @@ -444,7 +445,7 @@ bhkConvexVerticesShapeRef Exporter::makeConvexShape(Mesh& mesh, Matrix3& tm) value[0] = pt.x; value[1] = pt.y; value[2] = pt.z; - value[3] = -mesh.FaceCenter(i).Length(); + value[3] = -(mesh.FaceCenter(i) * tm).Length() / Exporter::bhkScaleFactor; } sortVector3(verts); sortFloat4(norms); diff --git a/NifExport/Exporter.cpp b/NifExport/Exporter.cpp index 525cc25..669ba2c 100755 --- a/NifExport/Exporter.cpp +++ b/NifExport/Exporter.cpp @@ -296,7 +296,7 @@ Exporter::Result Exporter::exportNodes(NiNodeRef &parent, INode *node) { return exportLight(nodeParent, node, (GenLight*)os.obj); } - else if (isMeshGroup(node) && local) // only create node if local + else if (isMeshGroup(node) && local && !mSkeletonOnly) // only create node if local { newParent = makeNode(parent, node, local); } diff --git a/NifProps/NifProps.rc b/NifProps/NifProps.rc index 92f8ce7..748a2b7 100755 --- a/NifProps/NifProps.rc +++ b/NifProps/NifProps.rc @@ -295,22 +295,23 @@ BEGIN LTEXT "Collision Meshes:",IDC_STATIC,9,28,77,8 END -IDD_PROXYPARAM1 DIALOGEX 0, 0, 107, 210 +IDD_PROXYPARAM1 DIALOGEX 0, 0, 107, 223 STYLE DS_SETFONT | WS_CHILD | WS_VISIBLE FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN CONTROL "Material",IDC_LBL_MATERIAL,"Static",SS_LEFTNOWORDWRAP | SS_CENTERIMAGE | WS_GROUP,12,4,83,8 COMBOBOX IDC_CB_MATERIAL,12,13,83,157,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - GROUPBOX "Bounding Volume",IDC_STATIC,4,31,97,74 + GROUPBOX "Bounding Volume",IDC_STATIC,4,31,97,81 CONTROL "No Collision",IDC_RDO_NO_COLL,"Button",BS_AUTORADIOBUTTON | WS_GROUP,8,41,82,10 CONTROL "Axis Aligned Box",IDC_RDO_AXIS_ALIGNED_BOX,"Button",BS_AUTORADIOBUTTON,8,52,82,10 CONTROL "Strips Shape",IDC_RDO_STRIPS_SHAPE,"Button",BS_AUTORADIOBUTTON,8,64,82,10 CONTROL "Packed Strips Shape",IDC_RDO_PACKED_STRIPS,"Button",BS_AUTORADIOBUTTON | WS_DISABLED,8,76,80,10 CONTROL "Convex Shape",IDC_RDO_CONVEX,"Button",BS_AUTORADIOBUTTON,8,88,80,10 - LTEXT "Proxied Collision Meshes:",IDC_STATIC,8,107,92,8 - LISTBOX IDC_LIST1,6,118,94,71,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP - CONTROL "Add",IDC_ADD,"CustButton",WS_TABSTOP,4,192,47,12 - CONTROL "Remove",IDC_REMOVE,"CustButton",WS_TABSTOP,56,192,46,12 + LTEXT "Proxied Collision Meshes:",IDC_STATIC,8,116,92,8 + LISTBOX IDC_LIST1,6,127,94,71,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + CONTROL "Add",IDC_ADD,"CustButton",WS_TABSTOP,4,201,47,12 + CONTROL "Remove",IDC_REMOVE,"CustButton",WS_TABSTOP,56,201,46,12 + CONTROL "Capsule",IDC_RDO_CAPSULE,"Button",BS_AUTORADIOBUTTON,8,99,80,10 END @@ -372,7 +373,7 @@ BEGIN IDD_PROXYPARAM1, DIALOG BEGIN RIGHTMARGIN, 106 - BOTTOMMARGIN, 208 + BOTTOMMARGIN, 221 END END #endif // APSTUDIO_INVOKED diff --git a/NifProps/bhkHelperFuncs.cpp b/NifProps/bhkHelperFuncs.cpp index 883fd0d..dbaeff2 100644 --- a/NifProps/bhkHelperFuncs.cpp +++ b/NifProps/bhkHelperFuncs.cpp @@ -5,6 +5,23 @@ #include "NifStrings.h" #include "NifPlugins.h" #include "NifGui.h" +#include "meshadj.h" + +// Includes for WildMagic so we can do the Capsule fitting +#ifdef USES_WILDMAGIC +# ifdef _DEBUG +# pragma comment (lib, "Wm4Foundation80d") +# else +# pragma comment (lib, "Wm4Foundation80") +# endif +#undef PI +#undef DEG_TO_RAD +#undef RAD_TO_DEG +#define WM4PLATFORMS_H +#define WM4_FOUNDATION_ITEM +#include <Wm4ContCapsule3.h> +#define PI (Wm4::Math<double>::PI) +#endif using namespace std; @@ -754,3 +771,56 @@ void BuildScubaMesh(Mesh &mesh, int segs, int smooth, int llsegs, // assert(nv==mesh.numVerts); mesh.InvalidateTopologyCache(); } + +// Calculate capsule from mesh. While radii on the endcaps is possible we do +// currently calculate then differently. +extern void CalcCapsule(Mesh &mesh, Point3& pt1, Point3& pt2, float& r1, float& r2) +{ +#ifdef USES_WILDMAGIC + int nv = mesh.getNumVerts(); + Wm4::Vector3<float>* akPoint = new Wm4::Vector3<float>[nv]; + for (int i=0; i<nv; i++) + { + Point3& mp = mesh.verts[i]; + Wm4::Vector3<float>& wp = akPoint[i]; + wp.X() = mp.x; + wp.Y() = mp.y; + wp.Z() = mp.z; + } + Wm4::Capsule3<float> capsule = ContCapsule (nv, akPoint); + delete [] akPoint; + + Wm4::Vector3<float> end1 = capsule.Segment.GetPosEnd(); + Wm4::Vector3<float> end2 = capsule.Segment.GetNegEnd(); + pt1.Set(end1.X(), end1.Y(), end1.Z()); + pt2.Set(end2.X(), end2.Y(), end2.Z()); + + r1 = r2 = capsule.Radius; +#endif + return; +} + +extern void BuildCapsule(Mesh &mesh, Point3 pt1, Point3 pt2, float r1, float r2) +{ + int segs = 12; + int hsegs = 1; + int smooth = 1; + + float h = (pt1 - pt2).Length(); + + Point3 center = ((pt2 + pt1) / 2.0f); + Point3 norm = Normalize(pt2 - pt1); + Matrix3 mat; + MatrixFromNormal(norm,mat); + Matrix3 newTM = mat * TransMatrix(center); + + // Build capsule to suggested size + BuildScubaMesh(mesh, segs, smooth, hsegs, r1, r2, h); + + // Reorient the capsule. + MNMesh mn(mesh); + Matrix3 tm(true); + tm.Translate(center); + mn.Transform(newTM); + mn.OutToTri(mesh); +} diff --git a/NifProps/bhkHelperFuncs.h b/NifProps/bhkHelperFuncs.h index 5d59f65..9697f08 100644 --- a/NifProps/bhkHelperFuncs.h +++ b/NifProps/bhkHelperFuncs.h @@ -5,9 +5,11 @@ extern void CalcAxisAlignedBox(Mesh& mesh, Box3& box); extern void CalcAxisAlignedBox(Mesh& mesh, Box3& box, Matrix3* tm); extern void CalcAxisAlignedSphere(Mesh& mesh, Point3& center, float& radius); extern void CalcCenteredSphere(Mesh& mesh, Point3& center, float& radius); +extern void CalcCapsule(Mesh &mesh, Point3& pt1, Point3& pt2, float& r1, float& r2); extern void BuildBox(Mesh&mesh, float l, float w, float h); extern void BuildSphere(Mesh&mesh, float radius, int segs=32, int smooth=1, float startAng = 0.0f); +extern void BuildCapsule(Mesh &mesh, Point3 pt1, Point3 pt2, float r1, float r2); extern void BuildScubaMesh(Mesh &mesh, int segs, int smooth, int llsegs, float radius1, float radius2, float cylh); diff --git a/NifProps/bhkProxyObj.cpp b/NifProps/bhkProxyObj.cpp index df6ea32..8e3ed05 100644 --- a/NifProps/bhkProxyObj.cpp +++ b/NifProps/bhkProxyObj.cpp @@ -105,6 +105,7 @@ public: void BuildColStrips(); void BuildColPackedStrips(); void BuildColConvex(); + void BuildColCapsule(); void BuildOptimize(Mesh&mesh); void UpdateUI(); @@ -151,7 +152,7 @@ enum PB_OPT_ENABLE, PB_MAXEDGE, PB_FACETHRESH, PB_EDGETHRESH, PB_BIAS, }; -enum { bv_type_none, bv_type_box, bv_type_shapes, bv_type_packed, bv_type_convex, }; // pblock ID +enum { bv_type_none, bv_type_box, bv_type_shapes, bv_type_packed, bv_type_convex, bv_type_capsule }; // pblock ID static ParamBlockDesc2 param_blk ( list_params, _T("parameters"), 0, NULL, P_AUTO_CONSTRUCT + P_AUTO_UI + P_MULTIMAP, 0, @@ -168,8 +169,8 @@ static ParamBlockDesc2 param_blk ( PB_BOUND_TYPE, _T("boundType"), TYPE_INT, 0, IDS_BV_BOUNDING_TYPE, p_default, 0, - p_range, 0, 4, - p_ui, list_params, TYPE_RADIO, 5, IDC_RDO_NO_COLL, IDC_RDO_AXIS_ALIGNED_BOX, IDC_RDO_STRIPS_SHAPE, IDC_RDO_PACKED_STRIPS, IDC_RDO_CONVEX, + p_range, 0, 5, + p_ui, list_params, TYPE_RADIO, 6, IDC_RDO_NO_COLL, IDC_RDO_AXIS_ALIGNED_BOX, IDC_RDO_STRIPS_SHAPE, IDC_RDO_PACKED_STRIPS, IDC_RDO_CONVEX, IDC_RDO_CAPSULE, end, PB_MESHLIST, _T("meshProxy"), TYPE_INODE_TAB, 0, P_AUTO_UI|P_VARIABLE_SIZE, IDS_MESHLIST, @@ -513,11 +514,14 @@ void bhkProxyObject::BuildMesh(TimeValue t) //BuildSphere(); break; - case bv_type_convex: // Capsule + case bv_type_convex: BuildColConvex(); - //BuildScubaMesh(); break; + + case bv_type_capsule: + BuildColCapsule(); + break; } } @@ -801,6 +805,39 @@ void bhkProxyObject::BuildColConvex() forceRedraw = true; } +void bhkProxyObject::BuildColCapsule() +{ + proxyMesh.FreeAll(); + MeshDelta md(proxyMesh); + for (int i = 0;i < pblock2->Count(PB_MESHLIST); i++) { + INode *tnode = NULL; + pblock2->GetValue(PB_MESHLIST,0,tnode,FOREVER,i); + if (tnode) + { + ObjectState os = tnode->EvalWorldState(0); + Matrix3 wm = tnode->GetNodeTM(0); + TriObject *tri = (TriObject *)os.obj->ConvertToType(0, Class_ID(TRIOBJ_CLASS_ID, 0)); + if (tri) + { + Mesh& mesh = tri->GetMesh(); + MeshDelta tmd (mesh); + md.AttachMesh(proxyMesh, mesh, wm, 0); + md.Apply(proxyMesh); + } + } + } + Point3 pt1 = Point3::Origin; + Point3 pt2 = Point3::Origin; + float r1 = 0.0; + float r2 = 0.0; + + CalcCapsule(proxyMesh, pt1, pt2, r1, r2); + BuildCapsule(proxyMesh, pt1, pt2, r1, r2); + + proxyPos = Point3::Origin; + forceRedraw = true; +} + void bhkProxyObject::BuildOptimize(Mesh& mesh) { diff --git a/NifProps/bhkRigidBodyModifer.cpp b/NifProps/bhkRigidBodyModifer.cpp index 111a47f..1578c41 100644 --- a/NifProps/bhkRigidBodyModifer.cpp +++ b/NifProps/bhkRigidBodyModifer.cpp @@ -431,12 +431,16 @@ void bhkRigidBodyModifier::ModifyObject (TimeValue t, ModContext &mc, ObjectStat BuildOptimize(proxyMesh); break; + case bv_type_capsule: + BuildColCapsule(proxyMesh); + break; + //case bv_type_packed: // Packed // BuildColPackedStrips(); // //BuildSphere(); // break; - case bv_type_convex: // Capsule + case bv_type_convex: BuildColConvex(proxyMesh); BuildOptimize(proxyMesh); //BuildScubaMesh(); @@ -649,16 +653,13 @@ void bhkRigidBodyModifier::BuildColSphere(Mesh& mesh) void bhkRigidBodyModifier::BuildColCapsule(Mesh& mesh) { - Point3 center = Point3::Origin; - float radius = 0.0f; - CalcCenteredSphere(mesh, center, radius); - BuildSphere(mesh, radius); + Point3 pt1 = Point3::Origin; + Point3 pt2 = Point3::Origin; + float r1 = 0.0; + float r2 = 0.0; - MNMesh mn(mesh); - Matrix3 tm(true); - tm.Translate(center); - mn.Transform(tm); - mn.OutToTri(mesh); + CalcCapsule(mesh, pt1, pt2, r1, r2); + BuildCapsule(mesh, pt1, pt2, r1, r2); } void bhkRigidBodyModifier::BuildColStrips(Mesh& mesh) -- GitLab