Go to the documentation of this file.00001 #ifndef OPENTISSUE_KINEMATICS_SKINNING_SBS_SKINNING_CENTER_OF_ROTATION_H
00002 #define OPENTISSUE_KINEMATICS_SKINNING_SBS_SKINNING_CENTER_OF_ROTATION_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/math/big/big_types.h>
00013 #include <OpenTissue/core/math/big/big_svd.h>
00014 #include <OpenTissue/core/math/math_quaternion.h>
00015 #include <OpenTissue/core/math/math_vector3.h>
00016
00017
00018
00019 namespace OpenTissue
00020 {
00021 namespace skinning
00022 {
00023
00024 template<typename value_type>
00025 value_type
00026 bsum( value_type val )
00027 {
00028 value_type result = 0;
00029 for( size_t i=1; i<val; ++i )
00030 result += i;
00031 return result;
00032 }
00033
00041 template<typename skeleton_type, typename container_type>
00042 typename skeleton_type::math_types::vector3_type
00043 center_of_rotation( skeleton_type const & skeleton, container_type const & bones )
00044 {
00045
00046 typedef typename skeleton_type::math_types::real_type real_type;
00047 typedef typename skeleton_type::math_types::vector3_type vector3_type;
00048 typedef typename skeleton_type::math_types::quaternion_type quaternion_type;
00049 typedef typename skeleton_type::math_types::coordsys_type coordsys_type;
00050 typedef typename skeleton_type::math_types::matrix3x3_type matrix3x3_type;
00051 typedef typename skeleton_type::bone_type bone_type;
00052
00053
00054 typedef ublas::matrix<double> svd_matrix_type;
00055 typedef ublas::vector<double> svd_vector_type;
00056
00057
00058 svd_matrix_type A;
00059 svd_vector_type x;
00060 svd_vector_type b;
00061
00062
00063 size_t dim_x = 3 * bsum( bones.size() );
00064
00065
00066 size_t dim_y = 3;
00067
00068
00069 A.resize( dim_x, dim_y, false );
00070 x.resize( dim_y );
00071 b.resize( dim_x );
00072
00073
00074 typename container_type::const_iterator it = bones.begin();
00075 typename container_type::const_iterator curr_pos = bones.begin();
00076 typename container_type::const_iterator end = bones.end();
00077
00078
00079 size_t pos = 1;
00080 unsigned int idx = 0;
00081
00082 int kc = 0;
00083
00084
00085 for(; it!=end; ++it )
00086 {
00087
00088 curr_pos = bones.begin();
00089 for( size_t i=0; i<pos; ++i )
00090 ++curr_pos;
00091
00092 coordsys_type const & xformA = (*it)->bone_space_transform();
00093 const vector3_type & transA = xformA.T();
00094 matrix3x3_type rotA( xformA.Q() );
00095
00096 for( ; curr_pos!=bones.end(); ++curr_pos )
00097 {
00098 coordsys_type const & xformB = (*curr_pos)->bone_space_transform();
00099 const vector3_type & transB = xformB.T();
00100 matrix3x3_type rotB( xformB.Q() );
00101
00102 vector3_type rhs = transB - transA;
00103 matrix3x3_type lhs = rotA - rotB;
00104
00105
00106
00107
00108
00109 b(idx) = rhs(0);
00110 b(idx+1) = rhs(1);
00111 b(idx+2) = rhs(2);
00112
00113
00114 A(idx,0) = lhs(0,0);
00115 A(idx,1) = lhs(0,1);
00116 A(idx,2) = lhs(0,2);
00117 A(idx+1,0) = lhs(1,0);
00118 A(idx+1,1) = lhs(1,1);
00119 A(idx+1,2) = lhs(1,2);
00120 A(idx+2,0) = lhs(2,0);
00121 A(idx+2,1) = lhs(2,1);
00122 A(idx+2,2) = lhs(2,2);
00123
00124 idx += 3;
00125 ++kc;
00126
00127 }
00128
00129
00130 ++pos;
00131 }
00132
00133
00134 math::big::svd(A,x,b);
00135
00136
00137
00138
00139
00140
00141 return vector3_type( x(0), x(1), x(2) );
00142 }
00143
00144 }
00145 }
00146
00147
00148 #endif