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 }
Filename
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:39
Filename::exists
bool exists() const
Returns true if the filename exists on the disk, false otherwise.
Definition: filename.cxx:1267
GeomVertexWriter
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
Definition: geomVertexWriter.h:55
GeomVertexWriter::set_data3f
void set_data3f(float x, float y, float z)
Sets the write row to a particular 3-component value, and advances the write row.
Definition: geomVertexWriter.I:376
GeomVertexWriter::add_data2f
void add_data2f(float x, float y)
Sets the write row to a particular 2-component value, and advances the write row.
Definition: geomVertexWriter.I:825
GeomVertexWriter::add_data3f
void add_data3f(float x, float y, float z)
Sets the write row to a particular 3-component value, and advances the write row.
Definition: geomVertexWriter.I:850
PhysxCloth
Definition: physxCloth.h:32
PhysxFileStream
Definition: physxFileStream.h:27
TypeHandle
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
geomVertexFormat.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
geomVertexWriter.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
physxClothNode.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
physxCloth.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
physxFileStream.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.