1
我想在OpenGL中實現骨架動畫。在這個階段,我試圖讓我的骨骼系統變形成網狀。我相信問題在於如何創建矩陣Bone::getMatrix()
。骨骼頂點蒙皮轉換
背景:
每個骨骼已經偏移到它的父,如果骨頭沒有父偏移反而是整個骨架的世界上的地位。骨骼的集合包括骨架。目前,爲了測試目的,我在骨骼中有3塊骨骼,使變形的網格變形。
此外,問題是,當變形網格時,視覺效果不會產生所需的效果。
代碼:
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 ;
}
形變網格:
void Armature::draw(const float& dt){
if(mesh == nullptr){
postMsg("reference copy to mesh is nullptr","draw",34);
return;
}
ArrayVertex3* mesh_Vertex = mesh->getVertex3();
ArrayVertex3 render_vertex;
if(mesh_Vertex == nullptr){
postMsg("mesh vertex structure is 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(i =0; i<this->getBoneCount(); i++){
glVertex3fv(glm::value_ptr( glm::vec3( glm::vec4() * getBone(i)->getMatrix() ) ));
}
glEnd();
glBegin(GL_LINES);
for(i =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 all vertices
for(i = 0 ; i < int(mesh->getNumberVertexes()); i ++){
render_vertex[i].vtx = glm::vec3(0.0f, 0.0f, 0.0f);
int inf_count = (*mesh_Vertex)[i].numInfluences;
//Loop all this 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);
}
}
結果
的旋轉不根據其關節位置完成
怎麼樣逆矩陣結合的工作? – ukaku
什麼是反向綁定矩陣?多一點解釋? –
我認爲問題出在glm :: inverse(parent-> getMatrix())上。如果getMatrix()提供的矩陣用於直接操作頂點,則矩陣需要是全局矩陣。我認爲你不需要對父矩陣進行求逆,只需將父矩陣的局部矩陣乘以多個矩陣即可。或者,如果您想稍後連接局部矩陣(例如在繪圖函數中),則使用get矩陣函數來獲得局部矩陣。父母的全局矩陣的逆可以將您的頂點轉移到本地空間,但這會與您的getMatrix()函數衝突,該函數爲您提供了一個局部矩陣。 –