Panda3D
physxClothNode.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file physxClothNode.cxx
10  * @author enn0x
11  * @date 2010-04-05
12  */
13 
14 #include "physxClothNode.h"
15 #include "physxCloth.h"
16 #include "physxFileStream.h"
17 
18 #include "geomVertexFormat.h"
19 #include "geomVertexWriter.h"
20 
21 TypeHandle PhysxClothNode::_type_handle;
22 
23 /**
24  *
25  */
26 void PhysxClothNode::
27 allocate(PhysxCloth *cloth) {
28 
29  _cloth = cloth;
30 
31  // Retrieve number of vertices and triangles the hard way
32  NxClothMeshDesc meshDesc;
33  _cloth->ptr()->getClothMesh()->saveToDesc(meshDesc);
34 
35  NxU32 numVertices = meshDesc.numVertices;
36  NxU32 numTriangles = meshDesc.numTriangles;
37 
38  NxReal factor = 1.0f; // TODO: max(1.0f, factor);
39 
40  // Reserve more memory for vertices than the initial mesh takes because
41  // tearing creates new vertices
42  NxU32 maxVertices = factor * numVertices;
43  _mesh.verticesPosBegin = (NxVec3 *)malloc(sizeof(NxVec3) * maxVertices);
44  _mesh.verticesNormalBegin = (NxVec3 *)malloc(sizeof(NxVec3) * maxVertices);
45  _mesh.verticesPosByteStride = sizeof(NxVec3);
46  _mesh.verticesNormalByteStride = sizeof(NxVec3);
47  _mesh.maxVertices = maxVertices;
48  _mesh.numVerticesPtr = (NxU32 *)malloc(sizeof(NxU32));
49 
50  // The number of triangles is constant, even if the cloth is torn
51  NxU32 maxIndices = 3 * numTriangles;
52  _mesh.indicesBegin = (NxU32 *)malloc(sizeof(NxU32) * maxIndices);
53  _mesh.indicesByteStride = sizeof(NxU32);
54  _mesh.maxIndices = maxIndices;
55  _mesh.numIndicesPtr = (NxU32 *)malloc(sizeof(NxU32));
56 
57  NxU32 maxParentIndices = maxVertices;
58  _mesh.parentIndicesBegin = (NxU32 *)malloc(sizeof(NxU32)*maxParentIndices);
59  _mesh.parentIndicesByteStride = sizeof(NxU32);
60  _mesh.maxParentIndices = maxParentIndices;
61  _mesh.numParentIndicesPtr = (NxU32 *)malloc(sizeof(NxU32));
62 
63  *(_mesh.numVerticesPtr) = 0;
64  *(_mesh.numIndicesPtr) = 0;
65 
66  _cloth->ptr()->setMeshData(_mesh);
67 }
68 
69 /**
70  *
71  */
72 void PhysxClothNode::
73 update() {
74 
75  NxU32 numVertices = *(_mesh.numVerticesPtr);
76 
77  if (numVertices == _numVertices) {
78  update_geom();
79  }
80  else {
81  update_texcoords();
82  create_geom();
83  _numVertices = numVertices;
84  }
85 }
86 
87 /**
88  *
89  */
90 void PhysxClothNode::
91 create_geom() {
92 
93  _prim->clear_vertices();
94 
95  GeomVertexWriter vwriter = GeomVertexWriter(_vdata, InternalName::get_vertex());
96  GeomVertexWriter nwriter = GeomVertexWriter(_vdata, InternalName::get_normal());
97  GeomVertexWriter twriter = GeomVertexWriter(_vdata, InternalName::get_texcoord());
98 
99  // Vertices and normals
100  NxU32 numVertices = *(_mesh.numVerticesPtr);
101  NxVec3 *v = (NxVec3 *)_mesh.verticesPosBegin;
102  NxVec3 *n = (NxVec3 *)_mesh.verticesNormalBegin;
103 
104  for (unsigned int i=0; i < numVertices; i++) {
105  vwriter.add_data3f(v->x, v->y, v->z);
106  v++;
107  nwriter.add_data3f(n->x, n->y, n->z);
108  n++;
109  }
110 
111  // Texture coordinates
112  NxReal tex_u;
113  NxReal tex_v;
114 
115  if (_texcoords) {
116  for (unsigned int i=0; i < numVertices; i++) {
117  tex_u = _texcoords[2*i];
118  tex_v = _texcoords[2*i+1];
119  twriter.add_data2f(tex_u, tex_v);
120  }
121  }
122 
123  // Indices
124  NxU32 numIndices = *(_mesh.numIndicesPtr);
125  NxU32 *idx = (NxU32 *)_mesh.indicesBegin;
126 
127  for (unsigned int i=0; i < numIndices; i++) {
128  _prim->add_vertex(*idx);
129  idx++;
130  }
131 
132  _prim->close_primitive();
133 }
134 
135 /**
136  *
137  */
138 void PhysxClothNode::
139 update_geom() {
140 
141  GeomVertexWriter vwriter = GeomVertexWriter(_vdata, InternalName::get_vertex());
142  GeomVertexWriter nwriter = GeomVertexWriter(_vdata, InternalName::get_normal());
143 
144  NxU32 numVertices = *(_mesh.numVerticesPtr);
145  NxVec3 *v = (NxVec3 *)_mesh.verticesPosBegin;
146  NxVec3 *n = (NxVec3 *)_mesh.verticesNormalBegin;
147 
148  for (unsigned int i=0; i < numVertices; i++) {
149  vwriter.set_data3f(v->x, v->y, v->z);
150  v++;
151  nwriter.set_data3f(n->x, n->y, n->z);
152  n++;
153  }
154 }
155 
156 /**
157  *
158  */
159 void PhysxClothNode::
160 update_texcoords() {
161 
162  if (!_texcoords) {
163  return;
164  }
165 
166  NxU32 numVertices = *(_mesh.numVerticesPtr);
167  NxU32 *parent = (NxU32 *)_mesh.parentIndicesBegin + _numTexcoords;
168 
169  for (NxU32 i=_numTexcoords; i < numVertices; i++, parent++) {
170  _texcoords[2*i] = _texcoords[2*(*parent)];
171  _texcoords[2*i+1] = _texcoords[2*(*parent)+1];
172  }
173 
174  _numTexcoords = numVertices;
175 }
176 
177 /**
178  *
179  */
180 bool PhysxClothNode::
181 set_texcoords(const Filename &filename) {
182 
183  if (filename.empty()) {
184  return false;
185  }
186 
187  Filename fn(filename);
188  fn.resolve_filename(get_model_path());
189 
190  if (!filename.exists()) {
191  return false;
192  }
193 
194  PhysxFileStream fs(filename.c_str(), true);
195 
196  fs.readByte(); // N
197  fs.readByte(); // X
198  fs.readByte(); // X
199  fs.readByte(); // 1
200  fs.readByte(); // T
201  fs.readByte(); // E
202  fs.readByte(); // X
203  fs.readByte(); // C
204  fs.readByte(); // 1
205 
206  _numTexcoords = fs.readDword();
207  _texcoords = new float[2 * _numTexcoords];
208 
209  for (unsigned int i=0; i<_numTexcoords; i++) {
210  _texcoords[2*i] = fs.readFloat();
211  _texcoords[2*i+1] = fs.readFloat();
212  }
213 
214  return true;
215 }
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
void add_data2f(float x, float y)
Sets the write row to a particular 2-component value, and advances the write row.
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.
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:39
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void add_data3f(float x, float y, float z)
Sets the write row to a particular 3-component value, and advances the write row.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
bool exists() const
Returns true if the filename exists on the disk, false otherwise.
Definition: filename.cxx:1267