Panda3D
 All Classes Functions Variables Enumerations
odeTriMeshData.cxx
00001 // Filename: odeTriMeshData.cxx
00002 // Created by:  joswilso (27Dec06)
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 #include "config_ode.h"
00015 #include "odeTriMeshData.h"
00016 
00017 TypeHandle OdeTriMeshData::_type_handle;
00018 OdeTriMeshData::TriMeshDataMap *OdeTriMeshData::_tri_mesh_data_map = NULL;
00019 
00020 void OdeTriMeshData::
00021 link_data(dGeomID id, PT(OdeTriMeshData) data) {
00022   odetrimeshdata_cat.debug() << get_class_type() << "::link_data(" << id << "->" << data << ")" << "\n";
00023   get_tri_mesh_data_map()[id] = data;
00024 }
00025 
00026 PT(OdeTriMeshData) OdeTriMeshData::
00027 get_data(dGeomID id) {
00028   const TriMeshDataMap &data_map = get_tri_mesh_data_map();
00029   TriMeshDataMap::const_iterator iter = data_map.find(id);
00030   if (iter != data_map.end()) {
00031     return iter->second;
00032   }
00033   return 0;
00034 }
00035 
00036 void OdeTriMeshData::
00037 unlink_data(dGeomID id) {
00038   odetrimeshdata_cat.debug() << get_class_type() << "::unlink_data(" << id << ")" << "\n";
00039   nassertv(_tri_mesh_data_map != (TriMeshDataMap *)NULL);
00040   TriMeshDataMap::iterator iter = _tri_mesh_data_map->find(id);
00041   if (iter != _tri_mesh_data_map->end()) {
00042     _tri_mesh_data_map->erase(iter);
00043   }
00044 }
00045 
00046 void OdeTriMeshData::
00047 print_data(const string &marker) {
00048   odetrimeshdata_cat.debug() << get_class_type() << "::print_data(" << marker << ")\n"; 
00049   const TriMeshDataMap &data_map = get_tri_mesh_data_map();
00050   TriMeshDataMap::const_iterator iter = data_map.begin();
00051   for (;iter != data_map.end(); ++iter) {
00052     odetrimeshdata_cat.debug() << "\t" << iter->first << " : " << iter->second << "\n";
00053   }
00054 }
00055 
00056 void OdeTriMeshData::
00057 remove_data(OdeTriMeshData *data) {
00058   odetrimeshdata_cat.debug() << get_class_type() << "::remove_data(" << data->get_id() << ")" << "\n";
00059   nassertv(_tri_mesh_data_map != (TriMeshDataMap *)NULL);
00060   TriMeshDataMap::iterator iter;
00061   
00062   for (iter = _tri_mesh_data_map->begin();
00063        iter != _tri_mesh_data_map->end();
00064        ++iter) {
00065     if ( iter->second == data ) {
00066       break;
00067     }
00068   }
00069   
00070   while (iter != _tri_mesh_data_map->end()) {
00071     _tri_mesh_data_map->erase(iter);
00072     
00073     for (iter = _tri_mesh_data_map->begin();
00074          iter != _tri_mesh_data_map->end();
00075          ++iter) {
00076       if ( iter->second == data ) {
00077         break;
00078       }
00079     }
00080   }
00081 }
00082 
00083 
00084 ////////////////////////////////////////////////////////////////////
00085 ////////////////////////////////////////////////////////////////////
00086 
00087 OdeTriMeshData::
00088 OdeTriMeshData(const NodePath& model, bool use_normals) :
00089   _id(dGeomTriMeshDataCreate()),
00090   _vertices(0),
00091   _faces(0),
00092   _normals(0),
00093   _num_vertices(0),
00094   _num_faces(0) {
00095   odetrimeshdata_cat.debug() << get_type() << "(" << _id << ")" << "\n";
00096   
00097   process_model(model, use_normals);
00098 
00099   write_faces(odetrimeshdata_cat.debug());
00100 
00101   if (!use_normals) {
00102     build_single(_vertices, sizeof(StridedVertex), _num_vertices,
00103                  _faces, _num_faces * 3, sizeof(StridedTri));
00104   } else {
00105     build_single1(_vertices, sizeof(StridedVertex), _num_vertices,
00106                   _faces, _num_faces * 3, sizeof(StridedTri),
00107                   _normals);
00108   }
00109 
00110   preprocess();
00111 }
00112 
00113 // Private copy constructor, shouldn't be copying these objects
00114 OdeTriMeshData::
00115 OdeTriMeshData(const OdeTriMeshData &other) {
00116 }
00117 
00118 OdeTriMeshData::
00119 ~OdeTriMeshData() {
00120   odetrimeshdata_cat.debug() << "~" << get_type() << "(" << _id << ")" << "\n";
00121   destroy();
00122   if (_vertices != 0) {
00123     PANDA_FREE_ARRAY(_vertices);
00124     _vertices = 0;
00125     _num_vertices = 0;
00126   }
00127   if (_faces != 0) {
00128     PANDA_FREE_ARRAY(_faces);
00129     _faces = 0;
00130   }
00131   if (_normals != 0) {
00132     // This is never allocated?  Until we use _normals, assert that we
00133     // don't accidentally free it here through some mistake.
00134     nassertv(false);
00135     PANDA_FREE_ARRAY(_normals);
00136   }
00137 }
00138 
00139 void OdeTriMeshData::
00140 destroy() {
00141   odetrimeshdata_cat.debug() << get_type() << "::destroy(" << _id << ")" << "\n";
00142   if (_id != 0) {
00143     dGeomTriMeshDataDestroy(_id);
00144     remove_data(this);
00145     _id = 0; 
00146   }
00147 }
00148 
00149 // Private assignment operator, shouldn't be copying these objects
00150 void OdeTriMeshData::
00151 operator = (const OdeTriMeshData &other) {
00152 }
00153 
00154 void OdeTriMeshData::
00155 process_model(const NodePath& model, bool &use_normals) {
00156   // TODO: assert if _vertices is something other than 0.
00157   ostream &out = odetrimeshdata_cat.debug();
00158   out << "process_model(" << model << ")" << "\n";
00159 
00160   NodePathCollection geomNodePaths = model.find_all_matches("**/+GeomNode");
00161   if (model.node()->get_type() == GeomNode::get_class_type()) {
00162     geomNodePaths.add_path(model);
00163   }
00164 
00165   for (int i = 0; i < geomNodePaths.get_num_paths(); ++i) {
00166     analyze((GeomNode*)geomNodePaths[i].node());
00167   }
00168 
00169   odetrimeshdata_cat.debug() << "Found " << _num_vertices << " vertices.\n";
00170   odetrimeshdata_cat.debug() << "Found " << _num_faces << " faces.\n";
00171   
00172   _vertices = (StridedVertex *)PANDA_MALLOC_ARRAY(_num_vertices * sizeof(StridedVertex));
00173   _faces = (StridedTri *)PANDA_MALLOC_ARRAY(_num_faces * sizeof(StridedTri));
00174   
00175   _num_vertices = 0, _num_faces = 0;
00176 
00177   for (int i = 0; i < geomNodePaths.get_num_paths(); ++i) {
00178     process_geom_node((GeomNode*)geomNodePaths[i].node());
00179     odetrimeshdata_cat.debug() << "_num_vertices now at " << _num_vertices << "\n";
00180   }
00181 
00182   odetrimeshdata_cat.debug() << "Filled " << _num_faces << " triangles(" \
00183                       << _num_vertices << " vertices)\n";
00184 }
00185 
00186 void OdeTriMeshData::
00187 process_geom_node(const GeomNode *geomNode) {
00188   ostream &out = odetrimeshdata_cat.debug();
00189   out.width(2); out << "" << "process_geom_node(" << *geomNode << ")" << "\n";
00190   for (int i = 0; i < geomNode->get_num_geoms(); ++i) {
00191     process_geom(geomNode->get_geom(i));
00192   }
00193 }
00194 
00195 void OdeTriMeshData::
00196 process_geom(const Geom *geom) {
00197   ostream &out = odetrimeshdata_cat.debug();
00198   out.width(4); out << "" << "process_geom(" << *geom << ")" << "\n";
00199   if (geom->get_primitive_type() != Geom::PT_polygons) {
00200     return;
00201   } 
00202 
00203   CPT(GeomVertexData) vData = geom->get_vertex_data();
00204 
00205   for (int i = 0; i < geom->get_num_primitives(); ++i) {
00206     process_primitive(geom->get_primitive(i), vData);
00207   }
00208 }
00209 
00210 void OdeTriMeshData::
00211 process_primitive(const GeomPrimitive *primitive, 
00212                    CPT(GeomVertexData) vData) {
00213   GeomVertexReader vReader(vData, "vertex");
00214   GeomVertexReader nReader(vData, "normal");
00215   LVecBase3f vertex, normal;
00216   //CPT(GeomPrimitive) dPrimitive = primitive->decompose();
00217   CPT(GeomPrimitive) dPrimitive = primitive;
00218   ostream &out = odetrimeshdata_cat.debug();
00219   out.width(6); out << "" << "process_primitive(" << *dPrimitive << ")" << "\n";
00220   
00221 
00222   if (dPrimitive->get_type() == GeomTriangles::get_class_type()) {
00223     for (int i = 0; i < dPrimitive->get_num_primitives(); i++, _num_faces++) {
00224       int s = dPrimitive->get_primitive_start(i);
00225       int e = dPrimitive->get_primitive_end(i);
00226       out.width(8); out << "" << "primitive " << i << ":" << "\n";
00227       for (int j = s, m = 0; j < e; j++, m++, _num_vertices++) {
00228         int vRowIndex = dPrimitive->get_vertex(j);
00229         vReader.set_row_unsafe(vRowIndex);
00230         nReader.set_row_unsafe(vRowIndex);
00231         vertex = vReader.get_data3f();
00232         //normal = nReader.get_data3f();
00233         _faces[_num_faces].Indices[m] = _num_vertices;
00234 
00235         _vertices[_num_vertices].Vertex[0] = vertex[0];
00236         _vertices[_num_vertices].Vertex[1] = vertex[1];
00237         _vertices[_num_vertices].Vertex[2] = vertex[2];
00238 
00239         out.width(10); out << "" << "vertex " << j << " has: pos(" \
00240                            << vertex << ") normal(" << "normal"  << ")" << "\n";
00241       }
00242     }
00243   } else if (dPrimitive->get_type() == GeomTristrips::get_class_type()){
00244     for (int i = 0; i < dPrimitive->get_num_primitives(); i++, _num_faces++) {
00245       int s = dPrimitive->get_primitive_start(i);
00246       int e = dPrimitive->get_primitive_end(i);
00247       out.width(8); out << "" << "primitive " << i << ":" << "\n";
00248       for (int j = s, m = 0; j < e; j++, m++, _num_vertices++) {
00249         int vRowIndex = dPrimitive->get_vertex(j);
00250         vReader.set_row_unsafe(vRowIndex);
00251         nReader.set_row_unsafe(vRowIndex);
00252         vertex = vReader.get_data3f();
00253         //normal = nReader.get_data3f();
00254 
00255         _vertices[_num_vertices].Vertex[0] = vertex[0];
00256         _vertices[_num_vertices].Vertex[1] = vertex[1];
00257         _vertices[_num_vertices].Vertex[2] = vertex[2];
00258         out.width(10); out << "" << "vertex " << j << " has: pos(" \
00259                            << vertex << ") normal(" << "normal" << ")" << "\n";
00260         if (m < 3) {
00261           _faces[_num_faces].Indices[m] = _num_vertices;
00262         } else {
00263           _num_faces++;
00264           if ( m & 1) {
00265             _faces[_num_faces].Indices[0] = _num_vertices-1;
00266             _faces[_num_faces].Indices[1] = _num_vertices-2;
00267             _faces[_num_faces].Indices[2] = _num_vertices;
00268           } else {
00269             _faces[_num_faces].Indices[0] = _num_vertices-2;
00270             _faces[_num_faces].Indices[1] = _num_vertices-1;
00271             _faces[_num_faces].Indices[2] = _num_vertices;
00272           }
00273         }      
00274       }
00275       out << "\n";
00276     }
00277   }
00278 }
00279 void OdeTriMeshData::
00280 analyze(const GeomNode *geomNode) {
00281   for (int i = 0; i < geomNode->get_num_geoms(); ++i) {
00282     analyze(geomNode->get_geom(i));
00283   }
00284 }
00285 
00286 void OdeTriMeshData::
00287 analyze(const Geom *geom) {
00288   if (geom->get_primitive_type() != Geom::PT_polygons) {
00289     return;
00290   } 
00291 
00292   for (int i = 0; i < geom->get_num_primitives(); ++i) {
00293     analyze(geom->get_primitive(i));
00294   }
00295 }
00296 
00297 void OdeTriMeshData::
00298 analyze(const GeomPrimitive *primitive) {
00299   for (int i = 0; i < primitive->get_num_primitives(); ++i) {
00300     _num_vertices += primitive->get_primitive_num_vertices(i);
00301     _num_faces += primitive->get_primitive_num_faces(i);
00302   }
00303 }
00304 
00305 void OdeTriMeshData::
00306 write_faces(ostream &out) const {
00307   out<<"\n";
00308   for (unsigned int i = 0; i < _num_faces; ++i) {
00309     out.width(2); out << "Face " << i << ":\n";
00310     for (int j = 0; j < 3; ++j) {
00311       out.width(4); 
00312       out << "(" << _vertices[_faces[i].Indices[j]].Vertex[0] \
00313           << ", " << _vertices[_faces[i].Indices[j]].Vertex[1] \
00314           << ", " << _vertices[_faces[i].Indices[j]].Vertex[2] << ")\n" ;
00315     }
00316   }
00317 }
00318 
00319 void OdeTriMeshData::
00320 write(ostream &out, unsigned int indent) const {
00321   out.width(indent); out << "" << get_type() << "(id = " << _id << ") : " \
00322                          << "" << "Vertices: " << (_id ? _num_vertices : 0) << ", " \
00323                          << "" << "Triangles: " << (_id ? _num_faces : 0);
00324 }
 All Classes Functions Variables Enumerations