package
{
import AS3s.SeaTurtleAnimated;
import away3d.animators.data.*;
import away3d.cameras.*;
import away3d.containers.*;
import away3d.core.base.*;
import away3d.core.math.*;
import away3d.core.render.*;
import away3d.core.utils.*;
import away3d.events.*;
import away3d.lights.DirectionalLight3D;
import away3d.loaders.*;
import away3d.materials.*;
import away3d.primitives.*;
import away3d.sprites.*;
import flash.display.*;
import flash.events.*;
import flash.filters.*;
[SWF(backgroundColor="#000000", frameRate="30", quality="LOW", width="800", height="600")]
public class SierpinskiTurtles extends Sprite
{
[Embed(source="assets/seaturtle.jpg")]
private var SeaTurtleTexture:Class;
[Embed(source="assets/sky.jpg")]
private var Sky:Class;
[Embed(source="assets/signature_peter.swf", symbol="Signature")]
private var SignatureSwf:Class;
private var scene:Scene3D;
private var camera:HoverCamera3D;
private var view:View3D;
private var Signature:Sprite;
private var SignatureBitmap:Bitmap;
private var skyMaterial:BitmapMaterial;
private var hiliteMaterial:ShadingColorMaterial;
private var turtleMaterial:BitmapMaterial;
private var skysphere:Sphere;
private var seaturtle:Mesh;
private var containers:ObjectContainer3D;
private var outlines:ObjectContainer3D;
private var light:DirectionalLight3D;
private var toRadians:Number = Math.PI/180;
private var turtles:Array = new Array();
private var turtle:Mesh;
private var v1:Vertex;
private var v2:Vertex;
private var v3:Vertex;
private var v4:Vertex;
private var move:Boolean = false;
private var sprite:DisplayObject;
private var mesh:Mesh;
private var lastPanAngle:Number;
private var lastTiltAngle:Number;
private var lastMouseX:Number;
private var lastMouseY:Number;
/**
* Constructor
*/
public function SierpinskiTurtles()
{
init();
}
/**
* Global initialise function
*/
private function init():void
{
initEngine();
initMaterials();
initObjects();
initGeometry();
initListeners();
}
/**
* Initialise the engine
*/
private function initEngine():void
{
scene = new Scene3D();
camera = new HoverCamera3D({zoom:10, focus:100, distance:1600, yfactor:1, mintiltangle:-45, steps:4});
camera.targetpanangle = 285.0;
camera.targettiltangle = 10;
view = new View3D({scene:scene, camera:camera});
view.x = 400;
view.y = 300;
view.addSourceURL("srcview/index.html");
addChild( view );
Signature = Sprite(new SignatureSwf());
SignatureBitmap = new Bitmap(new BitmapData(Signature.width, Signature.height, true, 0));
stage.quality = StageQuality.HIGH;
SignatureBitmap.bitmapData.draw(Signature);
stage.quality = StageQuality.LOW;
addChild(SignatureBitmap);
}
/**
* Initialise the materials
*/
private function initMaterials():void
{
skyMaterial = new BitmapMaterial( Cast.bitmap(Sky) );
hiliteMaterial = new ShadingColorMaterial(0x0099FF, {shininess:5});
turtleMaterial = new BitmapMaterial( Cast.bitmap(SeaTurtleTexture) );
}
/**
* Initialise the scene objects
*/
private function initObjects():void
{
skysphere = new Sphere({material:skyMaterial, radius:50000, rotationX:180, segmentsW:10, segmentsH:12});
skysphere.scale(-1);
scene.addChild( skysphere );
var angle:Number = 90-Math.atan(1/Math.sqrt(2))/toRadians;
seaturtle = new SeaTurtleAnimated();
seaturtle.material = turtleMaterial;
seaturtle.rotate(new Number3D(1, 0, -1), -angle);
seaturtle.scale(0.24);
light = new DirectionalLight3D({x:-60, y:100, z:60, ambient:0.002, diffuse:0.003, specular:0.002});
scene.addChild(light);
containers = new ObjectContainer3D();
containers.rotate(new Number3D(1, 0, -1), angle);
scene.addChild(containers);
containers.visible = false;
containers.addOnMouseOver(onMeshMouseOver);
containers.addOnMouseOut(onMeshMouseOut);
outlines = new ObjectContainer3D();
outlines.rotate(new Number3D(1, 0, -1), angle);
scene.addChild(outlines);
}
/**
* Initialise the sierpinski geometry
*/
private function initGeometry():void
{
generateContainers(4, 500, containers, 0, 0, 0);
generateOutline(3, 500, outlines, 0, 0, 0);
}
/**
* Creates container clones from the turtle mesh
*/
private function generateContainers(itr:int, size:Number, parent:ObjectContainer3D, x:Number, y:Number, z:Number):void
{
if (itr) {
itr--;
size /= 2;
generateContainers(itr, size, parent, x+size, y+size, z+size);
generateContainers(itr, size, parent, x+size, y-size, z-size);
generateContainers(itr, size, parent, x-size, y-size, z+size);
generateContainers(itr, size, parent, x-size, y+size, z-size);
return;
}
turtle = seaturtle.cloneAll() as Mesh;
turtle.ownCanvas = true;
turtle.x = x;
turtle.y = y;
turtle.z = z;
parent.addChild(turtle);
turtles.push(turtle);
}
/**
* Creates an outline model for movement
*/
private function generateOutline(itr:int, size:Number, parent:ObjectContainer3D, x:Number, y:Number, z:Number):void
{
if (itr) {
itr--;
size /= 2;
generateOutline(itr, size, parent, x+size, y+size, z+size);
generateOutline(itr, size, parent, x+size, y-size, z-size);
generateOutline(itr, size, parent, x-size, y-size, z+size);
generateOutline(itr, size, parent, x-size, y+size, z-size);
return;
}
mesh = new Mesh({material:new WireframeMaterial(0x0066CC), ownCanvas:true, x:x, y:y, z:z});
parent.addChild( mesh );
v1 = new Vertex(size, size, size);
v2 = new Vertex(size, -size, -size);
v3 = new Vertex(-size, -size, size);
v4 = new Vertex(-size, size, -size);
mesh.addSegment(new Segment(v1, v2));
mesh.addSegment(new Segment(v1, v3));
mesh.addSegment(new Segment(v1, v4));
mesh.addSegment(new Segment(v2, v3));
mesh.addSegment(new Segment(v2, v4));
mesh.addSegment(new Segment(v3, v4));
}
/**
* Initialise the listeners
*/
private function initListeners():void
{
addEventListener( Event.ENTER_FRAME, onEnterFrame );
stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
onResize(null);
}
/**
* Navigation and render loop
*/
private function onEnterFrame( e:Event ):void
{
if (move) {
outlines.visible = true;
containers.visible = false;
camera.targetpanangle = 0.3*(stage.mouseX - lastMouseX) + lastPanAngle;
camera.targettiltangle = 0.3*(stage.mouseY - lastMouseY) + lastTiltAngle;
} else if (camera.targetpanangle == camera.panangle && camera.targettiltangle == camera.tiltangle) {
outlines.visible = false;
containers.visible = true;
}
camera.hover();
view.render();
if (containers.visible)
for each (turtle in turtles) {
turtle.ownSession.getContainer(view).alpha = 1/(1 + (camera.viewTransforms[turtle].tz - 1100)/1000);
}
}
/**
* Updates the turtle material on rollover
*/
private function onMeshMouseOver(event:MouseEvent3D):void
{
mesh = (event.object as Mesh);
mesh.material = hiliteMaterial;
mesh.play(new AnimationSequence("swim", true, true, 6));
}
/**
* Resets the turtle material on rollout
*/
private function onMeshMouseOut(event:MouseEvent3D):void
{
mesh = (event.object as Mesh)
mesh.material = turtleMaterial;
mesh.gotoAndStop(0);
}
/**
* Mouse down listener for navigation
*/
private function onMouseDown(event:MouseEvent):void
{
lastPanAngle = camera.targetpanangle;
lastTiltAngle = camera.targettiltangle;
lastMouseX = stage.mouseX;
lastMouseY = stage.mouseY;
move = true;
stage.addEventListener(Event.MOUSE_LEAVE, onStageMouseLeave);
}
/**
* Mouse up listener for navigation
*/
private function onMouseUp(event:MouseEvent):void
{
move = false;
stage.removeEventListener(Event.MOUSE_LEAVE, onStageMouseLeave);
}
/**
* Mouse stage leave listener for navigation
*/
private function onStageMouseLeave(event:Event):void
{
move = false;
stage.removeEventListener(Event.MOUSE_LEAVE, onStageMouseLeave);
}
/**
* Stage listener for resize events
*/
private function onResize(event:Event):void
{
view.x = stage.stageWidth / 2;
view.y = stage.stageHeight / 2;
SignatureBitmap.y = stage.stageHeight - Signature.height;
}
}
}