Developer Documentation
Loading...
Searching...
No Matches
SkeletonT_impl.hh
1/*===========================================================================*\
2* *
3* OpenFlipper *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openflipper.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenFlipper. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39* *
40\*===========================================================================*/
41
42
43
44//-----------------------------------------------------------------------------
45//
46// CLASS SkeletonT - IMPLEMENTATION
47//
48//-----------------------------------------------------------------------------
49
50#define SKELETON_C
51
52//== INCLUDES =================================================================
53
54#include <iostream>
55#include <algorithm>
56#include <utility>
57
58#include "SkeletonT.hh"
59
60#include "Animation/FrameAnimationT.hh"
61
62
63//-----------------------------------------------------------------------------
64// ITERATOR - IMPLEMENTATION
65//-----------------------------------------------------------------------------
66
72template<typename PointT>
74{
75 pCurrent_ = 0;
76}
77
78//-----------------------------------------------------------------------------
79
85template<typename PointT>
87{
88 pCurrent_ = _root;
89}
90
91//-----------------------------------------------------------------------------
92
99template<typename PointT>
101{
102 pCurrent_ = other.pCurrent_;
103 stJoints_ = other.stJoints_;
104}
105
106//-----------------------------------------------------------------------------
107
112template<typename PointT>
116
117//-----------------------------------------------------------------------------
118
125template<typename PointT>
127{
128 pCurrent_ = other.pCurrent_;
129 stJoints_ = other.stJoints_;
130 return *this;
131}
132
133//-----------------------------------------------------------------------------
134
140template<typename PointT>
142{
143 if(pCurrent_ == 0)
144 return *this;
145
146 // try to make this iterator point to the first child
147 if(pCurrent_->size() > 0)
148 {
149 // there are children, so add the current joint to the stack and choose the first child as new current position
150 stJoints_.push(pCurrent_);
151 pCurrent_ = pCurrent_->child(0);
152 }else{
153
154 if ( pCurrent_->isRoot() ){
155 //root without children -> return invalid iterator
156 pCurrent_ = 0;
157
158 } else {
159 // there are no children left, so try to get the next sibling
160 Joint *pSibling = nextSibling(stJoints_.top(), pCurrent_);
161
162 while(pSibling == 0 && !stJoints_.empty())
163 {
164 // there is no sibling, so try the parents sibling and so on
165 Joint *pParent = stJoints_.top();
166 stJoints_.pop();
167 if(!stJoints_.empty())
168 pSibling = nextSibling(stJoints_.top(), pParent);
169 }
170
171 // did we fail to find a next node?
172 // if so pSibling is 0 now and will invalidate the iterator
173 pCurrent_ = pSibling;
174 }
175 }
176 return *this;
177}
178
179//-----------------------------------------------------------------------------
180
186template<typename PointT>
188{
189 return pCurrent_ != other.pCurrent_;
190}
191
192//-----------------------------------------------------------------------------
193
199template<typename PointT>
201{
202 return pCurrent_ == other.pCurrent_;
203}
204
205//-----------------------------------------------------------------------------
206
210template<typename PointT>
212{
213 return pCurrent_;
214}
215
216//-----------------------------------------------------------------------------
217
228template<typename PointT>
230{
231 return pCurrent_;
232}
233
234//-----------------------------------------------------------------------------
235
242template<typename PointT>
244{
245 return pCurrent_ != 0;
246}
247
248//-----------------------------------------------------------------------------
249
257template<typename PointT>
259{
260 // first find the current node in the parents list of children
261 typename Joint::ChildIter it;
262 for(it = _pParent->begin(); it != _pParent->end(); ++it)
263 {
264 if(*it == _pJoint)
265 {
266 // found it. If there is another child it is the wanted sibling
267 ++it;
268 if(it == _pParent->end())
269 return 0; // oh no, we ran out of siblings
270
271 return *it;
272 }
273 }
274
275 return 0;
276}
277
278//-----------------------------------------------------------------------------
279// AnimationIterator - IMPLEMENTATION
280//-----------------------------------------------------------------------------
281
287template<typename PointT>
288SkeletonT<PointT>::AnimationIterator::AnimationIterator(std::vector<Animation*>& _animations ) :
289 animations_(_animations)
290{
291 currentIndex_ = 0;
292
293 // Increment, until we are at the end or we found a valid animation which is not deleted ( == 0 )
294 while ( currentIndex_ < animations_.size() && animations_[currentIndex_] == 0) {
295 currentIndex_++;
296 }
297
298}
299
304template<typename PointT>
305SkeletonT<PointT>::AnimationIterator::AnimationIterator(std::vector<Animation*>& _animations, size_t _animationIndex ) :
306animations_(_animations)
307{
308 currentIndex_ = _animationIndex;
309
310 // Increment, until we are at the end or we found a valid animation which is not deleted ( == 0 )
311 while ( currentIndex_ < animations_.size() && animations_[currentIndex_] == 0) {
312 currentIndex_++;
313 }
314}
315
321template<typename PointT>
323 currentIndex_++;
324
325 // Increment, until we are at the end or we found a valid animation which is not deleted ( == 0 )
326 while ( currentIndex_ < animations_.size() && animations_[currentIndex_] == 0) {
327 currentIndex_++;
328 }
329
330 return *this;
331}
332
337template<typename PointT>
339 currentIndex_ = other.currentIndex_;
340 animations_ = other.animations_;
341 return *this;
342}
343
349template<typename PointT>
351 return ( currentIndex_ < animations_.size() );
352}
353
358template<typename PointT>
362
363//-----------------------------------------------------------------------------
364// SKELETONT - IMPLEMENTATION
365//-----------------------------------------------------------------------------
366
370template<typename PointT>
374
375//-----------------------------------------------------------------------------
376
382template<typename PointT>
384 Properties(),
385 referencePose_(this)
386{
387 // create a copy of the joints, not yet linked because they refer to each other using pointers
388 for(typename std::vector<Joint*>::const_iterator it = _other.joints_.begin(); it != _other.joints_.end(); ++it)
389 {
390 joints_.push_back(new Joint(**it));
391 insert_property_at( (*it)->id() );
392 }
393
394 // construct the links
395 for(typename std::vector<Joint*>::const_iterator it = _other.joints_.begin(); it != _other.joints_.end(); ++it)
396 {
397 Joint *pJoint = *it;
398
399 if(pJoint->parent() != 0)
400 joint(pJoint->id())->parent_ = joint(pJoint->parent()->id());
401 else
402 joint(pJoint->id())->parent_ = 0;
403 for(typename Joint::ChildIter it_ch = pJoint->begin(); it_ch != pJoint->end(); ++it_ch)
404 joint(pJoint->id())->children_.push_back( joint((*it_ch)->id()) );
405 }
406
407 names_.insert(_other.names_.begin(), _other.names_.end());
408
409 for(typename std::vector<Animation*>::const_iterator it = _other.animations_.begin(); it != _other.animations_.end(); ++it)
410 if (*it) {
411 animations_.push_back((**it).copy());
412 }
413
415}
416
417//-----------------------------------------------------------------------------
418
424template<typename PointT>
426
427 if (this != &_other){ // protect against invalid self-assignment
428
429 // clear the current skeleton
430 clear();
431
432 // create a copy of the joints, not yet linked because they refer to each other using pointers
433 for(typename std::vector<Joint*>::const_iterator it = _other.joints_.begin(); it != _other.joints_.end(); ++it){
434 joints_.push_back(new Joint(**it));
435 insert_property_at( (*it)->id() );
436 }
437
438 // construct the links
439 for(typename std::vector<Joint*>::const_iterator it = _other.joints_.begin(); it != _other.joints_.end(); ++it){
440 Joint *pJoint = *it;
441
442 if(pJoint->parent() != 0)
443 joint(pJoint->id())->parent_ = joint(pJoint->parent()->id());
444 else
445 joint(pJoint->id())->parent_ = 0;
446
447 for(typename Joint::ChildIter it_ch = pJoint->begin(); it_ch != pJoint->end(); ++it_ch)
448 joint(pJoint->id())->children_.push_back( joint((*it_ch)->id()) );
449 }
450
451 names_.insert(_other.names_.begin(), _other.names_.end());
452
453 for(typename std::vector<Animation*>::const_iterator it = _other.animations_.begin(); it != _other.animations_.end(); ++it)
454 if (*it)
455 animations_.push_back((**it).copy());
456
457 referencePose_ = _other.referencePose_;
458 }
459
460 return *this;
461}
462
463//-----------------------------------------------------------------------------
464
469template<typename PointT>
471{
472 // clear the joints and animations
473 clear();
474}
475
476//-----------------------------------------------------------------------------
477
487template<typename PointT>
489{
490 size_t newJointID;
491
492 if(_pParent == 0)
493 {
494 clear();
495 clean_properties();
496
497 _pJoint->setId(0);
498 joints_.push_back(_pJoint);
499
500 newJointID = 0;
501 }else{
502 _pParent->children_.push_back(_pJoint); // tell the parent about the new child
503 _pJoint->setId(joints_.size()); // set its id
504 joints_.push_back(_pJoint); // add it to the skeleton vector
505
506 newJointID = joints_.size() - 1;
507 }
508
509 //onAddJoint
510 insert_property_at(newJointID);
511
512 referencePose_.insertJointAt(newJointID);
513 for(typename std::vector<Animation*>::iterator it = animations_.begin(); it != animations_.end(); ++it)
514 if (*it)
515 (*it)->insertJointAt(newJointID);
516
517 referencePose_.updateFromGlobal(0, true);
518}
519
520//-----------------------------------------------------------------------------
521
531template<typename PointT>
533{
534
535 if (joints_.size() == 1){
536 std::cerr << "Cannot delete last joint. Delete the skeleton instead." << std::endl;
537 return;
538 }
539
540 remove_property_at(_pJoint->id());
541 referencePose_.removeJointAt(_pJoint->id());
542
543 for(typename std::vector<Animation*>::iterator it = animations_.begin(); it != animations_.end(); ++it)
544 if (*it) (*it)->removeJointAt(_pJoint->id());
545
546 // Reattach the deleted joint's children to the joint's parent
547 typename SkeletonT<PointT>::Joint::ChildIter c_it = _pJoint->begin();
548
549 if( _pJoint->parent() == 0 ){
550 //root removal
551 typename SkeletonT<PointT>::Joint* newRoot = *c_it; //first child is new root
552 newRoot->parent_ = 0;
553 ++c_it;
554
555 for ( ; c_it!=_pJoint->end(); ++c_it) {
556 (*c_it)->parent_ = newRoot;
557 newRoot->children_.push_back(*c_it);
558 }
559
560 } else {
561
562 for ( ; c_it!=_pJoint->end(); ++c_it) {
563 (*c_it)->parent_ = _pJoint->parent_;
564 _pJoint->parent_->children_.push_back(*c_it);
565 }
566
567 if(std::remove(_pJoint->parent_->children_.begin(), _pJoint->parent_->children_.end(), _pJoint) != _pJoint->parent_->children_.end()) // remove the joint from its parent
568 _pJoint->parent_->children_.resize(_pJoint->parent_->children_.size() - 1);
569 }
570
571 typename std::vector<Joint*>::iterator it = joints_.begin() + _pJoint->id(); // iterator pointing to the element that has to be erased
572 it = joints_.erase(it); // erase the element
573 for(; it != joints_.end(); ++it) // for all following elements
574 (*it)->setId((*it)->id() - 1); // reduce their index by one (since they have been moved there)
575
576 referencePose_.updateFromGlobal(0, true);
577 for (typename std::vector<Animation*>::iterator a_it = animations_.begin(); a_it != animations_.end(); ++a_it) {
578 if (*a_it)
579 (*a_it)->updateFromGlobal(0);
580 }
581}
582
583//-----------------------------------------------------------------------------
584
592template<typename PointT>
594{
595 // no joints, so no animation either
596 clean_properties();
597 clearAnimations();
598
599 // clear the joints
600 typename std::vector<Joint*>::iterator it;
601 for(it = joints_.begin(); it != joints_.end(); ++it)
602 delete *it;
603
604 joints_.clear();
605 names_.clear();
606}
607
608//-----------------------------------------------------------------------------
609
617template<typename PointT>
619{
620 if(joints_.empty())
621 return 0;
622 return joints_[0];
623}
624
625//-----------------------------------------------------------------------------
626
635template<typename PointT>
636inline typename SkeletonT<PointT>::Joint *SkeletonT<PointT>::joint(const size_t& _index)
637{
638 if(_index >= joints_.size())
639 return 0;
640 return joints_[_index];
641}
642
643//-----------------------------------------------------------------------------
644
651template<typename PointT>
653{
654 if(joints_[_joint]->parent() == 0)
655 return -1;
656 return joints_[_joint]->parent()->id();
657}
658
659//-----------------------------------------------------------------------------
660
664template<typename PointT>
665size_t SkeletonT<PointT>::childCount(size_t _joint)
666{
667 if ( _joint >= joints_.size() ){
668 std::cerr << "SkeletonT : childCount() called with non-existing joint " << _joint << std::endl;
669 return 0;
670 }
671
672 return joints_[_joint]->size();
673}
674
675//-----------------------------------------------------------------------------
676
683template<typename PointT>
684size_t SkeletonT<PointT>::child(size_t _joint, size_t _child)
685{
686 return joints_[_joint]->child(_child)->id();
687}
688
689//-----------------------------------------------------------------------------
690
694template<typename PointT>
696{
697 return joints_.size();
698}
699
700//-----------------------------------------------------------------------------
701
707template<typename PointT>
709{
710 return Iterator(root());
711}
712
713//-----------------------------------------------------------------------------
714
718template<typename PointT>
720{
721 // why return Iterator(0)? operator= will compare the current pointer, and 0 is used once the iterator
722 // passed the last joint
723 return Iterator(0);
724}
725
726
727//-----------------------------------------------------------------------------
728
734template<typename PointT>
736{
737 if(_hAni.isValid() && _hAni.animationIndex() < animations_.size() && animations_[_hAni.animationIndex()] != NULL)
738 return animations_[_hAni.animationIndex()]->pose(_hAni.frame());
739 else
740 return &referencePose_;
741}
742
743//-----------------------------------------------------------------------------
744
754template<typename PointT>
756{
757 return &referencePose_;
758}
759
760//-----------------------------------------------------------------------------
761
768template<typename PointT>
770{
771 // try to find an unused animation slot first
772 typename std::vector<Animation*>::iterator f;
773 for(f = animations_.begin(); f != animations_.end(); ++f)
774 if(*f == 0)
775 break;
776
777 if(f == animations_.end())
778 {
779 // all in use, append
780 names_.insert( std::pair<std::string, size_t>(_name, animations_.size()) );
781 animations_.push_back(_animation);
782 }else{
783 // found an empty one, use it
784 names_.insert( std::pair<std::string, size_t>(_name, f - animations_.begin()) );
785 *f = _animation;
786 }
787
788 if (_animation)
789 _animation->setName(_name);
790
791 return AnimationHandle(names_[_name]);
792}
793
794//-----------------------------------------------------------------------------
795
802template<typename PointT>
804{
805 // try to find an unused animation slot first
806 typename std::vector<Animation*>::iterator f;
807 for(f = animations_.begin(); f != animations_.end(); ++f)
808 if(*f == 0)
809 break;
810
811 if(f == animations_.end())
812 {
813 // all in use, append
814 names_.insert( std::pair<std::string, size_t>(_name, animations_.size()) );
815 if(animation(_hAni) != 0)
816 animations_.push_back((*animation(_hAni)).copy());
817 else
818 animations_.push_back(new FrameAnimationT<Point>(referencePose_));
819 }else{
820 // found an empty one, use it
821 names_.insert( std::pair<std::string, size_t>(_name, f - animations_.begin()) );
822 if(animation(_hAni) != 0)
823 *f = (*animation(_hAni)).copy();
824 else
825 *f = new FrameAnimationT<Point>(referencePose_);
826 }
827
828 return AnimationHandle(names_[_name]);
829}
830
831//-----------------------------------------------------------------------------
832
836template<typename PointT>
838{
839 std::map<std::string, size_t>::iterator f = names_.find(_name);
840 if(f == names_.end())
841 return AnimationHandle();
842
843 return AnimationHandle(f->second);
844}
845
846//-----------------------------------------------------------------------------
847
851template<typename PointT>
853{
854 std::map<std::string, size_t>::iterator f = names_.find(_name);
855 if(f == names_.end())
856 return 0;
857
858 return animations_[f->second];
859}
860
861//-----------------------------------------------------------------------------
862
866template<typename PointT>
868{
869 if(!_hAni.isValid())
870 return 0;
871 return animations_[_hAni.animationIndex()];
872}
873
874//-----------------------------------------------------------------------------
875
879template<typename PointT>
881{
882 // get an iterator for the animation
883 std::map<std::string, size_t>::iterator f = names_.find(_name);
884 if(f == names_.end())
885 return;
886
887 // delete the animation
888 delete animations_[f->second];
889 animations_[f->second] = 0;
890 // remove the name entry
891 names_.erase(f);
892}
893
894//-----------------------------------------------------------------------------
895
899template<typename PointT>
901{
902 // delete the animation
903 delete animations_[_hAni.animationIndex()];
904 animations_[_hAni.animationIndex()] = 0;
905
906 // remove the name entry
907 for(typename std::map<std::string, size_t>::iterator it = names_.begin(); it != names_.end(); ++it)
908 {
909 if(it->second == _hAni.animationIndex())
910 {
911 names_.erase(it);
912 break;
913 }
914 }
915}
916
917//-----------------------------------------------------------------------------
918
922template<typename PointT>
924{
925 names_.clear();
926
927 for(typename std::vector<Animation*>::iterator it = animations_.begin(); it != animations_.end(); ++it)
928 delete *it;
929 animations_.clear();
930}
931
932//-----------------------------------------------------------------------------
933
938template<typename PointT>
943
944//-----------------------------------------------------------------------------
945
949template<typename PointT>
951{
952
953 return AnimationIterator(animations_.size());
954}
955
956
957//-----------------------------------------------------------------------------
958
964template<typename PointT>
966{
967 return names_.size();
968}
969
970//-----------------------------------------------------------------------------
971
977template<typename PointT>
978const std::string &SkeletonT<PointT>::animationName(size_t _index)
979{
980 std::map<std::string, size_t>::iterator pos = names_.begin();
981
982 while(pos->second != _index && pos != names_.end())
983 {
984 ++pos;
985 }
986
987 return pos->first;
988}
989
990//-----------------------------------------------------------------------------
991
997template<typename PointT>
999{
1000 referencePose_.updateFromGlobal(_idJoint);
1001 for(typename std::vector<Animation*>::iterator it = animations_.begin(); it != animations_.end(); ++it) {
1002 if (*it)
1003 (*it)->updateFromGlobal(_idJoint);
1004 }
1005}
1006
1007//-----------------------------------------------------------------------------
1008
1015template<typename PointT>
1017{
1018 if (!_pChild || !_pChild->parent() || !_pInsert)
1019 return;
1020
1021 Joint* parent = _pChild->parent();
1022
1023 //update IDs of our joints
1024 size_t childID = _pChild->id();
1025 for(typename std::vector<Joint*>::iterator it = joints_.begin() + childID; it != joints_.end(); ++it)
1026 (*it)->setId((*it)->id() + 1);
1027
1028 //insert our new joint into this skeleton
1029 joints_.insert(joints_.begin() + childID, _pInsert);
1030 _pInsert->setId(childID);
1031
1032 //update the parents
1033 //note: pChild will be automatically erased in parent->children_
1034 _pInsert->setParent(parent, *this);
1035 _pChild->setParent(_pInsert, *this);
1036
1037 insert_property_at(childID);
1038
1039 referencePose_.insertJointAt(childID);
1040 for(typename std::vector<Animation*>::iterator it = animations_.begin(); it != animations_.end(); ++it)
1041 if (*it)
1042 (*it)->insertJointAt(childID);
1043
1044 referencePose_.updateFromGlobal(0, true);
1045}
1046
1047//-----------------------------------------------------------------------------
1048
A handle used to refer to an animation or to a specific frame in an animation.
bool isValid() const
Returns true if the handle is valid.
size_t frame() const
Returns the selected frame (zero based)
size_t animationIndex() const
Returns the animation index (zero based)
Stores a single animation.
Definition AnimationT.hh:59
Represents a single joint in the skeleton.
Definition JointT.hh:61
void setParent(Joint *_newParent, SkeletonT< PointT > &_skeleton)
access parent of the joint
ChildIter end()
Returns the end iterator for the joints children.
size_t id() const
returns the joint id
Joint * child(size_t _index)
Returns the child joint with the given index.
void setId(const size_t _id)
An unique identifier, guaranteed to be part of a continuous sequence starting from 0.
ChildIter begin()
Returns an iterator on the joints children.
std::vector< Joint * > children_
The joints children, use the JointT::getChild method to access them.
Definition JointT.hh:123
Joint * parent()
Returns the parent joint.
Joint * parent_
The parent joint; this joint is in its parents JointT::children_ vector. It's 0 for the root node.
Definition JointT.hh:121
A general pose, used to store the frames of the animation.
Definition PoseT.hh:59
The properties storage class.
Definition Properties.hh:93
void insert_property_at(int _index)
Inserts a property for a new object at the given index.
Iterator class for the animations attached to a skeleton.
Definition SkeletonT.hh:114
AnimationIterator & operator=(const AnimationIterator &other)
Operator =.
AnimationIterator & operator++()
Increase the iterator.
AnimationIterator(std::vector< Animation * > &_animations)
Default constructor.
AnimationHandle operator*() const
Get an animation handle for the current animation.
Iterator class for the skeleton.
Definition SkeletonT.hh:83
Joint * nextSibling(Joint *_pParent, Joint *_pJoint)
Given a parent and one of its child nodes this method finds and returns the next sibling.
Joint * operator*() const
Returns a pointer to the current joint.
Iterator & operator=(const Iterator &other)
Assignment Operator.
Iterator & operator++()
Increase the iterator.
bool operator!=(const Iterator &other) const
Compares the iterators.
bool operator==(const Iterator &other) const
Compares the iterators.
Iterator()
Default constructor.
Joint * operator->() const
Returns a pointer to the current joint.
std::map< std::string, size_t > names_
Binds a name to each animation.
Definition SkeletonT.hh:218
Pose * referencePose()
Returns a pointer to the reference pose.
Iterator begin()
Iterator over joints of the skeletal tree in TOP-DOWN order (from root to leafs)
size_t jointCount()
Returns the number of joints.
AnimationIterator animationsEnd()
Returns an iterator pointing behind the last animation.
void addJoint(typename SkeletonT< PointT >::Joint *_pParent, typename SkeletonT< PointT >::Joint *_pJoint)
Adds a joint as child of a given parent joint.
size_t animationCount()
Returns the number of animations stored in this skeleton.
void updateFromGlobal(size_t _idJoint)
update the structure when parent changes for a joint
AnimationHandle addAnimation(std::string _name, Animation *_animation)
Adds a new animation to the list.
AnimationHandle animationHandle(std::string _name)
Get an AnimationHandle to the animation with the given name.
Animation * animation(std::string _name)
Returns a pointer to the animation to the given name.
void clearAnimations()
Removes all animations.
void removeAnimation(std::string _name)
Removes an animation from the list.
SkeletonT()
Default constructor.
~SkeletonT()
Destructor.
void clear()
Removes all joints from the skeleton.
Pose * pose(const AnimationHandle &_hAni)
Returns a pointer to the pose with the given animation handle.
size_t child(size_t _joint, size_t _child)
Returns the child with the given index.
Joint * joint(const size_t &_index)
Returns the joint with the given index.
Pose referencePose_
The skeletons reference pose.
Definition SkeletonT.hh:223
size_t childCount(size_t _joint)
Returns the number of children of the given node.
const std::string & animationName(size_t _index)
Returns the name of the animation with the given index.
SkeletonT & operator=(const SkeletonT< PointT > &_other)
Assignment operator.
std::vector< Animation * > animations_
Animations defined on the skeleton.
Definition SkeletonT.hh:220
void insertJoint(typename SkeletonT< PointT >::Joint *_pChild, typename SkeletonT< PointT >::Joint *_pInsert)
insert a Joint given its future child joint
std::vector< Joint * > joints_
Joints of the skeleton.
Definition SkeletonT.hh:215
AnimationHandle cloneAnimation(std::string _name, const AnimationHandle &_hAni)
Creates a new animation by cloning an existing one.
AnimationIterator animationsBegin()
Iterator over the animations.
Iterator end()
Compare an iterator with the return value of this method to test if it is done.
int parent(size_t _joint)
Returns the parents id of the given node.
Joint * root()
Returns the root joint.
void removeJoint(typename SkeletonT< PointT >::Joint *_pJoint)
Remove the given joint from the tree.