00001 #ifndef OPENTISSUE_KINEMATICS_ANIMATION_ANIMATION_KEYFRAME_ANIMATION_H 00002 #define OPENTISSUE_KINEMATICS_ANIMATION_ANIMATION_KEYFRAME_ANIMATION_H 00003 // 00004 // OpenTissue Template Library 00005 // - A generic toolbox for physics-based modeling and simulation. 00006 // Copyright (C) 2008 Department of Computer Science, University of Copenhagen. 00007 // 00008 // OTTL is licensed under zlib: http://opensource.org/licenses/zlib-license.php 00009 // 00010 #include <OpenTissue/configuration.h> 00011 00012 #include <OpenTissue/core/math/math_precision.h> //--- Needed for math::working_precision 00013 #include <OpenTissue/kinematics/animation/animation_interface.h> 00014 #include <OpenTissue/kinematics/animation/animation_keyframe_joint_channels.h> 00015 00016 #include <list> 00017 #include <cassert> 00018 00019 00020 namespace OpenTissue 00021 { 00022 namespace animation 00023 { 00024 00028 template<typename skeleton_type_> 00029 class KeyframeAnimation : public Interface<skeleton_type_> 00030 { 00031 public: 00032 00033 typedef skeleton_type_ skeleton_type; 00034 typedef typename skeleton_type::bone_type bone_type; 00035 typedef typename skeleton_type::math_types math_types; 00036 typedef typename math_types::coordsys_type coordsys_type; 00037 typedef typename math_types::real_type real_type; 00038 typedef Interface<skeleton_type> animation_interface; 00039 typedef KeyframeJointChannels<skeleton_type> channels_type; 00040 typedef std::list<channels_type> channels_container; 00041 typedef typename channels_container::iterator channels_iterator; 00042 00043 protected: 00044 00045 channels_container m_channels; 00046 00047 public: 00048 00049 KeyframeAnimation(){} 00050 00055 channels_type * create_joint_channels() 00056 { 00057 m_channels.push_back(channels_type()); 00058 return &m_channels.back(); 00059 } 00060 00061 public: 00062 00063 void clear() { m_channels.clear(); }; 00064 00071 void blend_pose(skeleton_type & skeleton,real_type const & local_time) 00072 { 00073 typedef typename skeleton_type::bone_traits bone_traits; 00074 00075 static real_type const tiny = OpenTissue::math::working_precision<real_type>(); 00076 00077 if( this->m_weight < tiny ) 00078 return; 00079 00080 channels_iterator begin = m_channels.begin(); 00081 channels_iterator end = m_channels.end(); 00082 channels_iterator channel; 00083 00084 for(channel=begin; channel!=end; ++channel) 00085 { 00086 coordsys_type value = channel->get_value(local_time); 00087 00088 bone_type * bone = skeleton.get_bone(channel->get_bone_number()); 00089 00090 bone->accumulated_weight() += this->m_weight; 00091 real_type u = this->m_weight / bone->accumulated_weight(); 00092 00093 coordsys_type relative = bone_traits::convert( bone->relative() ); 00094 00095 relative.T() += u * (value.T() - relative.T()); 00096 relative.Q() = slerp(relative.Q(),value.Q(),u); 00097 00098 bone->relative() = bone_traits::convert( relative ); 00099 } 00100 } 00101 00107 real_type compute_duration() 00108 { 00109 using std::max; 00110 real_type duration = real_type(); //--- by standard default constructed integral types are zero. 00111 00112 channels_iterator begin = m_channels.begin(); 00113 channels_iterator end = m_channels.end(); 00114 channels_iterator channel; 00115 00116 for(channel=begin; channel!=end; ++channel) 00117 { 00118 duration = max(duration,channel->compute_duration()); 00119 } 00120 return duration; 00121 } 00122 00123 }; 00124 00125 } // namespace animation 00126 } // namespace OpenTissue 00127 00128 //OPENTISSUE_KINEMATICS_ANIMATION_ANIMATION_KEYFRAME_ANIMATION_H 00129 #endif