15 #include "physxSoftBodyNode.h" 16 #include "physxSoftBody.h" 17 #include "physxFileStream.h" 18 #include "physxManager.h" 19 #include "physxMeshHash.h" 21 #include "geomVertexFormat.h" 22 #include "geomVertexWriter.h" 23 #include "geomVertexRewriter.h" 32 void PhysxSoftBodyNode::
38 NxSoftBodyMeshDesc meshDesc;
39 _softbody->ptr()->getSoftBodyMesh()->saveToDesc(meshDesc);
41 NxU32 numVertices = meshDesc.numVertices;
42 NxU32 numTetrahedra = meshDesc.numTetrahedra;
48 NxU32 maxVertices = factor * numVertices;
49 _mesh.verticesPosBegin = (NxVec3 *)malloc(
sizeof(NxVec3) * maxVertices);
50 _mesh.verticesPosByteStride =
sizeof(NxVec3);
51 _mesh.maxVertices = maxVertices;
52 _mesh.numVerticesPtr = (NxU32 *)malloc(
sizeof(NxU32));
55 NxU32 maxIndices = 4 * numTetrahedra;
56 _mesh.indicesBegin = (NxU32 *)malloc(
sizeof(NxU32) * maxIndices);
57 _mesh.indicesByteStride =
sizeof(NxU32);
58 _mesh.maxIndices = maxIndices;
59 _mesh.numIndicesPtr = (NxU32 *)malloc(
sizeof(NxU32));
61 *(_mesh.numVerticesPtr) = 0;
62 *(_mesh.numIndicesPtr) = 0;
64 _softbody->ptr()->setMeshData(_mesh);
79 _prim->clear_vertices();
92 vwriter.
add_data3f(v.get_x(), v.get_y(), v.get_z());
97 nwriter.
add_data3f(n.get_x(), n.get_y(), n.get_z());
105 for (
int i=0; i<geom->get_num_primitives(); i++) {
108 prim = prim->decompose();
110 for (
int j=0; j<prim->get_num_primitives(); j++) {
112 int s = prim->get_primitive_start(j);
113 int e = prim->get_primitive_end(j);
115 for (
int l=s; l<e; l++) {
116 _prim->add_vertex(prim->get_vertex(l));
121 _prim->close_primitive();
132 void PhysxSoftBodyNode::
133 build_tetra_links() {
135 NxSoftBodyMeshDesc meshDesc;
136 _softbody->ptr()->getSoftBodyMesh()->saveToDesc(meshDesc);
137 const NxVec3 *vertices = (
const NxVec3 *) meshDesc.vertices;
138 const NxU32 *indices = (
const NxU32 *) meshDesc.tetrahedra;
139 const NxU32 numTets = meshDesc.numTetrahedra;
144 hash->set_grid_spacing(_bounds.min.distance(_bounds.max) * 0.1f);
146 for (NxU32 i=0; i<numTets; i++) {
147 const NxU32 *ix = &indices[4*i];
148 NxBounds3 tetraBounds;
149 tetraBounds.setEmpty();
150 tetraBounds.include(vertices[*ix++]);
151 tetraBounds.include(vertices[*ix++]);
152 tetraBounds.include(vertices[*ix++]);
153 tetraBounds.include(vertices[*ix++]);
154 hash->add(tetraBounds, i);
162 _drainedTriVertices.push_back(
false);
169 hash->query_unique(triVert, itemIndices);
171 NxReal minDist = 0.0f;
174 num = isize = itemIndices.size();
179 for (
int i=0; i<num; i++) {
185 const NxU32 *ix = &indices[j*4];
186 const NxVec3 &p0 = vertices[*ix++];
187 const NxVec3 &p1 = vertices[*ix++];
188 const NxVec3 &p2 = vertices[*ix++];
189 const NxVec3 &p3 = vertices[*ix++];
191 NxVec3 b = compute_bary_coords(triVert, p0, p1, p2, p3);
194 if (b.x >= 0.0f && b.y >= 0.0f && b.z >= 0.0f && (b.x + b.y + b.z) <= 1.0f) {
195 tmpLink.barycentricCoords = b;
202 if (b.x + b.y + b.z > 1.0f) dist = b.x + b.y + b.z - 1.0f;
203 if (b.x < 0.0f) dist = (-b.x < dist) ? dist : -b.x;
204 if (b.y < 0.0f) dist = (-b.y < dist) ? dist : -b.y;
205 if (b.z < 0.0f) dist = (-b.z < dist) ? dist : -b.z;
207 if (i == 0 || dist < minDist) {
209 tmpLink.barycentricCoords = b;
214 _tetraLinks.push_back(tmpLink);
225 void PhysxSoftBodyNode::
226 remove_tris_related_to_vertex(
const int vertexIndex) {
231 for (
int j=0; j<_prim->get_num_primitives(); j++) {
233 int s = _prim->get_primitive_start(j);
234 int idx0 = _prim->get_vertex(s);
235 int idx1 = _prim->get_vertex(s+1);
236 int idx2 = _prim->get_vertex(s+2);
238 if (vertexIndex == idx0 || vertexIndex == idx1 || vertexIndex == idx2) {
253 void PhysxSoftBodyNode::
271 void PhysxSoftBodyNode::
274 _normals.resize(_vdata->get_num_rows());
277 for (i=0; i<(int)_normals.size(); i++) {
284 for (
int j=0; j<_prim->get_num_primitives(); j++) {
286 int s = _prim->get_primitive_start(j);
287 int idx0 = _prim->get_vertex(s);
288 int idx1 = _prim->get_vertex(s+1);
289 int idx2 = _prim->get_vertex(s+2);
295 n = (v1 - v0).cross(v2 - v0);
302 for (i=0; i<(int)_normals.size(); i++) {
303 _normals[i].normalize();
307 for (i=0; i<(int)_normals.size(); i++) {
309 nwriter.
add_data3f(n.get_x(), n.get_y(), n.get_z());
318 NxVec3 PhysxSoftBodyNode::
319 compute_bary_coords(NxVec3 vertex, NxVec3 p0, NxVec3 p1, NxVec3 p2, NxVec3 p3)
const {
323 NxVec3 q = vertex - p3;
333 NxReal det = m.determinant();
336 baryCoords.x = m.determinant();
340 baryCoords.y = m.determinant();
344 baryCoords.z = m.determinant();
358 void PhysxSoftBodyNode::
361 update_tetra_links();
369 bool PhysxSoftBodyNode::
370 update_tetra_links() {
372 if (_tetraLinks.size() != _vdata->get_num_rows())
377 NxU32 numVertices = *_mesh.numVerticesPtr;
378 NxU32 numTetrahedra = *_mesh.numIndicesPtr / 4;
379 const NxVec3 *vertices = (NxVec3*)_mesh.verticesPosBegin;
380 NxU32* indices = (NxU32*)_mesh.indicesBegin;
387 TetraLink &link = _tetraLinks[i];
389 if (!_drainedTriVertices[i]) {
390 const NxU32 *ix = &indices[4*link.tetraNr];
392 if (*ix == *(ix + 1)) {
393 remove_tris_related_to_vertex(i);
394 _drainedTriVertices[i] =
true;
398 const NxVec3 &p0 = vertices[*ix++];
399 const NxVec3 &p1 = vertices[*ix++];
400 const NxVec3 &p2 = vertices[*ix++];
401 const NxVec3 &p3 = vertices[*ix++];
403 NxVec3 &b = link.barycentricCoords;
404 NxVec3 tmp = p0 * b.x + p1 * b.y + p2 * b.z + p3 * (1.0f - b.x - b.y - b.z);
bool is_at_end() const
Returns true if the reader or writer is currently at the end of the list of vertices, false otherwise.
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
This is the base class for all three-component vectors and points.
void add_data2f(float x, float y)
Sets the write row to a particular 2-component value, and advances the write row. ...
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
static const LVector3f & zero()
Returns a zero-length vector.
const LVecBase3f & get_data3f()
Returns the data associated with the read row, expressed as a 3-component value, and advances the rea...
void set_data3f(float x, float y, float z)
Sets the write row to a particular 3-component value, and advances the write row. ...
void set_row_unsafe(int row)
Sets the start row to the indicated value, without internal checks.
static NxVec3 vec3_to_nxVec3(const LVector3f &v)
Converts from LVector3f to NxVec3.
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
A container for geometry primitives.
This is the base class for all two-component vectors and points.
void add_data3f(float x, float y, float z)
Sets the write row to a particular 3-component value, and advances the write row. ...
const LVecBase2f & get_data2f()
Returns the data associated with the read row, expressed as a 2-component value, and advances the rea...
This object provides a high-level interface for quickly reading a sequence of numeric values from a v...
Utility class used in building links between a tetrahedron mesh (soft body) and a triangle mesh used ...
bool is_at_end() const
Returns true if the reader is currently at the end of the list of vertices, false otherwise...
void set_row_unsafe(int row)
Sets the start row to the indicated value, without internal checks.
TypeHandle is the identifier used to differentiate C++ class types.
This object provides the functionality of both a GeomVertexReader and a GeomVertexWriter, combined together into one convenient package.
void set_from_geom(const Geom *geom)
Reads the vertices and indices from an existing Geom and makes a decomposed copy of the data...