Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/ColladaPlugin/src/OgreColladaDocument.cpp @ 21

Last change on this file since 21 was 21, checked in by nicolasc, 16 years ago

added ogreode and Colladaplugin

File size: 9.3 KB
Line 
1/**
2 * This source file is part of OgreColladaPlugin
3 * an addon for OGRE (Object-oriented Graphics Rendering Engine)
4 * For the latest info, see http://www.ogre3d.org/
5 *
6 * This program is free software; you can redistribute it and/or modify it under
7 * the terms of the GNU Lesser General Public License as published by the Free Software
8 * Foundation; either version 2 of the License, or (at your option) any later
9 * version.
10
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14
15 * You should have received a copy of the GNU Lesser General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
17 * Place - Suite 330, Boston, MA 02111-1307, USA, or go to
18 * http://www.gnu.org/copyleft/lesser.txt.
19 *
20 * @authors     Philipp Hartl, Jeff Doyle (nfz)
21 * @see         README
22 */
23
24#include "OgreResourceGroupManager.h"
25
26#include "OgreColladaDocument.h"
27#include "OgreColladaGeometry.h"
28#include "OgreColladaLibrary.h"
29#include "OgreColladaScene.h"
30#include "OgreColladaSyntax.h"
31#include "OgreColladaUtils.h"
32#include "OgreColladaAsset.h"
33
34namespace Ogre
35{
36    //-----------------------------------------------------------------------
37        ColladaDocument::ColladaDocument(ResourceManager* creator, const String& name, ResourceHandle handle,
38                const String& group, bool isManual, ManualResourceLoader* loader)
39                :Resource(creator, name, handle, group, isManual, loader)
40        , mXmlDoc(0)
41        , mSceneMgr(0)
42        , mLibrary(0)
43        , mScene(0)
44        , mAsset(0)
45        , mUpRotation(Quaternion::IDENTITY)
46    {
47
48    }
49
50    //-------------------------------------------------------------------------
51        void ColladaDocument::setSceneManager(SceneManager *scenemgr)
52        {
53        mSceneMgr = scenemgr;
54        }
55
56        //-------------------------------------------------------------------------
57        ColladaDocument::~ColladaDocument()
58        {
59        // have to call this here rather than in Resource destructor
60        // since calling virtual methods in base destructors causes crash
61        LogManager::getSingleton().logMessage("COLLADA Document: " + getName() + " closing.");
62        unload();
63        }
64
65    //-----------------------------------------------------------------------
66    void ColladaDocument::loadImpl(void)
67    {
68        LogManager::getSingleton().logMessage("COLLADA Document: attempting to Load: " + mName + ".");
69        // get the data stream from Resource Group Manager
70        DataStreamPtr dataStream = 
71            ResourceGroupManager::getSingleton().openResource(mName, mGroup);
72
73                // make sure everything is still free
74                if (mXmlDoc) xmlFreeDoc(mXmlDoc);
75
76                // parse an XML file and build a tree
77                // returns the resulting document tree if the file was wellformed, NULL otherwise
78                if (!(mXmlDoc = xmlParseMemory(dataStream->getAsString().c_str(), static_cast<int>(dataStream->size()))))
79                {
80                        LogManager::getSingleton().logMessage("ColladaDocument::loadImpl - could not parse file");
81
82                        xmlCleanupParser();
83                        return;
84                }
85
86                // start import with root element of document <COLLADA>
87                bool status = importCollada(xmlDocGetRootElement(mXmlDoc));
88
89                // free up all the structures used by a document, tree included
90                if (mXmlDoc)
91                {
92                        xmlFreeDoc(mXmlDoc);
93                        mXmlDoc = NULL;
94                }
95
96                xmlCleanupParser();
97    }
98
99    //-----------------------------------------------------------------------
100    void ColladaDocument::unloadImpl(void)
101    {
102                OGRE_DELETE(mLibrary);
103                OGRE_DELETE(mScene);
104        OGRE_DELETE(mAsset);
105                mSceneMgr = NULL;
106    }
107
108        //-------------------------------------------------------------------------
109        bool ColladaDocument::doImport(const String &filename, const String &options)
110        {
111                bool status = false;
112
113                // import options - not yet implemented
114
115                /* TEST
116                FileInfoListPtr pFileInfo = ResourceGroupManager::getSingleton().findResourceFileInfo(ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, filename);
117                if (!pFileInfo->empty())
118                {
119                        LogManager::getSingleton().logMessage("test - " + pFileInfo->at(0).path);
120                }
121                */
122
123                // Macro to check that the libxml version in use is compatible with the
124                // version the software has been compiled against
125                LIBXML_TEST_VERSION
126
127                // test suffix against default collada extension ".dae"
128                String suffix = filename.substr(filename.length()-4,4);
129                if (suffix != ".dae")
130                {
131                        LogManager::getSingleton().logMessage("ColladaDocument::doImport - not valid file suffix: " + suffix);
132                        return false;
133                }
134
135                // make sure everything is still free
136                if (mXmlDoc) xmlFreeDoc(mXmlDoc);
137
138                // parse an XML file and build a tree
139                // returns the resulting document tree if the file was wellformed, NULL otherwise
140                if (!(mXmlDoc = xmlParseFile(filename.c_str())))
141                {
142                        LogManager::getSingleton().logMessage("ColladaDocument::doImport - could not parse file");
143
144                        xmlCleanupParser();
145                        return false;
146                }
147
148                // start import with root element of document <COLLADA>
149                status = importCollada(xmlDocGetRootElement(mXmlDoc));
150
151                // free up all the structures used by a document, tree included
152                if (mXmlDoc)
153                {
154                        xmlFreeDoc(mXmlDoc);
155                        mXmlDoc = NULL;
156                }
157                xmlCleanupParser();
158
159                return status;
160        }
161
162        //-------------------------------------------------------------------------
163        void ColladaDocument::importAsset(xmlNode *node)
164        {
165                mAsset = new ColladaAsset(node);
166        mAsset->doImport();
167        // setup up matrix based on settings in asset
168        switch (mAsset->getUpAxis())
169        {
170        case X_UP:
171            mUpRotation = Quaternion(Degree(-90), Vector3::UNIT_Z);
172            break;
173        case Y_UP:
174            break;
175        case Z_UP:
176            mUpRotation = Quaternion(Degree(-90), Vector3::UNIT_X);
177            break;
178        }
179        }
180
181        //-------------------------------------------------------------------------
182        bool ColladaDocument::importCollada(xmlNode *element)
183        {
184                // is document well-formed?
185                String tagname = (const char *)element->name;
186                if (tagname != CS_ELM_COLLADA)
187                {
188                        LogManager::getSingleton().logMessage("ColladaDocument::importCollada - not well-formed Collada XML document: " + tagname);     
189                        return false;
190                }
191
192                mLibrary = new ColladaLibraryContainer(this);
193
194                // get child elements of <COLLADA>
195                for (xmlNode *child = element->children; child != NULL; child = child->next)
196                {
197                        // we are interested on element nodes only
198                        if (child->type != XML_ELEMENT_NODE) continue;
199
200                        tagname = (const char *)child->name;
201
202                        // look for <asset> [0,1]
203                        if (tagname == CS_ELM_ASSET) 
204                        {
205                                importAsset(child);
206                        }
207                        // look for <library> [+]
208                        else if (tagname == CS_ELM_LIBRARY) 
209                        {
210                                mLibrary->doImport(child);
211                        }
212                        // look for <scene> [1,1]
213                        else if (tagname == CS_ELM_SCENE) 
214                        {
215                                mScene = new ColladaSceneNode(this, child);
216                        }
217                        // unknwon or unsupported tag
218                        else
219                        {
220                                LogManager::getSingleton().logMessage("ColladaDocument::importCollada - unknown child: " + tagname);
221                        }
222                }
223
224                if (mScene != NULL) return mScene->doImport();
225
226                return false;
227        }
228
229        //-------------------------------------------------------------------------
230    UpAxis ColladaDocument::getUpAxis() const
231    {
232        UpAxis axis = Y_UP;
233        if (mAsset)
234        {
235            axis = mAsset->getUpAxis();
236        }
237
238        return axis;
239    }
240
241    //-------------------------------------------------------------------------
242    void ColladaDocument::correctAxis(Vector3& vec) const
243    {
244        if (mAsset)
245        {
246            switch (mAsset->getUpAxis())
247            {
248            case X_UP:
249                {
250                    Real tmp = vec.y;
251                    vec.y = vec.x;
252                    vec.x = -tmp;
253                }
254                break;
255            case Y_UP:
256                break;
257            case Z_UP:
258                {
259                    Real tmp = vec.y;
260                    vec.y = vec.z;
261                    vec.z = -tmp;
262                }
263                break;
264            }
265        }
266    }
267
268    //-------------------------------------------------------------------------
269    void ColladaDocument::correctAxis(Real* vec) const
270    {
271        if (mAsset)
272        {
273            switch (mAsset->getUpAxis())
274            {
275            case X_UP:
276                {
277                    Real tmp = vec[1];
278                    vec[1] = vec[0];
279                    vec[0] = -tmp;
280                }
281                break;
282            case Y_UP:
283                break;
284            case Z_UP:
285                {
286                    Real tmp = vec[1];
287                    vec[1] = vec[2];
288                    vec[2] = -tmp;
289                }
290                break;
291            }
292        }
293    }
294
295    //-------------------------------------------------------------------------
296    void ColladaDocument::correctAxis(Quaternion& quat) const
297    {
298        if (mAsset)
299        {
300            switch (mAsset->getUpAxis())
301            {
302            case X_UP:
303                {
304                    Real tmp = quat.y;
305                    quat.y = quat.x;
306                    quat.x = -tmp;
307                }
308                break;
309            case Y_UP:
310                break;
311            case Z_UP:
312                {
313                    Real tmp = quat.y;
314                    quat.y = quat.z;
315                    quat.z = -tmp;
316                    //quat.w = -quat.w;
317                }
318                break;
319            }
320        }
321    }
322
323
324}
Note: See TracBrowser for help on using the repository browser.