1/** Defines the collada loader class */
2
3/*
4Open Asset Import Library (assimp)
5----------------------------------------------------------------------
6
7Copyright (c) 2006-2025, 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 "ColladaParser.h"
48#include <assimp/BaseImporter.h>
49
50struct aiNode;
51struct aiCamera;
52struct aiLight;
53struct aiTexture;
54struct aiAnimation;
55
56namespace Assimp {
57
58struct ColladaMeshIndex {
59 std::string mMeshID;
60 size_t mSubMesh;
61 std::string mMaterial;
62 ColladaMeshIndex(const std::string &pMeshID, size_t pSubMesh, const std::string &pMaterial) :
63 mMeshID(pMeshID), mSubMesh(pSubMesh), mMaterial(pMaterial) {
64 ai_assert(!pMeshID.empty());
65 }
66
67 bool operator<(const ColladaMeshIndex &p) const {
68 if (mMeshID == p.mMeshID) {
69 if (mSubMesh == p.mSubMesh)
70 return mMaterial < p.mMaterial;
71 else
72 return mSubMesh < p.mSubMesh;
73 } else {
74 return mMeshID < p.mMeshID;
75 }
76 }
77};
78
79/**
80 * @brief Loader class to read Collada scenes.
81 *
82 * Collada is over-engineered to death, with every new iteration bringing more useless stuff,
83 * so I limited the data to what I think is useful for games.
84*/
85class ColladaLoader : public BaseImporter {
86public:
87 /// The class constructor.
88 ColladaLoader();
89
90 /// The class destructor.
91 ~ColladaLoader() override = default;
92
93 /// Returns whether the class can handle the format of the given file.
94 /// @see BaseImporter::CanRead() for more details.
95 bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const override;
96
97protected:
98 /// See #BaseImporter::GetInfo for the details
99 const aiImporterDesc *GetInfo() const override;
100
101 /// See #BaseImporter::SetupProperties for the details
102 void SetupProperties(const Importer *pImp) override;
103
104 /// See #BaseImporter::InternReadFile for the details
105 void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override;
106
107 /// Recursively constructs a scene node for the given parser node and returns it.
108 aiNode *BuildHierarchy(const ColladaParser &pParser, const Collada::Node *pNode);
109
110 /// Resolve node instances
111 void ResolveNodeInstances(const ColladaParser &pParser, const Collada::Node *pNode,
112 std::vector<const Collada::Node *> &resolved) const;
113
114 /// Builds meshes for the given node and references them
115 void BuildMeshesForNode(const ColladaParser &pParser, const Collada::Node *pNode,
116 aiNode *pTarget);
117
118 /// Lookup for meshes by their name
119 aiMesh *findMesh(const std::string &meshid);
120
121 /// Creates a mesh for the given ColladaMesh face subset and returns the newly created mesh
122 aiMesh *CreateMesh(const ColladaParser &pParser, const Collada::Mesh *pSrcMesh, const Collada::SubMesh &pSubMesh,
123 const Collada::Controller *pSrcController, size_t pStartVertex, size_t pStartFace);
124
125 /// Builds cameras for the given node and references them
126 void BuildCamerasForNode(const ColladaParser &pParser, const Collada::Node *pNode,
127 aiNode *pTarget);
128
129 /// Builds lights for the given node and references them
130 void BuildLightsForNode(const ColladaParser &pParser, const Collada::Node *pNode,
131 aiNode *pTarget);
132
133 /// Stores all meshes in the given scene
134 void StoreSceneMeshes(aiScene *pScene);
135
136 /// Stores all materials in the given scene
137 void StoreSceneMaterials(aiScene *pScene);
138
139 /// Stores all lights in the given scene
140 void StoreSceneLights(aiScene *pScene);
141
142 /// Stores all cameras in the given scene
143 void StoreSceneCameras(aiScene *pScene);
144
145 /// Stores all textures in the given scene
146 void StoreSceneTextures(aiScene *pScene);
147
148 /// Stores all animations
149 /// @param pScene Target scene to store the anims
150 /// @param parser The collada parser
151 void StoreAnimations(aiScene *pScene, const ColladaParser &parser);
152
153 /** Stores all animations for the given source anim and its nested child animations
154 * @param pScene target scene to store the anims
155 * @param pSrcAnim the source animation to process
156 * @param pPrefix Prefix to the name in case of nested animations
157 */
158 void StoreAnimations(aiScene *pScene, const ColladaParser &pParser, const Collada::Animation *pSrcAnim, const std::string &pPrefix);
159
160 /** Constructs the animation for the given source anim */
161 void CreateAnimation(aiScene *pScene, const ColladaParser &pParser, const Collada::Animation *pSrcAnim, const std::string &pName);
162
163 /** Constructs materials from the collada material definitions */
164 void BuildMaterials(ColladaParser &pParser, aiScene *pScene);
165
166 /** Fill materials from the collada material definitions */
167 void FillMaterials(const ColladaParser &pParser, aiScene *pScene);
168
169 /** Add a texture and all of its sampling properties to a material*/
170 void AddTexture(aiMaterial &mat, const ColladaParser &pParser,
171 const Collada::Effect &effect,
172 const Collada::Sampler &sampler,
173 aiTextureType type, unsigned int idx = 0);
174
175 /** Resolves the texture name for the given effect texture entry */
176 aiString FindFilenameForEffectTexture(const ColladaParser &pParser,
177 const Collada::Effect &pEffect, const std::string &pName);
178
179 /** Reads a string value from an accessor and its data array.
180 * @param pAccessor The accessor to use for reading
181 * @param pData The data array to read from
182 * @param pIndex The index of the element to retrieve
183 * @return the specified value
184 */
185 [[nodiscard]] const std::string &ReadString(const Collada::Accessor &pAccessor, const Collada::Data &pData, size_t pIndex) const;
186
187 /** Recursively collects all nodes into the given array */
188 void CollectNodes(const aiNode *pNode, std::vector<const aiNode *> &poNodes) const;
189
190 /** Finds a node in the collada scene by the given name */
191 const Collada::Node *FindNode(const Collada::Node *pNode, const std::string &pName) const;
192 /** Finds a node in the collada scene by the given SID */
193 const Collada::Node *FindNodeBySID(const Collada::Node *pNode, const std::string &pSID) const;
194
195 /** Finds a proper name for a node derived from the collada-node's properties */
196 std::string FindNameForNode(const Collada::Node *pNode);
197
198private:
199 /** Filename, for a verbose error message */
200 std::string mFileName;
201
202 /** Which mesh-material compound was stored under which mesh ID */
203 std::map<ColladaMeshIndex, size_t> mMeshIndexByID;
204
205 /** Which material was stored under which index in the scene */
206 std::map<std::string, size_t> mMaterialIndexByName;
207
208 /** Accumulated meshes for the target scene */
209 std::vector<aiMesh *> mMeshes;
210
211 /** Accumulated morph target meshes */
212 std::vector<aiMesh *> mTargetMeshes;
213
214 /** Temporary material list */
215 std::vector<std::pair<Collada::Effect *, aiMaterial *>> newMats;
216
217 /** Temporary camera list */
218 std::vector<aiCamera *> mCameras;
219
220 /** Temporary light list */
221 std::vector<aiLight *> mLights;
222
223 /** Temporary texture list */
224 std::vector<aiTexture *> mTextures;
225
226 /** Accumulated animations for the target scene */
227 std::vector<aiAnimation *> mAnims;
228
229 bool noSkeletonMesh;
230 bool removeEmptyBones;
231 bool ignoreUpDirection;
232 bool ignoreUnitSize;
233 bool useColladaName;
234
235 /** Used by FindNameForNode() to generate unique node names */
236 unsigned int mNodeNameCounter;
237};
238
239} // end of namespace Assimp
240
241#endif // AI_COLLADALOADER_H_INC
242

source code of qtquick3d/src/3rdparty/assimp/src/code/AssetLib/Collada/ColladaLoader.h