General Category > ASL Scripts
BVH File Import into Anim8or
Steve:
What version of Anim8or are you using? I found a much more robust Rotation Matrix to Quaternion algorithm that the one you see everywhere on the web (and that Anim8or has been using since it's inception). It's in build 1178 and onwards and may fix the problem that you're seeing.
If you're interested in to algorithm, here's a link:
http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/
Trevor:
Personally Im using the latest beta. 1179.
As I kinda atated above, its the fact that as other software aproches gimble lock they add values to X and Z (eg, 90 90 -90)
The result in those apps is that nothing changes, the rotation = 0 90 0
However, since an8 does not lock out, it takes the values literally and so rotates the character 'oddly'.
This was the solution we came up with to overcome the limitation from GoldenEye (and xsi and blender etc)
Trev
P.S. Not sure if you saw the images, my PC was off yesterday at 02:40 UTC
Steve:
OK, thanks. I misread your post and thought Anim8or was locking up. Before build 1178 it could do that because some tools use rotation matrices internally and occasionally returned a default neutral quaternion.
SubDrag:
**I should note this working in bvh2anim8or, but I'd like to understand why mine isn't working.
Actually it only works for simpler models though. More complicated and I can't get the bone orientation correct (nothing to do with actual rotation keyframes, just talking bone structure now). I am using normalized Quat::RotateFromTo (root bone at 0,1,0) of absolute position of current - absolute position of previous, to go from previous bone to current, and assign that quaternion, but clearly something goes wrong at some point, to go from previous bone to next. Maybe your logic is slightly different somehow?
The issue seems to be (in my code) that sometimes the quaternion is backwards.
For example,
orientation { (-0.164697 0.000000 -0.000000 0.986344) } Wrong
vs
orientation { (0.16470 0.00000 0.00000 -0.98634) } Right
When startLink = {x=0.00000000 y=40.600006 z=-532.50000 ...}
And endLink = {x=0.00000000 y=-54.827942 z=-210.49976 ...}
Then Quat RotFromTo startLink to endLink basically
Quat MUST_USE_RESULT Quat::RotateFromTo(const float3 &sourceDirection, const float3 &targetDirection)
{
assume(sourceDirection.IsNormalized());
assume(targetDirection.IsNormalized());
float angle = sourceDirection.AngleBetweenNorm(targetDirection);
assume(angle >= 0.f);
// If sourceDirection == targetDirection, the cross product comes out zero, and normalization would fail. In that case, pick an arbitrary axis.
float3 axis = sourceDirection.Cross(targetDirection);
float oldLength = axis.Normalize();
if (oldLength == 0)
axis = float3(1, 0, 0);
return Quat(axis, angle);
}
Code is:
if (length > 0)
{
if (realParent == NULL) // From TopJoint
{
quat = Quat::RotateFromTo(float3(0,1,0), bone->boneEnd->positionAbsolute.Normalized());
length = bone->boneEnd->positionAbsolute.Length();
}
else
{
float3 startLink = realParent->boneEnd->positionAbsolute - ((realParent->boneStart == 0) ? float3(0,0,0) : realParent->boneStart->positionAbsolute);
float3 endLink = bone->boneEnd->positionAbsolute - bone->boneStart->positionAbsolute;
quat = Quat::RotateFromTo( startLink.Normalized(), endLink.Normalized() );
length = (bone->boneEnd->positionAbsolute - bone->boneStart->positionAbsolute).Length();
}
}
else
{
quat = Quat(0, 0, 0, 1);
}
Steve:
SubDrag: There a common problem when generating a series of quaternions to be used as orientations representing positions in an animation:
Q1, Q2, ... Qn-1, Qn.
As you stated there are two possible quaternions for each orientation, which I'll call Q and Q'. As orientations they are equivalent. But when used pairwise to generate rotations they are very different and need to be considered pair-wise..
If you want the animation to rotate using the shortest angle (i.e. from New York to London across the Atlantic) then each pair of consecutive quaternions Qk-1, Qk needs to be the "closest" distance, for lack of a better term. If they aren't, you will go from New York to London via the Pacific and Indian oceans.
So assume that you have generated Q1, ... Qk-1 and you want to add q as the next value. How can you tell which to use, q or q'? Compute the dot product:
dot(Qk-1, q) = Qk-1.x*q.x + Qk-1.y*q.y + Qk-1.z*q.z + Qk-1.w*q.w
If it is > 0 you need to use Qk = q, otherwise use Qk = q'.
If it is = 0 then there is no shortest path - the orientations are exactly opposite so there is not enough information for a solution. There needs to be another data point between those tow orientations.
Navigation
[0] Message Index
[#] Next page
[*] Previous page
Go to full version