MorphMe Part II

Description

This exercise is a continuation of MorphMe Part I, where we will improve the animation transition between the different structures. The objects will move uniformly into their next position over a certain time interval.

Tutorial

For this exercise, we will start with the complete code setup from MorphMe Part I.

Animation of object using State Machine method

As shown in the diagram above, we will use the state machine method of animation to move the objects to their next position. We will define state 0 as the state where the object is at a stand still and is awaiting the coordinates of its next position. Once it has that data it will transition to state 1. In the state 1, the object will move from its current position to the new position. Finally, once it is at the new position the object will be in state 0 once again and the process continues.

To get started, we set the global state to zero in the start() function.

this.state=0;

In our update() function, we then setup a switch statement against the global state variable and our cases are case 0 (when the state = 0) and case 1 (when the state = 1).

In Case 0, we first check if the global time passed is greater than or equal to our set wait time. If it is not, the switch statement will break and the state will remain unchanged. However, if it is greater the time passed will be reset to 0, the coordinates of the next position will be stored and the state will be changed to 1.

// STATE 0 : waiting stationary
case 0:
   if(this.time >= 3){
      this.time = 0;
      this.state= 1;
      //initalize animation
      this.constIndNext=(this.constInd +1)% this.constellations.length;
      this.positionsNext = this.constellations[this.constIndNext];
   }
break;

In Case 1, we define the animation time and pass the value through an easing function which returns a value between 0 and 1. This will give the animation the effect where it slightly speeds up more in the beginning and the end.

easeMe(t){
   // t is 0 - 1    
   let v=-Math.sin(Math.PI/2+t*Math.PI)/2+0.5;
   return v;
}

We also run a loop through all the items to change their position gradually to the new position with the help of the easing function.

Finally, if the animation time is greater than or equal to one, we reset the time to zero and update the global state back to zero. We also set the current index to the new position index.

// STATE 1: animating to next position
case 1:
    let anit=this.time/3;
    if(anit>1) anit=1;
    let aniteasy =this.easeMe(anit);
    // set the interpolated position
    for(let i=0;i< this.items.length;i++){
        let obj = this.items[i].obj;
        let pos1=this.positions[i];
        let pos2=this.positionsNext[i];
        obj.position.x= pos1.x + (pos2.x - pos1.x) * aniteasy;
        obj.position.y= pos1.y + (pos2.y - pos1.y) * aniteasy;
        obj.position.z= pos1.z + (pos2.z - pos1.z) * aniteasy;
    }
    if(anit>=1){
       this.state=0;
       this.time=0;
       this.constInd = this.constIndNext;
       this.positions = this.positionsNext;
    }
break;

Leave a Reply

Your email address will not be published.