aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/source/Irrlicht/CSceneLoaderIrr.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/CSceneLoaderIrr.cpp284
1 files changed, 284 insertions, 0 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CSceneLoaderIrr.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CSceneLoaderIrr.cpp
new file mode 100644
index 0000000..7705436
--- /dev/null
+++ b/libraries/irrlicht-1.8/source/Irrlicht/CSceneLoaderIrr.cpp
@@ -0,0 +1,284 @@
1// Copyright (C) 2010-2012 Nikolaus Gebhardt
2// This file is part of the "Irrlicht Engine".
3// For conditions of distribution and use, see copyright notice in irrlicht.h
4
5#include "CSceneLoaderIrr.h"
6#include "ISceneNodeAnimatorFactory.h"
7#include "ISceneUserDataSerializer.h"
8#include "ISceneManager.h"
9#include "IVideoDriver.h"
10#include "IFileSystem.h"
11#include "os.h"
12
13namespace irr
14{
15namespace scene
16{
17
18//! Constructor
19CSceneLoaderIrr::CSceneLoaderIrr(ISceneManager *smgr, io::IFileSystem* fs)
20 : SceneManager(smgr), FileSystem(fs),
21 IRR_XML_FORMAT_SCENE(L"irr_scene"), IRR_XML_FORMAT_NODE(L"node"), IRR_XML_FORMAT_NODE_ATTR_TYPE(L"type"),
22 IRR_XML_FORMAT_ATTRIBUTES(L"attributes"), IRR_XML_FORMAT_MATERIALS(L"materials"),
23 IRR_XML_FORMAT_ANIMATORS(L"animators"), IRR_XML_FORMAT_USERDATA(L"userData")
24{
25
26}
27
28//! Destructor
29CSceneLoaderIrr::~CSceneLoaderIrr()
30{
31
32}
33
34//! Returns true if the class might be able to load this file.
35bool CSceneLoaderIrr::isALoadableFileExtension(const io::path& filename) const
36{
37 return core::hasFileExtension(filename, "irr");
38}
39
40//! Returns true if the class might be able to load this file.
41bool CSceneLoaderIrr::isALoadableFileFormat(io::IReadFile *file) const
42{
43 // todo: check inside the file
44 return true;
45}
46
47//! Loads the scene into the scene manager.
48bool CSceneLoaderIrr::loadScene(io::IReadFile* file, ISceneUserDataSerializer* userDataSerializer,
49 ISceneNode* rootNode)
50{
51 if (!file)
52 {
53 os::Printer::log("Unable to open scene file", ELL_ERROR);
54 return false;
55 }
56
57 io::IXMLReader* reader = FileSystem->createXMLReader(file);
58 if (!reader)
59 {
60 os::Printer::log("Scene is not a valid XML file", file->getFileName().c_str(), ELL_ERROR);
61 return false;
62 }
63
64 // TODO: COLLADA_CREATE_SCENE_INSTANCES can be removed when the COLLADA loader is a scene loader
65 bool oldColladaSingleMesh = SceneManager->getParameters()->getAttributeAsBool(COLLADA_CREATE_SCENE_INSTANCES);
66 SceneManager->getParameters()->setAttribute(COLLADA_CREATE_SCENE_INSTANCES, false);
67
68 // read file
69 while (reader->read())
70 {
71 readSceneNode(reader, rootNode, userDataSerializer);
72 }
73
74 // restore old collada parameters
75 SceneManager->getParameters()->setAttribute(COLLADA_CREATE_SCENE_INSTANCES, oldColladaSingleMesh);
76
77 // clean up
78 reader->drop();
79 return true;
80}
81
82
83//! Reads the next node
84void CSceneLoaderIrr::readSceneNode(io::IXMLReader* reader, ISceneNode* parent,
85 ISceneUserDataSerializer* userDataSerializer)
86{
87 if (!reader)
88 return;
89
90 scene::ISceneNode* node = 0;
91
92 if (!parent && IRR_XML_FORMAT_SCENE==reader->getNodeName())
93 node = SceneManager->getRootSceneNode();
94 else if (parent && IRR_XML_FORMAT_NODE==reader->getNodeName())
95 {
96 // find node type and create it
97 core::stringc attrName = reader->getAttributeValue(IRR_XML_FORMAT_NODE_ATTR_TYPE.c_str());
98
99 node = SceneManager->addSceneNode(attrName.c_str(), parent);
100
101 if (!node)
102 os::Printer::log("Could not create scene node of unknown type", attrName.c_str());
103 }
104 else
105 node=parent;
106
107 // read attributes
108 while(reader->read())
109 {
110 bool endreached = false;
111
112 const wchar_t* name = reader->getNodeName();
113
114 switch (reader->getNodeType())
115 {
116 case io::EXN_ELEMENT_END:
117 if ((IRR_XML_FORMAT_NODE == name) ||
118 (IRR_XML_FORMAT_SCENE == name))
119 {
120 endreached = true;
121 }
122 break;
123 case io::EXN_ELEMENT:
124 if (IRR_XML_FORMAT_ATTRIBUTES == name)
125 {
126 // read attributes
127 io::IAttributes* attr = FileSystem->createEmptyAttributes(SceneManager->getVideoDriver());
128 attr->read(reader, true);
129
130 if (node)
131 node->deserializeAttributes(attr);
132
133 attr->drop();
134 }
135 else
136 if (IRR_XML_FORMAT_MATERIALS == name)
137 readMaterials(reader, node);
138 else
139 if (IRR_XML_FORMAT_ANIMATORS == name)
140 readAnimators(reader, node);
141 else
142 if (IRR_XML_FORMAT_USERDATA == name)
143 readUserData(reader, node, userDataSerializer);
144 else
145 if ((IRR_XML_FORMAT_NODE == name) ||
146 (IRR_XML_FORMAT_SCENE == name))
147 {
148 readSceneNode(reader, node, userDataSerializer);
149 }
150 else
151 {
152 os::Printer::log("Found unknown element in irrlicht scene file",
153 core::stringc(name).c_str());
154 }
155 break;
156 default:
157 break;
158 }
159
160 if (endreached)
161 break;
162 }
163 if (node && userDataSerializer)
164 userDataSerializer->OnCreateNode(node);
165}
166
167//! reads materials of a node
168void CSceneLoaderIrr::readMaterials(io::IXMLReader* reader, ISceneNode* node)
169{
170 u32 nr = 0;
171
172 while(reader->read())
173 {
174 const wchar_t* name = reader->getNodeName();
175
176 switch(reader->getNodeType())
177 {
178 case io::EXN_ELEMENT_END:
179 if (IRR_XML_FORMAT_MATERIALS == name)
180 return;
181 break;
182 case io::EXN_ELEMENT:
183 if (IRR_XML_FORMAT_ATTRIBUTES == name)
184 {
185 // read materials from attribute list
186 io::IAttributes* attr = FileSystem->createEmptyAttributes(SceneManager->getVideoDriver());
187 attr->read(reader);
188
189 if (node && node->getMaterialCount() > nr)
190 {
191 SceneManager->getVideoDriver()->fillMaterialStructureFromAttributes(
192 node->getMaterial(nr), attr);
193 }
194
195 attr->drop();
196 ++nr;
197 }
198 break;
199 default:
200 break;
201 }
202 }
203}
204
205
206//! reads animators of a node
207void CSceneLoaderIrr::readAnimators(io::IXMLReader* reader, ISceneNode* node)
208{
209 while(reader->read())
210 {
211 const wchar_t* name = reader->getNodeName();
212
213 switch(reader->getNodeType())
214 {
215 case io::EXN_ELEMENT_END:
216 if (IRR_XML_FORMAT_ANIMATORS == name)
217 return;
218 break;
219 case io::EXN_ELEMENT:
220 if (IRR_XML_FORMAT_ATTRIBUTES == name)
221 {
222 // read animator data from attribute list
223 io::IAttributes* attr = FileSystem->createEmptyAttributes(SceneManager->getVideoDriver());
224 attr->read(reader);
225
226 if (node)
227 {
228 core::stringc typeName = attr->getAttributeAsString("Type");
229 ISceneNodeAnimator* anim = SceneManager->createSceneNodeAnimator(typeName.c_str(), node);
230
231 if (anim)
232 {
233 anim->deserializeAttributes(attr);
234 anim->drop();
235 }
236 }
237
238 attr->drop();
239 }
240 break;
241 default:
242 break;
243 }
244 }
245}
246
247
248//! reads user data of a node
249void CSceneLoaderIrr::readUserData(io::IXMLReader* reader, ISceneNode* node, ISceneUserDataSerializer* userDataSerializer)
250{
251 while(reader->read())
252 {
253 const wchar_t* name = reader->getNodeName();
254
255 switch(reader->getNodeType())
256 {
257 case io::EXN_ELEMENT_END:
258 if (IRR_XML_FORMAT_USERDATA == name)
259 return;
260 break;
261 case io::EXN_ELEMENT:
262 if (IRR_XML_FORMAT_ATTRIBUTES == name)
263 {
264 // read user data from attribute list
265 io::IAttributes* attr = FileSystem->createEmptyAttributes(SceneManager->getVideoDriver());
266 attr->read(reader);
267
268 if (node && userDataSerializer)
269 {
270 userDataSerializer->OnReadUserData(node, attr);
271 }
272
273 attr->drop();
274 }
275 break;
276 default:
277 break;
278 }
279 }
280}
281
282} // scene
283} // irr
284