00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
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
00133
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
00150 void OdeTriMeshData::
00151 operator = (const OdeTriMeshData &other) {
00152 }
00153
00154 void OdeTriMeshData::
00155 process_model(const NodePath& model, bool &use_normals) {
00156
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
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
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
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 }