Go to the documentation of this file.00001 #ifndef OPENTISSUE_KINEMATICS_SKELETON_SKELETON_H
00002 #define OPENTISSUE_KINEMATICS_SKELETON_SKELETON_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/kinematics/skeleton/skeleton_bone_access.h>
00013
00014 #include <list>
00015 #include <vector>
00016 #include <map>
00017 #include <cassert>
00018 #include <cmath>
00019
00020 namespace OpenTissue
00021 {
00022 namespace skeleton
00023 {
00040 template<typename types>
00041 class Skeleton
00042 : public types::skeleton_traits
00043 {
00044 public:
00045
00046 typedef typename types::math_types math_types;
00047 typedef typename types::bone_traits bone_traits;
00048
00049 protected:
00050
00051 typedef typename math_types::value_traits value_traits;
00052 typedef typename math_types::vector3_type vector3_type;
00053 typedef typename math_types::quaternion_type quaternion_type;
00054 typedef typename math_types::real_type real_type;
00055
00056 public:
00057
00058 typedef typename types::bone_type bone_type;
00059 typedef typename types::skeleton_type skeleton_type;
00060
00061 protected:
00062
00063 typedef std::list<bone_type> bone_container;
00064 typedef std::map<std::string,size_t> bone_number_lut_container;
00065 typedef std::vector<bone_type*> bone_ptr_lut_container;
00066 typedef typename bone_number_lut_container::iterator lut_iterator;
00067
00068 public:
00069
00070 typedef typename bone_container::iterator bone_iterator;
00071 typedef typename bone_container::const_iterator const_bone_iterator;
00072
00073 protected:
00074
00075 bone_container m_bones;
00076 bone_number_lut_container m_bone_number_lut;
00077 bone_ptr_lut_container m_bone_ptr_lut;
00078 bone_type * m_root;
00079
00080 public:
00081
00082 Skeleton()
00083 : m_root(0)
00084 {}
00085
00086 public:
00087
00091 bone_iterator begin() { return bone_iterator(m_bones.begin()); }
00092 const_bone_iterator begin() const { return const_bone_iterator(m_bones.begin());}
00093
00098 bone_iterator end() { return bone_iterator(m_bones.end()); }
00099 const_bone_iterator end() const { return const_bone_iterator(m_bones.end());}
00100
00101 public:
00102
00108 bone_type * root() {return m_root; }
00109
00115 bone_type const * root() const {return m_root; }
00116
00122 size_t size() const { return m_bones.size(); }
00123
00131 bone_type * get_bone(size_t const & number) { return find_bone( number ); }
00132
00140 bone_type const * get_bone(size_t const & number) const { return find_bone( number ); }
00141
00142
00150 bone_iterator get_bone_iterator(size_t const & number)
00151 {
00152 bone_iterator bone = this->begin();
00153 bone_iterator end = this->end();
00154 for(;bone!=end;++bone)
00155 {
00156 if(bone->get_number() == number)
00157 return bone;
00158 }
00159 return end;
00160 }
00161
00169 bone_type * get_bone(std::string const & name)
00170 {
00171 lut_iterator lookup = m_bone_number_lut.find(name);
00172 if(lookup==m_bone_number_lut.end())
00173 return 0;
00174 size_t number = m_bone_number_lut[name];
00175 return get_bone( number );
00176 }
00177
00178 public:
00179
00188 bool rename_bone( bone_type * bone, std::string const & name)
00189 {
00190 assert( bone || !"rename_bone(): Bone was null");
00191 lut_iterator entry = m_bone_number_lut.find(bone->get_name());
00192
00193 if(entry!=m_bone_number_lut.end())
00194 m_bone_number_lut.erase(entry);
00195
00196 BoneAccess::set_name( bone, name );
00197
00198 m_bone_number_lut[bone->get_name()] = bone->get_number();
00199
00200 return true;
00201 }
00202
00210 bone_type * create_bone()
00211 {
00212 assert(!m_root || !"Skeleton::create_bone(): Sorry you forgot to specify a parent bone");
00213 assert(m_bones.empty() || !"Skeleton::create_bone(): Sorry you forgot to specify a parent bone");
00214
00215 bone_type * bone = register_bone();
00216 m_root = bone;
00217
00218 bone_type * const null = 0;
00219
00220 BoneAccess::set_parent( bone, null );
00221 return bone;
00222 }
00223
00233 bone_type * create_bone(bone_type * parent)
00234 {
00235 assert(parent->skeleton()==this || !"Skeleton::create_bone(): Sorry specified parent bone did not belong to skeleton");
00236
00237 bone_type * bone = register_bone();
00238
00239 BoneAccess::add_child( parent, bone );
00240 BoneAccess::set_parent( bone, parent );
00241 return bone;
00242 }
00243
00247 void clear()
00248 {
00249 m_root = 0;
00250 m_bones.clear();
00251 m_bone_number_lut.clear();
00252 m_bone_ptr_lut.clear();
00253 }
00254
00255 public:
00256
00262 void compute_pose()
00263 {
00264 bone_iterator end = m_bones.end();
00265 bone_iterator bone = m_bones.begin();
00266 for(;bone!=end;++bone)
00267 {
00268 if(bone->is_root())
00269 {
00270 bone->absolute() = bone->relative();
00271 }
00272 else
00273 {
00274 bone->absolute() = bone_traits::compute_absolute_pose_transform(bone->parent()->absolute(), bone->relative());
00275 }
00276 bone->bone_space_transform() = bone_traits::compute_bone_space_transform( bone->absolute(), bone->bone_space() );
00277 }
00278 }
00279
00285 void clear_pose()
00286 {
00287 bone_iterator end = m_bones.end();
00288 bone_iterator bone = m_bones.begin();
00289 for(;bone!=end;++bone)
00290 {
00291 bone->accumulated_weight() = value_traits::zero();
00292 bone->relative() = bone_traits::get_identity_transform();
00293 }
00294 }
00295
00301 void set_bind_pose()
00302 {
00303 bone_iterator end = m_bones.end();
00304 bone_iterator bone = m_bones.begin();
00305 for(;bone!=end;++bone)
00306 {
00307 bone->accumulated_weight() = value_traits::zero();
00308 bone->relative() = bone->bind_pose();
00309 }
00310 this->compute_pose();
00311 }
00312
00316 void clear_weights()
00317 {
00318 bone_iterator end = m_bones.end();
00319 bone_iterator bone = m_bones.begin();
00320 for(;bone!=end;++bone)
00321 {
00322 bone->accumulated_weight() = value_traits::zero();
00323 }
00324 }
00325
00326 protected:
00327
00335 bone_type * find_bone(size_t const & number) const
00336 {
00337 if(number<0)
00338 return 0;
00339 if(number >= size() )
00340 return 0;
00341 return m_bone_ptr_lut[number];
00342 }
00343
00349 bone_type * register_bone()
00350 {
00351 m_bones.push_back(bone_type());
00352 bone_type * bone = &m_bones.back();
00353
00354 assert(bone || !"Skeleont::register_bone(): Sorry something bad happen!");
00355
00356 size_t number = static_cast<size_t>( size() ) - 1;
00357
00358 BoneAccess::set_number( bone, number );
00359 BoneAccess::set_skeleton( bone, this );
00360
00361 m_bone_number_lut[ bone->get_name() ] = bone->get_number();
00362
00363 m_bone_ptr_lut.push_back(bone);
00364
00365 return bone;
00366 }
00367
00368 };
00369
00370 }
00371 }
00372
00373
00374 #endif