sceneGraphReducer.I 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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 sceneGraphReducer.I
  10. * @author drose
  11. * @date 2002-03-14
  12. */
  13. /**
  14. *
  15. */
  16. INLINE SceneGraphReducer::
  17. SceneGraphReducer(GraphicsStateGuardianBase *gsg) :
  18. _combine_radius(0.0f)
  19. {
  20. set_gsg(gsg);
  21. }
  22. /**
  23. *
  24. */
  25. INLINE SceneGraphReducer::
  26. ~SceneGraphReducer() {
  27. }
  28. /**
  29. * Returns the particular GraphicsStateGuardian that this object will attempt
  30. * to optimize to. See set_gsg().
  31. */
  32. INLINE GraphicsStateGuardianBase *SceneGraphReducer::
  33. get_gsg() const {
  34. return _gsg;
  35. }
  36. /**
  37. * Specifies the radius that is used in conjunction with CS_within_radius to
  38. * decide whether a subgraph's siblings should be combined into a single node
  39. * or not.
  40. *
  41. * If the CS_within_radius bit is included in the combine_siblings_bits
  42. * parameter passed to flatten, than any nodes whose bounding volume is
  43. * smaller than the indicated radius will be combined together (as if CS_other
  44. * were set).
  45. */
  46. INLINE void SceneGraphReducer::
  47. set_combine_radius(PN_stdfloat combine_radius) {
  48. _combine_radius = combine_radius;
  49. }
  50. /**
  51. * Returns the radius that is used in conjunction with CS_within_radius. See
  52. * set_combine_radius().
  53. */
  54. INLINE PN_stdfloat SceneGraphReducer::
  55. get_combine_radius() const {
  56. return _combine_radius;
  57. }
  58. /**
  59. * Walks the scene graph, accumulating attribs of the indicated types,
  60. * applying them to the vertices, and removing them from the scene graph.
  61. * This has a performance optimization benefit in itself, but is especially
  62. * useful to pave the way for a call to flatten() and greatly improve the
  63. * effectiveness of the flattening operation.
  64. *
  65. * Multiply instanced geometry is duplicated before the attribs are applied.
  66. *
  67. * Of course, this operation does make certain dynamic operations impossible.
  68. */
  69. INLINE void SceneGraphReducer::
  70. apply_attribs(PandaNode *node, int attrib_types) {
  71. nassertv(check_live_flatten(node));
  72. nassertv(node != nullptr);
  73. PStatTimer timer(_apply_collector);
  74. AccumulatedAttribs attribs;
  75. r_apply_attribs(node, attribs, attrib_types, _transformer);
  76. _transformer.finish_apply();
  77. }
  78. /**
  79. * This flavor of apply_attribs() can be called recursively from within
  80. * another flatten process (e.g. from
  81. * PandaNode::apply_attribs_to_vertices()). The parameters were presumably
  82. * received from a parent SceneGraphReducer object.
  83. */
  84. INLINE void SceneGraphReducer::
  85. apply_attribs(PandaNode *node, const AccumulatedAttribs &attribs,
  86. int attrib_types, GeomTransformer &transformer) {
  87. nassertv(node != nullptr);
  88. r_apply_attribs(node, attribs, attrib_types, transformer);
  89. }
  90. /**
  91. * Walks through the tree at this node and below and unifies the
  92. * GeomVertexFormat for any GeomVertexData objects that are found, so that all
  93. * eligible vdatas (according to collect_bits; see collect_vertex_data) will
  94. * share the same vertex format.
  95. *
  96. * This will add unused columns where necessary to match formats. It can
  97. * result in suboptimal performance if used needlessly.
  98. *
  99. * There is usually no reason to call this explicitly, since
  100. * collect_vertex_data() will do this anyway if it has not been done already.
  101. * However, calling it ahead of time can make that future call to
  102. * collect_vertex_data() run a little bit faster.
  103. *
  104. * The return value is the number of vertex datas modified.
  105. */
  106. INLINE int SceneGraphReducer::
  107. make_compatible_format(PandaNode *root, int collect_bits) {
  108. nassertr(root != nullptr, 0);
  109. nassertr(check_live_flatten(root), 0);
  110. PStatTimer timer(_collect_collector);
  111. int count = 0;
  112. count += r_collect_vertex_data(root, collect_bits, _transformer, true);
  113. count += _transformer.finish_collect(true);
  114. return count;
  115. }
  116. /**
  117. * Collects all different GeomVertexData blocks that have compatible formats
  118. * at this node and below into a single, unified block (or at least multiple
  119. * larger blocks). This is intended to reduce rendering overhead incurred by
  120. * switching vertex buffers. It can also make a subsequent call to unify()
  121. * much more effective than it would have been otherwise.
  122. *
  123. * The set of bits passed in collect_bits indicates which properties are used
  124. * to differentiate GeomVertexData blocks. If it is 0, then more blocks will
  125. * be combined together than if it is nonzero.
  126. */
  127. INLINE int SceneGraphReducer::
  128. collect_vertex_data(PandaNode *root, int collect_bits) {
  129. nassertr(root != nullptr, 0);
  130. nassertr(check_live_flatten(root), 0);
  131. PStatTimer timer(_collect_collector);
  132. int count = 0;
  133. count += r_collect_vertex_data(root, collect_bits, _transformer, false);
  134. count += _transformer.finish_collect(false);
  135. return count;
  136. }
  137. /**
  138. * Converts indexed geometry to nonindexed geometry at the indicated node and
  139. * below, by duplicating vertices where necessary. The parameter
  140. * nonindexed_bits is a union of bits defined in
  141. * SceneGraphReducer::MakeNonindexed, which specifes which types of geometry
  142. * to avoid making nonindexed.
  143. */
  144. INLINE int SceneGraphReducer::
  145. make_nonindexed(PandaNode *root, int nonindexed_bits) {
  146. nassertr(root != nullptr, 0);
  147. nassertr(check_live_flatten(root), 0);
  148. PStatTimer timer(_make_nonindexed_collector);
  149. return r_make_nonindexed(root, nonindexed_bits);
  150. }
  151. /**
  152. * Walks the scene graph rooted at this node and below, and uses the indicated
  153. * GSG to premunge every Geom found to optimize it for eventual rendering on
  154. * the indicated GSG. If there is no GSG indicated for the SceneGraphReducer,
  155. * this is a no-op.
  156. *
  157. * This operation will also apply to stashed children.
  158. */
  159. INLINE void SceneGraphReducer::
  160. premunge(PandaNode *root, const RenderState *initial_state) {
  161. nassertv(root != nullptr);
  162. nassertv(check_live_flatten(root));
  163. if (_gsg != nullptr) {
  164. PStatTimer timer(_premunge_collector);
  165. r_premunge(root, initial_state);
  166. }
  167. }