29void 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();
124void PhysxSoftBodyNode::
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);
215void PhysxSoftBodyNode::
216remove_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) {
241void PhysxSoftBodyNode::
257void 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());
302NxVec3 PhysxSoftBodyNode::
303compute_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();
340void PhysxSoftBodyNode::
343 update_tetra_links();
349bool PhysxSoftBodyNode::
350update_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);
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
This object provides a high-level interface for quickly reading a sequence of numeric values from a v...
bool is_at_end() const
Returns true if the reader is currently at the end of the list of vertices, false otherwise.
const LVecBase3f & get_data3f()
Returns the data associated with the read row, expressed as a 3-component value, and advances the rea...
const LVecBase2f & get_data2f()
Returns the data associated with the read row, expressed as a 2-component value, and advances the rea...
void set_row_unsafe(int row)
Sets the start row to the indicated value, without internal checks.
This object provides the functionality of both a GeomVertexReader and a GeomVertexWriter,...
void set_row_unsafe(int row)
Sets the start row to the indicated value, without internal checks.
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...
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 add_data2f(float x, float y)
Sets the write row to a particular 2-component value, and advances the write row.
void add_data3f(float x, float y, float z)
Sets the write row to a particular 3-component value, and advances the write row.
A container for geometry primitives.
static NxVec3 vec3_to_nxVec3(const LVector3f &v)
Converts from LVector3f to NxVec3.
Utility class used in building links between a tetrahedron mesh (soft body) and a triangle mesh used ...
void set_from_geom(const Geom *geom)
Reads the vertices and indices from an existing Geom and makes a decomposed copy of the data.
TypeHandle is the identifier used to differentiate C++ class types.
This is our own Panda specialization on the default STL vector.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.