eggMultiBase.cxx 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // Filename: eggMultiBase.cxx
  2. // Created by: drose (02Nov00)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. //
  6. // PANDA 3D SOFTWARE
  7. // Copyright (c) 2001 - 2004, 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://etc.cmu.edu/panda3d/docs/license/ .
  13. //
  14. // To contact the maintainers of this program write to
  15. // [email protected] .
  16. //
  17. ////////////////////////////////////////////////////////////////////
  18. #include "eggMultiBase.h"
  19. #include "eggBase.h"
  20. #include "eggData.h"
  21. #include "eggComment.h"
  22. #include "filename.h"
  23. #include "dSearchPath.h"
  24. ////////////////////////////////////////////////////////////////////
  25. // Function: EggMultiBase::Constructor
  26. // Access: Public
  27. // Description:
  28. ////////////////////////////////////////////////////////////////////
  29. EggMultiBase::
  30. EggMultiBase() {
  31. add_option
  32. ("f", "", 80,
  33. "Force complete loading: load up the egg file along with all of its "
  34. "external references.",
  35. &EggMultiBase::dispatch_none, &_force_complete);
  36. add_option
  37. ("noabs", "", 0,
  38. "Don't allow any of the named egg files to have absolute pathnames. "
  39. "If any do, abort with an error. This option is designed to help "
  40. "detect errors when populating or building a standalone model tree, "
  41. "which should be self-contained and include only relative pathnames.",
  42. &EggMultiBase::dispatch_none, &_noabs);
  43. }
  44. ////////////////////////////////////////////////////////////////////
  45. // Function: EggMultiBase::post_process_egg_files
  46. // Access: Public
  47. // Description: Performs any processing of the egg file(s) that is
  48. // appropriate before writing them out. This includes any
  49. // normal adjustments the user requested via -np, etc.
  50. //
  51. // Normally, you should not need to call this function
  52. // directly; write_egg_files() calls it for you. You
  53. // should call this only if you do not use
  54. // write_egg_files() to write out the resulting egg
  55. // files.
  56. ////////////////////////////////////////////////////////////////////
  57. void EggMultiBase::
  58. post_process_egg_files() {
  59. if (_eggs.empty()) {
  60. return;
  61. }
  62. Eggs::iterator ei;
  63. if (_got_transform) {
  64. nout << "Applying transform matrix:\n";
  65. _transform.write(nout, 2);
  66. LVecBase3d scale, hpr, translate;
  67. if (decompose_matrix(_transform, scale, hpr, translate,
  68. _eggs[0]->get_coordinate_system())) {
  69. nout << "(scale " << scale << ", hpr " << hpr << ", translate "
  70. << translate << ")\n";
  71. }
  72. for (ei = _eggs.begin(); ei != _eggs.end(); ++ei) {
  73. (*ei)->transform(_transform);
  74. }
  75. }
  76. switch (_normals_mode) {
  77. case NM_strip:
  78. nout << "Stripping normals.\n";
  79. for (ei = _eggs.begin(); ei != _eggs.end(); ++ei) {
  80. (*ei)->strip_normals();
  81. (*ei)->remove_unused_vertices(true);
  82. }
  83. break;
  84. case NM_polygon:
  85. nout << "Recomputing polygon normals.\n";
  86. for (ei = _eggs.begin(); ei != _eggs.end(); ++ei) {
  87. (*ei)->recompute_polygon_normals();
  88. (*ei)->remove_unused_vertices(true);
  89. }
  90. break;
  91. case NM_vertex:
  92. nout << "Recomputing vertex normals.\n";
  93. for (ei = _eggs.begin(); ei != _eggs.end(); ++ei) {
  94. (*ei)->recompute_vertex_normals(_normals_threshold);
  95. (*ei)->remove_unused_vertices(true);
  96. }
  97. break;
  98. case NM_preserve:
  99. // Do nothing.
  100. break;
  101. }
  102. }
  103. ////////////////////////////////////////////////////////////////////
  104. // Function: EggMultiBase::read_egg
  105. // Access: Protected, Virtual
  106. // Description: Allocates and returns a new EggData structure that
  107. // represents the indicated egg file. If the egg file
  108. // cannot be read for some reason, returns NULL.
  109. //
  110. // This can be overridden by derived classes to control
  111. // how the egg files are read, or to extend the
  112. // information stored with each egg structure, by
  113. // deriving from EggData.
  114. ////////////////////////////////////////////////////////////////////
  115. PT(EggData) EggMultiBase::
  116. read_egg(const Filename &filename) {
  117. PT(EggData) data = new EggData;
  118. if (!data->read(filename)) {
  119. // Failure reading.
  120. return (EggData *)NULL;
  121. }
  122. if (_noabs && data->original_had_absolute_pathnames()) {
  123. nout << filename.get_basename()
  124. << " includes absolute pathnames!\n";
  125. return (EggData *)NULL;
  126. }
  127. DSearchPath file_path;
  128. file_path.append_directory(filename.get_dirname());
  129. // We always resolve filenames first based on the source egg
  130. // filename, since egg files almost always store relative paths.
  131. // This is a temporary kludge around integrating the path_replace
  132. // system with the EggData better.
  133. //
  134. // Update: I believe this kludge is obsolete. Commenting out. - Josh.
  135. // data->resolve_filenames(file_path);
  136. if (_force_complete) {
  137. if (!data->load_externals()) {
  138. return (EggData *)NULL;
  139. }
  140. }
  141. // Now resolve the filenames again according to the user's
  142. // specified _path_replace.
  143. EggBase::convert_paths(data, _path_replace, file_path);
  144. if (_got_coordinate_system) {
  145. data->set_coordinate_system(_coordinate_system);
  146. } else {
  147. _coordinate_system = data->get_coordinate_system();
  148. _got_coordinate_system = true;
  149. }
  150. return data;
  151. }