source: GTP/trunk/Lib/Illum/GPUObscurancesGT/src/OgreXMLSkeletonSerializer.cpp @ 930

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