xFileMesh.cxx 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718
  1. // Filename: xFileMesh.cxx
  2. // Created by: drose (19Jun01)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. //
  6. // PANDA 3D SOFTWARE
  7. // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
  8. //
  9. // All use of this software is subject to the terms of the Panda 3d
  10. // Software license. You should have received a copy of this license
  11. // along with this source code; you will also find a current copy of
  12. // the license at http://www.panda3d.org/license.txt .
  13. //
  14. // To contact the maintainers of this program write to
  15. // [email protected] .
  16. //
  17. ////////////////////////////////////////////////////////////////////
  18. #include "xFileMesh.h"
  19. #include "xFileFace.h"
  20. #include "xFileVertex.h"
  21. #include "xFileNormal.h"
  22. #include "xFileMaterial.h"
  23. #include "eggVertexPool.h"
  24. #include "eggVertex.h"
  25. #include "eggPolygon.h"
  26. #include "eggGroupNode.h"
  27. ////////////////////////////////////////////////////////////////////
  28. // Function: XFileMesh::Constructor
  29. // Access: Public
  30. // Description:
  31. ////////////////////////////////////////////////////////////////////
  32. XFileMesh::
  33. XFileMesh() {
  34. _has_normals = false;
  35. _has_colors = false;
  36. _has_uvs = false;
  37. _has_materials = false;
  38. }
  39. ////////////////////////////////////////////////////////////////////
  40. // Function: XFileMesh::Destructor
  41. // Access: Public
  42. // Description:
  43. ////////////////////////////////////////////////////////////////////
  44. XFileMesh::
  45. ~XFileMesh() {
  46. clear();
  47. }
  48. ////////////////////////////////////////////////////////////////////
  49. // Function: XFileMesh::clear
  50. // Access: Public
  51. // Description: Empties all data from the mesh.
  52. ////////////////////////////////////////////////////////////////////
  53. void XFileMesh::
  54. clear() {
  55. Vertices::iterator vi;
  56. for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
  57. XFileVertex *vertex = (*vi);
  58. delete vertex;
  59. }
  60. Normals::iterator ni;
  61. for (ni = _normals.begin(); ni != _normals.end(); ++ni) {
  62. XFileNormal *normal = (*ni);
  63. delete normal;
  64. }
  65. Materials::iterator mi;
  66. for (mi = _materials.begin(); mi != _materials.end(); ++mi) {
  67. XFileMaterial *material = (*mi);
  68. delete material;
  69. }
  70. Faces::iterator fi;
  71. for (fi = _faces.begin(); fi != _faces.end(); ++fi) {
  72. XFileFace *face = (*fi);
  73. delete face;
  74. }
  75. _vertices.clear();
  76. _normals.clear();
  77. _materials.clear();
  78. _faces.clear();
  79. _unique_vertices.clear();
  80. _unique_normals.clear();
  81. _unique_materials.clear();
  82. }
  83. ////////////////////////////////////////////////////////////////////
  84. // Function: XFileMesh::add_polygon
  85. // Access: Public
  86. // Description: Adds the indicated polygon to the mesh.
  87. ////////////////////////////////////////////////////////////////////
  88. void XFileMesh::
  89. add_polygon(EggPolygon *egg_poly) {
  90. XFileFace *face = new XFileFace;
  91. face->set_from_egg(this, egg_poly);
  92. _faces.push_back(face);
  93. }
  94. ////////////////////////////////////////////////////////////////////
  95. // Function: XFileMesh::add_vertex
  96. // Access: Public
  97. // Description: Creates a new XFileVertex, if one does not already
  98. // exist for the indicated vertex, and returns its
  99. // index.
  100. ////////////////////////////////////////////////////////////////////
  101. int XFileMesh::
  102. add_vertex(EggVertex *egg_vertex, EggPrimitive *egg_prim) {
  103. int next_index = _vertices.size();
  104. XFileVertex *vertex = new XFileVertex;
  105. vertex->set_from_egg(egg_vertex, egg_prim);
  106. if (vertex->_has_color) {
  107. _has_colors = true;
  108. }
  109. if (vertex->_has_uv) {
  110. _has_uvs = true;
  111. }
  112. pair<UniqueVertices::iterator, bool> result =
  113. _unique_vertices.insert(UniqueVertices::value_type(vertex, next_index));
  114. if (result.second) {
  115. // Successfully added; this is a new vertex.
  116. _vertices.push_back(vertex);
  117. return next_index;
  118. } else {
  119. // Not successfully added; there is already a vertex with these
  120. // properties. Return that one instead.
  121. delete vertex;
  122. return (*result.first).second;
  123. }
  124. }
  125. ////////////////////////////////////////////////////////////////////
  126. // Function: XFileMesh::add_normal
  127. // Access: Public
  128. // Description: Creates a new XFileNormal, if one does not already
  129. // exist for the indicated normal, and returns its
  130. // index.
  131. ////////////////////////////////////////////////////////////////////
  132. int XFileMesh::
  133. add_normal(EggVertex *egg_vertex, EggPrimitive *egg_prim) {
  134. int next_index = _normals.size();
  135. XFileNormal *normal = new XFileNormal;
  136. normal->set_from_egg(egg_vertex, egg_prim);
  137. if (normal->_has_normal) {
  138. _has_normals = true;
  139. }
  140. pair<UniqueNormals::iterator, bool> result =
  141. _unique_normals.insert(UniqueNormals::value_type(normal, next_index));
  142. if (result.second) {
  143. // Successfully added; this is a new normal.
  144. _normals.push_back(normal);
  145. return next_index;
  146. } else {
  147. // Not successfully added; there is already a normal with these
  148. // properties. Return that one instead.
  149. delete normal;
  150. return (*result.first).second;
  151. }
  152. }
  153. ////////////////////////////////////////////////////////////////////
  154. // Function: XFileMesh::add_material
  155. // Access: Public
  156. // Description: Creates a new XFileMaterial, if one does not already
  157. // exist for the indicated material, and returns its
  158. // index.
  159. ////////////////////////////////////////////////////////////////////
  160. int XFileMesh::
  161. add_material(EggPrimitive *egg_prim) {
  162. int next_index = _materials.size();
  163. XFileMaterial *material = new XFileMaterial;
  164. material->set_from_egg(egg_prim);
  165. if (material->has_material()) {
  166. _has_materials = true;
  167. }
  168. pair<UniqueMaterials::iterator, bool> result =
  169. _unique_materials.insert(UniqueMaterials::value_type(material, next_index));
  170. if (result.second) {
  171. // Successfully added; this is a new material.
  172. _materials.push_back(material);
  173. return next_index;
  174. } else {
  175. // Not successfully added; there is already a material with these
  176. // properties. Return that one instead.
  177. delete material;
  178. return (*result.first).second;
  179. }
  180. }
  181. ////////////////////////////////////////////////////////////////////
  182. // Function: XFileMesh::add_vertex
  183. // Access: Public
  184. // Description: Adds the newly-created XFileVertex unequivocally to
  185. // the mesh, returning its index number. The XFileMesh
  186. // object becomes the owner of the XFileVertex
  187. // pointer, and will delete it when it destructs.
  188. ////////////////////////////////////////////////////////////////////
  189. int XFileMesh::
  190. add_vertex(XFileVertex *vertex) {
  191. int next_index = _vertices.size();
  192. _unique_vertices.insert(UniqueVertices::value_type(vertex, next_index));
  193. _vertices.push_back(vertex);
  194. return next_index;
  195. }
  196. ////////////////////////////////////////////////////////////////////
  197. // Function: XFileMesh::add_normal
  198. // Access: Public
  199. // Description: Adds the newly-created XFileNormal unequivocally to
  200. // the mesh, returning its index number. The XFileMesh
  201. // object becomes the owner of the XFileNormal
  202. // pointer, and will delete it when it destructs.
  203. ////////////////////////////////////////////////////////////////////
  204. int XFileMesh::
  205. add_normal(XFileNormal *normal) {
  206. int next_index = _normals.size();
  207. _unique_normals.insert(UniqueNormals::value_type(normal, next_index));
  208. _normals.push_back(normal);
  209. return next_index;
  210. }
  211. ////////////////////////////////////////////////////////////////////
  212. // Function: XFileMesh::add_material
  213. // Access: Public
  214. // Description: Adds the newly-created XFileMaterial unequivocally to
  215. // the mesh, returning its index number. The XFileMesh
  216. // object becomes the owner of the XFileMaterial
  217. // pointer, and will delete it when it destructs.
  218. ////////////////////////////////////////////////////////////////////
  219. int XFileMesh::
  220. add_material(XFileMaterial *material) {
  221. int next_index = _materials.size();
  222. _unique_materials.insert(UniqueMaterials::value_type(material, next_index));
  223. _materials.push_back(material);
  224. return next_index;
  225. }
  226. ////////////////////////////////////////////////////////////////////
  227. // Function: XFileMesh::create_polygons
  228. // Access: Public
  229. // Description: Creates a slew of EggPolygons according to the faces
  230. // in the mesh, and adds them to the indicated parent
  231. // node.
  232. ////////////////////////////////////////////////////////////////////
  233. bool XFileMesh::
  234. create_polygons(EggGroupNode *egg_parent,
  235. EggTextureCollection &textures,
  236. EggMaterialCollection &materials) {
  237. EggVertexPool *vpool = new EggVertexPool(get_name());
  238. egg_parent->add_child(vpool);
  239. Faces::const_iterator fi;
  240. for (fi = _faces.begin(); fi != _faces.end(); ++fi) {
  241. XFileFace *face = (*fi);
  242. EggPolygon *egg_poly = new EggPolygon;
  243. egg_parent->add_child(egg_poly);
  244. // Set up the vertices for the polygon.
  245. XFileFace::Vertices::reverse_iterator vi;
  246. for (vi = face->_vertices.rbegin(); vi != face->_vertices.rend(); ++vi) {
  247. int vertex_index = (*vi)._vertex_index;
  248. int normal_index = (*vi)._normal_index;
  249. if (vertex_index < 0 || vertex_index >= (int)_vertices.size()) {
  250. cerr << "Vertex index out of range in Mesh.\n";
  251. return false;
  252. }
  253. XFileVertex *vertex = _vertices[vertex_index];
  254. XFileNormal *normal = (XFileNormal *)NULL;
  255. if (normal_index >= 0 && normal_index < (int)_normals.size()) {
  256. normal = _normals[normal_index];
  257. }
  258. // Create a temporary EggVertex before adding it to the pool.
  259. EggVertex temp_vtx;
  260. temp_vtx.set_pos(LCAST(double, vertex->_point));
  261. if (vertex->_has_color) {
  262. temp_vtx.set_color(vertex->_color);
  263. }
  264. if (vertex->_has_uv) {
  265. TexCoordd uv = LCAST(double, vertex->_uv);
  266. // Windows draws the UV's upside-down.
  267. uv[1] = 1.0 - uv[1];
  268. temp_vtx.set_uv(uv);
  269. }
  270. if (normal != (XFileNormal *)NULL && normal->_has_normal) {
  271. temp_vtx.set_normal(LCAST(double, normal->_normal));
  272. }
  273. // Now get a real EggVertex matching our template.
  274. EggVertex *egg_vtx = vpool->create_unique_vertex(temp_vtx);
  275. egg_poly->add_vertex(egg_vtx);
  276. }
  277. // And apply the material for the polygon.
  278. int material_index = face->_material_index;
  279. if (material_index >= 0 && material_index < (int)_materials.size()) {
  280. XFileMaterial *material = _materials[material_index];
  281. material->apply_to_egg(egg_poly, textures, materials);
  282. }
  283. }
  284. return true;
  285. }
  286. ////////////////////////////////////////////////////////////////////
  287. // Function: XFileMesh::has_normals
  288. // Access: Public
  289. // Description: Returns true if any of the vertices or faces added to
  290. // this mesh used a normal, false otherwise.
  291. ////////////////////////////////////////////////////////////////////
  292. bool XFileMesh::
  293. has_normals() const {
  294. return _has_normals;
  295. }
  296. ////////////////////////////////////////////////////////////////////
  297. // Function: XFileMesh::has_colors
  298. // Access: Public
  299. // Description: Returns true if any of the vertices or faces added to
  300. // this mesh used a color, false otherwise.
  301. ////////////////////////////////////////////////////////////////////
  302. bool XFileMesh::
  303. has_colors() const {
  304. return _has_colors;
  305. }
  306. ////////////////////////////////////////////////////////////////////
  307. // Function: XFileMesh::has_uvs
  308. // Access: Public
  309. // Description: Returns true if any of the vertices added to this
  310. // mesh used a texture coordinate, false otherwise.
  311. ////////////////////////////////////////////////////////////////////
  312. bool XFileMesh::
  313. has_uvs() const {
  314. return _has_uvs;
  315. }
  316. ////////////////////////////////////////////////////////////////////
  317. // Function: XFileMesh::has_materials
  318. // Access: Public
  319. // Description: Returns true if any of the faces added to this mesh
  320. // used a real material, false otherwise.
  321. ////////////////////////////////////////////////////////////////////
  322. bool XFileMesh::
  323. has_materials() const {
  324. return _has_materials;
  325. }
  326. ////////////////////////////////////////////////////////////////////
  327. // Function: XFileMesh::get_num_materials
  328. // Access: Public
  329. // Description: Returns the number of distinct materials associated
  330. // with the mesh.
  331. ////////////////////////////////////////////////////////////////////
  332. int XFileMesh::
  333. get_num_materials() const {
  334. return _materials.size();
  335. }
  336. ////////////////////////////////////////////////////////////////////
  337. // Function: XFileMesh::get_material
  338. // Access: Public
  339. // Description: Returns a pointer to the nth materials associated
  340. // with the mesh.
  341. ////////////////////////////////////////////////////////////////////
  342. XFileMaterial *XFileMesh::
  343. get_material(int n) const {
  344. nassertr(n >= 0 && n < (int)_materials.size(), (XFileMaterial *)NULL);
  345. return _materials[n];
  346. }
  347. ////////////////////////////////////////////////////////////////////
  348. // Function: XFileMesh::make_mesh_data
  349. // Access: Public
  350. // Description: Fills the datagram with the raw data for the DX
  351. // Mesh template.
  352. ////////////////////////////////////////////////////////////////////
  353. void XFileMesh::
  354. make_mesh_data(Datagram &raw_data) {
  355. raw_data.clear();
  356. raw_data.add_int32(_vertices.size());
  357. Vertices::const_iterator vi;
  358. for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
  359. XFileVertex *vertex = (*vi);
  360. const Vertexf &point = vertex->_point;
  361. raw_data.add_float32(point[0]);
  362. raw_data.add_float32(point[1]);
  363. raw_data.add_float32(point[2]);
  364. }
  365. raw_data.add_int32(_faces.size());
  366. Faces::const_iterator fi;
  367. for (fi = _faces.begin(); fi != _faces.end(); ++fi) {
  368. XFileFace *face = (*fi);
  369. raw_data.add_int32(face->_vertices.size());
  370. XFileFace::Vertices::const_iterator fvi;
  371. for (fvi = face->_vertices.begin();
  372. fvi != face->_vertices.end();
  373. ++fvi) {
  374. raw_data.add_int32((*fvi)._vertex_index);
  375. }
  376. }
  377. }
  378. ////////////////////////////////////////////////////////////////////
  379. // Function: XFileMesh::make_normal_data
  380. // Access: Public
  381. // Description: Fills the datagram with the raw data for the DX
  382. // MeshNormals template.
  383. ////////////////////////////////////////////////////////////////////
  384. void XFileMesh::
  385. make_normal_data(Datagram &raw_data) {
  386. raw_data.clear();
  387. raw_data.add_int32(_normals.size());
  388. Normals::const_iterator ni;
  389. for (ni = _normals.begin(); ni != _normals.end(); ++ni) {
  390. XFileNormal *normal = (*ni);
  391. const Normalf &norm = normal->_normal;
  392. raw_data.add_float32(norm[0]);
  393. raw_data.add_float32(norm[1]);
  394. raw_data.add_float32(norm[2]);
  395. }
  396. raw_data.add_int32(_faces.size());
  397. Faces::const_iterator fi;
  398. for (fi = _faces.begin(); fi != _faces.end(); ++fi) {
  399. XFileFace *face = (*fi);
  400. raw_data.add_int32(face->_vertices.size());
  401. XFileFace::Vertices::const_iterator fvi;
  402. for (fvi = face->_vertices.begin();
  403. fvi != face->_vertices.end();
  404. ++fvi) {
  405. raw_data.add_int32((*fvi)._normal_index);
  406. }
  407. }
  408. }
  409. ////////////////////////////////////////////////////////////////////
  410. // Function: XFileMesh::make_color_data
  411. // Access: Public
  412. // Description: Fills the datagram with the raw data for the DX
  413. // MeshVertexColors template.
  414. ////////////////////////////////////////////////////////////////////
  415. void XFileMesh::
  416. make_color_data(Datagram &raw_data) {
  417. raw_data.clear();
  418. raw_data.add_int32(_vertices.size());
  419. Vertices::const_iterator vi;
  420. int i = 0;
  421. for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
  422. XFileVertex *vertex = (*vi);
  423. const Colorf &color = vertex->_color;
  424. raw_data.add_int32(i);
  425. raw_data.add_float32(color[0]);
  426. raw_data.add_float32(color[1]);
  427. raw_data.add_float32(color[2]);
  428. raw_data.add_float32(color[3]);
  429. i++;
  430. }
  431. }
  432. ////////////////////////////////////////////////////////////////////
  433. // Function: XFileMesh::make_uv_data
  434. // Access: Public
  435. // Description: Fills the datagram with the raw data for the DX
  436. // MeshTextureCoords template.
  437. ////////////////////////////////////////////////////////////////////
  438. void XFileMesh::
  439. make_uv_data(Datagram &raw_data) {
  440. raw_data.clear();
  441. raw_data.add_int32(_vertices.size());
  442. Vertices::const_iterator vi;
  443. for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
  444. XFileVertex *vertex = (*vi);
  445. const TexCoordf &uv = vertex->_uv;
  446. raw_data.add_float32(uv[0]);
  447. raw_data.add_float32(uv[1]);
  448. }
  449. }
  450. ////////////////////////////////////////////////////////////////////
  451. // Function: XFileMesh::make_material_list_data
  452. // Access: Public
  453. // Description: Fills the datagram with the raw data for the DX
  454. // MeshMaterialList template.
  455. ////////////////////////////////////////////////////////////////////
  456. void XFileMesh::
  457. make_material_list_data(Datagram &raw_data) {
  458. raw_data.clear();
  459. raw_data.add_int32(_materials.size());
  460. raw_data.add_int32(_faces.size());
  461. Faces::const_iterator fi;
  462. for (fi = _faces.begin(); fi != _faces.end(); ++fi) {
  463. XFileFace *face = (*fi);
  464. raw_data.add_int32(face->_material_index);
  465. }
  466. }
  467. ////////////////////////////////////////////////////////////////////
  468. // Function: XFileMesh::read_mesh_data
  469. // Access: Public
  470. // Description: Fills the structure based on the raw data from the
  471. // Mesh template.
  472. ////////////////////////////////////////////////////////////////////
  473. bool XFileMesh::
  474. read_mesh_data(const Datagram &raw_data) {
  475. DatagramIterator di(raw_data);
  476. clear();
  477. int i, j;
  478. int num_vertices = di.get_int32();
  479. for (i = 0; i < num_vertices; i++) {
  480. XFileVertex *vertex = new XFileVertex;
  481. vertex->_point[0] = di.get_float32();
  482. vertex->_point[1] = di.get_float32();
  483. vertex->_point[2] = di.get_float32();
  484. add_vertex(vertex);
  485. }
  486. int num_faces = di.get_int32();
  487. for (i = 0; i < num_faces; i++) {
  488. XFileFace *face = new XFileFace;
  489. num_vertices = di.get_int32();
  490. for (j = 0; j < num_vertices; j++) {
  491. XFileFace::Vertex vertex;
  492. vertex._vertex_index = di.get_int32();
  493. vertex._normal_index = -1;
  494. face->_vertices.push_back(vertex);
  495. }
  496. _faces.push_back(face);
  497. }
  498. if (di.get_remaining_size() != 0) {
  499. cerr << "Ignoring " << di.get_remaining_size() << " trailing Mesh.\n";
  500. }
  501. return true;
  502. }
  503. ////////////////////////////////////////////////////////////////////
  504. // Function: XFileMesh::read_normal_data
  505. // Access: Public
  506. // Description: Fills the structure based on the raw data from the
  507. // MeshNormals template.
  508. ////////////////////////////////////////////////////////////////////
  509. bool XFileMesh::
  510. read_normal_data(const Datagram &raw_data) {
  511. DatagramIterator di(raw_data);
  512. int num_normals = di.get_int32();
  513. int i;
  514. for (i = 0; i < num_normals; i++) {
  515. XFileNormal *normal = new XFileNormal;
  516. normal->_normal[0] = di.get_float32();
  517. normal->_normal[1] = di.get_float32();
  518. normal->_normal[2] = di.get_float32();
  519. normal->_has_normal = true;
  520. add_normal(normal);
  521. }
  522. int num_faces = di.get_int32();
  523. if (num_faces != _faces.size()) {
  524. cerr << "Incorrect number of faces in MeshNormals.\n";
  525. return false;
  526. }
  527. for (i = 0; i < num_faces; i++) {
  528. XFileFace *face = _faces[i];
  529. int num_vertices = di.get_int32();
  530. if (num_vertices != face->_vertices.size()) {
  531. cerr << "Incorrect number of vertices for face in MeshNormals.\n";
  532. return false;
  533. }
  534. for (int j = 0; j < num_vertices; j++) {
  535. face->_vertices[j]._normal_index = di.get_int32();
  536. }
  537. }
  538. if (di.get_remaining_size() != 0) {
  539. cerr << "Ignoring " << di.get_remaining_size()
  540. << " trailing MeshNormals.\n";
  541. }
  542. return true;
  543. }
  544. ////////////////////////////////////////////////////////////////////
  545. // Function: XFileMesh::read_color_data
  546. // Access: Public
  547. // Description: Fills the structure based on the raw data from the
  548. // MeshVertexColors template.
  549. ////////////////////////////////////////////////////////////////////
  550. bool XFileMesh::
  551. read_color_data(const Datagram &raw_data) {
  552. DatagramIterator di(raw_data);
  553. int num_colors = di.get_int32();
  554. int i;
  555. for (i = 0; i < num_colors; i++) {
  556. int vertex_index = di.get_int32();
  557. if (vertex_index < 0 || vertex_index >= _vertices.size()) {
  558. cerr << "Vertex index out of range in MeshVertexColors.\n";
  559. return false;
  560. }
  561. XFileVertex *vertex = _vertices[vertex_index];
  562. vertex->_color[0] = di.get_float32();
  563. vertex->_color[1] = di.get_float32();
  564. vertex->_color[2] = di.get_float32();
  565. vertex->_color[3] = di.get_float32();
  566. vertex->_has_color = true;
  567. }
  568. if (di.get_remaining_size() != 0) {
  569. cerr << "Ignoring " << di.get_remaining_size()
  570. << " trailing MeshVertexColors.\n";
  571. }
  572. return true;
  573. }
  574. ////////////////////////////////////////////////////////////////////
  575. // Function: XFileMesh::read_uv_data
  576. // Access: Public
  577. // Description: Fills the structure based on the raw data from the
  578. // MeshTextureCoords template.
  579. ////////////////////////////////////////////////////////////////////
  580. bool XFileMesh::
  581. read_uv_data(const Datagram &raw_data) {
  582. DatagramIterator di(raw_data);
  583. int num_vertices = di.get_int32();
  584. if (num_vertices != _vertices.size()) {
  585. cerr << "Wrong number of vertices in MeshTextureCoords.\n";
  586. return false;
  587. }
  588. int i;
  589. for (i = 0; i < num_vertices; i++) {
  590. XFileVertex *vertex = _vertices[i];
  591. vertex->_uv[0] = di.get_float32();
  592. vertex->_uv[1] = di.get_float32();
  593. vertex->_has_uv = true;
  594. }
  595. if (di.get_remaining_size() != 0) {
  596. cerr << "Ignoring " << di.get_remaining_size()
  597. << " trailing MeshTextureCoords.\n";
  598. }
  599. return true;
  600. }
  601. ////////////////////////////////////////////////////////////////////
  602. // Function: XFileMesh::read_material_list_data
  603. // Access: Public
  604. // Description: Fills the structure based on the raw data from the
  605. // MaterialList template.
  606. ////////////////////////////////////////////////////////////////////
  607. bool XFileMesh::
  608. read_material_list_data(const Datagram &raw_data) {
  609. DatagramIterator di(raw_data);
  610. di.get_int32(); /* num_materials */
  611. int num_faces = di.get_int32();
  612. if (num_faces > _faces.size()) {
  613. cerr << "Too many faces in MaterialList.\n";
  614. return false;
  615. }
  616. int material_index = -1;
  617. int i = 0;
  618. while (i < num_faces) {
  619. XFileFace *face = _faces[i];
  620. material_index = di.get_int32();
  621. face->_material_index = material_index;
  622. i++;
  623. }
  624. // The rest of the faces get the same material index as the last
  625. // one in the list.
  626. while (i < (int)_faces.size()) {
  627. XFileFace *face = _faces[i];
  628. face->_material_index = material_index;
  629. i++;
  630. }
  631. if (di.get_remaining_size() != 0) {
  632. cerr << "Ignoring " << di.get_remaining_size()
  633. << " trailing MeshMaterialList.\n";
  634. }
  635. return true;
  636. }