29 void PhysxSoftBodyNode::
35 NxSoftBodyMeshDesc meshDesc;
36 _softbody->ptr()->getSoftBodyMesh()->saveToDesc(meshDesc);
38 NxU32 numVertices = meshDesc.numVertices;
39 NxU32 numTetrahedra = meshDesc.numTetrahedra;
45 NxU32 maxVertices = factor * numVertices;
46 _mesh.verticesPosBegin = (NxVec3 *)malloc(
sizeof(NxVec3) * maxVertices);
47 _mesh.verticesPosByteStride =
sizeof(NxVec3);
48 _mesh.maxVertices = maxVertices;
49 _mesh.numVerticesPtr = (NxU32 *)malloc(
sizeof(NxU32));
52 NxU32 maxIndices = 4 * numTetrahedra;
53 _mesh.indicesBegin = (NxU32 *)malloc(
sizeof(NxU32) * maxIndices);
54 _mesh.indicesByteStride =
sizeof(NxU32);
55 _mesh.maxIndices = maxIndices;
56 _mesh.numIndicesPtr = (NxU32 *)malloc(
sizeof(NxU32));
58 *(_mesh.numVerticesPtr) = 0;
59 *(_mesh.numIndicesPtr) = 0;
61 _softbody->ptr()->setMeshData(_mesh);
73 _prim->clear_vertices();
86 vwriter.
add_data3f(v.get_x(), v.get_y(), v.get_z());
91 nwriter.
add_data3f(n.get_x(), n.get_y(), n.get_z());
99 for (
int i=0; i<geom->get_num_primitives(); i++) {
102 prim = prim->decompose();
104 for (
int j=0; j<prim->get_num_primitives(); j++) {
106 int s = prim->get_primitive_start(j);
107 int e = prim->get_primitive_end(j);
109 for (
int l=s; l<e; l++) {
110 _prim->add_vertex(prim->get_vertex(l));
115 _prim->close_primitive();
124 void PhysxSoftBodyNode::
125 build_tetra_links() {
127 NxSoftBodyMeshDesc meshDesc;
128 _softbody->ptr()->getSoftBodyMesh()->saveToDesc(meshDesc);
129 const NxVec3 *vertices = (
const NxVec3 *) meshDesc.vertices;
130 const NxU32 *indices = (
const NxU32 *) meshDesc.tetrahedra;
131 const NxU32 numTets = meshDesc.numTetrahedra;
136 hash->set_grid_spacing(_bounds.min.distance(_bounds.max) * 0.1f);
138 for (NxU32 i=0; i<numTets; i++) {
139 const NxU32 *ix = &indices[4*i];
140 NxBounds3 tetraBounds;
141 tetraBounds.setEmpty();
142 tetraBounds.include(vertices[*ix++]);
143 tetraBounds.include(vertices[*ix++]);
144 tetraBounds.include(vertices[*ix++]);
145 tetraBounds.include(vertices[*ix++]);
146 hash->add(tetraBounds, i);
154 _drainedTriVertices.push_back(
false);
161 hash->query_unique(triVert, itemIndices);
163 NxReal minDist = 0.0f;
166 num = isize = itemIndices.size();
171 for (
int i=0; i<num; i++) {
177 const NxU32 *ix = &indices[j*4];
178 const NxVec3 &p0 = vertices[*ix++];
179 const NxVec3 &p1 = vertices[*ix++];
180 const NxVec3 &p2 = vertices[*ix++];
181 const NxVec3 &p3 = vertices[*ix++];
183 NxVec3 b = compute_bary_coords(triVert, p0, p1, p2, p3);
186 if (b.x >= 0.0f && b.y >= 0.0f && b.z >= 0.0f && (b.x + b.y + b.z) <= 1.0f) {
187 tmpLink.barycentricCoords = b;
194 if (b.x + b.y + b.z > 1.0f) dist = b.x + b.y + b.z - 1.0f;
195 if (b.x < 0.0f) dist = (-b.x < dist) ? dist : -b.x;
196 if (b.y < 0.0f) dist = (-b.y < dist) ? dist : -b.y;
197 if (b.z < 0.0f) dist = (-b.z < dist) ? dist : -b.z;
199 if (i == 0 || dist < minDist) {
201 tmpLink.barycentricCoords = b;
206 _tetraLinks.push_back(tmpLink);
215 void PhysxSoftBodyNode::
216 remove_tris_related_to_vertex(
const int vertexIndex) {
221 for (
int j=0; j<_prim->get_num_primitives(); j++) {
223 int s = _prim->get_primitive_start(j);
224 int idx0 = _prim->get_vertex(s);
225 int idx1 = _prim->get_vertex(s+1);
226 int idx2 = _prim->get_vertex(s+2);
228 if (vertexIndex == idx0 || vertexIndex == idx1 || vertexIndex == idx2) {
241 void PhysxSoftBodyNode::
257 void PhysxSoftBodyNode::
260 _normals.resize(_vdata->get_num_rows());
263 for (i=0; i<(int)_normals.size(); i++) {
264 _normals[i] = LVector3f::zero();
267 LVecBase3f n, v0, v1, v2;
270 for (
int j=0; j<_prim->get_num_primitives(); j++) {
272 int s = _prim->get_primitive_start(j);
273 int idx0 = _prim->get_vertex(s);
274 int idx1 = _prim->get_vertex(s+1);
275 int idx2 = _prim->get_vertex(s+2);
281 n = (v1 - v0).cross(v2 - v0);
288 for (i=0; i<(int)_normals.size(); i++) {
289 _normals[i].normalize();
293 for (i=0; i<(int)_normals.size(); i++) {
295 nwriter.
add_data3f(n.get_x(), n.get_y(), n.get_z());
302 NxVec3 PhysxSoftBodyNode::
303 compute_bary_coords(NxVec3 vertex, NxVec3 p0, NxVec3 p1, NxVec3 p2, NxVec3 p3)
const {
307 NxVec3 q = vertex - p3;
317 NxReal det = m.determinant();
320 baryCoords.x = m.determinant();
324 baryCoords.y = m.determinant();
328 baryCoords.z = m.determinant();
340 void PhysxSoftBodyNode::
343 update_tetra_links();
349 bool PhysxSoftBodyNode::
350 update_tetra_links() {
352 if (_tetraLinks.size() != _vdata->get_num_rows())
357 NxU32 numVertices = *_mesh.numVerticesPtr;
358 NxU32 numTetrahedra = *_mesh.numIndicesPtr / 4;
359 const NxVec3 *vertices = (NxVec3*)_mesh.verticesPosBegin;
360 NxU32* indices = (NxU32*)_mesh.indicesBegin;
367 TetraLink &link = _tetraLinks[i];
369 if (!_drainedTriVertices[i]) {
370 const NxU32 *ix = &indices[4*link.tetraNr];
372 if (*ix == *(ix + 1)) {
373 remove_tris_related_to_vertex(i);
374 _drainedTriVertices[i] =
true;
378 const NxVec3 &p0 = vertices[*ix++];
379 const NxVec3 &p1 = vertices[*ix++];
380 const NxVec3 &p2 = vertices[*ix++];
381 const NxVec3 &p3 = vertices[*ix++];
383 NxVec3 &b = link.barycentricCoords;
384 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,...
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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...
const LVecBase3f & get_data3f()
Returns the data associated with the read row, expressed as a 3-component value, and advances the rea...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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.
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...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This object provides the functionality of both a GeomVertexReader and a GeomVertexWriter,...
void set_from_geom(const Geom *geom)
Reads the vertices and indices from an existing Geom and makes a decomposed copy of the data.