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