[Bf-committers] Matrix "brain teaser"

Brecht Van Lommel brechtvanlommel at pandora.be
Fri Jul 21 16:26:11 CEST 2006


Hey,

Roland Hess wrote:
> While having BlenderPeople build NLA animation, and thus putting 
> MatchBone into strenuous use for the first time, I ran into a problem I 
> had not noticed before. Blendin/Blendout is not working properly in 
> certain cases, and it's because I was making some bad assumptions. 
> Rather than burden (and confuse) you with the details of MatchBone, 
> etc., I'll just present the problem as it's currently broken down (all 
> matrices are 4x4s)
> 
> your givens:
> ObMatrixA * BoneMatrixA == ObMatrixB * BoneMatrixB
> ObMatrixB * inverse(ObMatrixA) == BoneMatrixB * inverse(BoneMatrixA)
> 
> Now, supposing that BoneMatrixX is a linear interpolation between 
> BoneMatrixA and BoneMatrixB, find ObMatrixX such that ObMatrixX * 
> BoneMatrixX == ObMatrixA * BoneMatrixA == ObMatrixB * BoneMatrixB
> 
> The constraint is that you do not have access to the values of 
> BoneMatrixA, BoneMatrixB, or BoneMatrixX.
> 
> Is it even possible to correctly find ObMatrixX under these conditions?
> 
> If so, how? Any matrix math wizards please feel free to chime in.

Lineair interpolation between rotation matrices is not meaningful, and it's
probably not what is being used here. But assuming that this is the case, the
problem can be solved:

We have:

(1)	 Bx = t*Ba + (1-t)*Bb
(2)	 Ox*Bx = Oa*Ba = Ob*Bb

 From (2) we can see:

(3)	 Ba = (Oa^-1)*Ox*Bx
(4)	 Bb = (Ob^-1)*Ox*Bx

Filling (3) and (4) into (1) gives:

(5)	 Bx = (t*(Oa^-1) + (1-t)*(Ob^-1))*Ox*Bx

Eliminating Bx, moving Ox to the other side, and taking the inverse:

(6) 	Ox = (t*(Oa^-1) + (1-t)*(Ob^-1))^-1


If a similar derivation for quaternion interpolation would work also I don't know.
The following property would need to hold:

qlerp(A*C, B*C, t) = qlerp(A, B, t)*C

But it might be worth a try to do:

Ox = qlerp(Oa^-1, Ob^-1, t)^-1


Brecht.


More information about the Bf-committers mailing list