`
jgsj
  • 浏览: 962338 次
文章分类
社区版块
存档分类
最新评论

关键帧和动画

 
阅读更多

关键帧和动画

Keyframes and Animation

关键帧就是预先记录各个级别的动画数据。前面的机械手和太阳系系统都是在运行的时候计算出动画的。

关键帧就是一个对于模型各级别在某个时刻的重要位置。比如关键转完处,动作变向处等。

通过一定算法,计算机能自动计算出其关键帧之间的动作位置。这样我们就能产生平滑的动画了。如果做过flash和photoshop的朋友都知道这个概念。

但是怎么计算出?用什么算法?这就是个非常复杂的大问题了。比如用photoshop的会知道bezier曲线,那是由挺复杂的数学支持的。

而且一般不直接用矩阵来计算,而是把变换矩阵分解为三个部分旋转(rotation),缩放( scaling),移位(translation),(为什么?因为算法需要)。使用Direct3D函数:D3DXMatrixDecompose .

一般会用到四元组来表示旋转。

计算中间帧的过程,计算t时段的中间帧:

1 找到两个关键帧Kj和kj+1发生在t0,和t1,这样t0<=t<=t1。

2 单位化t[t0,t1]到t[0,1],并使用插值算法计算其旋转矩阵。

如下计算其中间帧的旋转矩阵:

struct Keyframe
{
    float time;
    D3DXQUATERNION R;
    D3DXVECTOR3    S;
    D3DXVECTOR3    T;
};
 
//用L返回计算所得的变换矩阵。
void interpolateBone(Keyframe& K0, Keyframe& K1, D3DXMATRIX& L)
{
    // Transform to [0, 1]
    float t0 = K0.time;
    float t1 = K1.time;
    float lerpTime = (t - t0) / (t1 - t0);

    // Compute interpolated RST values.
    D3DXVECTOR3 lerpedT;
    D3DXVECTOR3 lerpedS;
    D3DXQUATERNION lerpedR;
    D3DXVec3Lerp(&lerpedT, &K0.T, &K1.T, lerpTime);//Direct3D函数,线性插值算法
    D3DXVec3Lerp(&lerpedS, &K0.S, &K1.S, lerpTime);
    D3DXQuaternionSlerp(&lerpedR, &K0.R, &K1.R, lerpTime);//圆形插值算法

 
    // Build and return the interpolated to-parent
    // matrix for this bone.
    D3DXMATRIX T, S, R;
    D3DXMatrixTranslation(&T, lerpedT.x, lerpedT.y, lerpedT.z);
    D3DXMatrixScaling(&S, lerpedS.x, lerpedS.y, lerpedS.z);
    D3DXMatrixRotationQuaternion(&R, &lerpedQ);

    L  = R * S * T;//用L返回计算所得的变换矩阵。
}


.X文件可以存储相关矩阵信息。D3DX中有API IDSDXAnimationController接口可以自动计算其中间位置。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics