Sorry to barge in with a help request on my very first post.
I am attempting to write a script that can convert animatinos from one skeletal system to another.
The core idea is to compare the properties of two similar bones on different armatures and generate an appropriate transform (Matrix or Quat) that can be applied to transformations on the first bone to produce roghly similar results on the second bone.
Unfortunately, the transforms don’t appear to be working the way I expected.
I had hoped that a transform which would rotate the first bone into the orientation of the second bone could be used a s a generic key that could be applied to a bone rotation to produce the desired results. Unfortunately, and maybe it is my code, the results have been terrifying.
I’ve experimented with matrix, roll, head, and tail properties (and various combinations) without much success.
Does anyone have any suggestions or ideas how I should be approaching this problem?
Here’s an example of one of the thing’s I’ve tried.
v1 and v2 are vectors that define the direction of the first and second bone respectively. I’ve calculated them in various ways as I’ve tried ever stranger things in my debugging, for example, bone1.head - bone1.tail, derived them from the bone matrix, etc.
def getRotationQuaternion(v1, v2, add = False):
'''Find the shortest rotation to rotate direction of vector v1 into direction of vector v2'''
v1 = v1.normalize()
v2 = v2.normalize()
if v1.dot(v2) > 0.999999:
if add:
q = Quaternion(0,0,0,0)
else:
q = Quaternion(1,0,0,0)
elif v1.dot(v2) < -0.999999:
if add:
q = Quaternion(0,0,0,0)
else:
q = Quaternion(-1,0,0,0)
else:
v = v1.cross(v2)
w = sqrt((v1.length ** 2) * (v2.length ** 2)) + v1.dot(v2)
if add:
q = Quaternion(w,v[0],v[1],v[2]).normalize()
else:
q = Quaternion(w,v[0],v[1],v[2]).normalize()
return q
I had hoped that I could then multiply the quat from each key frame of the animation by the returned quaternion, apply it to the second bone, and end up with a result that vaguely resembled the animation on the first bone.
I got so frustrated, I wrote my own Quaternion multiplication function:
def multiplyQuaternion(Quat1, Quat2):
'''Multiply the first Quaternion by the second. Return the product.'''
w1 = Quat1.w
w2 = Quat2.w
x1 = Quat1.x
x2 = Quat2.x
y1 = Quat1.y
y2 = Quat2.y
z1 = Quat1.z
z2 = Quat2.z
w = (w1 * w2 - x1 * x2 - y1 * y2 - z1 * z2)
x = (w1 * x2 + x1 * w2 + y1 * z2 - z1 * y2)
y = (w1 * y2 - x1 * z2 + y1 * w2 + z1 * x2)
z = (w1 * z2 + x1 * y2 - y1 * x2 + z1 * w2)
quatProduct = Quaternion(w,x,y,z).normalize()
return quatProduct
But I’m getting crazy twists and distortions that I can’t explain. I’m either missing something basic or something very very complicated. Does anyone have any ideas?