Panda3D

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