OptimizeGraphProcess.h 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. /*
  2. Open Asset Import Library (ASSIMP)
  3. ----------------------------------------------------------------------
  4. Copyright (c) 2006-2008, ASSIMP Development Team
  5. All rights reserved.
  6. Redistribution and use of this software in source and binary forms,
  7. with or without modification, are permitted provided that the
  8. following conditions are met:
  9. * Redistributions of source code must retain the above
  10. copyright notice, this list of conditions and the
  11. following disclaimer.
  12. * Redistributions in binary form must reproduce the above
  13. copyright notice, this list of conditions and the
  14. following disclaimer in the documentation and/or other
  15. materials provided with the distribution.
  16. * Neither the name of the ASSIMP team, nor the names of its
  17. contributors may be used to endorse or promote products
  18. derived from this software without specific prior
  19. written permission of the ASSIMP Development Team.
  20. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23. A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24. OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25. SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27. DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28. THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. ----------------------------------------------------------------------
  32. */
  33. /** Defines a post processing step to refactor the output node graph to
  34. be more compact */
  35. #ifndef AI_OPTIMIZEGRAPHPROCESS_H_INC
  36. #define AI_OPTIMIZEGRAPHPROCESS_H_INC
  37. #include "BaseProcess.h"
  38. struct aiMesh;
  39. struct aiNode;
  40. struct aiBone;
  41. class OptimizeGraphProcessTest;
  42. namespace Assimp {
  43. // NOTE: If you change these limits, don't forget to change the
  44. // corresponding values in all Assimp ports
  45. // **********************************************************
  46. // Java: ConfigProperty.java,
  47. // ConfigProperty.OG_MIN_NUM_FACES
  48. // ConfigProperty.JOIN_INEQUAL_TRANSFORMS
  49. // **********************************************************
  50. #if (!defined AI_OG_MAX_DEPTH)
  51. # define AI_OG_MAX_DEPTH 0x4
  52. #endif // !! AI_LMW_MAX_WEIGHTS
  53. #if (!defined AI_OG_MIN_NUM_FACES)
  54. # define AI_OG_MIN_NUM_FACES 0xffffffff
  55. #endif // !! AI_LMW_MAX_WEIGHTS
  56. #if (!defined AI_OG_JOIN_INEQUAL_TRANSFORMS)
  57. # define AI_OG_JOIN_INEQUAL_TRANSFORMS false
  58. #endif // !! AI_LMW_MAX_WEIGHTS
  59. // ---------------------------------------------------------------------------
  60. struct NodeIndexEntry : public std::pair<unsigned int, unsigned int>
  61. {
  62. // binary operator < for use with std::sort
  63. bool operator< (const NodeIndexEntry& other)
  64. {
  65. return second < other.second;
  66. }
  67. // pointer to the original node
  68. aiNode* pNode;
  69. };
  70. typedef std::vector<NodeIndexEntry> NodeIndexList;
  71. // ---------------------------------------------------------------------------
  72. /** This post processing step reformats the output node graph to be more
  73. * compact. There are several options, e.g. maximum hierachy depth or
  74. * minimum mesh size. Some files store every face as a new mesh, so
  75. * some Assimp steps (such as FixInfacingNormals or SmoothNormals) don't
  76. * work properly on these meshes. This step joins such small meshes and
  77. * nodes. Animations are kept during the step.
  78. * @note Use the PretransformVertices step to remove the node graph
  79. * completely (and all animations, too).
  80. */
  81. class ASSIMP_API OptimizeGraphProcess : public BaseProcess
  82. {
  83. friend class Importer;
  84. friend class ::OptimizeGraphProcessTest;
  85. protected:
  86. /** Constructor to be privately used by Importer */
  87. OptimizeGraphProcess();
  88. /** Destructor, private as well */
  89. ~OptimizeGraphProcess();
  90. typedef std::pair< unsigned int, aiNode* > MeshRefCount;
  91. typedef unsigned int MeshHash;
  92. public:
  93. // -------------------------------------------------------------------
  94. /** Returns whether the processing step is present in the given flag.
  95. * @param pFlags The processing flags the importer was called with.
  96. * A bitwise combination of #aiPostProcessSteps.
  97. * @return true if the process is present in this flag fields,
  98. * false if not.
  99. */
  100. bool IsActive( unsigned int pFlags) const;
  101. // -------------------------------------------------------------------
  102. /** Called prior to ExecuteOnScene().
  103. * The function is a request to the process to update its configuration
  104. * basing on the Importer's configuration property list.
  105. */
  106. void SetupProperties(const Importer* pImp);
  107. // set the configMinNumfaces property
  108. inline void SetMinNumFaces(unsigned int n)
  109. {
  110. configMinNumFaces = n;
  111. }
  112. protected:
  113. // -------------------------------------------------------------------
  114. /** Executes the post processing step on the given imported data.
  115. * At the moment a process is not supposed to fail.
  116. * @param pScene The imported data to work at.
  117. */
  118. void Execute( aiScene* pScene);
  119. // -------------------------------------------------------------------
  120. /** Removes animation nodes from the tree.
  121. * @param node Current node
  122. * @param out Receives a list of replacement nodes for *this* node -
  123. * if *this* node should be kept, it must be added to the list.
  124. */
  125. void RemoveAnimationNodes (aiNode* node,std::vector<aiNode*>& out);
  126. // -------------------------------------------------------------------
  127. /** Finds and marks all locked nodes in the tree.
  128. * A node is locked if it is referenced by animations.
  129. * @param node ROot node to start with
  130. * @note A locked node has the MSB set in its mNumChildren member
  131. */
  132. void FindLockedNodes(aiNode* node);
  133. // -------------------------------------------------------------------
  134. /** Searches for locked meshes. A mesh is locked if it is referenced
  135. * by more than one node in the hierarchy.
  136. * @param node Root node to start with
  137. */
  138. void FindLockedMeshes(aiNode* node);
  139. void FindLockedMeshes(aiNode* node, MeshRefCount* pRefCount);
  140. // -------------------------------------------------------------------
  141. /** Unlocks all nodes in the output tree.
  142. * @param node Root node to start with
  143. */
  144. void UnlockNodes(aiNode* node);
  145. // -------------------------------------------------------------------
  146. /** Unlocks all meshes in the output tree.
  147. */
  148. void UnlockMeshes();
  149. // -------------------------------------------------------------------
  150. /** Apply the final optimization algorithm to the tree.
  151. * See the Execute-method for a detailled description of the algorithm.
  152. * @param node Root node to start with
  153. */
  154. void ApplyOptimizations(aiNode* node);
  155. // -------------------------------------------------------------------
  156. /** Binary search for the first element that is >= min.
  157. * @param sortedArray Input array
  158. * @param min Treshold
  159. */
  160. unsigned int BinarySearch(NodeIndexList& sortedArray,
  161. unsigned int min, unsigned int& index, unsigned int iStart);
  162. // -------------------------------------------------------------------
  163. /** Compute stable hashes for all meshes and fill mMeshHashes
  164. * with the results.
  165. */
  166. void ComputeMeshHashes();
  167. // -------------------------------------------------------------------
  168. /** Optimizes the meshes in a single node aftr the joining process.
  169. * @param pNode Node to be optimized. Childs noded won't be processed
  170. * automatically.
  171. */
  172. void ApplyNodeMeshesOptimization(aiNode* pNode);
  173. // -------------------------------------------------------------------
  174. /** Build the output mesh list.
  175. */
  176. void BuildOutputMeshList();
  177. // -------------------------------------------------------------------
  178. /** Transform meshes from one coordinate space into another.
  179. * @param quak Input space. All meshes referenced by this node -
  180. * assuming none of them is locked - are transformed in the
  181. * local coordinate space of pNode
  182. * @param pNode Destination coordinate space
  183. */
  184. void TransformMeshes(aiNode* quak,aiNode* pNode);
  185. private:
  186. /** Configuration option: specifies the minimum number of faces
  187. a node should have. The steps tries to join meshes with less
  188. vertices that are on the same hierarchy level.
  189. If this value is set to a very large value (e.g. 0xffffffff)
  190. all meshes on the same hierarchy level are joined - if they
  191. aren't animation nodes and if they have the same world matrices
  192. */
  193. unsigned int configMinNumFaces;
  194. /** Configuration option: specifies whether nodes with inequal
  195. world matrices are joined if they are on the same hierarchy
  196. level and if it seems to make sense.
  197. */
  198. bool configJoinInequalTransforms;
  199. /** Working data */
  200. aiScene* pScene;
  201. /** List of hash identifiers for all meshes.
  202. The hashes are build from both the meshes vertex format
  203. and the material indices. Bones are not taken into account.
  204. */
  205. std::vector<MeshHash> mMeshHashes;
  206. /** List of output meshes.
  207. */
  208. std::vector<aiMesh*> mOutputMeshes;
  209. };
  210. } // end of namespace Assimp
  211. #endif // AI_LIMITBONEWEIGHTSPROCESS_H_INC