Skinned Class Reference

#include <Skinned.h>

Collaboration diagram for Skinned:

Collaboration graph
[legend]

List of all members.

Public Member Functions

 Skinned ()
 Skinned (const Skinned &)
 ~Skinned ()
Mesh_objectget_mesh ()
Mesh_objectget_deformed_mesh ()
Skeletonget_skeleton ()
Skeletonget_deformed_skeleton ()
int set_skeleton (Skeleton *)
int set_deformed_skeleton (Skeleton *_skeleton)
int set_mesh (Mesh_object *)
int set_deformed_mesh (Mesh_object *)
int skinning ()
int size_weight ()
int add_weight (double w)
int set_weight (int k_index, double value)
int set_weight (std::vector< double > &_weight)
double get_weight (int k_index)
double get_weight (int k_vertex, int k_index)
int set_weight (int k_vertex, int k_index_bone, double value)
int size_index_weight ()
int size_index_weight (int k_vertex)
int set_size_index_weight (int size)
int set_size_index_weight (int k_vertex, int size)
int get_size_index_weight (int k_vertex)
int add_index_weight (int k_vertex, int index)
int add_index_weight (int k_vertex, std::vector< int > &index)
int set_index_weight (int k_vertex, int k_index, int _index_weight)
int set_index_weight (std::vector< int_vector > &_index_weight)
int get_index_weight (int k_vertex, int k_index)
int size_index_joint ()
int size_index_joint (int k_vertex)
int set_size_index_joint (int size)
int set_size_index_joint (int k_vertex, int size)
int add_index_joint (int k_vertex, int index)
int add_index_joint (int k_vertex, std::vector< int > &index)
int set_index_joint (int k_vertex, int k_index, int _index_joint)
int set_index_joint (std::vector< int_vector > &_index_joint)
int get_index_joint (int k_vertex, int k_index)
int fill_vertex_depending_on_bone ()
int get_number_of_vertex_depending_on_bone (int k_bone)
int get_index_vertex_depending_on_bone (int k_bone, int k_index)
int check_integrity_skinning ()
double get_min_distance_to_any_bone (int k_vertex)
double get_vertex_to_bone_distance (int k_vertex, int k_bone)
int get_max_weight_influence (int k_vertex, int *k_bone_max, double *weight_max)
int automatic_weight_calculation ()
double calculate_weight (int k_vertex, int k_joint)
int normalize_weight ()

Private Attributes

Mesh_objectmesh
Mesh_objectdeformed_mesh
Skeletonskeleton
Skeletondeformed_skeleton
std::vector< double > weight
std::vector< int_vectorindex_weight
std::vector< int_vectorindex_joint
std::vector< int_vectorvertex_depending_on_bone


Detailed Description

Definition at line 30 of file Skinned.h.


Constructor & Destructor Documentation

Skinned::Skinned (  ) 

Definition at line 5 of file Skinned.cpp.

00005                 :mesh(NULL),deformed_mesh(NULL),skeleton(NULL),deformed_skeleton(NULL)
00006 {}

Skinned::Skinned ( const Skinned  ) 

Definition at line 8 of file Skinned.cpp.

00009 {}

Skinned::~Skinned (  ) 

Definition at line 11 of file Skinned.cpp.

00012 {}


Member Function Documentation

Mesh_object * Skinned::get_mesh (  ) 

Definition at line 23 of file Skinned.cpp.

References mesh.

Referenced by File_parser::load_collada_skining_attribute().

00024 {return mesh;}

Here is the caller graph for this function:

Mesh_object * Skinned::get_deformed_mesh (  ) 

Definition at line 400 of file Skinned.cpp.

References deformed_mesh.

00401 {
00402   return deformed_mesh;
00403 }

Skeleton * Skinned::get_skeleton (  ) 

Definition at line 19 of file Skinned.cpp.

References skeleton.

Referenced by File_parser::load_collada_skining_attribute().

00020 {return skeleton;}

Here is the caller graph for this function:

Skeleton * Skinned::get_deformed_skeleton (  ) 

Definition at line 395 of file Skinned.cpp.

References deformed_skeleton.

00396 {
00397   return deformed_skeleton;
00398 }

int Skinned::set_skeleton ( Skeleton _skeleton  ) 

Definition at line 28 of file Skinned.cpp.

References skeleton.

Referenced by load_model_1(), load_model_2(), and load_model_3().

00029 {skeleton = _skeleton;return 0;}

Here is the caller graph for this function:

int Skinned::set_deformed_skeleton ( Skeleton _skeleton  ) 

Definition at line 30 of file Skinned.cpp.

References deformed_skeleton.

Referenced by load_model_1(), load_model_2(), and load_model_3().

00031 {deformed_skeleton = _skeleton;return 0;}

Here is the caller graph for this function:

int Skinned::set_mesh ( Mesh_object _mesh  ) 

Definition at line 33 of file Skinned.cpp.

References mesh.

Referenced by load_model_1(), load_model_2(), and load_model_3().

00034 {mesh = _mesh;return 0;}

Here is the caller graph for this function:

int Skinned::set_deformed_mesh ( Mesh_object _mesh  ) 

Definition at line 35 of file Skinned.cpp.

References deformed_mesh.

Referenced by load_model_1(), load_model_2(), and load_model_3().

00036 {deformed_mesh = _mesh;return 0;}

Here is the caller graph for this function:

int Skinned::skinning (  ) 

Definition at line 263 of file Skinned.cpp.

References deformed_mesh, deformed_skeleton, get_index_vertex_depending_on_bone(), Skeleton::get_joint(), Skeleton::get_N_joint(), get_number_of_vertex_depending_on_bone(), Joint::get_T(), Mesh_object::get_vertex_normal(), Mesh_object::get_vertex_number(), Mesh_object::get_vertex_v3d(), get_weight(), mesh, V_3D::norm(), Mesh_object::set_vertex(), Mesh_object::set_vertex_normal(), and skeleton.

Referenced by evolve(), load_model_1(), load_model_2(), and load_model_3().

00264 {
00265   if(deformed_mesh->get_vertex_number()!=mesh->get_vertex_number())
00266     *deformed_mesh = *mesh;
00267   if((deformed_skeleton->get_N_joint()) != (skeleton->get_N_joint()))
00268     *deformed_skeleton = *skeleton;
00269 
00270 
00271   Joint *current = NULL;
00272   int k_vertex=0;
00273   int k_index_vertex=0;
00274   int k_joint=0;
00275   int N_joint=skeleton->get_N_joint();
00276   double current_weight=0.0;
00277 
00278   std::vector <Matrix> vector_T;
00279   vector_T.resize(mesh->get_vertex_number());
00280   for(int k=0;k<mesh->get_vertex_number();k++)
00281     vector_T[k].set_zero();
00282   Matrix T;
00283 
00284 
00285 
00286 
00287   for(k_joint=0;k_joint<N_joint;k_joint++)
00288     {
00289       current = deformed_skeleton->get_joint(k_joint);
00290       T = current->get_T();
00291 
00292       
00293 
00294       for(k_index_vertex=0;k_index_vertex<get_number_of_vertex_depending_on_bone(k_joint);k_index_vertex++)
00295         {
00296           k_vertex = get_index_vertex_depending_on_bone(k_joint,k_index_vertex);
00297           current_weight = get_weight(k_vertex,k_joint);
00298 
00299           vector_T[k_vertex] += (current_weight*T);
00300         }
00301     }
00302 
00303 
00304   V_3D current_vertex;
00305   V_3D current_normal;
00306   for(k_vertex=0;k_vertex<mesh->get_vertex_number();k_vertex++)
00307     {
00308       current_vertex = mesh->get_vertex_v3d(k_vertex);
00309       current_vertex = vector_T[k_vertex]*current_vertex;
00310       deformed_mesh->set_vertex(k_vertex,current_vertex);
00311 
00312       current_normal = mesh->get_vertex_normal(k_vertex);
00313       current_normal = (vector_T[k_vertex].get_rotation_part())*current_normal;
00314       current_normal = current_normal/current_normal.norm();
00315       deformed_mesh->set_vertex_normal(k_vertex,current_normal);
00316     }
00317   return 0;
00318 
00319 }

Here is the caller graph for this function:

int Skinned::size_weight (  ) 

Definition at line 38 of file Skinned.cpp.

References weight.

Referenced by get_weight(), and set_weight().

00039 {
00040   return weight.size();
00041 }

Here is the caller graph for this function:

int Skinned::add_weight ( double  w  ) 

Definition at line 43 of file Skinned.cpp.

References weight.

Referenced by automatic_weight_calculation(), and File_parser::load_collada_skining_attribute().

00044 {
00045   weight.push_back(w);
00046   return 0;
00047 }

Here is the caller graph for this function:

int Skinned::set_weight ( int  k_index,
double  value 
)

Definition at line 49 of file Skinned.cpp.

References size_weight(), and weight.

Referenced by File_parser::load_collada_skining_attribute(), normalize_weight(), and set_weight().

00050 {
00051   if(k_index<0 || k_index>=size_weight())
00052     {printf("Error in set_weight in Skinned, k_index[%d] is not correct\n",k_index);exit(-1);}
00053 
00054   weight[k_index] = value;
00055   return 0;
00056 
00057 }

Here is the call graph for this function:

Here is the caller graph for this function:

int Skinned::set_weight ( std::vector< double > &  _weight  ) 

Definition at line 365 of file Skinned.cpp.

References weight.

00366 {
00367   weight.resize(0);
00368   weight.resize(_weight.size());
00369   int k=0;
00370   for(k=0;k<(int)_weight.size();k++)
00371     weight[k] = _weight[k];
00372   return 0;
00373 }

double Skinned::get_weight ( int  k_index  ) 

Definition at line 59 of file Skinned.cpp.

References size_weight(), and weight.

Referenced by fill_vertex_depending_on_bone(), get_max_weight_influence(), get_weight(), File_parser::load_collada_skining_attribute(), normalize_weight(), and skinning().

00060 {
00061   if(k_index<0 || k_index>=size_weight())
00062     {printf("Error in get_weight in Skinned, k_index[%d] is not correct\n",k_index);exit(-1);}
00063 
00064   return weight[k_index];
00065 
00066 }

Here is the call graph for this function:

Here is the caller graph for this function:

double Skinned::get_weight ( int  k_vertex,
int  k_index 
)

Definition at line 230 of file Skinned.cpp.

References get_weight(), and index_weight.

00231 {
00232   if(k_vertex<0 || k_vertex>(int)index_weight.size())
00233     {printf("Error k_vertex[%d] is not correct for index_weight.size [%d] in get_weight in Skinned\n",k_vertex,index_weight.size());exit(-1);}
00234   int k_index_weight = index_weight[k_vertex][k_index];
00235   return get_weight(k_index_weight);
00236 }

Here is the call graph for this function:

int Skinned::set_weight ( int  k_vertex,
int  k_index_bone,
double  value 
)

Definition at line 237 of file Skinned.cpp.

References get_index_weight(), and set_weight().

00238 {
00239   int k_index_weight = get_index_weight(k_vertex,k_index_bone);
00240   set_weight(k_index_weight,value);
00241   return 0;
00242 }

Here is the call graph for this function:

int Skinned::size_index_weight (  ) 

Definition at line 68 of file Skinned.cpp.

References index_weight.

00069 {return index_weight.size();}

int Skinned::size_index_weight ( int  k_vertex  ) 

Definition at line 71 of file Skinned.cpp.

References index_weight.

00072 {
00073   if(k_index<0 || k_index>=(int)index_weight.size())
00074     {printf("Error k_index too large in size_index_weight in Skinned\n");exit(-1);}
00075 
00076   return index_weight[k_index].size();
00077 }

int Skinned::set_size_index_weight ( int  size  ) 

Definition at line 79 of file Skinned.cpp.

References index_weight.

Referenced by automatic_weight_calculation(), and File_parser::load_collada_skining_attribute().

00080 {index_weight.resize(size);return 0;}

Here is the caller graph for this function:

int Skinned::set_size_index_weight ( int  k_vertex,
int  size 
)

Definition at line 88 of file Skinned.cpp.

References index_weight.

00089 {index_weight[k_index].resize(size);return 0;}

int Skinned::get_size_index_weight ( int  k_vertex  ) 

Definition at line 81 of file Skinned.cpp.

References index_weight.

Referenced by File_parser::load_collada_skining_attribute(), and normalize_weight().

00082 {
00083   if(k_vertex<0 || k_vertex>(int)index_weight.size())
00084     {printf("Error k_vertex[%d] is too large compared to index_weight.size()[%d] in get_size_index_weight in Skinned\n",k_vertex,index_weight.size());exit(-1);}
00085   return index_weight[k_vertex].size();
00086 
00087 }

Here is the caller graph for this function:

int Skinned::add_index_weight ( int  k_vertex,
int  index 
)

Definition at line 91 of file Skinned.cpp.

References index_weight.

Referenced by automatic_weight_calculation(), and File_parser::load_collada_skining_attribute().

00092 {
00093   if(k_index<0 || k_index>=(int)index_weight.size())
00094     {printf("Error k_index too large in add_index_weight in Skinned\n");exit(-1);}
00095   index_weight[k_index].add(index);
00096   return 0;
00097 }

Here is the caller graph for this function:

int Skinned::add_index_weight ( int  k_vertex,
std::vector< int > &  index 
)

Definition at line 99 of file Skinned.cpp.

References index_weight.

00100 {
00101   if(k_vertex<0 || k_vertex>=(int)index_weight.size())
00102     {printf("Error k_vertex too large in add_index_weight in Skinned\n");exit(-1);}
00103   index_weight[k_vertex].add(index);
00104   return 0;
00105 }

int Skinned::set_index_weight ( int  k_vertex,
int  k_index,
int  _index_weight 
)

Definition at line 107 of file Skinned.cpp.

References index_weight.

Referenced by File_parser::load_collada_skining_attribute().

00108 {
00109   if(k_index<0 || k_index>=(int)index_weight.size())
00110     {printf("Error k_index too large in set_index_weight in Skinned\n");exit(-1);}
00111   index_weight[k_vertex][k_index]=_index_weight;
00112   return 0;
00113 }

Here is the caller graph for this function:

int Skinned::set_index_weight ( std::vector< int_vector > &  _index_weight  ) 

Definition at line 385 of file Skinned.cpp.

References index_weight.

00386 {
00387   index_weight.resize(0);
00388   index_weight.resize(_index_weight.size());
00389   int k=0;
00390   for(k=0;k<(int)_index_weight.size();k++)
00391     index_weight[k] = _index_weight[k];
00392   return 0;
00393 }

int Skinned::get_index_weight ( int  k_vertex,
int  k_index 
)

Definition at line 114 of file Skinned.cpp.

References index_weight.

Referenced by set_weight().

00115 {
00116   if(k_vertex<0 || k_vertex>=(int)index_weight.size())
00117     {printf("Error k_vertex too large in get_index_weight in Skinned\n");exit(-1);}
00118 
00119   return index_weight[k_vertex][k_index];
00120 }

Here is the caller graph for this function:

int Skinned::size_index_joint (  ) 

Definition at line 126 of file Skinned.cpp.

References index_joint.

00127 {return index_joint.size();}

int Skinned::size_index_joint ( int  k_vertex  ) 

Definition at line 129 of file Skinned.cpp.

References index_joint.

00130 {
00131   if(k_index<0 || k_index>=(int)index_joint.size())
00132     {printf("Error k_index too large in size_index_joint in Skinned\n");exit(-1);}
00133 
00134   return index_joint[k_index].size();
00135 }

int Skinned::set_size_index_joint ( int  size  ) 

Definition at line 137 of file Skinned.cpp.

References index_joint.

Referenced by automatic_weight_calculation(), and File_parser::load_collada_skining_attribute().

00138 {index_joint.resize(size);return 0;}

Here is the caller graph for this function:

int Skinned::set_size_index_joint ( int  k_vertex,
int  size 
)

Definition at line 140 of file Skinned.cpp.

References index_joint.

00141 {index_joint[k_index].resize(size);return 0;}

int Skinned::add_index_joint ( int  k_vertex,
int  index 
)

Definition at line 143 of file Skinned.cpp.

References index_joint.

Referenced by automatic_weight_calculation(), and File_parser::load_collada_skining_attribute().

00144 {
00145   if(k_index<0 || k_index>=(int)index_joint.size())
00146     {printf("Error k_index too large in add_index_joint in Skinned\n");exit(-1);}
00147   index_joint[k_index].add(index);
00148   return 0;
00149 }

Here is the caller graph for this function:

int Skinned::add_index_joint ( int  k_vertex,
std::vector< int > &  index 
)

Definition at line 151 of file Skinned.cpp.

References index_joint.

00152 {
00153   if(k_vertex<0 || k_vertex>=(int)index_joint.size())
00154     {printf("Error k_vertex too large in add_index_joint in Skinned\n");exit(-1);}
00155   index_joint[k_vertex].add(index);
00156   return 0;
00157 }

int Skinned::set_index_joint ( int  k_vertex,
int  k_index,
int  _index_joint 
)

Definition at line 159 of file Skinned.cpp.

References index_joint.

Referenced by File_parser::load_collada_skining_attribute().

00160 {
00161   if(k_index<0 || k_index>=(int)index_joint.size())
00162     {printf("Error k_index too large in set_index_joint in Skinned\n");exit(-1);}
00163   index_joint[k_vertex][k_index]=_index_joint;
00164   return 0;
00165 }

Here is the caller graph for this function:

int Skinned::set_index_joint ( std::vector< int_vector > &  _index_joint  ) 

Definition at line 375 of file Skinned.cpp.

References index_joint.

00376 {
00377   index_joint.resize(0);
00378   index_joint.resize(_index_joint.size());
00379   int k=0;
00380   for(k=0;k<(int)_index_joint.size();k++)
00381     index_joint[k] = _index_joint[k];
00382   return 0;
00383 }

int Skinned::get_index_joint ( int  k_vertex,
int  k_index 
)

Definition at line 166 of file Skinned.cpp.

References index_joint.

Referenced by fill_vertex_depending_on_bone(), File_parser::load_collada_skining_attribute(), and normalize_weight().

00167 {
00168   if(k_vertex<0 || k_vertex>=(int)index_joint.size())
00169     {printf("Error k_vertex too large in get_index_joint in Skinned\n");exit(-1);}
00170 
00171   return index_joint[k_vertex][k_index];
00172 }

Here is the caller graph for this function:

int Skinned::fill_vertex_depending_on_bone (  ) 

Definition at line 177 of file Skinned.cpp.

References get_index_joint(), Skeleton::get_N_joint(), Mesh_object::get_vertex_number(), get_weight(), index_joint, index_weight, mesh, skeleton, and vertex_depending_on_bone.

Referenced by automatic_weight_calculation(), and File_parser::load_collada_skining_attribute().

00178 {
00179 
00180   int N_total_bones = skeleton->get_N_joint();
00181   vertex_depending_on_bone.resize(0);
00182   if(N_total_bones>0 && N_total_bones<1000)
00183     vertex_depending_on_bone.resize(N_total_bones);
00184   else
00185     {printf("N_total_bone [%d] is not correct in fill_vertex_depending_on_bone in Mesh\n",N_total_bones);exit(-1);};
00186 
00187   if((int)index_weight.size()!=mesh->get_vertex_number() || (int)index_joint.size()!=mesh->get_vertex_number())
00188     {printf("Error index_weight size[%d] or index_joint size[%d] are not equal to the number of vertex [%d]\n",index_weight.size(),index_joint.size(),mesh->get_vertex_number());exit(-1);}
00189 
00190 
00191 
00192 
00193   int k_vertex=0;
00194   int i_bone=0;
00195   int k_weight_dependencies=0;
00196   float current_weight=0.0f;
00197   float epsilon=0.00001;
00198   double verif_sum_one=0.0;
00199   for(k_vertex=0;k_vertex<mesh->get_vertex_number();k_vertex++)
00200     {
00201       verif_sum_one=0.0;
00202       for(k_weight_dependencies=0;k_weight_dependencies<index_weight[k_vertex].size();k_weight_dependencies++)
00203         {
00204 
00205 
00206           i_bone = get_index_joint(k_vertex,k_weight_dependencies);
00207           current_weight = get_weight(k_vertex,k_weight_dependencies);
00208           verif_sum_one += current_weight;
00209 
00210           
00211           if(current_weight>epsilon)
00212           if(i_bone>=0 && i_bone<N_total_bones)
00213             vertex_depending_on_bone[i_bone].add(k_vertex);
00214           else
00215             {printf("Error in fill_vertex_depending_on_bone in Mesh, i_bone[%d] is not correct\n",i_bone);exit(-1);}
00216 
00217         }
00218       if(fabs(verif_sum_one-1.0)>0.001)
00219         {printf("Erreur in fill_vertex_depending_on_bone in skinned, skinning weights does not summed up to one [k_vertex=%d]\n",k_vertex);exit(-1);}
00220      }
00221 
00222 
00223 
00224 
00225 
00226   return 0;
00227 
00228 }

Here is the call graph for this function:

Here is the caller graph for this function:

int Skinned::get_number_of_vertex_depending_on_bone ( int  k_bone  ) 

Definition at line 244 of file Skinned.cpp.

References vertex_depending_on_bone.

Referenced by check_integrity_skinning(), and skinning().

00245 {
00246   if(k_bone<0 || k_bone>=(int)vertex_depending_on_bone.size())
00247     {printf("Error k_bone [%d] is not correct with vertex_depending_on_bone.size() [%d] in get_number_of_vertex_depending_on_bone in Skinned\n",k_bone,vertex_depending_on_bone.size());exit(-1);}
00248 
00249   return vertex_depending_on_bone[k_bone].size();
00250 }

Here is the caller graph for this function:

int Skinned::get_index_vertex_depending_on_bone ( int  k_bone,
int  k_index 
)

Definition at line 252 of file Skinned.cpp.

References vertex_depending_on_bone.

Referenced by check_integrity_skinning(), and skinning().

00253 {
00254   if(k_bone<0 || k_bone>=(int)vertex_depending_on_bone.size())
00255     {printf("Error k_bone [%d] is not correct with vertex_depending_on_bone.size() [%d] in get_index_vertex_depending_on_bone in Skinned\n",k_bone,vertex_depending_on_bone.size());exit(-1);}
00256   
00257   return vertex_depending_on_bone[k_bone][k_index];
00258 
00259 }

Here is the caller graph for this function:

int Skinned::check_integrity_skinning (  ) 

Definition at line 321 of file Skinned.cpp.

References get_index_vertex_depending_on_bone(), Skeleton::get_N_joint(), get_number_of_vertex_depending_on_bone(), Mesh_object::get_vertex_number(), index_joint, index_weight, mesh, skeleton, vertex_depending_on_bone, and weight.

00322 {
00323 
00324   printf("\n\n[N weight vector %d elements]\n",weight.size());
00325   printf("[N_index_weight %d elements (N_vertex = %d)]\n",index_weight.size(),mesh->get_vertex_number());
00326   printf("[N_index_joint %d elements (N_vertex = %d)]\n",index_joint.size(),mesh->get_vertex_number());
00327 
00328   int k=0;
00329   int k2=0;
00330   for(k=0;k<(int)index_weight.size();k++)
00331     {
00332       for(k2=0;k2<index_weight[k].size();k2++)
00333         {
00334           if(index_weight[k][k2]<0 || index_weight[k][k2]>=(int)weight.size())
00335             {printf("Error index_weight[%d][%d] is too large [%d] compared to weight vector size(%d]\n",k,k2,index_weight[k][k2],weight.size());exit(-1);}
00336 
00337           if(index_joint[k][k2]<0 || index_joint[k][k2]>=(int)skeleton->get_N_joint())
00338             {printf("Error index_joint[%d][%d] is too large [%d] compared to the number of joints (%d]\n",k,k2,index_joint[k][k2],skeleton->get_N_joint());exit(-1);}       
00339         }
00340     }
00341   
00342   int k_vertex;
00343   printf("[%d N_vertex_depending_on_bone (N_bones = %d)]\n",vertex_depending_on_bone.size(),skeleton->get_N_joint());
00344   for(k=0;k<(int)vertex_depending_on_bone.size();k++)
00345     {
00346       //printf("[bone:%d (%s) dependencies:%d]\n",k,skeleton->get_joint(k)->get_name(),get_number_of_vertex_depending_on_bone(k));
00347       for(k2=0;k2<get_number_of_vertex_depending_on_bone(k);k2++)
00348         {
00349           k_vertex = get_index_vertex_depending_on_bone(k,k2);
00350           if(k_vertex<0 || k_vertex>=mesh->get_vertex_number())
00351             {printf("Error for bone %d, index %d, k_vertex[%d] is too large compared to mesh size [%d]\n",k,k2,k_vertex,mesh->get_vertex_number());exit(-1);}
00352 
00353         }
00354     }
00355   
00356 
00357   printf("[Check Skinned integrity OK]\n\n");
00358 
00359   
00360 
00361   return 0;
00362 }

Here is the call graph for this function:

double Skinned::get_min_distance_to_any_bone ( int  k_vertex  ) 

Definition at line 411 of file Skinned.cpp.

References Skeleton::get_N_joint(), get_vertex_to_bone_distance(), and skeleton.

00412 {
00413   int k_bone=0;
00414   double min_distance=9999;
00415   double current_distance=0;
00416   for(k_bone=0;k_bone<skeleton->get_N_joint();k_bone++)
00417     {
00418       current_distance = get_vertex_to_bone_distance(k_vertex,k_bone);
00419       if(min_distance>current_distance)
00420         min_distance=current_distance;
00421     }
00422   
00423   return min_distance;
00424 }

Here is the call graph for this function:

double Skinned::get_vertex_to_bone_distance ( int  k_vertex,
int  k_bone 
)

Definition at line 426 of file Skinned.cpp.

References V_3D::dot(), Joint::get_access_number(), Skeleton::get_joint(), Joint::get_N_son(), Joint::get_son(), Mesh_object::get_vertex_v3d(), Skeleton::get_world_position_of_bone(), mesh, and skeleton.

Referenced by calculate_weight(), and get_min_distance_to_any_bone().

00427 {
00428   Joint *current = NULL;
00429   Joint *son = NULL;
00430   int k_son=0;
00431 
00432   V_3D x,b1,b2,u1,u2;
00433   V_3D closest;
00434 
00435   x = mesh->get_vertex_v3d(k_vertex);
00436   b1 = skeleton->get_world_position_of_bone(k_bone);
00437   u1 = x-b1;
00438 
00439   current = skeleton->get_joint(k_bone);
00440   double projection=0.0;
00441   double distance=0.0;
00442   double min_distance=99999;
00443   for(k_son=0;k_son<current->get_N_son();k_son++)
00444     {
00445       son = current->get_son(current->get_N_son()-k_son-1);
00446       b2 = skeleton->get_world_position_of_bone(son->get_access_number());
00447       u2 = b2-b1;
00448 
00449       projection = u1.dot(u2)/u2.dot(u2);
00450       if(projection<0)
00451         closest=b1;
00452       else if(projection>1)
00453         closest=b2;
00454       else
00455         closest = b1+projection*u2;
00456       distance = (x-closest).norm();
00457       
00458       if(min_distance>distance)
00459         min_distance = distance;
00460     }
00461 
00462   return min_distance;
00463 }

Here is the call graph for this function:

Here is the caller graph for this function:

int Skinned::get_max_weight_influence ( int  k_vertex,
int *  k_bone_max,
double *  weight_max 
)

Definition at line 466 of file Skinned.cpp.

References Skeleton::get_N_joint(), get_weight(), and skeleton.

00467 {
00468   *weight_max=0.0;
00469   *k_bone_max=-1;
00470   int k_joint=0;
00471   double current_weight=0;
00472   for(k_joint=0;k_joint<skeleton->get_N_joint();k_joint++)
00473     {
00474       current_weight=get_weight(k_vertex,k_joint);
00475       if(current_weight>*weight_max)
00476         {
00477           *weight_max = current_weight;
00478           *k_bone_max = k_joint;
00479         }
00480     }
00481 
00482   return 0;
00483 }

Here is the call graph for this function:

int Skinned::automatic_weight_calculation (  ) 

Definition at line 486 of file Skinned.cpp.

References add_index_joint(), add_index_weight(), add_weight(), calculate_weight(), fill_vertex_depending_on_bone(), Skeleton::get_N_joint(), Mesh_object::get_vertex_number(), index_joint, index_weight, mesh, normalize_weight(), set_size_index_joint(), set_size_index_weight(), skeleton, and weight.

Referenced by load_model_1().

00487 {
00488 
00489 
00490 #ifdef DEBUG
00491   printf("\n[Automatic Weight Calculation ...]\n");
00492 #endif 
00493 
00494 
00495 
00496   int N_vertex=mesh->get_vertex_number();
00497   int N_joint = skeleton->get_N_joint();
00498 
00499   weight.resize(0);
00500   index_weight.resize(0);
00501   index_joint.resize(0);
00502   set_size_index_weight(N_vertex);
00503   set_size_index_joint(N_vertex);
00504 
00505 
00506   int k_vertex=0;
00507   int k_joint=0;
00508   for(k_joint=0;k_joint<N_joint;k_joint++)
00509     {
00510       for(k_vertex=0;k_vertex<N_vertex;k_vertex++)
00511         {
00512           add_index_weight(k_vertex,k_vertex+k_joint*N_vertex); 
00513           add_index_joint(k_vertex,k_joint);
00514           add_weight(calculate_weight(k_vertex,k_joint));
00515         }
00516     }
00517 
00518 
00519   //weight normalization
00520   normalize_weight();
00521 
00522   //fill vector of vertex_depending_on_bone
00523   fill_vertex_depending_on_bone();
00524 
00525 
00526 #ifdef DEBUG
00527   printf("[Weight Calculated [OK]]\n\n");
00528 #endif 
00529 
00530   return 0;
00531 }

Here is the caller graph for this function:

double Skinned::calculate_weight ( int  k_vertex,
int  k_joint 
)

Definition at line 533 of file Skinned.cpp.

References get_vertex_to_bone_distance(), and WEIGHT_EXPONENT.

Referenced by automatic_weight_calculation().

00534 {
00535   double dist = 0.0;
00536   double weight_power = WEIGHT_EXPONENT;
00537   dist = get_vertex_to_bone_distance(k_vertex,k_joint);
00538   
00539   double current_weight=0.0;
00540   current_weight = powf(1/dist,weight_power);
00541 
00542   return current_weight;
00543 }

Here is the call graph for this function:

Here is the caller graph for this function:

int Skinned::normalize_weight (  ) 

Definition at line 545 of file Skinned.cpp.

References get_index_joint(), get_size_index_weight(), Mesh_object::get_vertex_number(), get_weight(), mesh, and set_weight().

Referenced by automatic_weight_calculation().

00546 {
00547 
00548   int k_vertex=0;
00549   int k_b=0,k_bone=0;
00550   std::vector <double> vector_weight;
00551   double sum_weight=0.0;
00552   double small_weight = 1.0/200000.0;
00553   for(k_vertex=0;k_vertex<mesh->get_vertex_number();k_vertex++)
00554     {
00555       vector_weight.resize(0);
00556       for(k_b=0;k_b<get_size_index_weight(k_vertex);k_b++)
00557         {
00558           k_bone = get_index_joint(k_vertex,k_b);
00559           vector_weight.push_back(get_weight(k_vertex,k_bone));
00560         }
00561 
00562 
00563       //JUST KEEP THE THREE FIRST MAX WEIGHT (OPTIONAL)
00564       //*********************************************************//
00565       //get three first wax_weights
00566       double max_weight[3]={-10.0,-10.0,-10.0};
00567       int bones_to_keep[3]={-1,-1,-1};
00568       //first pass
00569       for(k_b=0;k_b<(int)vector_weight.size();k_b++)
00570         if(vector_weight[k_b]>max_weight[0])
00571           {max_weight[0]=vector_weight[k_b];bones_to_keep[0]=k_b;}
00572       //second pass
00573       for(k_b=0;k_b<(int)vector_weight.size();k_b++)
00574         if(k_b!=bones_to_keep[0] && vector_weight[k_b]>max_weight[1])
00575           {max_weight[1]=vector_weight[k_b];bones_to_keep[1]=k_b;}
00576       //third pass
00577       for(k_b=0;k_b<(int)vector_weight.size();k_b++)
00578         if(k_b!=bones_to_keep[1] && k_b!=bones_to_keep[0] && vector_weight[k_b]>max_weight[2])
00579           {max_weight[2]=vector_weight[k_b];bones_to_keep[2]=k_b;}
00580       //just keep them
00581       for(k_b=0;k_b<(int)vector_weight.size();k_b++)
00582         if(k_b!=bones_to_keep[0] && k_b!=bones_to_keep[1] && k_b!=bones_to_keep[2])
00583           vector_weight[k_b]=0.0;
00584       //**********************************************************//
00585 
00586 
00587       //get sum
00588       sum_weight=0.0;
00589       for(k_b=0;k_b<(int)vector_weight.size();k_b++)
00590         sum_weight += vector_weight[k_b];
00591 
00592       //normalize
00593       for(k_b=0;k_b<(int)vector_weight.size();k_b++)
00594         vector_weight[k_b] /= sum_weight;
00595 
00596       //get_to_small_weight
00597       for(k_b=0;k_b<(int)vector_weight.size();k_b++)
00598         if(vector_weight[k_b]<small_weight)
00599           vector_weight[k_b] = 0.0;
00600 
00601       //get sum again
00602       sum_weight=0.0;
00603       for(k_b=0;k_b<(int)vector_weight.size();k_b++)
00604         sum_weight += vector_weight[k_b];
00605 
00606       //normalize again
00607       for(k_b=0;k_b<(int)vector_weight.size();k_b++)
00608         vector_weight[k_b] /= sum_weight;
00609 
00610 
00611       //set weights back
00612       for(k_b=0;k_b<get_size_index_weight(k_vertex);k_b++)
00613         set_weight(k_vertex,k_b,vector_weight[k_b]);
00614     }
00615 
00616   return 0;
00617 }

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 125 of file Skinned.h.

Referenced by get_deformed_mesh(), set_deformed_mesh(), and skinning().

Definition at line 128 of file Skinned.h.

Referenced by get_deformed_skeleton(), set_deformed_skeleton(), and skinning().

std::vector<double> Skinned::weight [private]

std::vector<int_vector> Skinned::index_weight [private]

std::vector<int_vector> Skinned::index_joint [private]


The documentation for this class was generated from the following files:

Generated on Mon Mar 30 16:58:44 2009 by  doxygen 1.5.6