Author: Max Pellizzaro
Date: October 27th 2007
Update: July 12th 2009
version: 3.1.1

Moving objects around the Scene3D

Objective of the tutorial

In this tutorial, we will learn how to make the object move around.

In the previous tutorial, we saw how to move the camera around, giving the effect that the objects where moving around. But they were actually all standing in their spot. We now want to move them!

You can move an object on screen, by either moving a single object or moving a group containing one or more objects. In order to move a single object, once you have a reference to it, you can rotate it around the three reference axes using its rotateX, rotateY, and rotateZ properties. Use the pan, roll, and tilt properties to rotate the object around its local axes. If you want to move a group of objects, you need to introduce a new class, named TransformGroup. Don’t get scared. It’s just a group that implements the interface ATransformable, so we can move it as it would be a single object.

For this tutorial, we are going to draw two objects. And we will see the difference between moving a single object and the entire group.

How to

Set up

The Document class must be changed to Example004.as The name of the class written inside the .as file and the name of the constructor now is: Example004

example004.rar

The new updated version can be found here:
example004_v3.1.1.zip

The AS Code

In this section, we report the AS code as a reference, and it will be explained in the next paragraph.

package
{
   import flash.display.Sprite; 
   import flash.events.*;
   import flash.ui.*;
   import sandy.core.Scene3D;
   import sandy.core.data.*;
   import sandy.core.scenegraph.*;
   import sandy.materials.*;
   import sandy.materials.attributes.*;
   import sandy.primitive.*;

   public class Example004 extends Sprite 
   {
      private var scene:Scene3D;
	  private var camera:Camera3D;
	  private var tg:TransformGroup;
	  private var myCone:Cone;
	  private var myHedra:Hedra;

      public function Example004()
      { 
		 // We create the camera
		 camera = new Camera3D( 300, 300 );
		 camera.x = 100;
		 camera.y = 100;
		 camera.z = -400;
		 camera.lookAt(0,0,0);
		 
		 // We create the "group" that is the tree of all the visible objects
         var root:Group = createScene();
		 
		 // We create a Scene and we add the camera and the objects tree 
	     scene = new Scene3D( "scene", this, camera, root );
		 
		 // Listen to the heart beat and render the scene
		 addEventListener( Event.ENTER_FRAME, enterFrameHandler );
		 stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
		 
      }

      // Create the scene graph based on the root Group of the scene
      private function createScene():Group
      {
         // Create the root Group
         var g:Group = new Group();
		 
		 // first we will create a simple coordinate system
		 var myXLine:Line3D = new Line3D( "x-coord", new Point3D(-50, 0, 0), new Point3D( 50, 0, 0 ));
		 var myYLine:Line3D = new Line3D( "y-coord", new Point3D(0, -50, 0), new Point3D( 0, 50, 0 ));
		 var myZLine:Line3D = new Line3D( "z-coord", new Point3D(0, 0, -50), new Point3D( 0, 0, 50 ));
		 
		 // We need to create a transformGroup
		 tg = new TransformGroup('myGroup');
		 
         // we now create the two new objects
		 myCone = new Cone("theObj1",50, 100);
		 myHedra = new Hedra( "theObj2", 80, 60, 60 );
		 
		 // let's spread them apart, moving the cone to the left and the hedra to the right
		 myCone.x = -160;
		 myCone.z = 150;
		 myHedra.x = 90;
		 
		 // we define a new material
		 var materialAttr:MaterialAttributes = new MaterialAttributes( 
				new LineAttributes( 0.5, 0x2111BB, 0.4 ),
				new LightAttributes( true, 0.1)
				);

	     var material:Material = new ColorMaterial( 0xFFCC33, 1, materialAttr );
	     material.lightingEnable = true;
	     var app:Appearance = new Appearance( material );

	     myCone.appearance = app;
		 myHedra.appearance = app;
		  
		 // we add both object to the transform group		 
		 tg.addChild(myCone);
		 tg.addChild(myHedra);
		 
		 // we now add all the object to the root group:
		 g.addChild(tg);
		 g.addChild(myXLine);
		 g.addChild(myYLine);
		 g.addChild(myZLine);
		  
		  return g;
      }

      // The Event.ENTER_FRAME event handler tells the world to render
      private function enterFrameHandler( event : Event ) : void
      {
         myHedra.pan +=4;
		 myCone.pan +=4;
		 scene.render();
      }
	  
	  private function keyPressed(event:KeyboardEvent):void {
            switch(event.keyCode) {
				case Keyboard.UP:
					tg.y +=2;
					break;
				case Keyboard.DOWN:
					tg.y -=2;
					break;
				case Keyboard.RIGHT:
					tg.roll +=2;
					break;
				case Keyboard.LEFT:
					tg.roll -=2;
					break;
			}
        }
   }
}

Examining the code

Let’s see what we did in the code…

Declaring the objects we need

private var tg:TransformGroup;
private var myCone:Cone;
private var myHedra:Hedra;

This allows us to refer to these variables from anywhere in this class. Maybe it is not the best approach, but it’s easy, fast, and helps me to explain the code better.

Creating the TransformGroup

tg = new TransformGroup('myGroup');

This TransformGroup will hold our two new elements: a Cone and a Hedra.

Instanciate and position the objects

myCone = new Cone("theObj1",50, 100);
myHedra = new Hedra( "theObj2", 80, 60, 60 );
 
myCone.x = -160;
myCone.z = 150;
myHedra.x = 90;

Adding the appearance

myCone.appearance = app;
myHedra.appearance = app;

Adding the object to the TransformGroup

tg.addChild(myCone);
tg.addChild(myHedra);

Adding all remaining objects into the main group

g.addChild(tg);
g.addChild(myXLine);
g.addChild(myYLine);
g.addChild(myZLine);

Remember, we need to add: the TransformGroup we just created and the three lines. We do not add the two other objects since we have added them to the TransformGroup.

Handling the enterFrame event

Let’s see what we do in the two event handler function

myHedra.pan +=4;
myCone.pan +=4;
scene.render();

Handling the key input event

switch(event.keyCode) {
   case Keyboard.UP:
      tg.y +=2;
      break;
   case Keyboard.DOWN:
      tg.y -=2;
      break;
   case Keyboard.RIGHT:
      tg.roll +=2;
      break;
   case Keyboard.LEFT:
      tg.roll -=2;
      break;
}

And now, let’s see the result together…

The output

For this Flash, you have the UP, DOWN, RIGHT and LEFT key to play with it. Notice that the three axes do not move, since we are not moving the camera. And the axes are not inside the transformGroup.

Now, you should be able to combine the notions learned in this tutorial and in the previous one, in order to move object and in order to move around fixed objects (like wall for examples).