Coverage Report

Created: 2026-05-23 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/assimp/code/AssetLib/Collada/ColladaExporter.h
Line
Count
Source
1
/*
2
Open Asset Import Library (assimp)
3
----------------------------------------------------------------------
4
5
Copyright (c) 2006-2026, assimp team
6
7
All rights reserved.
8
9
Redistribution and use of this software in source and binary forms,
10
with or without modification, are permitted provided that the
11
following conditions are met:
12
13
* Redistributions of source code must retain the above
14
  copyright notice, this list of conditions and the
15
  following disclaimer.
16
17
* Redistributions in binary form must reproduce the above
18
  copyright notice, this list of conditions and the
19
  following disclaimer in the documentation and/or other
20
  materials provided with the distribution.
21
22
* Neither the name of the assimp team, nor the names of its
23
  contributors may be used to endorse or promote products
24
  derived from this software without specific prior
25
  written permission of the assimp team.
26
27
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
39
----------------------------------------------------------------------
40
*/
41
42
/** @file ColladaExporter.h
43
 * Declares the exporter class to write a scene to a Collada file
44
 */
45
#ifndef AI_COLLADAEXPORTER_H_INC
46
#define AI_COLLADAEXPORTER_H_INC
47
48
#include <assimp/ai_assert.h>
49
#include <assimp/material.h>
50
51
#include <array>
52
#include <map>
53
#include <sstream>
54
#include <unordered_set>
55
#include <vector>
56
57
struct aiScene;
58
struct aiNode;
59
struct aiLight;
60
struct aiBone;
61
62
namespace Assimp {
63
64
class IOSystem;
65
66
/// Helper class to export a given scene to a Collada file. Just for my personal
67
/// comfort when implementing it.
68
class ColladaExporter final {
69
public:
70
    /// Constructor for a specific scene to export
71
    ColladaExporter(const aiScene *pScene, IOSystem *pIOSystem, const std::string &path, const std::string &file);
72
73
    /// Destructor
74
0
    virtual ~ColladaExporter() = default;
75
76
protected:
77
    /// Starts writing the contents
78
    void WriteFile();
79
80
    /// Writes the asset header
81
    void WriteHeader();
82
83
    /// Writes the embedded textures
84
    void WriteTextures();
85
86
    /// Writes the material setup
87
    void WriteMaterials();
88
89
    /// Writes the cameras library
90
    void WriteCamerasLibrary();
91
92
    // Write a camera entry
93
    void WriteCamera(size_t pIndex);
94
95
    /// Writes the cameras library
96
    void WriteLightsLibrary();
97
98
    // Write a camera entry
99
    void WriteLight(size_t pIndex);
100
    void WritePointLight(const aiLight *const light);
101
    void WriteDirectionalLight(const aiLight *const light);
102
    void WriteSpotLight(const aiLight *const light);
103
    void WriteAmbientLight(const aiLight *const light);
104
105
    /// Writes the controller library
106
    void WriteControllerLibrary();
107
108
    /// Writes a skin controller of the given mesh
109
    void WriteController(size_t pIndex);
110
111
    /// Writes the geometry library
112
    void WriteGeometryLibrary();
113
114
    /// Writes the given mesh
115
    void WriteGeometry(size_t pIndex);
116
117
    //enum FloatDataType { FloatType_Vector, FloatType_TexCoord2, FloatType_TexCoord3, FloatType_Color, FloatType_Mat4x4, FloatType_Weight };
118
    // customized to add animation related type
119
    enum FloatDataType { FloatType_Vector,
120
        FloatType_TexCoord2,
121
        FloatType_TexCoord3,
122
        FloatType_Color,
123
        FloatType_Mat4x4,
124
        FloatType_Weight,
125
        FloatType_Time };
126
127
    /// Writes a float array of the given type
128
    void WriteFloatArray(const std::string &pIdString, FloatDataType pType, const ai_real *pData, size_t pElementCount);
129
130
    /// Writes the scene library
131
    void WriteSceneLibrary();
132
133
    // customized, Writes the animation library
134
    void WriteAnimationsLibrary();
135
    void WriteAnimationLibrary(size_t pIndex);
136
    std::string mFoundSkeletonRootNodeID = "skeleton_root"; // will be replaced by found node id in the WriteNode call.
137
138
    /// Recursively writes the given node
139
    void WriteNode(const aiNode *pNode);
140
141
    /// Enters a new xml element, which increases the indentation
142
0
    void PushTag() { startstr.append("  "); }
143
    /// Leaves an element, decreasing the indentation
144
0
    void PopTag() {
145
0
        ai_assert(startstr.length() > 1);
146
0
        startstr.erase(startstr.length() - 2);
147
0
    }
148
149
    void CreateNodeIds(const aiNode *node);
150
151
    /// Get or Create a unique Node ID string for the given Node
152
    std::string GetNodeUniqueId(const aiNode *node);
153
    std::string GetNodeName(const aiNode *node);
154
155
    std::string GetBoneUniqueId(const aiBone *bone);
156
157
    enum class AiObjectType {
158
        Mesh,
159
        Material,
160
        Animation,
161
        Light,
162
        Camera,
163
        Count,
164
    };
165
    /// Get or Create a unique ID string for the given scene object index
166
    std::string GetObjectUniqueId(AiObjectType type, size_t pIndex);
167
    /// Get or Create a name string for the given scene object index
168
    std::string GetObjectName(AiObjectType type, size_t pIndex);
169
170
    typedef std::map<size_t, std::string> IndexIdMap;
171
    typedef std::pair<std::string, std::string> NameIdPair;
172
    NameIdPair AddObjectIndexToMaps(AiObjectType type, size_t pIndex);
173
174
    // Helpers
175
0
    inline IndexIdMap &GetObjectIdMap(AiObjectType type) { return mObjectIdMap[static_cast<size_t>(type)]; }
176
0
    inline IndexIdMap &GetObjectNameMap(AiObjectType type) { return mObjectNameMap[static_cast<size_t>(type)]; }
177
178
private:
179
    std::unordered_set<std::string> mUniqueIds; // Cache of used unique ids
180
    std::map<const void *, std::string> mNodeIdMap; // Cache of encoded node and bone ids
181
    std::array<IndexIdMap, static_cast<size_t>(AiObjectType::Count)> mObjectIdMap; // Cache of encoded unique IDs
182
    std::array<IndexIdMap, static_cast<size_t>(AiObjectType::Count)> mObjectNameMap; // Cache of encoded names
183
184
public:
185
    /// Stringstream to write all output into
186
    std::stringstream mOutput;
187
188
    /// The IOSystem for output
189
    IOSystem *mIOSystem;
190
191
    /// Path of the directory where the scene will be exported
192
    const std::string mPath;
193
194
    /// Name of the file (without extension) where the scene will be exported
195
    const std::string mFile;
196
197
    /// The scene to be written
198
    const aiScene *const mScene;
199
    std::string mSceneId;
200
    bool mAdd_root_node = false;
201
202
    /// current line start string, contains the current indentation for simple stream insertion
203
    std::string startstr;
204
    /// current line end string for simple stream insertion
205
    const std::string endstr;
206
207
    // pair of color and texture - texture precedences color
208
    struct Surface {
209
        bool exist;
210
        aiColor4D color;
211
        std::string texture;
212
        size_t channel;
213
0
        Surface() {
214
0
            exist = false;
215
0
            channel = 0;
216
0
        }
217
    };
218
219
    struct Property {
220
        bool exist;
221
        ai_real value;
222
        Property() :
223
0
                exist(false),
224
0
                value(0.0) {}
225
    };
226
227
    // summarize a material in an convenient way.
228
    struct Material {
229
        std::string id;
230
        std::string name;
231
        std::string shading_model;
232
        Surface ambient, diffuse, specular, emissive, reflective, transparent, normal;
233
        Property shininess, transparency, index_refraction;
234
235
0
        Material() = default;
236
    };
237
238
    std::map<unsigned int, std::string> textures;
239
240
public:
241
    /// Dammit C++ - y u no compile two-pass? No I have to add all methods below the struct definitions
242
    /// Reads a single surface entry from the given material keys
243
    bool ReadMaterialSurface(Surface &poSurface, const aiMaterial &pSrcMat, aiTextureType pTexture, const char *pKey, size_t pType, size_t pIndex);
244
    /// Writes an image entry for the given surface
245
    void WriteImageEntry(const Surface &pSurface, const std::string &imageId);
246
    /// Writes the two parameters necessary for referencing a texture in an effect entry
247
    void WriteTextureParamEntry(const Surface &pSurface, const std::string &pTypeName, const std::string &materialId);
248
    /// Writes a color-or-texture entry into an effect definition
249
    void WriteTextureColorEntry(const Surface &pSurface, const std::string &pTypeName, const std::string &imageId);
250
    /// Writes a scalar property
251
    void WriteFloatEntry(const Property &pProperty, const std::string &pTypeName);
252
};
253
254
} // namespace Assimp
255
256
#endif // !! AI_COLLADAEXPORTER_H_INC