quaternion / slerp 3d-animaton is jumpy / proscene library

edited October 2015 in Library Questions

hi,

i am trying to develop an animation where a 3d object is changing its orientation several times. so it's first in orientation1 then in orientation2 and so on. the changes between orientations should be smooth. i produced some demo code using the quaternion implementation of the proscene library. problem is: at some point the animation it's not smooth. it jumps.

if you want to test the demo code: press space to make the object move to the next orientation. you always have to wait till the current animation reaches its end before pressing space to see the next animation. the jump happens right after pressing space the second time.

any idea how to get rid of that? thanks.

import remixlab.dandelion.geom.*;
import remixlab.bias.core.*;

  Quat[] quats = new Quat[3];

  int quatIndex = 0;

  public void setup(){
    size(1024, 768, P3D);

    colorMode(RGB, 255, 255, 255);
    noStroke();    

    // orientations o1, o2, o3
    quats[0] = new Quat(radians(0), radians(0), radians(90));
    quats[1] = Quat.multiply(quats[0], new Quat(radians(-45),radians(0), radians(0)));
    quats[2] = Quat.multiply(quats[1], new Quat(radians(0), radians(15), radians(-65)));
  }  

  float t = 1.0;
  public void draw(){
    lights();
    background(0);

    // get angles    
    Quat quatTemp;
    if(quatIndex > 0){  
      quatTemp = Quat.slerp(quats[quatIndex-1], quats[quatIndex], t, false);
      t += 0.004; 
      t = t > 1 ? 1 : t;  
    }else{
      quatTemp = quats[quatIndex];    
    } 
    Vec angles = quatTemp.eulerAngles(); 
    //

    //draw
    pushMatrix();

    translate(width/2, height/2, 0);
    rotateY(angles.y());
    rotateZ(angles.z());
    rotateX(angles.x());

    fill(255, 255, 255);
    box(200, 5, 200);

    // debug    
    if(true){

        println(t + " " + degrees(angles.x()) + " " + degrees(angles.y()) + " " + degrees(angles.z()));      

        // x=grün y=rot z=blau

        fill(255,0,0);
        box(10,100,10);    
        pushMatrix();
        translate(0, 50, 0); 
        sphere(10);
        popMatrix();

        fill(0,255,0);
        box(100,10,10);
        pushMatrix();
        translate(50, 0, 0); 
        sphere(10);
        popMatrix();

        fill(0,0,255);
        box(10,10,100);
        pushMatrix();
        translate(0, 0, 50); 
        sphere(10);
        popMatrix();
    }
    //

    popMatrix();     
  }

  void keyPressed() {
    if(key == ' '){
      if(t < 1.0) return;

      if(quatIndex == quats.length - 1) 
        quatIndex = 0;
      else
        quatIndex++;

      t = 0.0;
    }
  }

Answers

  • edited October 2015

    i tracked the problem down. seems that there is a problem in the conversion from quartenion to euler. good thing is the conversion is not necessary. processing has a rotate-function that takes quaternion values as input: rotation axis + rotation angle. this solved my problem.

Sign In or Register to comment.