/src/assimp/code/AssetLib/Collada/ColladaLoader.h
Line | Count | Source |
1 | | /** Defines the collada loader class */ |
2 | | |
3 | | /* |
4 | | Open Asset Import Library (assimp) |
5 | | ---------------------------------------------------------------------- |
6 | | |
7 | | Copyright (c) 2006-2026, 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 "ColladaParser.h" |
48 | | #include <assimp/BaseImporter.h> |
49 | | |
50 | | struct aiNode; |
51 | | struct aiCamera; |
52 | | struct aiLight; |
53 | | struct aiTexture; |
54 | | struct aiAnimation; |
55 | | |
56 | | namespace Assimp { |
57 | | |
58 | | struct 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 | 9.14k | mMeshID(pMeshID), mSubMesh(pSubMesh), mMaterial(pMaterial) { |
64 | 9.14k | ai_assert(!pMeshID.empty()); |
65 | 9.14k | } |
66 | | |
67 | 79.7k | bool operator<(const ColladaMeshIndex &p) const { |
68 | 79.7k | if (mMeshID == p.mMeshID) { |
69 | 21.4k | if (mSubMesh == p.mSubMesh) |
70 | 8.73k | return mMaterial < p.mMaterial; |
71 | 12.7k | else |
72 | 12.7k | return mSubMesh < p.mSubMesh; |
73 | 58.2k | } else { |
74 | 58.2k | return mMeshID < p.mMeshID; |
75 | 58.2k | } |
76 | 79.7k | } |
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 | | */ |
85 | | class ColladaLoader final : public BaseImporter { |
86 | | public: |
87 | | /// The class constructor. |
88 | | ColladaLoader(); |
89 | | |
90 | | /// The class destructor. |
91 | 40.0k | ~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 | | |
97 | | protected: |
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 | | |
198 | | private: |
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 |