Ms3d动画文件渲染

最近做的一个项目, 要能实现鱼类的动作仿真, 经过一些调研, 最后决定使用Ms3d格式文件, 这是我做的第一个实现动画渲染的program, 采用这种文件, 主要是因为这种文件格式够简单, 做为入门级的选择, 还是不错的,呵呵.

网上有不少介绍Ms3d动画文件的格式的,却很少有渲染动画的完整的程序, 像nehe的opengl教程,只是把其中的三维物体给渲染出来了, 对其中的动画信息没有作任何处理, 而这恰在此时好是实现动画渲染的关键之处, 经过一番刻苦钻研, 终于搞定了动画渲染, 当然, 也参考了不少网上的资料.

以前研究过3ds文件格式, ms3d和3ds一样, 都包括点, 线, 面, 材质, 信息. ( 貌似3ds 也支技动画, 可能是我孤陋寡闻, 还没有看谁用3ds做动画的), ms3d中的点还有骨骼信息, 用以记录每个点用到那个骨骼, 接下来是关键帧信息, 每渲染一帧用当前点的所对应的骨骼和所在的关键帧对它进行插值变换, 然后渲染出来. 下面介绍画动实现原理和我所遇到的困难.

在骨骼动画文件里, 骨骼是挡照深度优先顺序存储的, 这就保证了, 当你进行顺序遍历时, 当前骨骼的父骨骼已经遍历过了,  由于对每个骨骼的变换都是在它父骨骼的基上进行变换的, 所以在计算变换矩阵时要乘上它的父骨骼变换矩阵. 每个骨骼的变换矩阵计算如伪代码所示:

 

program calcMatFinal()

{

   matrix MCurTransform;

   for each bone in model

   {

       MCurTransform.SetRotation(ThisBone.thisFrame.Rotation);

       MCurTransform.SetTranslation(ThisBone.thisFrame.Translation);   //计算当前本地变换信息

       if (the bone has parent)

       {

          thisBone.MatFinal = thisBone.ParentBone.MatFinal* thisBone.matLocal*MCurTransform;

       }

       else

       {

          thisBone.MatFinal = thisBone.MatLocal*MCurTransform;

       }

   }

}

上面的代码中,thisBone.MatLocal为每个骨骼的初始变换矩阵,该矩阵由骨骼的初始平移和初始旋转数据计算得到。在骨骼动画中,每一帧的变换应累加于初始变换矩阵之上。这就是为什么我们的绝对转换矩阵的计算公式是:

 

ThisBone.MatLocal*MCurTransform。

 

还应该注意的是,我们计算出来的绝对变换矩阵是针对所谓“原始状态”的顶点而言的。我们从模型中读出的顶点数据,并非所谓“原始状态”的顶点,因此在读取步骤完成之后,必须要进行一个初始化的过程,将顶点变换到“原始状态”。可以使用下面的公式:

VertexInit = Vertex * [Bone.MatAbsolute]-1;

 

其中,VertexInit是“原始状态”的顶点,Vertex是转换前的顶点,Bone.MatAbsolute是顶点的对应骨骼绝对初始转换矩阵。Bone.MatAbsolute的计算可参考下面的伪代码:

program CalcMaAbsolute()

{

      for each Bone in Model

      {

        ThisBone.MatLocal.SetRotation(ThisBone.OriginalRotation);

        ThisBone.MatLocal.SetTranslation(ThisBone.OriginalTranslation);

        if ThisBone has parent

        {

            ThisBone.MatAbsolute = ThisBone.Parent.MatAbsolute*ThisBone.MatLocal;

        }

        else

        {

            ThisBone.MatAbsolute = ThisBone.MatLocal;

        }

      }

}

在进行渲染的时候, 每渲染一帧, 以当前时间为因子, 对算当前变换所使用的变换矩阵, 为了实现平滑插值,对于旋转,  一般用四元数进行插值处理地. 平移和缩放使用线性插值即可.

该程序演示了水底光线,粒子系统,和仿真鱼

 

再发一张

同上,只是角度不同

对ms3d文件渲染所做的改进

原顶点数据存储在顶点结构体中,其数据直接从文件中读取,这里面的顶点位置没有重复的,由后面的三角形信息得到每个三角形所对应的点,法线,贴图坐标得,缺点是在渲染时每个三角形信息要临时计算.

我的改进思路如下:建立两个缓冲区A和B,A用于保存动画初始信息,里面的数据不变,每渲染一帧把A中的数据复制到B中,对B的数据做变换,作为当前要渲染的顶点.其中要解决的一个问题是,原模型中的顶点数据并不能直接拿来渲染,因为它并不是真正的三角面的数据,而我们希望B中的数接可以直接拿来用glInterleavedArrays直接渲染,因此B中的数据格式为每三个单元为一个进行渲染,但如果每渲染一帧对B中的每个顶点计算一次,会有很大的冗余量,因为模形中的三角面是由索引顶点得到的,一个点可以被几个面使中,要消除冗作计算,还得存储点那些点被重复使用,这样只计算一次.经过改进渲染效率得到了很大的提高.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值