Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/ogre/Tools/XMLConverter/src/OgreXMLSkeletonSerializer.cpp @ 15

Last change on this file since 15 was 6, checked in by anonymous, 17 years ago

=…

File size: 23.6 KB
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2006 Torus Knot Software Ltd
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23
24You may alternatively use this source under the terms of a specific version of
25the OGRE Unrestricted License provided you have obtained such a license from
26Torus Knot Software Ltd.
27-----------------------------------------------------------------------------
28*/
29
30#include "OgreXMLSkeletonSerializer.h"
31#include "OgreSkeleton.h"
32#include "OgreAnimation.h"
33#include "OgreAnimationTrack.h"
34#include "OgreKeyFrame.h"
35#include "OgreBone.h"
36#include "OgreString.h"
37#include "OgreLogManager.h"
38#include "OgreStringConverter.h"
39#include "Ogre.h"
40
41#include <map>
42
43namespace Ogre {
44
45   
46    //---------------------------------------------------------------------
47    XMLSkeletonSerializer::XMLSkeletonSerializer()
48    {
49    }
50    //---------------------------------------------------------------------
51    XMLSkeletonSerializer::~XMLSkeletonSerializer()
52    {
53    }
54
55    //---------------------------------------------------------------------
56    void XMLSkeletonSerializer::importSkeleton(const String& filename, Skeleton* pSkeleton)
57    {   
58                LogManager::getSingleton().logMessage("XMLSkeletonSerializer: reading XML data from " + filename + "...");
59
60                mXMLDoc = new TiXmlDocument(filename);
61        mXMLDoc->LoadFile();
62
63                TiXmlElement* elem;
64
65        TiXmlElement* rootElem = mXMLDoc->RootElement();
66
67        // Bones
68        elem = rootElem->FirstChildElement("bones");
69        if (elem)
70                {
71            readBones(pSkeleton, elem);                 
72                        elem = rootElem->FirstChildElement("bonehierarchy");
73
74                        if (elem)
75                        {
76                                createHierarchy(pSkeleton, elem) ;
77                                elem = rootElem->FirstChildElement("bones");
78                                if (elem)
79                                {
80                                        readBones2(pSkeleton, elem);
81                                        elem = rootElem->FirstChildElement("animations");
82                                        if (elem)
83                                        {
84                                                readAnimations(pSkeleton, elem);
85                                        }
86                                        elem = rootElem->FirstChildElement("animationlinks");
87                                        if (elem)
88                                        {
89                                                readSkeletonAnimationLinks(pSkeleton, elem);
90                                        }
91                                }
92                        }
93                }
94                LogManager::getSingleton().logMessage("XMLSkeletonSerializer: Finished. Running SkeletonSerializer..." );
95    }
96       
97
98        //---------------------------------------------------------------------
99        // sets names
100        void XMLSkeletonSerializer::readBones(Skeleton* skel, TiXmlElement* mBonesNode)
101    {
102        LogManager::getSingleton().logMessage("XMLSkeletonSerializer: Reading Bones name...");
103               
104                Bone* btmp ;
105                Quaternion quat ;
106
107        for (TiXmlElement* bonElem = mBonesNode->FirstChildElement();
108            bonElem != 0; bonElem = bonElem->NextSiblingElement())
109        {
110            String name = bonElem->Attribute("name");
111                        int id = StringConverter::parseInt(bonElem->Attribute("id"));                           
112                        btmp = skel->createBone(name,id) ;
113
114        }
115    }
116        // ---------------------------------------------------------
117        // set positions and orientations.
118        void XMLSkeletonSerializer::readBones2(Skeleton* skel, TiXmlElement* mBonesNode)
119    {
120        LogManager::getSingleton().logMessage("XMLSkeletonSerializer: Reading Bones data...");
121               
122                Bone* btmp ;
123                Quaternion quat ;
124
125        for (TiXmlElement* bonElem = mBonesNode->FirstChildElement();
126            bonElem != 0; bonElem = bonElem->NextSiblingElement())
127        {
128            String name = bonElem->Attribute("name");
129                        int id = StringConverter::parseInt(bonElem->Attribute("id"));
130
131                        TiXmlElement* posElem = bonElem->FirstChildElement("position");
132                        TiXmlElement* rotElem = bonElem->FirstChildElement("rotation");
133                        TiXmlElement* axisElem = rotElem->FirstChildElement("axis");
134            TiXmlElement* scaleElem = bonElem->FirstChildElement("scale");
135                       
136                        Vector3 pos;
137                        Vector3 axis;
138                        Radian angle ;
139            Vector3 scale;
140
141                        pos.x = StringConverter::parseReal(posElem->Attribute("x"));
142                        pos.y = StringConverter::parseReal(posElem->Attribute("y"));
143                        pos.z = StringConverter::parseReal(posElem->Attribute("z"));
144                       
145                        angle = Radian(StringConverter::parseReal(rotElem->Attribute("angle")));
146
147                        axis.x = StringConverter::parseReal(axisElem->Attribute("x"));
148                        axis.y = StringConverter::parseReal(axisElem->Attribute("y"));
149                        axis.z = StringConverter::parseReal(axisElem->Attribute("z"));
150                       
151            // Optional scale
152            if (scaleElem)
153            {
154                // Uniform scale or per axis?
155                const char* factorAttrib = scaleElem->Attribute("factor");
156                if (factorAttrib)
157                {
158                    // Uniform scale
159                    Real factor = StringConverter::parseReal(factorAttrib);
160                    scale = Vector3(factor, factor, factor);
161                }
162                else
163                {
164                    // axis scale
165                    scale = Vector3::UNIT_SCALE;
166                    const char* factorString = scaleElem->Attribute("x");
167                    if (factorString)
168                    {
169                        scale.x = StringConverter::parseReal(factorString);
170                    }
171                    factorString = scaleElem->Attribute("y");
172                    if (factorString)
173                    {
174                        scale.y = StringConverter::parseReal(factorString);
175                    }
176                    factorString = scaleElem->Attribute("z");
177                    if (factorString)
178                    {
179                        scale.z = StringConverter::parseReal(factorString);
180                    }
181                }
182            }
183            else
184            {
185                scale = Vector3::UNIT_SCALE;
186            }
187
188                        /*LogManager::getSingleton().logMessage("bone " + name + " : position("
189                                + StringConverter::toString(pos.x) + "," + StringConverter::toString(pos.y) + "," + StringConverter::toString(pos.z) + ")"
190                                + " - angle: " + StringConverter::toString(angle) +" - axe: "
191                                + StringConverter::toString(axis.x) + "," + StringConverter::toString(axis.y) + "," + StringConverter::toString(axis.z) );
192                        */             
193                       
194                        btmp = skel->getBone(name) ;
195
196                        btmp -> setPosition(pos);
197                        quat.FromAngleAxis(angle,axis);
198                        btmp -> setOrientation(quat) ;
199            btmp -> setScale(scale);
200
201        } // bones
202    }
203        //-------------------------------------------------------------------
204        void XMLSkeletonSerializer::createHierarchy(Skeleton* skel, TiXmlElement* mHierNode) {
205               
206                LogManager::getSingleton().logMessage("XMLSkeletonSerializer: Reading Hierarchy data...");
207               
208                Bone* bone ;
209                Bone* parent ;
210                String boneName ;
211                String parentName ;
212
213                for (TiXmlElement* hierElem = mHierNode->FirstChildElement() ; hierElem != 0; hierElem = hierElem->NextSiblingElement())
214        {
215                        boneName = hierElem->Attribute("bone");
216                        parentName = hierElem->Attribute("parent");
217                        bone = skel->getBone(boneName);
218                        parent = skel->getBone(parentName);
219                        parent ->addChild(bone) ;
220                        //LogManager::getSingleton().logMessage("XMLSkeletonSerialiser: lien: " + parent->getName() + "->" + bone->getName());
221                       
222                }
223        }
224        //---------------------------------------------------------------------
225        void XMLSkeletonSerializer::readAnimations(Skeleton* skel, TiXmlElement* mAnimNode) {
226               
227                Animation * anim ;
228                NodeAnimationTrack * track ;
229                LogManager::getSingleton().logMessage("XMLSkeletonSerializer: Reading Animations data...");
230
231                for (TiXmlElement* animElem = mAnimNode->FirstChildElement("animation"); animElem != 0; animElem = animElem->NextSiblingElement())
232        {
233            String name = animElem->Attribute("name");
234                        Real length = StringConverter::parseReal(animElem->Attribute("length"));
235                        anim = skel->createAnimation(name,length);
236                        anim->setInterpolationMode(Animation::IM_LINEAR) ;
237
238                       
239                        LogManager::getSingleton().logMessage("Animation: nom: " + name + " et longueur: "
240                                + StringConverter::toString(length) );
241                       
242                        // lecture des tracks
243                        int trackIndex = 0;
244                        TiXmlElement* tracksNode = animElem->FirstChildElement("tracks");
245                       
246                        for (TiXmlElement* trackElem = tracksNode->FirstChildElement("track"); trackElem != 0; trackElem = trackElem->NextSiblingElement())
247                        {
248                                String boneName = trackElem->Attribute("bone");
249
250                                //LogManager::getSingleton().logMessage("Track sur le bone: " + boneName );
251
252                                track = anim->createNodeTrack(trackIndex++,skel->getBone(boneName));
253                                readKeyFrames(track, trackElem->FirstChildElement("keyframes"));
254                        }
255                       
256                }
257
258
259        }
260        //---------------------------------------------------------------------
261        void XMLSkeletonSerializer::readKeyFrames(NodeAnimationTrack* track, TiXmlElement* mKeyfNode) {
262               
263                TransformKeyFrame* kf ;
264                Quaternion q ;
265
266                for (TiXmlElement* keyfElem = mKeyfNode->FirstChildElement("keyframe"); keyfElem != 0; keyfElem = keyfElem->NextSiblingElement())
267        {
268                        Vector3 trans;
269                        Vector3 axis;
270                        Radian angle;
271                        Real time;
272
273            // Get time and create keyframe
274                        time = StringConverter::parseReal(keyfElem->Attribute("time"));
275                        kf = track->createNodeKeyFrame(time);
276            // Optional translate
277                        TiXmlElement* transElem = keyfElem->FirstChildElement("translate");
278            if (transElem)
279            {
280                            trans.x = StringConverter::parseReal(transElem->Attribute("x"));
281                            trans.y = StringConverter::parseReal(transElem->Attribute("y"));
282                            trans.z = StringConverter::parseReal(transElem->Attribute("z"));
283                            kf->setTranslate(trans) ;
284            }
285            // Optional rotate
286                        TiXmlElement* rotElem = keyfElem->FirstChildElement("rotate");
287            if (rotElem)
288            {
289                TiXmlElement* axisElem = rotElem->FirstChildElement("axis");
290                if (!axisElem)
291                {
292                    OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Missing 'axis' element "
293                    "expected under parent 'rotate'", "MXLSkeletonSerializer::readKeyFrames");
294                }
295                            angle = Radian(StringConverter::parseReal(rotElem->Attribute("angle")));
296
297                            axis.x = StringConverter::parseReal(axisElem->Attribute("x"));
298                            axis.y = StringConverter::parseReal(axisElem->Attribute("y"));
299                            axis.z = StringConverter::parseReal(axisElem->Attribute("z"));
300
301                            q.FromAngleAxis(angle,axis);
302                            kf->setRotation(q) ;
303
304            }
305            // Optional scale
306                        TiXmlElement* scaleElem = keyfElem->FirstChildElement("scale");
307            if (scaleElem)
308            {
309                // Uniform scale or per axis?
310                                const char* factorAttrib = scaleElem->Attribute("factor");
311                                if (factorAttrib)
312                                {
313                                        // Uniform scale
314                                        Real factor = StringConverter::parseReal(factorAttrib);
315                                        kf->setScale(Vector3(factor, factor, factor));
316                                }
317                                else
318                                {
319                                        // axis scale
320                    Real xs = 1.0f, ys = 1.0f, zs=1.0f;
321                    const char* factorString = scaleElem->Attribute("x");
322                    if(factorString)
323                    {
324                        xs = StringConverter::parseReal(factorString);
325                    }
326                    factorString = scaleElem->Attribute("y");
327                    if(factorString)
328                    {
329                        ys = StringConverter::parseReal(factorString);
330                    }
331                    factorString = scaleElem->Attribute("z");
332                    if(factorString)
333                    {
334                        zs = StringConverter::parseReal(factorString);
335                    }
336                                        kf->setScale(Vector3(xs, ys, zs));
337                                       
338                                }
339            }
340
341                       
342                        /*
343                        LogManager::getSingleton().logMessage("Keyframe: translation("
344                                + StringConverter::toString(trans.x) + "," + StringConverter::toString(trans.y) + "," + StringConverter::toString(trans.z) + ")"
345                                + " - angle: " + StringConverter::toString(angle) +" - axe: "
346                                + StringConverter::toString(axis.x) + "," + StringConverter::toString(axis.y) + "," + StringConverter::toString(axis.z) );
347                        */
348                       
349
350                }
351        }
352
353    //---------------------------------------------------------------------
354    void XMLSkeletonSerializer::exportSkeleton(const Skeleton* pSkeleton, 
355        const String& filename)
356    {
357               
358        LogManager::getSingleton().logMessage("XMLSkeletonSerializer writing "
359            " skeleton data to " + filename + "...");
360
361        mXMLDoc = new TiXmlDocument();
362        mXMLDoc->InsertEndChild(TiXmlElement("skeleton"));
363        TiXmlElement* rootNode = mXMLDoc->RootElement();
364
365        LogManager::getSingleton().logMessage("Populating DOM...");
366
367
368        // Write main skeleton data
369        LogManager::getSingleton().logMessage("Exporting bones..");
370        writeSkeleton(pSkeleton);
371        LogManager::getSingleton().logMessage("Bones exported.");
372               
373        // Write all animations
374        unsigned short numAnims = pSkeleton->getNumAnimations();
375                String msg = "Exporting animations, count=" + StringConverter::toString(numAnims);
376        LogManager::getSingleton().logMessage(msg);
377
378        TiXmlElement* animsNode = 
379            rootNode->InsertEndChild(TiXmlElement("animations"))->ToElement();
380       
381        for (unsigned short i = 0; i < numAnims; ++i)
382        {
383            Animation* pAnim = pSkeleton->getAnimation(i);
384            msg = "Exporting animation: " + pAnim->getName();
385            LogManager::getSingleton().logMessage(msg);
386            writeAnimation(animsNode, pAnim);
387            LogManager::getSingleton().logMessage("Animation exported.");
388
389        }
390
391                // Write links
392                Skeleton::LinkedSkeletonAnimSourceIterator linkIt = 
393                        pSkeleton->getLinkedSkeletonAnimationSourceIterator();
394                if (linkIt.hasMoreElements())
395                {
396                        LogManager::getSingleton().logMessage("Exporting animation links.");
397                        TiXmlElement* linksNode = 
398                                rootNode->InsertEndChild(TiXmlElement("animationlinks"))->ToElement();
399                        while(linkIt.hasMoreElements())
400                        {
401                                const LinkedSkeletonAnimationSource& link = linkIt.getNext();
402                                writeSkeletonAnimationLink(linksNode, link);
403                        }
404                }
405
406        LogManager::getSingleton().logMessage("DOM populated, writing XML file..");
407
408        // Write out to a file
409        mXMLDoc->SaveFile(filename);
410
411   
412        delete mXMLDoc;
413
414        LogManager::getSingleton().logMessage("XMLSkeletonSerializer export successful.");
415       
416    }
417    //---------------------------------------------------------------------
418    void XMLSkeletonSerializer::writeSkeleton(const Skeleton* pSkel)
419    {
420        TiXmlElement* rootNode = mXMLDoc->RootElement();
421
422        TiXmlElement* bonesElem = 
423            rootNode->InsertEndChild(TiXmlElement("bones"))->ToElement();
424
425        unsigned short numBones = pSkel->getNumBones();
426                LogManager::getSingleton().logMessage("There are " + StringConverter::toString(numBones) + " bones.");
427        unsigned short i;
428        for (i = 0; i < numBones; ++i)
429        {
430                        LogManager::getSingleton().logMessage("   Exporting Bone number " + StringConverter::toString(i));
431            Bone* pBone = pSkel->getBone(i);
432            writeBone(bonesElem, pBone);
433        }
434
435        // Write parents
436        TiXmlElement* hierElem = 
437            rootNode->InsertEndChild(TiXmlElement("bonehierarchy"))->ToElement();
438        for (i = 0; i < numBones; ++i)
439        {
440            Bone* pBone = pSkel->getBone(i);
441            unsigned short handle = pBone->getHandle();
442                        String name = pBone->getName() ;
443            /* BEFORE
444                        if (handle != 0) // root bone
445            {
446                Bone* pParent = (Bone*)pBone->getParent();
447                writeBoneParent(hierElem, name, pParent->getName());
448            }
449                        *//* AFTER */
450                        if ((pBone->getParent())!=NULL) // root bone
451            {
452                Bone* pParent = (Bone*)pBone->getParent();
453                writeBoneParent(hierElem, name, pParent->getName());
454            }
455        }
456
457
458    }
459    //---------------------------------------------------------------------
460    void XMLSkeletonSerializer::writeBone(TiXmlElement* bonesElement, const Bone* pBone)
461    {
462        TiXmlElement* boneElem = 
463            bonesElement->InsertEndChild(TiXmlElement("bone"))->ToElement();
464
465       
466        // Bone name & handle
467        boneElem->SetAttribute("id", 
468            StringConverter::toString(pBone->getHandle()));
469        boneElem->SetAttribute("name", pBone->getName());
470
471        // Position
472        TiXmlElement* subNode = 
473            boneElem->InsertEndChild(TiXmlElement("position"))->ToElement();
474        Vector3 pos = pBone->getPosition();
475        subNode->SetAttribute("x", StringConverter::toString(pos.x));
476        subNode->SetAttribute("y", StringConverter::toString(pos.y));
477        subNode->SetAttribute("z", StringConverter::toString(pos.z));
478       
479        // Orientation
480        subNode = 
481            boneElem->InsertEndChild(TiXmlElement("rotation"))->ToElement();
482        // Show Quaternion as angle / axis
483        Radian angle;
484        Vector3 axis;
485        pBone->getOrientation().ToAngleAxis(angle, axis);
486        TiXmlElement* axisNode = 
487            subNode->InsertEndChild(TiXmlElement("axis"))->ToElement();
488        subNode->SetAttribute("angle", StringConverter::toString(angle.valueRadians()));
489        axisNode->SetAttribute("x", StringConverter::toString(axis.x));
490        axisNode->SetAttribute("y", StringConverter::toString(axis.y));
491        axisNode->SetAttribute("z", StringConverter::toString(axis.z));
492
493        // Scale optional
494        Vector3 scale = pBone->getScale();
495        if (scale != Vector3::UNIT_SCALE)
496        {
497            TiXmlElement* scaleNode =
498                boneElem->InsertEndChild(TiXmlElement("scale"))->ToElement();
499            scaleNode->SetAttribute("x", StringConverter::toString(scale.x));
500            scaleNode->SetAttribute("y", StringConverter::toString(scale.y));
501            scaleNode->SetAttribute("z", StringConverter::toString(scale.z));
502        }
503
504
505    }
506    //---------------------------------------------------------------------
507        //
508        // Modifications effectuées:
509        //
510        // on stoque les noms et pas les Id. c'est plus lisibles.
511
512
513    void XMLSkeletonSerializer::writeBoneParent(TiXmlElement* boneHierarchyNode, 
514        String boneName, String parentName)
515    {
516        TiXmlElement* boneParentNode = 
517            boneHierarchyNode->InsertEndChild(TiXmlElement("boneparent"))->ToElement();
518                /*
519            boneParentNode->SetAttribute("boneid", StringConverter::toString(boneId));
520        boneParentNode->SetAttribute("parentid", StringConverter::toString(parentId));
521                */
522                // Modifications: on stoque les noms./
523                boneParentNode->SetAttribute("bone", boneName);
524        boneParentNode->SetAttribute("parent", parentName);
525
526    }
527    //---------------------------------------------------------------------
528    void XMLSkeletonSerializer::writeAnimation(TiXmlElement* animsNode, 
529        const Animation* anim)
530    {
531        TiXmlElement* animNode = 
532            animsNode->InsertEndChild(TiXmlElement("animation"))->ToElement();
533
534        animNode->SetAttribute("name", anim->getName());
535        animNode->SetAttribute("length", StringConverter::toString(anim->getLength()));
536
537        // Write all tracks
538        TiXmlElement* tracksNode = 
539            animNode->InsertEndChild(TiXmlElement("tracks"))->ToElement();
540
541        Animation::NodeTrackIterator trackIt = anim->getNodeTrackIterator();
542        while (trackIt.hasMoreElements())
543        {
544            writeAnimationTrack(tracksNode, trackIt.getNext());
545        }
546
547    }
548    //---------------------------------------------------------------------
549    void XMLSkeletonSerializer::writeAnimationTrack(TiXmlElement* tracksNode, 
550        const NodeAnimationTrack* track)
551    {
552        TiXmlElement* trackNode = 
553            tracksNode->InsertEndChild(TiXmlElement("track"))->ToElement();
554       
555       
556        // unsigned short boneIndex     : Index of bone to apply to
557        Bone* bone = (Bone*)track->getAssociatedNode();
558        //unsigned short boneid = bone->getHandle();
559                String boneName = bone->getName();
560        trackNode->SetAttribute("bone", boneName);
561
562        // Write all keyframes
563        TiXmlElement* keysNode = 
564            trackNode->InsertEndChild(TiXmlElement("keyframes"))->ToElement();
565        for (unsigned short i = 0; i < track->getNumKeyFrames(); ++i)
566        {
567            writeKeyFrame(keysNode, track->getNodeKeyFrame(i));
568        }
569    }
570    //---------------------------------------------------------------------
571    void XMLSkeletonSerializer::writeKeyFrame(TiXmlElement* keysNode, 
572                const TransformKeyFrame* key)
573    {
574        TiXmlElement* keyNode = 
575            keysNode->InsertEndChild(TiXmlElement("keyframe"))->ToElement();
576
577        keyNode->SetAttribute("time", StringConverter::toString(key->getTime()));
578
579        TiXmlElement* transNode = 
580            keyNode->InsertEndChild(TiXmlElement("translate"))->ToElement();
581        Vector3 trans = key->getTranslate();
582        transNode->SetAttribute("x", StringConverter::toString(trans.x));
583        transNode->SetAttribute("y", StringConverter::toString(trans.y));
584        transNode->SetAttribute("z", StringConverter::toString(trans.z));
585
586        TiXmlElement* rotNode = 
587            keyNode->InsertEndChild(TiXmlElement("rotate"))->ToElement();
588        // Show Quaternion as angle / axis
589        Radian angle;
590        Vector3 axis;
591        key->getRotation().ToAngleAxis(angle, axis);
592        TiXmlElement* axisNode = 
593            rotNode->InsertEndChild(TiXmlElement("axis"))->ToElement();
594        rotNode->SetAttribute("angle", StringConverter::toString(angle.valueRadians()));
595        axisNode->SetAttribute("x", StringConverter::toString(axis.x));
596        axisNode->SetAttribute("y", StringConverter::toString(axis.y));
597        axisNode->SetAttribute("z", StringConverter::toString(axis.z));
598
599        // Scale optional
600        if (key->getScale() != Vector3::UNIT_SCALE)
601        {
602            TiXmlElement* scaleNode = 
603                keyNode->InsertEndChild(TiXmlElement("scale"))->ToElement();
604
605            scaleNode->SetAttribute("x", StringConverter::toString(key->getScale().x));
606            scaleNode->SetAttribute("y", StringConverter::toString(key->getScale().y));
607            scaleNode->SetAttribute("z", StringConverter::toString(key->getScale().z));
608        }
609
610    }
611    //---------------------------------------------------------------------
612        void XMLSkeletonSerializer::writeSkeletonAnimationLink(TiXmlElement* linksNode, 
613                const LinkedSkeletonAnimationSource& link)
614        {
615                TiXmlElement* linkNode = 
616                        linksNode->InsertEndChild(TiXmlElement("animationlink"))->ToElement();
617                linkNode->SetAttribute("skeletonName", link.skeletonName);
618                linkNode->SetAttribute("scale", StringConverter::toString(link.scale));
619
620        }
621        //---------------------------------------------------------------------
622        void XMLSkeletonSerializer::readSkeletonAnimationLinks(Skeleton* skel, 
623                TiXmlElement* linksNode)
624        {
625                LogManager::getSingleton().logMessage("XMLSkeletonSerializer: Reading Animations links...");
626
627                for (TiXmlElement* linkElem = linksNode->FirstChildElement("animationlink"); 
628                        linkElem != 0; linkElem = linkElem->NextSiblingElement())
629                {
630                        String skelName = linkElem->Attribute("skeletonName");
631                        const char* strScale = linkElem->Attribute("scale");
632                        Real scale;
633                        // Scale optional
634                        if (strScale == 0)
635                        {
636                                scale = 1.0f;
637                        }
638                        else
639                        {
640                                scale = StringConverter::parseReal(strScale);
641                        }
642                        skel->addLinkedSkeletonAnimationSource(skelName, scale);
643
644                }
645        }
646}
647
648
Note: See TracBrowser for help on using the repository browser.