Home Labs Galleries PetitOn

Using Sandy 3.0 Flash Library

Part 4, Transformations

Page 2 - this is just a sketch, but I have to pause, so I thought ... you know ;)

Transform Groups

As we have seen, all 3D objects are highly movable all by them selves. The reason for this is that the Shape3D class is a sub class of Atransformable. While it sometimes is enough to manipulate the visible objects directly, you usually want to operate on multiple objects simultaneously or to make more complex animations.

In these cases you will group objects together, using a Group or a TransformGroup. Objects of both classes are nodes in the node graph, and can have child nodes. The children can be other group nodes or visible Shape3D objects. The Group class extends Node directly, and have no properties or methods for transformations, while the TransformGroup extends Atransformable, and can be transformed in the same manners as the Shape3D objects.

As we shall see this allows for very flexible systems for moving groups and shapes around in the world.  Let's say we have a group of 3D objects as children of a transform group. We can then apply transforms to the transform group, and other transforms directly to the different 3D objects. Each object will affected by the transform on the group in addition to the transform directly on the object.

The satellite system

If you want move an object along a circular path around a specific point, you could calculate the position of the object in the next frame using trigonometric functions. Then you would its setPosition method, and pass the x, y and z values.  That seems a natural thing to do for a math guy like yourself, but there are smarter alternaives.

We can add our object as a child of a TransformGroup, and start by translating it in the plane of our circular path by the radius. Then we rotate the group. Let's see.

We want to access the transform group from more than one method, so we declare it as an instance variable in our document class. We also want to animate the motion this time, and we want to be able to start and stop the animation.

	private var tg:TransformGroup;
	private var running:Boolean = false; // should we animate?

To get some space for our rotating object, we make the stage a little bigger, say 400 by 200. We still want to have the origin of the world in the middle of the scene, so we will have to change the view port of the camera, which we do when we create the camera.

	camera = new Camera3D( 400, 200 );
	camera.z = -200;
	camera.y = 40;
	camera.x = 20;
	camera.lookAt( 0, 0, 0 );

We still want some perspective on the scene, so we displace the camera and make it look towards the origin.

In the createScene method we instantiate the transform group, add the box to it add the transform group to the root group.

private function createScene():Group
{
	var root:Group = new Group();

	// Definitions of materials and appearance go here

	tg = new TransformGroup('path');
	box.appearance = app;
	box.x = 100;
	tg.addChild( box );
	root.addChild( tg );
	return root;
}

Here we give the box a translation by 100 along the x axis of its parent. This will be the  radius of our circular path.

There are a few other things to take care of, as we want an animation, that we can start and stop. First of all we will create an event handler, that toggles between running and not running mode, that is it simply changes the value of the running variable.

We listen for mouse events on the stage, by setting up ourselves as listeners, which we can do in the constructor.

	stage.addEventListener(MouseEvent.CLICK, toggleRunning);

The event handler just toggles the global running variable.

	private function toggleRunning(event:MouseEvent){
		running = !running;
	}


Our usual enter frame handler checks to see if we are in fact running, and if so rotates the transform group around ( an axis parallel to ) the global y axis.

	private function enterFrameHandler( event : Event ) : void
	{
		if(running){
			tg.rotateY++;
		}
		if (Key.isDown(Keyboard.HOME)) {
 			camera.moveForward(2);
		}
		if (Key.isDown(Keyboard.END)) {
 			camera.moveForward(-2);
		}
		world.render();
	}

We also have the possibility to move the camera back and forth.

Click to start and stop.

We can note that the cube shows the same side to the origin, as it moves around the y axis. The cube has a fixed position in the coordinate system of its parent, the transform group.

Relative motion

Now we can apply some transform directly to the cube inside the transform group. Let's make it a rotation around the x axes!  We add the animation in the frame handler.

		if(running){
			tg.rotateY++;
			box.rotateX+=3;
		}

What axis does the box rotate around?
It is the x axis of its parent, the transform group.

Or, to be precise: the box rotates around an axis through the reference point or the box an parallel to the x axis of its parent. In this case the x axis of the parent transform group goes through the center of the box, so both statements are true.

OK, so we can rotate an object, or indeed a bunch of objects in a circle around the global y axis of the world, with the circular path in the zx plane ( the ground plane ).
What if we want the the path in some plane that is not a global coordinate plane?

We can try to rotate the plane, by giving the transform group a fix rotation around its z axis, which is a roll when we add it to the root group. To make it simpler to look at, I have commented out the box rotation around its x axis.

tg.roll=30; // For Satellite2

So, what happened?
The transform group rotated 30 degrees left, lifting the box up above the ground plane, but we still rotate the group around the y axis of the world.

There are many solutions to this problem. One would be to use only local rotations for the transform group. We already have a fixed roll to give the plane an inclination against the ground plane. Why not let the transform group pan, i.e. rotate around its own y axis?

	if(running){
		tg.pan++; // Satellite3
		//tg.rotateY++; // Satellite
		//box.rotateX+=3;
	}

------------------------ Here endest the sketch for now

There is more to come, so stay tuned!

Meanwile, we'll study how to dress up our objects.

ToDo.

Does rotate with reference work?
Show what happens if you translate - then rotate & v.v.
Circle a body around another ( calculate and set positions - or do it with a trafo group )

Moveforwards and side ways etc. ( for the camera show sideways lookat spiral and tg inspect)

The camera rotate and look at 000 - compare 1.1 either calculate circle step around and lookAt or moveSideways and lookAt, making for a spiraling movement ( a little bit outward for each step ) - now correct and much simpler.

How about animations with interpolators - no longer part of Sandy . there are animation paxkages as Tweener and the built in tweener.