1 // Copyright (C) 2002-2012 Nikolaus Gebhardt
\r
2 // This file is part of the "Irrlicht Engine".
\r
3 // For conditions of distribution and use, see copyright notice in irrlicht.h
\r
5 #ifndef __C_COLLADA_MESH_FILE_LOADER_H_INCLUDED__
\r
6 #define __C_COLLADA_MESH_FILE_LOADER_H_INCLUDED__
\r
8 #include "IMeshLoader.h"
\r
9 #include "IFileSystem.h"
\r
10 #include "IVideoDriver.h"
\r
11 #include "irrString.h"
\r
13 #include "SMeshBuffer.h"
\r
14 #include "ISceneManager.h"
\r
16 #include "CAttributes.h"
\r
24 //#define COLLADA_READER_DEBUG
\r
27 class IColladaPrefab;
\r
29 enum ECOLLADA_PARAM_NAME
\r
44 enum ECOLLADA_PARAM_TYPE
\r
54 //! Collada Parameter
\r
55 struct SColladaParam
\r
58 : Name(ECPN_COUNT), Type(ECPT_COUNT)
\r
60 for (int i=0; i<4; ++i) Floats[i] = 0;
\r
63 ECOLLADA_PARAM_NAME Name;
\r
64 ECOLLADA_PARAM_TYPE Type;
\r
69 enum ECOLLADA_INPUT_SEMANTIC
\r
85 struct SColladaInput
\r
88 : Semantic(ECIS_COUNT), Data(0), Offset(0), Set(0), Stride(1)
\r
92 ECOLLADA_INPUT_SEMANTIC Semantic;
\r
93 core::stringc Source;
\r
101 struct SColladaImage
\r
104 core::stringc Source;
\r
105 core::dimension2du Dimension;
\r
106 bool SourceIsFilename;
\r
110 //! Collada texture
\r
111 struct SColladaTexture
\r
113 video::ITexture* Texture;
\r
118 //! Collada material
\r
119 struct SColladaMaterial
\r
121 video::SMaterial Mat;
\r
123 core::stringc InstanceEffectId;
\r
126 inline bool operator< (const SColladaMaterial & other) const
\r
128 return Id < other.Id;
\r
132 //! Collada effect (materials, shaders, and programs)
\r
133 struct SColladaEffect
\r
137 core::array<core::stringc> Textures;
\r
138 video::SMaterial Mat;
\r
139 // TODO: Parameters looks somewhat lazy workaround, I think we should really read all parameters correct.
\r
140 io::IAttributes * Parameters;
\r
142 inline bool operator< (const SColladaEffect & other) const
\r
144 return Id < other.Id;
\r
149 struct SNumberArray // for storing float and int arrays
\r
151 core::stringc Name;
\r
152 core::array<f32> Data;
\r
158 : Count(0), Offset(0), Stride(1) {}
\r
159 // I don't store the source of the accessor here because I assume
\r
160 // it to use the array of the source this accessor is located in.
\r
166 core::array<SColladaParam> Parameters; // parameters defining the accessor
\r
172 SNumberArray Array;
\r
173 core::array<SAccessor> Accessors;
\r
176 class CScenePrefab;
\r
178 //! Meshloader capable of loading COLLADA meshes and scene descriptions into Irrlicht.
\r
179 class CColladaFileLoader : public IMeshLoader
\r
184 CColladaFileLoader(scene::ISceneManager* smgr, io::IFileSystem* fs);
\r
187 virtual ~CColladaFileLoader();
\r
189 //! returns true if the file maybe is able to be loaded by this class
\r
190 //! based on the file extension (e.g. ".cob")
\r
191 virtual bool isALoadableFileExtension(const io::path& filename) const _IRR_OVERRIDE_;
\r
193 //! creates/loads an animated mesh from the file.
\r
194 //! \return Pointer to the created mesh. Returns 0 if loading failed.
\r
195 //! If you no longer need the mesh, you should call IAnimatedMesh::drop().
\r
196 //! See IReferenceCounted::drop() for more information.
\r
197 virtual IAnimatedMesh* createMesh(io::IReadFile* file) _IRR_OVERRIDE_;
\r
201 //! skips an (unknown) section in the collada document
\r
202 void skipSection(io::IXMLReaderUTF8* reader, bool reportSkipping);
\r
204 //! reads the <COLLADA> section and its content
\r
205 void readColladaSection(io::IXMLReaderUTF8* reader);
\r
207 //! reads a <library> section and its content
\r
208 void readLibrarySection(io::IXMLReaderUTF8* reader);
\r
210 //! reads a <visual_scene> element and stores it as a prefab
\r
211 void readVisualScene(io::IXMLReaderUTF8* reader);
\r
213 //! reads a <scene> section and its content
\r
214 void readSceneSection(io::IXMLReaderUTF8* reader);
\r
216 //! reads a <asset> section and its content
\r
217 void readAssetSection(io::IXMLReaderUTF8* reader);
\r
219 //! reads a <node> section and its content
\r
220 //! if a prefab pointer is passed the nodes are created as scene prefabs children of that prefab
\r
221 void readNodeSection(io::IXMLReaderUTF8* reader, scene::ISceneNode* parent, CScenePrefab* p=0);
\r
223 //! reads a <lookat> element and its content and creates a matrix from it
\r
224 core::matrix4 readLookAtNode(io::IXMLReaderUTF8* reader);
\r
226 //! reads a <matrix> element and its content and creates a matrix from it
\r
227 core::matrix4 readMatrixNode(io::IXMLReaderUTF8* reader);
\r
229 //! reads a <perspective> element and its content and creates a matrix from it
\r
230 core::matrix4 readPerspectiveNode(io::IXMLReaderUTF8* reader);
\r
232 //! reads a <rotate> element and its content and creates a matrix from it
\r
233 core::matrix4 readRotateNode(io::IXMLReaderUTF8* reader);
\r
235 //! reads a <skew> element and its content and creates a matrix from it
\r
236 core::matrix4 readSkewNode(io::IXMLReaderUTF8* reader);
\r
238 //! reads a <boundingbox> element and its content and stores it in bbox
\r
239 void readBboxNode(io::IXMLReaderUTF8* reader, core::aabbox3df& bbox);
\r
241 //! reads a <scale> element and its content and creates a matrix from it
\r
242 core::matrix4 readScaleNode(io::IXMLReaderUTF8* reader);
\r
244 //! reads a <translate> element and its content and creates a matrix from it
\r
245 core::matrix4 readTranslateNode(io::IXMLReaderUTF8* reader);
\r
247 //! reads a <color> element
\r
248 video::SColorf readColorNode(io::IXMLReaderUTF8* reader);
\r
250 //! reads a <float> element
\r
251 f32 readFloatNode(io::IXMLReaderUTF8* reader);
\r
253 //! reads a <instance> node
\r
254 void readInstanceNode(io::IXMLReaderUTF8* reader,
\r
255 scene::ISceneNode* parent, scene::ISceneNode** outNode,
\r
256 CScenePrefab* p=0, const core::stringc& type=core::stringc());
\r
258 //! creates a scene node from Prefabs (with name given in 'url')
\r
259 void instantiateNode(scene::ISceneNode* parent, scene::ISceneNode** outNode=0,
\r
260 CScenePrefab* p=0, const core::stringc& url="",
\r
261 const core::stringc& type=core::stringc());
\r
263 //! reads a <light> element and stores it as prefab
\r
264 void readLightPrefab(io::IXMLReaderUTF8* reader);
\r
266 //! reads a <camera> element and stores it as prefab
\r
267 void readCameraPrefab(io::IXMLReaderUTF8* reader);
\r
269 //! reads a <image> element and stores it in the image section
\r
270 void readImage(io::IXMLReaderUTF8* reader);
\r
272 //! reads a <texture> element and stores it in the texture section
\r
273 void readTexture(io::IXMLReaderUTF8* reader);
\r
275 //! reads a <material> element and stores it in the material section
\r
276 void readMaterial(io::IXMLReaderUTF8* reader);
\r
278 //! reads a <effect> element and stores it in the effects section
\r
279 void readEffect(io::IXMLReaderUTF8* reader, SColladaEffect * effect = 0);
\r
281 //! reads a <geometry> element and stores it as mesh if possible
\r
282 void readGeometry(io::IXMLReaderUTF8* reader);
\r
284 //! parses a float from a char pointer and moves the pointer to
\r
285 //! the end of the parsed float
\r
286 inline f32 readFloat(const c8** p);
\r
288 //! parses an int from a char pointer and moves the pointer to
\r
289 //! the end of the parsed float
\r
290 inline s32 readInt(const c8** p);
\r
292 //! places pointer to next begin of a token
\r
293 void findNextNoneWhiteSpace(const c8** p);
\r
295 //! reads floats from inside of xml element until end of xml element
\r
296 void readFloatsInsideElement(io::IXMLReaderUTF8* reader, f32* floats, u32 count);
\r
298 //! reads ints from inside of xml element until end of xml element
\r
299 void readIntsInsideElement(io::IXMLReaderUTF8* reader, s32* ints, u32 count);
\r
301 //! clears all loaded data
\r
304 //! parses all collada parameters inside an element and stores them in ColladaParameters
\r
305 void readColladaParameters(io::IXMLReaderUTF8* reader, const core::stringc& parentName);
\r
307 //! returns a collada parameter or none if not found
\r
308 SColladaParam* getColladaParameter(ECOLLADA_PARAM_NAME name);
\r
310 //! parses all collada inputs inside an element and stores them in Inputs. Reads
\r
311 //! until first tag which is not an input tag or the end of the parent is reached
\r
312 void readColladaInputs(io::IXMLReaderUTF8* reader, const core::stringc& parentName);
\r
314 //! reads a collada input tag and adds it to the input parameter
\r
315 void readColladaInput(io::IXMLReaderUTF8* reader, core::array<SColladaInput>& inputs);
\r
317 //! returns a collada input or none if not found
\r
318 SColladaInput* getColladaInput(ECOLLADA_INPUT_SEMANTIC input);
\r
320 //! read Collada Id, uses id or name if id is missing
\r
321 core::stringc readId(io::IXMLReaderUTF8* reader);
\r
323 //! changes the XML URI into an internal id
\r
324 void uriToId(core::stringc& str);
\r
326 //! reads a polygons section and creates a mesh from it
\r
327 void readPolygonSection(io::IXMLReaderUTF8* reader,
\r
328 core::array<SSource>& sources, scene::SMesh* mesh,
\r
329 const core::stringc& geometryId);
\r
331 //! finds a material, possible instancing it
\r
332 const SColladaMaterial * findMaterial(const core::stringc & materialName);
\r
334 //! reads and bind materials as given by the symbol->target bind mapping
\r
335 void readBindMaterialSection(io::IXMLReaderUTF8* reader, const core::stringc & id);
\r
337 //! create an Irrlicht texture from the SColladaImage
\r
338 video::ITexture* getTextureFromImage(core::stringc uri, SColladaEffect * effect);
\r
340 //! read a parameter and value
\r
341 void readParameter(io::IXMLReaderUTF8* reader, io::IAttributes* parameters);
\r
343 //! Flip z axis in matrix around to convert between right-handed and left-handed coordinate system.
\r
344 //! Note that function is symmetric (no difference if called before or after a transpose).
\r
345 core::matrix4 flipZAxis(const core::matrix4& m);
\r
347 //! replace escape characters with the unescaped ones
\r
348 void unescape(irr::core::stringc& uri);
\r
350 scene::ISceneManager* SceneManager;
\r
351 io::IFileSystem* FileSystem;
\r
353 scene::IAnimatedMesh* DummyMesh;
\r
354 core::stringc CurrentlyLoadingMesh;
\r
356 scene::IAnimatedMesh* FirstLoadedMesh;
\r
357 io::path FirstLoadedMeshName;
\r
358 s32 LoadedMeshCount;
\r
362 core::array<IColladaPrefab*> Prefabs;
\r
363 core::array<SColladaParam> ColladaParameters;
\r
364 core::array<SColladaImage> Images;
\r
365 core::array<SColladaTexture> Textures;
\r
366 core::array<SColladaMaterial> Materials;
\r
367 core::array<SColladaInput> Inputs;
\r
368 core::array<SColladaEffect> Effects;
\r
369 //! meshbuffer reference ("geomid/matname") -> index into MeshesToBind
\r
370 core::map<core::stringc,u32> MaterialsToBind;
\r
371 //! Array of buffers for each material binding
\r
372 core::array< core::array<irr::scene::IMeshBuffer*> > MeshesToBind;
\r
374 bool CreateInstances;
\r
376 struct EscapeCharacterURL
\r
378 EscapeCharacterURL(irr::c8 c, const irr::c8* e)
\r
384 irr::c8 Character; // unescaped (like ' ')
\r
385 irr::core::stringc Escape; // escaped (like '%20')
\r
387 irr::core::array<EscapeCharacterURL> EscapeCharsAnyURI;
\r
392 //! following class is for holding and createing instances of library objects,
\r
393 //! named prefabs in this loader.
\r
394 class IColladaPrefab : public virtual IReferenceCounted
\r
397 //! creates an instance of this prefab
\r
398 virtual scene::ISceneNode* addInstance(scene::ISceneNode* parent,
\r
399 scene::ISceneManager* mgr) = 0;
\r
401 //! returns id of this prefab
\r
402 virtual const core::stringc& getId() = 0;
\r
406 } // end namespace scene
\r
407 } // end namespace irr
\r