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