Panda3D
 All Classes Functions Variables Enumerations
physxClothNode.cxx
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 
 All Classes Functions Variables Enumerations