Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include "pch.h"
int Exporter::addVertex(vector<Vector3> &verts, vector<Vector3> &vnorms, const Point3 &pt, const Point3 &norm)
{
for (int i=0; i<verts.size(); i++)
{
if (equal(verts[i], pt, mWeldThresh) &&
equal(vnorms[i], norm, 0))
return i;
}
verts.push_back(Vector3(pt.x, pt.y, pt.z));
vnorms.push_back(Vector3(norm.x, norm.y, norm.z));
return verts.size()-1;
}
void Exporter::addFace(Triangles &tris, vector<Vector3> &verts, vector<Vector3> &vnorms,
int face, const int vi[3], Mesh *mesh)
{
Triangle tri;
for (int i=0; i<3; i++)
{
tri[i] = addVertex(verts, vnorms,
mesh->verts[ mesh->faces[ face ].v[ vi[i] ] ],
getVertexNormal(mesh, face, mesh->getRVertPtr(mesh->faces[ face ].v[ vi[i] ])));
}
tris.push_back(tri);
}
bool Exporter::makeCollisionHierarchy(NiNodeRef &parent, INode *node, TimeValue t)
{
Matrix3 tm = node->GetObjTMAfterWSM(t);
// Order of the vertices. Get 'em counter clockwise if the objects is
// negatively scaled.
int vi[3];
if (TMNegParity(tm))
{
vi[0] = 2;
vi[1] = 1;
vi[2] = 0;
} else
{
vi[0] = 0;
vi[1] = 1;
vi[2] = 2;
}
ObjectState os = node->EvalWorldState(t);
if (!os.obj || os.obj->SuperClassID()!=GEOMOBJECT_CLASS_ID)
return Error;
Object *obj = os.obj;
if (!obj->CanConvertToType(Class_ID(TRIOBJ_CLASS_ID, 0)))
return Error;
TriObject *tri = (TriObject *)obj->ConvertToType(t, Class_ID(TRIOBJ_CLASS_ID, 0));
if (!tri)
return false;
Mesh *mesh = &tri->GetMesh();
mesh->buildNormals();
// get data from node
int lyr, mtl, msys, qtype;
float mass, lindamp, angdamp, frict, maxlinvel, maxangvel, resti, pendepth;
Vector3 center;
npGetProp(node, NP_HVK_LAYER, lyr, NP_DEFAULT_HVK_LAYER);
npGetProp(node, NP_HVK_MATERIAL, mtl, NP_DEFAULT_HVK_MATERIAL);
npGetProp(node, NP_HVK_MOTION_SYSTEM, msys, NP_DEFAULT_HVK_MOTION_SYSTEM);
npGetProp(node, NP_HVK_QUALITY_TYPE, qtype, NP_DEFAULT_HVK_QUALITY_TYPE);
npGetProp(node, NP_HVK_MASS, mass, NP_DEFAULT_HVK_MASS);
npGetProp(node, NP_HVK_LINEAR_DAMPING, lindamp, NP_DEFAULT_HVK_LINEAR_DAMPING);
npGetProp(node, NP_HVK_ANGULAR_DAMPING, angdamp, NP_DEFAULT_HVK_ANGULAR_DAMPING);
npGetProp(node, NP_HVK_FRICTION, frict, NP_DEFAULT_HVK_FRICTION);
npGetProp(node, NP_HVK_RESTITUTION, resti, NP_DEFAULT_HVK_RESTITUTION);
npGetProp(node, NP_HVK_MAX_LINEAR_VELOCITY, maxlinvel, NP_DEFAULT_HVK_MAX_LINEAR_VELOCITY);
npGetProp(node, NP_HVK_MAX_ANGULAR_VELOCITY, maxangvel, NP_DEFAULT_HVK_MAX_ANGULAR_VELOCITY);
npGetProp(node, NP_HVK_PENETRATION_DEPTH, pendepth, NP_DEFAULT_HVK_PENETRATION_DEPTH);
npGetProp(node, NP_HVK_CENTER, center);
// setup shape data
vector<Vector3> verts;
vector<Vector3> vnorms;
Triangles tris;
for (int i=0; i<mesh->getNumFaces(); i++)
addFace(tris, verts, vnorms, i, vi, mesh);
TriStrips strips;
strippify(strips, verts, vnorms, tris);
NiTriStripsDataRef data = makeTriStripsData(strips);
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
data->SetVertices(verts);
data->SetNormals(vnorms);
// setup shape
bhkNiTriStripsShapeRef shape = DynamicCast<bhkNiTriStripsShape>(CreateBlock("bhkNiTriStripsShape"));
shape->SetNumStripsData(1);
shape->SetStripsData(0, data);
shape->SetMaterial(mtl);
array<float, 2> unknownFloats1;
uint i1 = 0x3DCCCCCD;
uint i2 = 0x004ABE60;
unknownFloats1[0] = *((float*)&i1);
unknownFloats1[1] = *((float*)&i2);
shape->SetUnknownFloats1(unknownFloats1);
array<float, 3> unknownFloats2;
unknownFloats2[0] = 1;
unknownFloats2[1] = 1;
unknownFloats2[2] = 1;
shape->SetUnknownFloats2(unknownFloats2);
array<uint, 5> unknownInts1;
unknownInts1[4] = 1;
shape->SetUnknownInts1(unknownInts1);
vector<uint> unknownInts3;
unknownInts3.resize(1);
shape->SetUnknownInts3(unknownInts3);
// setup collision object
bhkCollisionObjectRef co = DynamicCast<bhkCollisionObject>(CreateBlock("bhkCollisionObject"));
// setup body
bhkRigidBodyTRef body = DynamicCast<bhkRigidBodyT>(CreateBlock("bhkRigidBodyT"));
Vector3 trans;
QuaternionXYZW q;
nodeTransform(q, trans, node, t, false);
body->SetRotation(q);
body->SetTranslation(Vector3(trans.x/7, trans.y/7, trans.z/7));
body->SetLayer(lyr);
body->SetLayerCopy(lyr);
body->SetMotionSystem(msys);
body->SetQualityType(qtype);
body->SetMass(mass);
body->SetLinearDamping(lindamp);
body->SetAngularDamping(angdamp);
body->SetFriction(frict);
body->SetRestitution(resti);
body->SetMaxLinearVelocity(maxlinvel);
body->SetMaxAngularVelocity(maxangvel);
body->SetPenetrationDepth(pendepth);
body->SetCenter(center);
// link
parent->SetCollisionObject(DynamicCast<NiCollisionObject>(co));
co->SetParent(parent);
co->SetBody(DynamicCast<NiObject>(body));
body->SetShape(DynamicCast<bhkShape>(shape));
if (obj != tri)
tri->DeleteMe();
return true;
}