1/** Defines the collada loader class */
2
3/*
4Open Asset Import Library (assimp)
5----------------------------------------------------------------------
6
7Copyright (c) 2006-2017, assimp team
8
9All rights reserved.
10
11Redistribution and use of this software in source and binary forms,
12with or without modification, are permitted provided that the
13following conditions are met:
14
15* Redistributions of source code must retain the above
16copyright notice, this list of conditions and the
17following disclaimer.
18
19* Redistributions in binary form must reproduce the above
20copyright notice, this list of conditions and the
21following disclaimer in the documentation and/or other
22materials provided with the distribution.
23
24* Neither the name of the assimp team, nor the names of its
25contributors may be used to endorse or promote products
26derived from this software without specific prior
27written permission of the assimp team.
28
29THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39OF 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
50struct aiNode;
51struct aiCamera;
52struct aiLight;
53struct aiTexture;
54struct aiAnimation;
55
56namespace Assimp
57{
58
59struct 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*/
86class ColladaLoader : public BaseImporter
87{
88public:
89 ColladaLoader();
90 ~ColladaLoader();
91
92
93public:
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
98protected:
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
217protected:
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