Coverage Report

Created: 2026-09-14 07:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/assimp/code/AssetLib/Irr/IRRLoader.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 IRRLoader.h
43
 *  @brief Declaration of the .irrMesh (Irrlight Engine Mesh Format)
44
 *  importer class.
45
 */
46
#ifndef AI_IRRLOADER_H_INCLUDED
47
#define AI_IRRLOADER_H_INCLUDED
48
49
#include "IRRShared.h"
50
#include "Common/Importer.h"
51
52
#include <assimp/SceneCombiner.h>
53
#include <assimp/StringUtils.h>
54
#include <assimp/anim.h>
55
#include <assimp/material.h>
56
57
namespace Assimp {
58
59
// ---------------------------------------------------------------------------
60
/** Irr importer class.
61
 *
62
 * Irr is the native scene file format of the Irrlight engine and its editor
63
 * irrEdit. As IrrEdit itself is capable of importing quite many file formats,
64
 * it might be a good file format for data exchange.
65
 */
66
class IRRImporter : public BaseImporter, public IrrlichtBase {
67
public:
68
    IRRImporter();
69
    ~IRRImporter() override;
70
71
    // -------------------------------------------------------------------
72
    /** Returns whether the class can handle the format of the given file.
73
     *  See BaseImporter::CanRead() for details.
74
     */
75
    bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
76
            bool checkSig) const override;
77
78
protected:
79
    const aiImporterDesc *GetInfo() const override;
80
    void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override;
81
    void SetupProperties(const Importer *pImp) override;
82
83
private:
84
    /** Data structure for a scene-graph node animator
85
     */
86
    struct Animator {
87
        // Type of the animator
88
        enum AT {
89
            UNKNOWN = 0x0,
90
            ROTATION = 0x1,
91
            FLY_CIRCLE = 0x2,
92
            FLY_STRAIGHT = 0x3,
93
            FOLLOW_SPLINE = 0x4,
94
            OTHER = 0x5
95
96
        } type;
97
98
        explicit Animator(AT t = UNKNOWN) :
99
828
                type(t), speed(ai_real(0.001)), direction(ai_real(0.0), ai_real(1.0), ai_real(0.0)), circleRadius(ai_real(1.0)), tightness(ai_real(0.5)), loop(true), timeForWay(100) {
100
828
        }
101
102
        // common parameters
103
        ai_real speed;
104
        aiVector3D direction;
105
106
        // FLY_CIRCLE
107
        aiVector3D circleCenter;
108
        ai_real circleRadius;
109
110
        // FOLLOW_SPLINE
111
        ai_real tightness;
112
        std::vector<aiVectorKey> splineKeys;
113
114
        // ROTATION (angles given in direction)
115
116
        // FLY STRAIGHT
117
        // circleCenter = start, direction = end
118
        bool loop;
119
        int timeForWay;
120
    };
121
122
    /** Data structure for a scene-graph node in an IRR file
123
     */
124
    struct Node {
125
        // Type of the node
126
        enum ET {
127
            LIGHT,
128
            CUBE,
129
            MESH,
130
            SKYBOX,
131
            DUMMY,
132
            CAMERA,
133
            TERRAIN,
134
            SPHERE,
135
            ANIMMESH
136
        } type;
137
138
        explicit Node(ET t) :
139
4.43k
                type(t), scaling(1.0, 1.0, 1.0) // assume uniform scaling by default
140
                ,
141
                parent(),
142
4.43k
                framesPerSecond(0.0),
143
                id(),
144
4.43k
                sphereRadius(1.0),
145
4.43k
                spherePolyCountX(100),
146
4.43k
                spherePolyCountY(100) {
147
148
            // Generate a default name for the node
149
4.43k
            char buffer[128];
150
4.43k
            static int cnt;
151
4.43k
            ai_snprintf(buffer, 128, "IrrNode_%i", cnt++);
152
4.43k
            name = std::string(buffer);
153
154
            // reserve space for up to 5 materials
155
4.43k
            materials.reserve(5);
156
157
            // reserve space for up to 5 children
158
4.43k
            children.reserve(5);
159
4.43k
        }
160
161
        // Transformation of the node
162
        aiVector3D position, rotation, scaling;
163
164
        // Name of the node
165
        std::string name;
166
167
        // List of all child nodes
168
        std::vector<std::unique_ptr<Node> > children;
169
170
        // Parent node
171
        Node *parent;
172
173
        // Animated meshes: frames per second
174
        // 0.f if not specified
175
        ai_real framesPerSecond;
176
177
        // Meshes: path to the mesh to be loaded
178
        std::string meshPath;
179
        unsigned int id;
180
181
        // Meshes: List of materials to be assigned
182
        // along with their corresponding material flags
183
        std::vector<std::pair<std::unique_ptr<aiMaterial>, unsigned int>> materials;
184
185
        // Spheres: radius of the sphere to be generates
186
        ai_real sphereRadius;
187
188
        // Spheres: Number of polygons in the x,y direction
189
        unsigned int spherePolyCountX, spherePolyCountY;
190
191
        // List of all animators assigned to the node
192
        std::list<Animator> animators;
193
    };
194
195
    /** Data structure for a vertex in an IRR skybox
196
     */
197
    struct SkyboxVertex {
198
        SkyboxVertex() = default;
199
200
        //! Construction from single vertex components
201
        SkyboxVertex(ai_real px, ai_real py, ai_real pz,
202
                ai_real nx, ai_real ny, ai_real nz,
203
                ai_real uvx, ai_real uvy)
204
205
                :
206
0
                position(px, py, pz), normal(nx, ny, nz), uv(uvx, uvy, 0.0) {}
207
208
        aiVector3D position, normal, uv;
209
    };
210
211
    // -------------------------------------------------------------------
212
    // Parse <node> tag from XML file and extract child node
213
    // @param node XML node
214
    // @param guessedMeshesContained number of extra guessed meshes
215
    std::unique_ptr<IRRImporter::Node> ParseNode(pugi::xml_node &node, BatchLoader& batch);
216
217
    // -------------------------------------------------------------------
218
    // Parse <attributes> tags within <node> tags and apply to scene node
219
    // @param attributeNode XML child node
220
    // @param nd Attributed scene node
221
    void ParseNodeAttributes(pugi::xml_node &attributeNode, IRRImporter::Node *nd, BatchLoader& batch);
222
223
    // -------------------------------------------------------------------
224
    // Parse an <animator> node and attach an animator to a node
225
    // @param animatorNode XML animator node
226
    // @param nd Animated scene node
227
    void ParseAnimators(pugi::xml_node &animatorNode, IRRImporter::Node *nd);
228
229
    // -------------------------------------------------------------------
230
    /// Fill the scene-graph recursively
231
    void GenerateGraph(Node *root, aiNode *rootOut, aiScene *scene,
232
            BatchLoader &batch,
233
            std::vector<aiMesh *> &meshes,
234
            std::vector<aiNodeAnim *> &anims,
235
            std::vector<AttachmentInfo> &attach,
236
            std::vector<std::unique_ptr<aiMaterial> > &materials,
237
            unsigned int &defaultMatIdx);
238
239
    // -------------------------------------------------------------------
240
    /// Generate a mesh that consists of just a single quad
241
    aiMesh *BuildSingleQuadMesh(const SkyboxVertex &v1,
242
            const SkyboxVertex &v2,
243
            const SkyboxVertex &v3,
244
            const SkyboxVertex &v4);
245
246
    // -------------------------------------------------------------------
247
    /// Build a sky-box
248
    ///
249
    /// @param meshes Receives 6 output meshes
250
    /// @param materials The last 6 materials are assigned to the newly
251
    ///                  created meshes. The names of the materials are adjusted.
252
    void BuildSkybox(std::vector<aiMesh *> &meshes,
253
                     std::vector<std::unique_ptr<aiMaterial> > &materials);
254
255
    // -------------------------------------------------------------------
256
    /** Copy a material for a mesh to the output material list
257
     *
258
     *  @param materials Receives an output material
259
     *  @param inmaterials List of input materials
260
     *  @param defMatIdx Default material index - UINT_MAX if not present
261
     *  @param mesh Mesh to work on
262
     */
263
    void CopyMaterial(std::vector<std::unique_ptr<aiMaterial> > &materials,
264
            std::vector<std::pair<std::unique_ptr<aiMaterial>, unsigned int>> &inmaterials,
265
            unsigned int &defMatIdx,
266
            aiMesh *mesh);
267
268
    // -------------------------------------------------------------------
269
    /** Compute animations for a specific node
270
     *
271
     *  @param root Node to be processed
272
     *  @param anims The list of output animations
273
     */
274
    void ComputeAnimations(Node *root, aiNode *real,
275
            std::vector<aiNodeAnim *> &anims);
276
277
private:
278
    /// Configuration option: desired output FPS
279
    double fps;
280
281
    /// Configuration option: speed flag was set?
282
    bool configSpeedFlag;
283
284
    std::vector<aiCamera*> cameras;
285
    std::vector<aiLight*> lights;
286
    unsigned int guessedMeshCnt;
287
    unsigned int guessedMatCnt;
288
    unsigned int guessedAnimCnt;
289
};
290
291
} // end of namespace Assimp
292
293
#endif // AI_IRRIMPORTER_H_INC