Panda3D
|
00001 // Filename: physxClothNode.cxx 00002 // Created by: enn0x (05Apr10) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "physxClothNode.h" 00016 #include "physxCloth.h" 00017 #include "physxFileStream.h" 00018 00019 #include "geomVertexFormat.h" 00020 #include "geomVertexWriter.h" 00021 00022 TypeHandle PhysxClothNode::_type_handle; 00023 00024 //////////////////////////////////////////////////////////////////// 00025 // Function: PhysxClothNode::allocate 00026 // Access: Public 00027 // Description: 00028 //////////////////////////////////////////////////////////////////// 00029 void PhysxClothNode:: 00030 allocate(PhysxCloth *cloth) { 00031 00032 _cloth = cloth; 00033 00034 // Retrieve number of vertices and triangles the hard way 00035 NxClothMeshDesc meshDesc; 00036 _cloth->ptr()->getClothMesh()->saveToDesc(meshDesc); 00037 00038 NxU32 numVertices = meshDesc.numVertices; 00039 NxU32 numTriangles = meshDesc.numTriangles; 00040 00041 NxReal factor = 1.0f; // TODO: max(1.0f, factor); 00042 00043 // Reserve more memory for vertices than the initial mesh takes because 00044 // tearing creates new vertices 00045 NxU32 maxVertices = factor * numVertices; 00046 _mesh.verticesPosBegin = (NxVec3 *)malloc(sizeof(NxVec3) * maxVertices); 00047 _mesh.verticesNormalBegin = (NxVec3 *)malloc(sizeof(NxVec3) * maxVertices); 00048 _mesh.verticesPosByteStride = sizeof(NxVec3); 00049 _mesh.verticesNormalByteStride = sizeof(NxVec3); 00050 _mesh.maxVertices = maxVertices; 00051 _mesh.numVerticesPtr = (NxU32 *)malloc(sizeof(NxU32)); 00052 00053 // The number of triangles is constant, even if the cloth is torn 00054 NxU32 maxIndices = 3 * numTriangles; 00055 _mesh.indicesBegin = (NxU32 *)malloc(sizeof(NxU32) * maxIndices); 00056 _mesh.indicesByteStride = sizeof(NxU32); 00057 _mesh.maxIndices = maxIndices; 00058 _mesh.numIndicesPtr = (NxU32 *)malloc(sizeof(NxU32)); 00059 00060 NxU32 maxParentIndices = maxVertices; 00061 _mesh.parentIndicesBegin = (NxU32 *)malloc(sizeof(NxU32)*maxParentIndices); 00062 _mesh.parentIndicesByteStride = sizeof(NxU32); 00063 _mesh.maxParentIndices = maxParentIndices; 00064 _mesh.numParentIndicesPtr = (NxU32 *)malloc(sizeof(NxU32)); 00065 00066 *(_mesh.numVerticesPtr) = 0; 00067 *(_mesh.numIndicesPtr) = 0; 00068 00069 _cloth->ptr()->setMeshData(_mesh); 00070 } 00071 00072 //////////////////////////////////////////////////////////////////// 00073 // Function: PhysxClothNode::update 00074 // Access: Public 00075 // Description: 00076 //////////////////////////////////////////////////////////////////// 00077 void PhysxClothNode:: 00078 update() { 00079 00080 NxU32 numVertices = *(_mesh.numVerticesPtr); 00081 00082 if (numVertices == _numVertices) { 00083 update_geom(); 00084 } 00085 else { 00086 update_texcoords(); 00087 create_geom(); 00088 _numVertices = numVertices; 00089 } 00090 } 00091 00092 //////////////////////////////////////////////////////////////////// 00093 // Function: PhysxClothNode::create_geom 00094 // Access: Private 00095 // Description: 00096 //////////////////////////////////////////////////////////////////// 00097 void PhysxClothNode:: 00098 create_geom() { 00099 00100 _prim->clear_vertices(); 00101 00102 GeomVertexWriter vwriter = GeomVertexWriter(_vdata, InternalName::get_vertex()); 00103 GeomVertexWriter nwriter = GeomVertexWriter(_vdata, InternalName::get_normal()); 00104 GeomVertexWriter twriter = GeomVertexWriter(_vdata, InternalName::get_texcoord()); 00105 00106 // Vertices and normals 00107 NxU32 numVertices = *(_mesh.numVerticesPtr); 00108 NxVec3 *v = (NxVec3 *)_mesh.verticesPosBegin; 00109 NxVec3 *n = (NxVec3 *)_mesh.verticesNormalBegin; 00110 00111 for (unsigned int i=0; i < numVertices; i++) { 00112 vwriter.add_data3f(v->x, v->y, v->z); 00113 v++; 00114 nwriter.add_data3f(n->x, n->y, n->z); 00115 n++; 00116 } 00117 00118 // Texture coordinates 00119 NxReal tex_u; 00120 NxReal tex_v; 00121 00122 if (_texcoords) { 00123 for (unsigned int i=0; i < numVertices; i++) { 00124 tex_u = _texcoords[2*i]; 00125 tex_v = _texcoords[2*i+1]; 00126 twriter.add_data2f(tex_u, tex_v); 00127 } 00128 } 00129 00130 // Indices 00131 NxU32 numIndices = *(_mesh.numIndicesPtr); 00132 NxU32 *idx = (NxU32 *)_mesh.indicesBegin; 00133 00134 for (unsigned int i=0; i < numIndices; i++) { 00135 _prim->add_vertex(*idx); 00136 idx++; 00137 } 00138 00139 _prim->close_primitive(); 00140 } 00141 00142 //////////////////////////////////////////////////////////////////// 00143 // Function: PhysxClothNode::update_geom 00144 // Access: Private 00145 // Description: 00146 //////////////////////////////////////////////////////////////////// 00147 void PhysxClothNode:: 00148 update_geom() { 00149 00150 GeomVertexWriter vwriter = GeomVertexWriter(_vdata, InternalName::get_vertex()); 00151 GeomVertexWriter nwriter = GeomVertexWriter(_vdata, InternalName::get_normal()); 00152 00153 NxU32 numVertices = *(_mesh.numVerticesPtr); 00154 NxVec3 *v = (NxVec3 *)_mesh.verticesPosBegin; 00155 NxVec3 *n = (NxVec3 *)_mesh.verticesNormalBegin; 00156 00157 for (unsigned int i=0; i < numVertices; i++) { 00158 vwriter.set_data3f(v->x, v->y, v->z); 00159 v++; 00160 nwriter.set_data3f(n->x, n->y, n->z); 00161 n++; 00162 } 00163 } 00164 00165 //////////////////////////////////////////////////////////////////// 00166 // Function: PhysxClothNode::update_texcoords 00167 // Access: Private 00168 // Description: 00169 //////////////////////////////////////////////////////////////////// 00170 void PhysxClothNode:: 00171 update_texcoords() { 00172 00173 if (!_texcoords) { 00174 return; 00175 } 00176 00177 NxU32 numVertices = *(_mesh.numVerticesPtr); 00178 NxU32 *parent = (NxU32 *)_mesh.parentIndicesBegin + _numTexcoords; 00179 00180 for (NxU32 i=_numTexcoords; i < numVertices; i++, parent++) { 00181 _texcoords[2*i] = _texcoords[2*(*parent)]; 00182 _texcoords[2*i+1] = _texcoords[2*(*parent)+1]; 00183 } 00184 00185 _numTexcoords = numVertices; 00186 } 00187 00188 //////////////////////////////////////////////////////////////////// 00189 // Function: PhysxClothNode::set_texcoords 00190 // Access: Published 00191 // Description: 00192 //////////////////////////////////////////////////////////////////// 00193 bool PhysxClothNode:: 00194 set_texcoords(const Filename &filename) { 00195 00196 if (filename.empty()) { 00197 return false; 00198 } 00199 00200 Filename fn(filename); 00201 fn.resolve_filename(get_model_path()); 00202 00203 if (!filename.exists()) { 00204 return false; 00205 } 00206 00207 PhysxFileStream fs(filename.c_str(), true); 00208 00209 fs.readByte(); // N 00210 fs.readByte(); // X 00211 fs.readByte(); // X 00212 fs.readByte(); // 1 00213 fs.readByte(); // T 00214 fs.readByte(); // E 00215 fs.readByte(); // X 00216 fs.readByte(); // C 00217 fs.readByte(); // 1 00218 00219 _numTexcoords = fs.readDword(); 00220 _texcoords = new float[2 * _numTexcoords]; 00221 00222 for (unsigned int i=0; i<_numTexcoords; i++) { 00223 _texcoords[2*i] = fs.readFloat(); 00224 _texcoords[2*i+1] = fs.readFloat(); 00225 } 00226 00227 return true; 00228 } 00229