在网上找到的一个帮助我理解骨骼动画实现中的几个空间和矩阵的一个回答

One of the links you posted provides a method, and two equations describing how to calculate the offset matrix. See the section titled Back into Initialization - The Offset Matrix

 

I.e., one of the equations -
 

offsetMatrix = MeshFrame.ToRoot * Inverse( bone.ToParent * parent.ToParent * ... * root.ToParent );


Each bone frame has a matrix transforming that bone into it's parent's space (called in that article the ToParent matrix). That sounds like your bone "local matrix." Combine each bone's ToParent matrix with it's parent's ToParent recursively done to the root. Take the inverse of that matrix to form the offset matrix.

 

Note: that method also accounts for the transform for the mesh vertices (MeshFrame.ToRoot) to transform the vertices from world space into root frame space, if required. Be sure to check whether the mesh data that you import has vertices in world space, or in root frame space. IF, and only IF, the root frame is at the world origin, then MeshFrame.ToRoot can be omitted (or set to the Identity matrix.)

 

In your post, you have:

 

Compute "inverse bindpos matrices", be eing the inverse of each bones "local matrix" in bindposition

 


It's not clear what you mean by in bindposition. If, by in bindposition, you mean each bone's local matrix combined with it's parent's "local matrix" combined with the parent's parent's "local matrix," etc., then it appears your "inverse bindpos matrix" is the offset matrix. Compare how you calculate your "inverse bindpos matrix" with the method for calculating the "offset matrix" posted above.

 

If your inverse bindpos matrix is just the inverse of the bone's local matrix (not combined with its parent's local matrix), that's incorrect. The local matrices (from bone to parent to parent..to root) must be combined before you take the inverse.

 

Also, in that same article, the Final Matrix is calculated as:
 

FinalMatrix[ boneIndex ] = OffsetMatrix[ boneIndex ] * boneFrame.TransformationMatrix;


where boneFrame.TransformationMatrix is the combined animation transforms (bone.localAnimMat * parent.localAnimMat * parent's-parent.localAnimMat..)

 

It appears that's what you're trying to do with your CalcCombinedMatrix function, but, as noted above and below, your code is incorrect.

 

Note the order of the matrix multiplication of offset * TransformationMatrix.The order is important. It appears you have the order reversed in your posted code.

 

 

In general, it's a bit difficult to determine whether you're talking about bind pose matrices or animation matrices at various places in your code and discussion. For me, that's causing a bit of confusion. 

 

Also, are you using row-major matrices, and multiplying matrices in left-to-right order? That's more common in DirectX code, but you may be doing it differently.

 

Maybe a litte review: the goal is to transform vertices from bind pose to animation pose.

 

N.B. Assuming left-to-right multiplication order-

 

anim-pose-vertex = bind-pose-vertex * offset-matrix * anim-pose-matrix

 

If you think in terms of the order of operations required to do that:

 

1. Transform the bind-pose vertex from model-bind-pose-space into local-bone-bind-space. That's done by applying the offset-matrix first.

 

It's the equivalent of:

 

offset-matrix = root-toChildA * childA-toChildB * ... * to-influence-bone

 

[ it appears that your "local" bone matrices are bind-pose-from-parent-to-child matrices. ]

 

influence-bone-bind-space-vertex-position = model-space-vertex-position * offset-matrix

 

2. Transform the influence-bone-bind-space-vertex to the animation position, i.e., from influence-bone-bind-pose-space to model-animation-space, by applying the anim-pose-matrix

 

where:

 

anim-pose-matrix = influence-bone-local-anim-mat * parent-local-anim-mat * ... * root-anim-mat

 

and

 

anim-pose-vertex = influence-bone-bind-space-vertex * anim-pose-matrix

 

Putting it all together:

 

anim-pose-vertex = model-space-vertex-position * offset-matrix * anim-pose-matrix

 

That is, from that last equation, the matrix used to transform a model-space-vertex to animation-space-vertex for one of its influence bones is:

 

offset-matrix * anim-pose-matrix

 

where those matrices are for a specific influence bone.

 

And, again, that assumes you're using left-to-right multiplication order.

 

Hopefully that doesn't confuse things more. 

Don't know if you're still having problems, but one thing you said leads me to believe you may not be interpreting things correctly. Specifically, I'm curious if you're confusing what a ToParent matrix is, and how a ToParent matrix is applied.

 

 

 


what the article refers to as the "ToParent Matrix" is the same as my "local Matrix". But should it not be the inverse, since it is supp[o]sed to transform from the bone back to the parents space?

 

When you say "should it not be the inverse..?" what you refer to as it, isn't clear. However, if you're referring to the ToParent matrix, the answer is "no." If you're referring to your "local matrix," and it is the same as the ToParent matrix, then the answer is still "no."

 

That is, the ToParent matrix transforms from bone space to the parent's space. I.e., that's why it's termed "to parent."

 

An example of a ToParent matrx:

 

1. Assume that the root frame is the origin of the skeletal hierarchy.

2. Assume that the root frame has a child frame Hip, located 6 units in the +Y direction from the root frame.

 

The Hip frame's ToParent matrix is, in row-major order:

1 0 0 0
0 1 0 0
0 0 1 0
0 6 0 0

That is a matrix with no rotation, and a translation of +6 along the Y axis.

 

Assume a mesh vertex is positioned in space coincident with the origin of the Hip frame. By definition, origin is ( 0, 0, 0 ) in the Hip reference frame. To determine that vertex position in the root reference frame, transform the vertex position as defined in Hip space by the Hip's ToParent matrix to transform the vertex from Hip space to root space. I.e.,

( 0, 0, 0) * Hip-ToParent-matrix = ( 0, 6, 0)

As mentioned, a vertex positioned at the origin of the Hip frame (that frame already specified to be located at +6 along the Y axis), is also positioned at +6 along the Y axis in the root reference frame.

 

Now consider a vertex positioned at ( 0, 6, 0) in the root reference frame. To correctly apply rotations in the Hip reference frame, the vertex must be transformed from root frame space to Hip reference frame space. See the section of the article titled "A Slight Diversion from the Initialization Process." To transform from root frame to Hip frame, a ToChild matrix is needed. That matrix can be calculated as the inverse of the ToParent matrix.

 

The inverse of the Hip's ToParent matrix is:

1  0 0 0
0  1 0 0
0  0 1 0
0 -6 0 1

So, root-frame-position * ToChild-matrix = Hip-frame-position

 

I.e.,  ( 0, 6, 0) * ToChild-matrix = ( 0, 0, 0)

 

And, indeed, the vertex at ( 0, 6, 0) in the root reference frame is located at ( 0, 0, 0) in the Hip reference frame.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值