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