1 /** Defines the collada loader class */ 2 3 /* 4 Open Asset Import Library (assimp) 5 ---------------------------------------------------------------------- 6 7 Copyright (c) 2006-2019, assimp team 8 9 10 All rights reserved. 11 12 Redistribution and use of this software in source and binary forms, 13 with or without modification, are permitted provided that the 14 following conditions are met: 15 16 * Redistributions of source code must retain the above 17 copyright notice, this list of conditions and the 18 following disclaimer. 19 20 * Redistributions in binary form must reproduce the above 21 copyright notice, this list of conditions and the 22 following disclaimer in the documentation and/or other 23 materials provided with the distribution. 24 25 * Neither the name of the assimp team, nor the names of its 26 contributors may be used to endorse or promote products 27 derived from this software without specific prior 28 written permission of the assimp team. 29 30 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 31 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 32 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 33 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 34 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 35 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 36 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 37 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 38 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 39 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 40 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 41 42 ---------------------------------------------------------------------- 43 */ 44 45 #ifndef AI_COLLADALOADER_H_INC 46 #define AI_COLLADALOADER_H_INC 47 48 #include <assimp/BaseImporter.h> 49 #include "ColladaParser.h" 50 51 struct aiNode; 52 struct aiCamera; 53 struct aiLight; 54 struct aiTexture; 55 struct aiAnimation; 56 57 namespace Assimp 58 { 59 60 struct ColladaMeshIndex 61 { 62 std::string mMeshID; 63 size_t mSubMesh; 64 std::string mMaterial; ColladaMeshIndexColladaMeshIndex65 ColladaMeshIndex( const std::string& pMeshID, size_t pSubMesh, const std::string& pMaterial) 66 : mMeshID( pMeshID), mSubMesh( pSubMesh), mMaterial( pMaterial) 67 { } 68 69 bool operator < (const ColladaMeshIndex& p) const 70 { 71 if( mMeshID == p.mMeshID) 72 { 73 if( mSubMesh == p.mSubMesh) 74 return mMaterial < p.mMaterial; 75 else 76 return mSubMesh < p.mSubMesh; 77 } else 78 { 79 return mMeshID < p.mMeshID; 80 } 81 } 82 }; 83 84 /** Loader class to read Collada scenes. Collada is over-engineered to death, with every new iteration bringing 85 * more useless stuff, so I limited the data to what I think is useful for games. 86 */ 87 class ColladaLoader : public BaseImporter 88 { 89 public: 90 ColladaLoader(); 91 ~ColladaLoader(); 92 93 94 public: 95 /** Returns whether the class can handle the format of the given file. 96 * See BaseImporter::CanRead() for details. */ 97 bool CanRead(const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const override; 98 99 protected: 100 /** Return importer meta information. 101 * See #BaseImporter::GetInfo for the details 102 */ 103 const aiImporterDesc* GetInfo () const override; 104 105 void SetupProperties(const Importer* pImp) override; 106 107 /** Imports the given file into the given scene structure. 108 * See BaseImporter::InternReadFile() for details 109 */ 110 void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) override; 111 112 /** Recursively constructs a scene node for the given parser node and returns it. */ 113 aiNode* BuildHierarchy( const ColladaParser& pParser, const Collada::Node* pNode); 114 115 /** Resolve node instances */ 116 void ResolveNodeInstances( const ColladaParser& pParser, const Collada::Node* pNode, 117 std::vector<const Collada::Node*>& resolved); 118 119 /** Builds meshes for the given node and references them */ 120 void BuildMeshesForNode( const ColladaParser& pParser, const Collada::Node* pNode, 121 aiNode* pTarget); 122 123 aiMesh *findMesh(const std::string& meshid); 124 125 /** Creates a mesh for the given ColladaMesh face subset and returns the newly created mesh */ 126 aiMesh* CreateMesh( const ColladaParser& pParser, const Collada::Mesh* pSrcMesh, const Collada::SubMesh& pSubMesh, 127 const Collada::Controller* pSrcController, size_t pStartVertex, size_t pStartFace); 128 129 /** Builds cameras for the given node and references them */ 130 void BuildCamerasForNode( const ColladaParser& pParser, const Collada::Node* pNode, 131 aiNode* pTarget); 132 133 /** Builds lights for the given node and references them */ 134 void BuildLightsForNode( const ColladaParser& pParser, const Collada::Node* pNode, 135 aiNode* pTarget); 136 137 /** Stores all meshes in the given scene */ 138 void StoreSceneMeshes( aiScene* pScene); 139 140 /** Stores all materials in the given scene */ 141 void StoreSceneMaterials( aiScene* pScene); 142 143 /** Stores all lights in the given scene */ 144 void StoreSceneLights( aiScene* pScene); 145 146 /** Stores all cameras in the given scene */ 147 void StoreSceneCameras( aiScene* pScene); 148 149 /** Stores all textures in the given scene */ 150 void StoreSceneTextures( aiScene* pScene); 151 152 /** Stores all animations 153 * @param pScene target scene to store the anims 154 */ 155 void StoreAnimations( aiScene* pScene, const ColladaParser& pParser); 156 157 /** Stores all animations for the given source anim and its nested child animations 158 * @param pScene target scene to store the anims 159 * @param pSrcAnim the source animation to process 160 * @param pPrefix Prefix to the name in case of nested animations 161 */ 162 void StoreAnimations( aiScene* pScene, const ColladaParser& pParser, const Collada::Animation* pSrcAnim, const std::string& pPrefix); 163 164 /** Constructs the animation for the given source anim */ 165 void CreateAnimation( aiScene* pScene, const ColladaParser& pParser, const Collada::Animation* pSrcAnim, const std::string& pName); 166 167 /** Constructs materials from the collada material definitions */ 168 void BuildMaterials( ColladaParser& pParser, aiScene* pScene); 169 170 /** Fill materials from the collada material definitions */ 171 void FillMaterials( const ColladaParser& pParser, aiScene* pScene); 172 173 /** Resolve UV channel mappings*/ 174 void ApplyVertexToEffectSemanticMapping(Collada::Sampler& sampler, 175 const Collada::SemanticMappingTable& table); 176 177 /** Add a texture and all of its sampling properties to a material*/ 178 void AddTexture ( aiMaterial& mat, const ColladaParser& pParser, 179 const Collada::Effect& effect, 180 const Collada::Sampler& sampler, 181 aiTextureType type, unsigned int idx = 0); 182 183 /** Resolves the texture name for the given effect texture entry */ 184 aiString FindFilenameForEffectTexture( const ColladaParser& pParser, 185 const Collada::Effect& pEffect, const std::string& pName); 186 187 /** Reads a float value from an accessor and its data array. 188 * @param pAccessor The accessor to use for reading 189 * @param pData The data array to read from 190 * @param pIndex The index of the element to retrieve 191 * @param pOffset Offset into the element, for multipart elements such as vectors or matrices 192 * @return the specified value 193 */ 194 ai_real ReadFloat( const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex, size_t pOffset) const; 195 196 /** Reads a string value from an accessor and its data array. 197 * @param pAccessor The accessor to use for reading 198 * @param pData The data array to read from 199 * @param pIndex The index of the element to retrieve 200 * @return the specified value 201 */ 202 const std::string& ReadString( const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex) const; 203 204 /** Recursively collects all nodes into the given array */ 205 void CollectNodes( const aiNode* pNode, std::vector<const aiNode*>& poNodes) const; 206 207 /** Finds a node in the collada scene by the given name */ 208 const Collada::Node* FindNode( const Collada::Node* pNode, const std::string& pName) const; 209 /** Finds a node in the collada scene by the given SID */ 210 const Collada::Node* FindNodeBySID( const Collada::Node* pNode, const std::string& pSID) const; 211 212 /** Finds a proper name for a node derived from the collada-node's properties */ 213 std::string FindNameForNode( const Collada::Node* pNode); 214 215 protected: 216 /** Filename, for a verbose error message */ 217 std::string mFileName; 218 219 /** Which mesh-material compound was stored under which mesh ID */ 220 std::map<ColladaMeshIndex, size_t> mMeshIndexByID; 221 222 /** Which material was stored under which index in the scene */ 223 std::map<std::string, size_t> mMaterialIndexByName; 224 225 /** Accumulated meshes for the target scene */ 226 std::vector<aiMesh*> mMeshes; 227 228 /** Accumulated morph target meshes */ 229 std::vector<aiMesh*> mTargetMeshes; 230 231 /** Temporary material list */ 232 std::vector<std::pair<Collada::Effect*, aiMaterial*> > newMats; 233 234 /** Temporary camera list */ 235 std::vector<aiCamera*> mCameras; 236 237 /** Temporary light list */ 238 std::vector<aiLight*> mLights; 239 240 /** Temporary texture list */ 241 std::vector<aiTexture*> mTextures; 242 243 /** Accumulated animations for the target scene */ 244 std::vector<aiAnimation*> mAnims; 245 246 bool noSkeletonMesh; 247 bool ignoreUpDirection; 248 bool useColladaName; 249 250 /** Used by FindNameForNode() to generate unique node names */ 251 unsigned int mNodeNameCounter; 252 }; 253 254 } // end of namespace Assimp 255 256 #endif // AI_COLLADALOADER_H_INC 257