Coverage Report

Created: 2026-03-12 06:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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