vrshoot

view libs/assimp/SceneCombiner.h @ 0:b2f14e535253

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 01 Feb 2014 19:58:19 +0200
parents
children
line source
1 /*
2 Open Asset Import Library (assimp)
3 ----------------------------------------------------------------------
5 Copyright (c) 2006-2012, assimp team
6 All rights reserved.
8 Redistribution and use of this software in source and binary forms,
9 with or without modification, are permitted provided that the
10 following conditions are met:
12 * Redistributions of source code must retain the above
13 copyright notice, this list of conditions and the
14 following disclaimer.
16 * Redistributions in binary form must reproduce the above
17 copyright notice, this list of conditions and the
18 following disclaimer in the documentation and/or other
19 materials provided with the distribution.
21 * Neither the name of the assimp team, nor the names of its
22 contributors may be used to endorse or promote products
23 derived from this software without specific prior
24 written permission of the assimp team.
26 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 ----------------------------------------------------------------------
39 */
41 /** @file Declares a helper class, "SceneCombiner" providing various
42 * utilities to merge scenes.
43 */
44 #ifndef AI_SCENE_COMBINER_H_INC
45 #define AI_SCENE_COMBINER_H_INC
47 #include "assimp/ai_assert.h"
49 namespace Assimp {
51 // ---------------------------------------------------------------------------
52 /** \brief Helper data structure for SceneCombiner.
53 *
54 * Describes to which node a scene must be attached to.
55 */
56 struct AttachmentInfo
57 {
58 AttachmentInfo()
59 : scene (NULL)
60 , attachToNode (NULL)
61 {}
63 AttachmentInfo(aiScene* _scene, aiNode* _attachToNode)
64 : scene (_scene)
65 , attachToNode (_attachToNode)
66 {}
68 aiScene* scene;
69 aiNode* attachToNode;
70 };
72 // ---------------------------------------------------------------------------
73 struct NodeAttachmentInfo
74 {
75 NodeAttachmentInfo()
76 : node (NULL)
77 , attachToNode (NULL)
78 , resolved (false)
79 , src_idx (SIZE_MAX)
80 {}
82 NodeAttachmentInfo(aiNode* _scene, aiNode* _attachToNode,size_t idx)
83 : node (_scene)
84 , attachToNode (_attachToNode)
85 , resolved (false)
86 , src_idx (idx)
87 {}
89 aiNode* node;
90 aiNode* attachToNode;
91 bool resolved;
92 size_t src_idx;
93 };
95 // ---------------------------------------------------------------------------
96 /** @def AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES
97 * Generate unique names for all named scene items
98 */
99 #define AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES 0x1
101 /** @def AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES
102 * Generate unique names for materials, too.
103 * This is not absolutely required to pass the validation.
104 */
105 #define AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES 0x2
107 /** @def AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY
108 * Use deep copies of duplicate scenes
109 */
110 #define AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY 0x4
112 /** @def AI_INT_MERGE_SCENE_RESOLVE_CROSS_ATTACHMENTS
113 * If attachment nodes are not found in the given master scene,
114 * search the other imported scenes for them in an any order.
115 */
116 #define AI_INT_MERGE_SCENE_RESOLVE_CROSS_ATTACHMENTS 0x8
118 /** @def AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY
119 * Can be combined with AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES.
120 * Unique names are generated, but only if this is absolutely
121 * required to avoid name conflicts.
122 */
123 #define AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY 0x10
126 typedef std::pair<aiBone*,unsigned int> BoneSrcIndex;
128 // ---------------------------------------------------------------------------
129 /** @brief Helper data structure for SceneCombiner::MergeBones.
130 */
131 struct BoneWithHash : public std::pair<uint32_t,aiString*> {
132 std::vector<BoneSrcIndex> pSrcBones;
133 };
136 // ---------------------------------------------------------------------------
137 /** @brief Utility for SceneCombiner
138 */
139 struct SceneHelper
140 {
141 SceneHelper ()
142 : scene (NULL)
143 , idlen (0)
144 {
145 id[0] = 0;
146 }
148 SceneHelper (aiScene* _scene)
149 : scene (_scene)
150 , idlen (0)
151 {
152 id[0] = 0;
153 }
155 AI_FORCE_INLINE aiScene* operator-> () const
156 {
157 return scene;
158 }
160 // scene we're working on
161 aiScene* scene;
163 // prefix to be added to all identifiers in the scene ...
164 char id [32];
166 // and its strlen()
167 unsigned int idlen;
169 // hash table to quickly check whether a name is contained in the scene
170 std::set<unsigned int> hashes;
171 };
173 // ---------------------------------------------------------------------------
174 /** \brief Static helper class providing various utilities to merge two
175 * scenes. It is intended as internal utility and NOT for use by
176 * applications.
177 *
178 * The class is currently being used by various postprocessing steps
179 * and loaders (ie. LWS).
180 */
181 class SceneCombiner
182 {
183 // class cannot be instanced
184 SceneCombiner() {}
186 public:
188 // -------------------------------------------------------------------
189 /** Merges two or more scenes.
190 *
191 * @param dest Receives a pointer to the destination scene. If the
192 * pointer doesn't point to NULL when the function is called, the
193 * existing scene is cleared and refilled.
194 * @param src Non-empty list of scenes to be merged. The function
195 * deletes the input scenes afterwards. There may be duplicate scenes.
196 * @param flags Combination of the AI_INT_MERGE_SCENE flags defined above
197 */
198 static void MergeScenes(aiScene** dest,std::vector<aiScene*>& src,
199 unsigned int flags = 0);
202 // -------------------------------------------------------------------
203 /** Merges two or more scenes and attaches all sceenes to a specific
204 * position in the node graph of the masteer scene.
205 *
206 * @param dest Receives a pointer to the destination scene. If the
207 * pointer doesn't point to NULL when the function is called, the
208 * existing scene is cleared and refilled.
209 * @param master Master scene. It will be deleted afterwards. All
210 * other scenes will be inserted in its node graph.
211 * @param src Non-empty list of scenes to be merged along with their
212 * corresponding attachment points in the master scene. The function
213 * deletes the input scenes afterwards. There may be duplicate scenes.
214 * @param flags Combination of the AI_INT_MERGE_SCENE flags defined above
215 */
216 static void MergeScenes(aiScene** dest, aiScene* master,
217 std::vector<AttachmentInfo>& src,
218 unsigned int flags = 0);
221 // -------------------------------------------------------------------
222 /** Merges two or more meshes
223 *
224 * The meshes should have equal vertex formats. Only components
225 * that are provided by ALL meshes will be present in the output mesh.
226 * An exception is made for VColors - they are set to black. The
227 * meshes should have the same material indices, too. The output
228 * material index is always the material index of the first mesh.
229 *
230 * @param dest Destination mesh. Must be empty.
231 * @param flags Currently no parameters
232 * @param begin First mesh to be processed
233 * @param end Points to the mesh after the last mesh to be processed
234 */
235 static void MergeMeshes(aiMesh** dest,unsigned int flags,
236 std::vector<aiMesh*>::const_iterator begin,
237 std::vector<aiMesh*>::const_iterator end);
240 // -------------------------------------------------------------------
241 /** Merges two or more bones
242 *
243 * @param out Mesh to receive the output bone list
244 * @param flags Currently no parameters
245 * @param begin First mesh to be processed
246 * @param end Points to the mesh after the last mesh to be processed
247 */
248 static void MergeBones(aiMesh* out,std::vector<aiMesh*>::const_iterator it,
249 std::vector<aiMesh*>::const_iterator end);
252 // -------------------------------------------------------------------
253 /** Builds a list of uniquely named bones in a mesh list
254 *
255 * @param asBones Receives the output list
256 * @param it First mesh to be processed
257 * @param end Last mesh to be processed
258 */
259 static void BuildUniqueBoneList(std::list<BoneWithHash>& asBones,
260 std::vector<aiMesh*>::const_iterator it,
261 std::vector<aiMesh*>::const_iterator end);
263 // -------------------------------------------------------------------
264 /** Add a name prefix to all nodes in a scene.
265 *
266 * @param Current node. This function is called recursively.
267 * @param prefix Prefix to be added to all nodes
268 * @param len STring length
269 */
270 static void AddNodePrefixes(aiNode* node, const char* prefix,
271 unsigned int len);
273 // -------------------------------------------------------------------
274 /** Add an offset to all mesh indices in a node graph
275 *
276 * @param Current node. This function is called recursively.
277 * @param offset Offset to be added to all mesh indices
278 */
279 static void OffsetNodeMeshIndices (aiNode* node, unsigned int offset);
281 // -------------------------------------------------------------------
282 /** Attach a list of node graphs to well-defined nodes in a master
283 * graph. This is a helper for MergeScenes()
284 *
285 * @param master Master scene
286 * @param srcList List of source scenes along with their attachment
287 * points. If an attachment point is NULL (or does not exist in
288 * the master graph), a scene is attached to the root of the master
289 * graph (as an additional child node)
290 * @duplicates List of duplicates. If elem[n] == n the scene is not
291 * a duplicate. Otherwise elem[n] links scene n to its first occurence.
292 */
293 static void AttachToGraph ( aiScene* master,
294 std::vector<NodeAttachmentInfo>& srcList);
296 static void AttachToGraph (aiNode* attach,
297 std::vector<NodeAttachmentInfo>& srcList);
300 // -------------------------------------------------------------------
301 /** Get a deep copy of a scene
302 *
303 * @param dest Receives a pointer to the destination scene
304 * @param src Source scene - remains unmodified.
305 */
306 static void CopyScene(aiScene** dest,const aiScene* source,bool allocate = true);
309 // -------------------------------------------------------------------
310 /** Get a flat copy of a scene
311 *
312 * Only the first hierarchy layer is copied. All pointer members of
313 * aiScene are shared by source and destination scene. If the
314 * pointer doesn't point to NULL when the function is called, the
315 * existing scene is cleared and refilled.
316 * @param dest Receives a pointer to the destination scene
317 * @param src Source scene - remains unmodified.
318 */
319 static void CopySceneFlat(aiScene** dest,const aiScene* source);
322 // -------------------------------------------------------------------
323 /** Get a deep copy of a mesh
324 *
325 * @param dest Receives a pointer to the destination mesh
326 * @param src Source mesh - remains unmodified.
327 */
328 static void Copy (aiMesh** dest, const aiMesh* src);
330 // similar to Copy():
331 static void Copy (aiMaterial** dest, const aiMaterial* src);
332 static void Copy (aiTexture** dest, const aiTexture* src);
333 static void Copy (aiAnimation** dest, const aiAnimation* src);
334 static void Copy (aiCamera** dest, const aiCamera* src);
335 static void Copy (aiBone** dest, const aiBone* src);
336 static void Copy (aiLight** dest, const aiLight* src);
337 static void Copy (aiNodeAnim** dest, const aiNodeAnim* src);
339 // recursive, of course
340 static void Copy (aiNode** dest, const aiNode* src);
343 private:
345 // -------------------------------------------------------------------
346 // Same as AddNodePrefixes, but with an additional check
347 static void AddNodePrefixesChecked(aiNode* node, const char* prefix,
348 unsigned int len,
349 std::vector<SceneHelper>& input,
350 unsigned int cur);
352 // -------------------------------------------------------------------
353 // Add node identifiers to a hashing set
354 static void AddNodeHashes(aiNode* node, std::set<unsigned int>& hashes);
357 // -------------------------------------------------------------------
358 // Search for duplicate names
359 static bool FindNameMatch(const aiString& name,
360 std::vector<SceneHelper>& input, unsigned int cur);
361 };
363 }
365 #endif // !! AI_SCENE_COMBINER_H_INC