Panda3D
|
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 }