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 }
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:39
bool exists() const
Returns true if the filename exists on the disk, false otherwise.
Definition: filename.cxx:1267
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.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
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.