animation - Bone Vertex Skinning transformation -
i trying implement skeletal animation in opengl. @ stage, trying have bone system deform mesh. believe problem how create matrix bone::getmatrix()
.
background:
each bone has offset it's parent, , if bone not have parent offset instead world position of entire skeleton. collection of bones comprise skeleton. currently, testing purposes, have 3 bones in skeleton deforming skinned mesh.
again, issue when deforming mesh, visual result not produce desired effect.
code:
glm::mat4 bone::getmatrix(){ bone* parent = getparent(); glm::mat4 rot = glm::mat4(1.0f); glm::mat4 trans= glm::mat4(1.0f); glm::vec3 orient = getorientation(); //create rotation matrix; rot *= glm::rotate(orient.x,1.0f,0.0f,0.0f); rot *= glm::rotate(orient.y,0.0f,1.0f,0.0f); rot *= glm::rotate(orient.z,0.0f,0.0f,1.0f); //create translation matrix if(parent != nullptr){ glm::vec3 off = offset; trans = glm::translate(off.x,off.y,off.z); }else{ glm::vec3 pos = getposition(); //trans = glm::translate(pos.x,pos.y,pos.z); } glm::mat4 pm = glm::mat4(1.0f); if(parent != nullptr){ pm *= glm::inverse( parent->getmatrix() ); }else{ } return pm * trans * rot ; }
deforming mesh:
void armature::draw(const float& dt){ if(mesh == nullptr){ postmsg("reference copy mesh nullptr","draw",34); return; } arrayvertex3* mesh_vertex = mesh->getvertex3(); arrayvertex3 render_vertex; if(mesh_vertex == nullptr){ postmsg("mesh vertex structure null during draw","draw",30); }else{ render_vertex.reserve(mesh_vertex->size()); } int i=0,j=0,k=0; glpushmatrix(); gltranslatef(10,0,0); glbegin(gl_points); for( =0; i<this->getbonecount(); i++){ glvertex3fv( glm::value_ptr( glm::vec3( glm::vec4() * getbone(i)->getmatrix() ) )); } glend(); glbegin(gl_lines); for( =1; i<this->getbonecount(); i++){ // glvertex3fv( glm::value_ptr(getbone(i)->gettranslationmatrix() * glm::mat3(getbone(i)->getrotationmatrix()) )); // glvertex3fv( glm::value_ptr(getbone(i-1)->gettranslationmatrix() * glm::mat3(getbone(i-1)->getrotationmatrix()) )); } glend(); glpopmatrix(); //loop vertices for( = 0 ; < int(mesh->getnumbervertexes()); ++){ render_vertex[i].vtx = glm::vec3(0.0f, 0.0f, 0.0f); int inf_count = (*mesh_vertex)[i].numinfluences; //loop vertices influences for( j=0; j < inf_count; j ++){ bone *bone = getbone( (*mesh_vertex)[i].boneids[j] ); float weight = (*mesh_vertex)[i].boneweights[j]; glm::vec4 original_vert = glm::vec4((*mesh_vertex)[i].vtx,1.0f); glm::vec4 original_norm = glm::vec4((*mesh_vertex)[i].norm,0.0f); glm::vec3 t = bone->gettranslationmatrix(); render_vertex[i].vtx += glm::vec3( bone->getmatrix() * original_vert ) * (weight) ; //transform normal render_vertex[i].norm = glm::vec3( bone->getrotationmatrix() * original_norm ) ; } (*mesh_vertex)[i].vtx = render_vertex[i].vtx; (*mesh_vertex)[i].norm = glm::normalize(render_vertex[i].norm); } }
result
the rotation not done according joint location
i fount bone matrix function bit chaotic. understanding, vertexes need transformed global transformation matrix. global transformation matrix concatenation of local transformation matrix. following code used calculate global transformation. article useful. http://graphics.ucsd.edu/courses/cse169_w05/2-skeleton.htm
some of previous work using glsl + assimp + glm http://www.youtube.com/watch?v=bxbfvl-msyw&list=hl1385555185&feature=mh_lolz
glm::mat4 t = glm::translate(bone->offset); glm::mat4 r = glm::tomat4(bone->rotate); glm::mat4 s = glm::scale(bone->scale); glm::mat4 localtransform = t * r * s; if(bone->getid()!=0) { bone->globaltransform = bone->getparent()->globaltransform * localtransform; } else { bone->globaltransform = localtransform; } (uint = 0 ; < bone->getchildren().size() ; i++) { updatetransform(bone->getchildren()[i]); }
Comments
Post a Comment