package
{
import away3d.cameras.*;
import away3d.containers.*;
import away3d.core.clip.RectangleClipping;
import away3d.core.math.*;
import away3d.core.render.*;
import away3d.core.utils.Cast;
import away3d.core.utils.DofCache;
import away3d.materials.*;
import away3d.primitives.*;
import away3d.sprites.*;
import flash.display.*;
import flash.events.*;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
[SWF(backgroundColor="#000000", frameRate="30", quality="LOW", width="800", height="600")]
public class DofAtom extends Sprite
{
[Embed(source="assets/red.png")]
public var RedMarble:Class;
[Embed(source="assets/green.png")]
public var GreenMarble:Class;
[Embed(source="assets/blue.png")]
public var BlueMarble:Class;
[Embed(source="assets/signature.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 bitmapProton:BitmapData;
private var bitmapNeutron:BitmapData;
private var bitmapElectron:BitmapData;
private var skyboxMaterial:TransformBitmapMaterial;
private var skyboxBitmap:BitmapData;
private var skyboxColorTransform:ColorTransform = new ColorTransform(1, 1, 1, 0.5);
private var proton:DofSprite2D;
private var neutron:DofSprite2D;
private var nucleicContainer:ObjectContainer3D;
private var electron:DofSprite2D;
private var electronContainer:ObjectContainer3D;
private var skybox:Skybox;
private var electrons:Array = new Array();
private var electronNum:int = 50;
private var electronSpeed:int = 5;
private var move:Boolean = false;
private var lastPanAngle:Number;
private var lastTiltAngle:Number;
private var lastMouseX:Number;
private var lastMouseY:Number;
/**
* Constructor
*/
public function DofAtom()
{
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:100, distance:2000, yfactor:1});
camera.targetpanangle = camera.panangle = 45;
camera.targettiltangle = camera.tiltangle = 20;
view = new View3D({scene:scene, camera:camera, session:new BitmapRenderSession(1), clip:new RectangleClipping(-400, -300, 400, 300)});
view.x = 400;
view.y = 300;
view.addSourceURL("srcview/index.html");
view.render();
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
{
bitmapProton = Cast.bitmap(RedMarble);
bitmapNeutron = Cast.bitmap(BlueMarble);
bitmapElectron = Cast.bitmap(GreenMarble);
skyboxBitmap = view.getBitmapData().clone();
skyboxMaterial = new TransformBitmapMaterial(Cast.bitmap(skyboxBitmap), {scaleX:0.1, scaleY:0.1, repeat:true});
}
/**
* Initialise the scene objects
*/
private function initObjects():void
{
DofCache.aperture = 100;
DofCache.usedof = true;
DofCache.maxblur = 50;
DofCache.focus = 2000;
var i:int = electronNum;
while (i--)
{
proton = new DofSprite2D(bitmapProton, {scaling:1, x:180, y:0, z:0, ownCanvas:true});
proton.blendMode = BlendMode.DIFFERENCE;
neutron = new DofSprite2D(bitmapNeutron, {scaling:1, x:-180, y:0, z:0, ownCanvas:true});
neutron.blendMode = BlendMode.DIFFERENCE;
nucleicContainer = new ObjectContainer3D({rotationX:i*360/electronNum, rotationZ:i*180/electronNum, rotationY:i*200/6}, proton, neutron);
scene.addChild( nucleicContainer );
electron = new DofSprite2D(bitmapElectron, {scaling:1, x:0, y:500, z:0,ownCanvas:true});
electron.blendMode = BlendMode.DIFFERENCE;
electronContainer = new ObjectContainer3D({rotationX:i*360/electronNum, rotationZ:i*180/electronNum, rotationY:i*360/6}, electron );
electrons.push(electronContainer);
scene.addChild( electronContainer );
}
skybox = new Skybox(skyboxMaterial, skyboxMaterial, skyboxMaterial, skyboxMaterial, skyboxMaterial, skyboxMaterial);
scene.addChild(skybox);
}
/**
* 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) {
camera.targetpanangle = 0.3*(stage.mouseX - lastMouseX) + lastPanAngle;
camera.targettiltangle = 0.3*(stage.mouseY - lastMouseY) + lastTiltAngle;
}
for each (electronContainer in electrons)
electronContainer.rotationX += electronSpeed;
skyboxBitmap.fillRect(skyboxBitmap.rect, 0);
skyboxBitmap.draw(view.getBitmapData(), null, skyboxColorTransform, BlendMode.DIFFERENCE);
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;
}
}
}