2
0

odeTriMeshData.cxx 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. /**
  2. * PANDA 3D SOFTWARE
  3. * Copyright (c) Carnegie Mellon University. All rights reserved.
  4. *
  5. * All use of this software is subject to the terms of the revised BSD
  6. * license. You should have received a copy of this license along
  7. * with this source code in a file named "LICENSE."
  8. *
  9. * @file odeTriMeshData.cxx
  10. * @author joswilso
  11. * @date 2006-12-27
  12. */
  13. #include "odeTriMeshData.h"
  14. TypeHandle OdeTriMeshData::_type_handle;
  15. OdeTriMeshData::TriMeshDataMap *OdeTriMeshData::_tri_mesh_data_map = NULL;
  16. void OdeTriMeshData::
  17. link_data(dGeomID id, PT(OdeTriMeshData) data) {
  18. odetrimeshdata_cat.debug() << get_class_type() << "::link_data(" << id << "->" << data << ")" << "\n";
  19. get_tri_mesh_data_map()[id] = data;
  20. }
  21. PT(OdeTriMeshData) OdeTriMeshData::
  22. get_data(dGeomID id) {
  23. const TriMeshDataMap &data_map = get_tri_mesh_data_map();
  24. TriMeshDataMap::const_iterator iter = data_map.find(id);
  25. if (iter != data_map.end()) {
  26. return iter->second;
  27. }
  28. return NULL;
  29. }
  30. void OdeTriMeshData::
  31. unlink_data(dGeomID id) {
  32. odetrimeshdata_cat.debug() << get_class_type() << "::unlink_data(" << id << ")" << "\n";
  33. nassertv(_tri_mesh_data_map != (TriMeshDataMap *)NULL);
  34. TriMeshDataMap::iterator iter = _tri_mesh_data_map->find(id);
  35. if (iter != _tri_mesh_data_map->end()) {
  36. _tri_mesh_data_map->erase(iter);
  37. }
  38. }
  39. void OdeTriMeshData::
  40. print_data(const string &marker) {
  41. odetrimeshdata_cat.debug() << get_class_type() << "::print_data(" << marker << ")\n";
  42. const TriMeshDataMap &data_map = get_tri_mesh_data_map();
  43. TriMeshDataMap::const_iterator iter = data_map.begin();
  44. for (;iter != data_map.end(); ++iter) {
  45. odetrimeshdata_cat.debug() << "\t" << iter->first << " : " << iter->second << "\n";
  46. }
  47. }
  48. void OdeTriMeshData::
  49. remove_data(OdeTriMeshData *data) {
  50. if (odetrimeshdata_cat.is_debug()) {
  51. odetrimeshdata_cat.debug()
  52. << get_class_type() << "::remove_data(" << data->get_id() << ")" << "\n";
  53. }
  54. if (_tri_mesh_data_map == (TriMeshDataMap *)NULL) {
  55. return;
  56. }
  57. TriMeshDataMap::iterator iter;
  58. for (iter = _tri_mesh_data_map->begin();
  59. iter != _tri_mesh_data_map->end();
  60. ++iter) {
  61. if (iter->second == data) {
  62. break;
  63. }
  64. }
  65. while (iter != _tri_mesh_data_map->end()) {
  66. _tri_mesh_data_map->erase(iter);
  67. for (iter = _tri_mesh_data_map->begin();
  68. iter != _tri_mesh_data_map->end();
  69. ++iter) {
  70. if (iter->second == data) {
  71. break;
  72. }
  73. }
  74. }
  75. }
  76. OdeTriMeshData::
  77. OdeTriMeshData(const NodePath& model, bool use_normals) :
  78. _id(dGeomTriMeshDataCreate()),
  79. _vertices(0),
  80. _faces(0),
  81. _normals(0),
  82. _num_vertices(0),
  83. _num_faces(0) {
  84. odetrimeshdata_cat.debug() << get_type() << "(" << _id << ")" << "\n";
  85. process_model(model, use_normals);
  86. write_faces(odetrimeshdata_cat.debug());
  87. if (!use_normals) {
  88. build_single(_vertices, sizeof(StridedVertex), _num_vertices,
  89. _faces, _num_faces * 3, sizeof(StridedTri));
  90. } else {
  91. build_single1(_vertices, sizeof(StridedVertex), _num_vertices,
  92. _faces, _num_faces * 3, sizeof(StridedTri),
  93. _normals);
  94. }
  95. preprocess();
  96. }
  97. // Private copy constructor, shouldn't be copying these objects
  98. OdeTriMeshData::
  99. OdeTriMeshData(const OdeTriMeshData &other) {
  100. }
  101. OdeTriMeshData::
  102. ~OdeTriMeshData() {
  103. odetrimeshdata_cat.debug() << "~" << get_type() << "(" << _id << ")" << "\n";
  104. destroy();
  105. if (_vertices != 0) {
  106. PANDA_FREE_ARRAY(_vertices);
  107. _vertices = 0;
  108. _num_vertices = 0;
  109. }
  110. if (_faces != 0) {
  111. PANDA_FREE_ARRAY(_faces);
  112. _faces = 0;
  113. }
  114. if (_normals != 0) {
  115. // This is never allocated? Until we use _normals, assert that we don't
  116. // accidentally free it here through some mistake.
  117. nassertv(false);
  118. PANDA_FREE_ARRAY(_normals);
  119. }
  120. }
  121. void OdeTriMeshData::
  122. destroy() {
  123. odetrimeshdata_cat.debug() << get_type() << "::destroy(" << _id << ")" << "\n";
  124. if (_id != 0) {
  125. dGeomTriMeshDataDestroy(_id);
  126. remove_data(this);
  127. _id = 0;
  128. }
  129. }
  130. // Private assignment operator, shouldn't be copying these objects
  131. void OdeTriMeshData::
  132. operator = (const OdeTriMeshData &other) {
  133. }
  134. void OdeTriMeshData::
  135. process_model(const NodePath& model, bool &use_normals) {
  136. // TODO: assert if _vertices is something other than 0.
  137. if (odetrimeshdata_cat.is_debug()) {
  138. odetrimeshdata_cat.debug()
  139. << "process_model(" << model << ")" << "\n";
  140. }
  141. if (model.is_empty()) {
  142. return;
  143. }
  144. NodePathCollection geomNodePaths = model.find_all_matches("**/+GeomNode");
  145. if (model.node()->get_type() == GeomNode::get_class_type()) {
  146. geomNodePaths.add_path(model);
  147. }
  148. for (int i = 0; i < geomNodePaths.get_num_paths(); ++i) {
  149. analyze((GeomNode*)geomNodePaths[i].node());
  150. }
  151. odetrimeshdata_cat.debug() << "Found " << _num_vertices << " vertices.\n";
  152. odetrimeshdata_cat.debug() << "Found " << _num_faces << " faces.\n";
  153. _vertices = (StridedVertex *)PANDA_MALLOC_ARRAY(_num_vertices * sizeof(StridedVertex));
  154. _faces = (StridedTri *)PANDA_MALLOC_ARRAY(_num_faces * sizeof(StridedTri));
  155. _num_vertices = 0, _num_faces = 0;
  156. for (int i = 0; i < geomNodePaths.get_num_paths(); ++i) {
  157. process_geom_node((GeomNode*)geomNodePaths[i].node());
  158. odetrimeshdata_cat.debug() << "_num_vertices now at " << _num_vertices << "\n";
  159. }
  160. odetrimeshdata_cat.debug() << "Filled " << _num_faces << " triangles(" \
  161. << _num_vertices << " vertices)\n";
  162. }
  163. void OdeTriMeshData::
  164. process_geom_node(const GeomNode *geomNode) {
  165. ostream &out = odetrimeshdata_cat.debug();
  166. out.width(2); out << "" << "process_geom_node(" << *geomNode << ")" << "\n";
  167. for (int i = 0; i < geomNode->get_num_geoms(); ++i) {
  168. process_geom(geomNode->get_geom(i));
  169. }
  170. }
  171. void OdeTriMeshData::
  172. process_geom(const Geom *geom) {
  173. ostream &out = odetrimeshdata_cat.debug();
  174. out.width(4); out << "" << "process_geom(" << *geom << ")" << "\n";
  175. if (geom->get_primitive_type() != Geom::PT_polygons) {
  176. return;
  177. }
  178. CPT(GeomVertexData) vData = geom->get_vertex_data();
  179. for (int i = 0; i < geom->get_num_primitives(); ++i) {
  180. process_primitive(geom->get_primitive(i), vData);
  181. }
  182. }
  183. void OdeTriMeshData::
  184. process_primitive(const GeomPrimitive *primitive,
  185. CPT(GeomVertexData) vData) {
  186. GeomVertexReader vReader(vData, "vertex");
  187. GeomVertexReader nReader(vData, "normal");
  188. LVecBase3f vertex, normal;
  189. // CPT(GeomPrimitive) dPrimitive = primitive->decompose();
  190. CPT(GeomPrimitive) dPrimitive = primitive;
  191. ostream &out = odetrimeshdata_cat.debug();
  192. out.width(6); out << "" << "process_primitive(" << *dPrimitive << ")" << "\n";
  193. if (dPrimitive->get_type() == GeomTriangles::get_class_type()) {
  194. for (int i = 0; i < dPrimitive->get_num_primitives(); i++, _num_faces++) {
  195. int s = dPrimitive->get_primitive_start(i);
  196. int e = dPrimitive->get_primitive_end(i);
  197. out.width(8); out << "" << "primitive " << i << ":" << "\n";
  198. for (int j = s, m = 0; j < e; j++, m++, _num_vertices++) {
  199. int vRowIndex = dPrimitive->get_vertex(j);
  200. vReader.set_row_unsafe(vRowIndex);
  201. nReader.set_row_unsafe(vRowIndex);
  202. vertex = vReader.get_data3f();
  203. // normal = nReader.get_data3f();
  204. _faces[_num_faces].Indices[m] = _num_vertices;
  205. _vertices[_num_vertices].Vertex[0] = vertex[0];
  206. _vertices[_num_vertices].Vertex[1] = vertex[1];
  207. _vertices[_num_vertices].Vertex[2] = vertex[2];
  208. out.width(10); out << "" << "vertex " << j << " has: pos(" \
  209. << vertex << ") normal(" << "normal" << ")" << "\n";
  210. }
  211. }
  212. } else if (dPrimitive->get_type() == GeomTristrips::get_class_type()){
  213. for (int i = 0; i < dPrimitive->get_num_primitives(); i++, _num_faces++) {
  214. int s = dPrimitive->get_primitive_start(i);
  215. int e = dPrimitive->get_primitive_end(i);
  216. out.width(8); out << "" << "primitive " << i << ":" << "\n";
  217. for (int j = s, m = 0; j < e; j++, m++, _num_vertices++) {
  218. int vRowIndex = dPrimitive->get_vertex(j);
  219. vReader.set_row_unsafe(vRowIndex);
  220. nReader.set_row_unsafe(vRowIndex);
  221. vertex = vReader.get_data3f();
  222. // normal = nReader.get_data3f();
  223. _vertices[_num_vertices].Vertex[0] = vertex[0];
  224. _vertices[_num_vertices].Vertex[1] = vertex[1];
  225. _vertices[_num_vertices].Vertex[2] = vertex[2];
  226. out.width(10); out << "" << "vertex " << j << " has: pos(" \
  227. << vertex << ") normal(" << "normal" << ")" << "\n";
  228. if (m < 3) {
  229. _faces[_num_faces].Indices[m] = _num_vertices;
  230. } else {
  231. _num_faces++;
  232. if ( m & 1) {
  233. _faces[_num_faces].Indices[0] = _num_vertices-1;
  234. _faces[_num_faces].Indices[1] = _num_vertices-2;
  235. _faces[_num_faces].Indices[2] = _num_vertices;
  236. } else {
  237. _faces[_num_faces].Indices[0] = _num_vertices-2;
  238. _faces[_num_faces].Indices[1] = _num_vertices-1;
  239. _faces[_num_faces].Indices[2] = _num_vertices;
  240. }
  241. }
  242. }
  243. out << "\n";
  244. }
  245. }
  246. }
  247. void OdeTriMeshData::
  248. analyze(const GeomNode *geomNode) {
  249. for (int i = 0; i < geomNode->get_num_geoms(); ++i) {
  250. analyze(geomNode->get_geom(i));
  251. }
  252. }
  253. void OdeTriMeshData::
  254. analyze(const Geom *geom) {
  255. if (geom->get_primitive_type() != Geom::PT_polygons) {
  256. return;
  257. }
  258. for (int i = 0; i < geom->get_num_primitives(); ++i) {
  259. analyze(geom->get_primitive(i));
  260. }
  261. }
  262. void OdeTriMeshData::
  263. analyze(const GeomPrimitive *primitive) {
  264. for (int i = 0; i < primitive->get_num_primitives(); ++i) {
  265. _num_vertices += primitive->get_primitive_num_vertices(i);
  266. _num_faces += primitive->get_primitive_num_faces(i);
  267. }
  268. }
  269. void OdeTriMeshData::
  270. write_faces(ostream &out) const {
  271. out<<"\n";
  272. for (unsigned int i = 0; i < _num_faces; ++i) {
  273. out.width(2); out << "Face " << i << ":\n";
  274. for (int j = 0; j < 3; ++j) {
  275. out.width(4);
  276. out << "(" << _vertices[_faces[i].Indices[j]].Vertex[0] \
  277. << ", " << _vertices[_faces[i].Indices[j]].Vertex[1] \
  278. << ", " << _vertices[_faces[i].Indices[j]].Vertex[2] << ")\n" ;
  279. }
  280. }
  281. }
  282. void OdeTriMeshData::
  283. write(ostream &out, unsigned int indent) const {
  284. out.width(indent); out << "" << get_type() << "(id = " << _id << ") : " \
  285. << "" << "Vertices: " << (_id ? _num_vertices : 0) << ", " \
  286. << "" << "Triangles: " << (_id ? _num_faces : 0);
  287. }