vrshoot

annotate libs/assimp/SceneCombiner.h @ 1:e7ca128b8713

looks nice :)
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 02 Feb 2014 00:35:22 +0200
parents
children
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