11011110110011011001100110011001000110011001100111010001011

May 1, 2007

Skinned Mesh in M3G

Filed under: Programming

Skinned Mesh,就是根据skeleton去变换顶点,通过addTransform函数将Vertex和bone绑定,Specification中给出了计算式子:

Denote the set of nodes (bones) associated with a vertex by { N1, N2, …, NN }.
Denote by Mi the transformation from the local coordinate system of node Ni to a reference coordinate system.
The choice of the reference coordinate system is not critical; depending on the implementation,
good choices may include the world coordinate system, the coordinate system of the SkinnedMesh node,
or the coordinate system of the current camera. Finally, let us denote the weight associated with node Ni as Wi.
The blended position of a vertex in the reference coordinate system is then:

    v‘ = sum [ wi Mi Bi v ]

其中,

  • 0 <= i < N, 其中N 是和顶点v 关联的bone个数;
  • v 是VertexBuffer中初始的顶点位置;
  • Bi 是"at rest"变换,即从SkinnedMesh到顶点bone的初始变换矩阵,可以用Node.getTransformTo(bone, transform)取得;
  • Mi 是当前顶点bone到参考坐标系的变换矩阵,我们取SkinnedMesh的坐标系,这样得到的是一个标准的Mesh,方便调用渲染;
  • wi is the normalized weight of bone Ni, computed as wi = Wi / (W1 + … + WN).

Bi 在addTransform时,就可以得到,而Mi 则需要在渲染时获取,bone.getTransformTo(skinnedMesh, Mi) ,
注意对应的Normal变换有点不一样,不是直接的用Mi ,而需要用对应的inverse transpose矩阵:

       n‘ = sum [ wi (Mi * Bi)-1T  n ]


 

Morphing Mesh in M3G

Filed under: Programming

M3G Specification中已有了详细的说明,根据权值对Mesh做简单的变形:

Denoting the base mesh with B, the morph targets with Ti, and the weights corresponding to the morph targets with wi,
the resultant mesh R is computed as follows:

    R = B + sum [ wi (Ti - B) ]

我们只要做简单的变化,

        R = B + sum[ wi (Ti - B)]

           = B + sum(wi * Ti ) - sum(wi  * B)

           = [1 - sum(wi )] * B + sum(wi * Ti )

这样就容易理解,根据上式也很容易编码。

==============

Kemulator中,是在每次渲染前,根据上式计算出对应的Mesh,如果顶点数比较多,则需要消耗一定的计算时间。
假如遇到有的手机对Morphing Mesh渲染比较慢,就可以考虑自己封装一个Morphing的实现,
当Mesh需要改变时才计算新的mesh,渲染时就不需要额外的计算了。