/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 |