使用boost进行插值:计时器和slerp,四元数

时间:2011-03-25 12:12:37

标签: c++ animation

我知道这段代码看起来像是一块巨大的混乱,所以我尽力评论我能做什么......如果有人经常做骨骼动画,我希望你能看到这里发生的事情。

我遇到的问题是float interp = (next-current)/(next-start);没有返回预期的内容,例如值大于1和负值...我猜这是动画没有显示的全部原因,没有其他潜在的错误..如果有任何明显的突出,请告诉我。

m_animations存储关节的所有关键帧信息。

void Animation::getRotation(Joint& J) {
int i=0,j=0; //i for bone to animation j for which keyframe in animation
float start, next, current = m_time.elapsed(); //storing time elapsed to keep it the same thoughout method to avoid errors
for (i=0; i<m_animations.size(); i++) {
    if(m_animations[i].m_bname == J.name)   //finds which bone is being animated
        break;
}               //retrieve the correct 'anim' for Joint
if (current > m_animations[i].rx_time[m_animations[i].rx_time.size()-1]) {  //checks to see if end of animation
    m_time.restart();
    current = m_time.elapsed(); //resets the animation at its end
}
for (j=0; j<m_animations[i].rx_time.size()-1; j++) {
    if(m_animations[i].rx_time[j] >= next && next < m_animations[i].rx_time[j+1]) { //finds the keyframe
        start = m_animations[i].rx_time[j]; //start time of current frame
        next = m_animations[i].rx_time[j+1]; //end time of current frame
        break;
    }
}
cout << start <<" "<< current <<" "<< m_time.elapsed() <<" "<< next << endl;
//Get start and end quaternions for slerp
Rotation3 Rj(m_animations[i].rx_angle[j], m_animations[i].ry_angle[j], m_animations[i].rz_angle[j], J.translation);
J.quat = Rj.GetQuat(); //rotating to
Rotation3 R = Rotation3(m_animations[i].rx_angle[j+1], m_animations[i].ry_angle[j+1], m_animations[i].rz_angle[j+1], J.translation);
Quat4 q = R.GetQuat(); //rotating from

float interp = (next-current)/(next-start); //find interpolation point

Quat4 slerp = Slerp(J.quat, q, interp); //sphereical linear interpolation
R = Rotation3(slerp,J.translation);

J.rotation.PasteRotation(R.GetRotationMatrix());
}

此外,如果它有助于继承调用getRotation的更新骨架函数

void Animation::update_skeleton(Joint& J) {

getRotation(J);
J.world.PasteTranslation(J.translation); //world becomes translation matrix
J.world *= J.rotation;
if(J.pName != "") {
    J.world = Mat4(J.parent->world) *= J.world; //as not to overwrite the parents world matrix
}
J.translation = J.world.ExtractTranslation();
for(int i=0; i<J.children.size(); i++) {
    update_skeleton(*J.children[i]);
}

}

此外,当我运行我的程序时,似乎只有一个关节...所以我猜测getRotation期间J.translation值可能出错,但我希望修复我的插值问题可能会解决这个问题......

任何帮助都将非常感激。

2 个答案:

答案 0 :(得分:0)

你似乎在使用start和next的原始值之前重置电流,如果我正确读取了会导致电流大于next的代码,导致yor负插值。

答案 1 :(得分:0)

原来有很多错误......但主要的错误是指针,我通过为父母,孩子和自己提供骨骼id来修复它。然后我更改了函数以获取骨骼ID而不是引用关节。问题=修复:D