package
{
import away3d.cameras.*;
import away3d.containers.*;
import away3d.core.base.*;
import away3d.core.math.Number3D;
import away3d.core.render.RectangleClipping;
import away3d.core.utils.*;
import away3d.lights.AmbientLight3D;
import away3d.lights.DirectionalLight3D;
import away3d.loaders.*;
import away3d.materials.*;
import away3d.primitives.*;
import flash.display.*;
import flash.events.*;
import flash.filters.ColorMatrixFilter;
import flash.utils.getTimer;
[SWF(backgroundColor="#B2DBE6", frameRate="30", quality="LOW", width="800", height="600")]
public class Away3DTextureProjection extends Sprite
{
[Embed(source="assets/bathroomtilegray3.jpg")]
public static var PoolTile:Class;
[Embed(source="assets/caustics.swf", symbol="caustics")]
public var Caustics:Class;
[Embed(source="assets/caustics.swf", symbol="lifering")]
public var LifeRing:Class;
[Embed(source="assets/signature.swf", symbol="Signature")]
public static 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 poolTileMaterial:TransformBitmapMaterial;
private var poolWaterMaterial:AnimatedBitmapMaterial;
private var poolMaterial:CompositeMaterial;
private var lifeRingMaterial:TransformBitmapMaterial;
private var ringMaterial:CompositeMaterial;
private var poolCaustics:MovieClip;
private var poolContainer:MovieClip;
private var projectionVector:Number3D = new Number3D(0.5, -1, 0.5);
private var pool:Cube;
private var ring:Torus;
private var move:Boolean = false;
private var lastPanAngle:Number;
private var lastTiltAngle:Number;
private var lastMouseX:Number;
private var lastMouseY:Number;
/**
* Constructor
*/
public function Away3DTextureProjection()
{
init();
}
/**
* Global initialise function
*/
private function init():void
{
initEngine();
initMaterials();
initObjects();
initListeners();
}
/**
* Initialise the engine
*/
private function initEngine():void
{
scene = new Scene3D();
camera = new HoverCamera3D({zoom:10, focus:50, lookat:"center"});
camera.distance = 30000;
camera.yfactor = 1;
camera.maxtiltangle = 90;
camera.mintiltangle = 10;
camera.targetpanangle = camera.panangle = 0;
camera.targettiltangle = camera.tiltangle = 10;
view = new View3D({scene:scene, camera:camera, clip:new RectangleClipping(-400, -300, 400, 300)});
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
{
poolTileMaterial = new TransformBitmapMaterial(Cast.bitmap(PoolTile), {offsetX:-1.2, offsetY:-0.6, scaleX:0.2, scaleY:0.2, repeat:true});
poolCaustics = new Caustics() as MovieClip;
poolCaustics.filters = [new ColorMatrixFilter([1, 0, 0, 0, 0, 0, 1, 0, 0, 127, 0, 0, 1, 0, 200, 0.25, 0, 0, 0, 64])];
poolContainer = new MovieClip();
poolContainer.addChild(poolCaustics);
poolWaterMaterial = new AnimatedBitmapMaterial(poolContainer, {projectionVector:projectionVector, throughProjection:true, globalProjection:true, repeat:true, scaleX:50, scaleY:50});
var i:int = poolCaustics.totalFrames;
var frames:Array = new Array();
var bitmapData:BitmapData;
while(i--) {
bitmapData = new BitmapData(256, 256, true, 0);
poolCaustics.gotoAndStop(i+1);
bitmapData.draw(poolContainer);
frames.unshift(bitmapData);
}
poolWaterMaterial.setFrames(frames);
poolTileMaterial.precision = 1;
poolMaterial = new CompositeMaterial({materials:[poolTileMaterial, poolWaterMaterial]});
lifeRingMaterial = new TransformBitmapMaterial(Cast.bitmap(LifeRing), {projectionVector:new Number3D(0, 1, 0), scaleX:100, scaleY:100, offsetX:-12800, offsetY:-12800, throughProjection:true});
ringMaterial = new CompositeMaterial({materials:[lifeRingMaterial, poolWaterMaterial]});
}
/**
* Initialise the scene objects
*/
private function initObjects():void
{
pool = new Cube({material:poolMaterial, width:50000, height:50000, depth:50000});
pool.y = 10000;
pool.quarterFaces();
pool.quarterFaces();
pool.scale(-1);
scene.addChild(pool);
ring = new Torus({ownCanvas:true, material:ringMaterial, radius:6000, tube:2500, segmentsR:20, segmentsT:10});
scene.addChild(ring);
}
/**
* 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(event:Event):void
{
if (move) {
camera.targetpanangle = 0.3*(stage.mouseX - lastMouseX) + lastPanAngle;
camera.targettiltangle = 0.3*(stage.mouseY - lastMouseY) + lastTiltAngle;
}
ring.rotationX += 3;
ring.rotationY += 3;
camera.hover();
view.render();
}
/**
* 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;
}
}
}