Character Essences, Research & Coding

Cube Limbo

While tutoring Fundamentals of Visual Computing at Bath University, I got acquainted with WebGL and ThreeJS. This is a quick weekend project, where cubes of random sizes and animations do the limbo. The students laughed, so mission accomplished!

The main idea is to create a state machine for the procedural animation. Each cube needs to be created, then translated towards the limbo bar, then scaled down to fit underneath it, scaled back up and translated out of view. The snippet of code below gives a glimpse of all the states needed. We start off by setting the cube creation mode to true.

 var cubeCreationMode = true;
 var cubeScaleMode = false;
 var cubeTranslationMode = false;
 var cubeSquashMode = false;
 var cubeSquashTranslationMode = false;
 var cubeStretchMode = false;
 var cubeRemoveMode = false;

ThreeJS, a wrapper around WebGL, works between the script tags in the html file where our application is. This application is mainly composed of two functions, init() and animate(). The former is used to initialize the camera, the scene and any objects needed to be rendered in it (eg. floor and limbo bar), lights and the WebGL renderer. The latter function is used as a loop, which updates the rendered scene at a number of frames per second (eg. 30 fps). If objects move in the scene, they’ll be drawn at their new location.

function animate()
{
  requestAnimationFrame(animate);
  makeMove(); 
  renderer.render(scene, camera); 
}

As it can be observed in the function definition above, animate() requests a new frame to be drawn, makes a move on the objects in the scene and then renderes the current frame.

Depending on the current true state, the cubes in the scene will have a different movement pattern. For example, the code below shows how a cube translates, when the cubeTranslationMode is true. 

If the cube is still within the appropriate distance from the limbo bar, it will translate towards it. Also, the little side to side movement of the cube is given by a rotation around the local x axis. Cosine of time was used for the transaltion in the hope of creating an ease in and ease out effect, which doesn’t seem very noticeable.

if (cubeTranslationMode) 
{
  distanceToStop =  tempCube.position.distanceTo(cubeTargetPoint); 
  if (distanceToStop > cubeStopDistance)   
    { 
      //Keep translating
      tempCube.position.x += Math.cos(clock.elapsedTime) * cubeTranslationSpeed;
      //Keep rotating 
      if (cubeCurrentRotationIteration <= cubeRotationIterations) 
      { 
        tempCube.rotation.x += cubeRotationDirection*cubeRotationSpeed;
        cubeCurrentRotationIteration++; 
      } 
      else 
      { 
        cubeCurrentRotationIteration = -cubeRotationIterations;
        cubeRotationDirection = -cubeRotationDirection; 
      }
   }
...
}

Similar snippets of code can be written for the rest of the animation states. One must remember to set the current flag to false when the animation segment has finished. In this example, once the cube is close enough to the limbo bar, cubeTranslationMode is set to false, while cubeSquashMode becomes true.

Reference: ThreeJS scripting 

Standard

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s