Hello Guest

Transformation Matrix Interpolation math issue EDIT

  • 0 Replies
  • 5354 Views
Transformation Matrix Interpolation math issue EDIT
« on: March 01, 2015, 22:54:38 »
Edit: When trying to interpolate between two frames what is a good way to come up with the value to interpolate by? I can't seem to get a good 0-1 value worked out right. I have a time variable that resets to 0 when it's larger than the last frames time, the current frame and the next frame. I thought it would be as simple as value = ((currentFrameTime+time) / nextFrameTime) * 1; //or time. I've tried this in a ton of different ways with the above being the closest to working but it's not right.  So, my goal here is with the currentFrameTime, nextFrameTime and the actual time passed to come up with a number between 0 and 1 based on the percent time is between current and next frame times.. -.-

Edit: (frameTime / nextFrame) * time; seems to give the results 0-1 accurately but now I've still got a choppy animation. If anyone has some experience with this please let me know. nvm this isn't right I think my whole issue is I need to calculate this part right.

Edit2: I was messing around with it more but I'm still unsure of the issue. If you look at this picture(I know it's wierd looking) it's a picture of all the places the arm is moving during my animation, it goes smooth for a bit then jumps and repeats that. I can't figure out what might be causing it unless the lerp or slerp is wrong or maybe I'm somehow apply it wrong?



I'm trying to interpolate between frames of animation. So far all of the sources I've found are telling me to get the interpolation value like so..which is not returning the needed 0-1 value.

I need to get a 0-1 value based on how close the "time" is to the "nextFrame" time.
nextFrame is the next frames time key, frameTime is the current frames time key in a loop thru all the frames.
Code: [Select]
for(int i = 0; i < joints.get(0).frames.size()-1; i++)
{
float frameTime = joints.get(0).frames.get(0).frameTimes.get(i);
float nextFrame = joints.get(0).frames.get(0).frameTimes.get(i+1);
//.......
}
Code: [Select]
float time = (float) (Sys.getTime() - startTime) / 1000;
float value =(nextFrame - frameTime)*time / (nextFrame - frameTime );// * frameTime;


For the interpolation functions
Code: [Select]
public static void slerp(Quaternion start, Quaternion target, float alpha, Quaternion dest) {
final float dot = Math.abs(start.x * target.x + start.y * target.y + start.z * target.z + start.w * target.w);
float scale1, scale2;
if ((1.0f - dot) > 0.1) {
final float angle = (float) Math.acos(dot);
final float sinAngle = 1f / (float) Math.sin(angle);
scale1 = ((float) Math.sin((1f - alpha) * angle) * sinAngle);
scale2 = ((float) Math.sin((alpha * angle)) * sinAngle);
} else {
scale1 = 1f - alpha;
scale2 = alpha;
}
if (dot < 0.f) {
scale2 = -scale2;
}
dest.x = (scale1 * start.x) + (scale2 * target.x);
dest.y = (scale1 * start.y) + (scale2 * target.y);
dest.z = (scale1 * start.z) + (scale2 * target.z);
dest.w = (scale1 * start.w) + (scale2 * target.w);
}

public static Vector3f lerp(Vector3f v0, Vector3f v1, float alpha )
{
Vector3f.sub(v1, v0, v1);
v1.x *= alpha;
v1.y *= alpha;
v1.z *= alpha;
v1 =  Vector3f.add(v1, v0, null);
return  v1;
}

The full animation function I'm using for testing. This is probably hard to figure out and I don't think it really matters much because I think the real issue is in calculating the value to interpolate by...
Code: [Select]
public void startAnimation()
{
for(int i = 0; i < joints.get(0).frames.size()-1; i++)
{
float frameTime = joints.get(0).frames.get(0).frameTimes.get(i);
float nextFrame = joints.get(0).frames.get(0).frameTimes.get(i+1);

float time = (float) (Sys.getTime() - startTime) / 1000;
//System.out.println(frameTime + " : " + nextFrame);

if(time > joints.get(0).frames.get(0).frameTimes.get(joints.get(0).frames.get(0).frameTimes.size()-1))
startTime = Sys.getTime();

if(frameTime < time && nextFrame > time)
{
    for(int j = 0; j < joints.size(); j++)
    {
    time = (float) (Sys.getTime() - startTime) / 1000;
    float value =(nextFrame - frameTime)*time / (nextFrame - frameTime ) * frameTime;
    System.out.println(value);
   
    Matrix4f curMat = joints.get(j).frames.get(i).frameMatrices.get(i);
    Matrix4f nextMat = joints.get(j).frames.get(i).frameMatrices.get(i+1);
   
    Vector3f curTrans = Maths.getTranslation(curMat);
    Vector3f nextTrans = Maths.getTranslation(nextMat);
    Vector3f lerpVec = Maths.lerp(curTrans, nextTrans, value);
   
    Quaternion curQuat = Maths.matrixToQuaternion(curMat);
    Quaternion nextQuat = Maths.matrixToQuaternion(nextMat);
    Quaternion slerpQuat = new Quaternion();
    Maths.slerp(curQuat, nextQuat,  value, slerpQuat);

   
    Matrix4f transMat = Maths.createTransformationMatrix(lerpVec, slerpQuat, 1f);
    joints.get(j).jointMatrix = transMat;
//joints.get(j).jointMatrix = joints.get(j).frames.get(i).frameMatrices.get(i);
    }

calculateMatrices();
}
}
}

« Last Edit: March 04, 2015, 03:18:12 by Exempt »