diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/irrlicht-1.8/source/Irrlicht/CSceneLoaderIrr.cpp | 284 |
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 | |||
13 | namespace irr | ||
14 | { | ||
15 | namespace scene | ||
16 | { | ||
17 | |||
18 | //! Constructor | ||
19 | CSceneLoaderIrr::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 | ||
29 | CSceneLoaderIrr::~CSceneLoaderIrr() | ||
30 | { | ||
31 | |||
32 | } | ||
33 | |||
34 | //! Returns true if the class might be able to load this file. | ||
35 | bool 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. | ||
41 | bool 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. | ||
48 | bool 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 | ||
84 | void 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 | ||
168 | void 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 | ||
207 | void 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 | ||
249 | void 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 | |||