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