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