package
{
import away3d.cameras.Camera3D;
import away3d.containers.ObjectContainer3D;
import away3d.containers.Scene3D;
import away3d.containers.View3D;
import away3d.core.base.Face;
import away3d.core.base.Vertex;
import away3d.core.clip.RectangleClipping;
import away3d.core.math.Number3D;
import away3d.geom.AlignToPath;
import away3d.lights.PointLight3D;
import away3d.loaders.Swf;
import away3d.materials.ColorMaterial;
import away3d.materials.ShadingColorMaterial;
import away3d.materials.WireframeMaterial;
import away3d.primitives.Plane;
import away3d.primitives.Sphere;
import away3d.primitives.TextField3D;
import com.adobe.viewsource.ViewSource;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequest;
import flash.net.navigateToURL;
import wumedia.vector.VectorText;
SWF'#000000', frameRate='60')]
public class Main extends Sprite
{
Embed"assets/assets.swf", symbol="AwayLogo")]
private var LogoAsset:Class;
Embed"assets/assets.swf", mimeType="application/octet-stream")]
private var SwfAsset:Class;
private var _scene:Scene3D;
private var _view:View3D;
private var _camera:Camera3D;
private var _width3d:Number;
private var _height3d:Number;
private var _loader:URLLoader;
private var _center:Number3D = new Number3D();
private var _textfield:TextField3D;
private var _aligner:AlignToPath;
private var _pathLength:Number;
private var _xOffset:Number = 0;
private var _speed:Number = 10;
private var _textWidth:Number;
private var _pointLight:PointLight3D;
/**
* Constructor.
*/
public function Main()
{
ViewSource.addMenuItem(this, "srcview/index.html");
initStage();
loadFonts();
}
/**
* Lights used to shade the sphere.
*/
private function initLights():void
{
_pointLight = new PointLight3D();
_pointLight.color = 0xFFFFFF;
_pointLight.ambient = 0.5;
_pointLight.diffuse = 1;
_pointLight.specular = 1;
_scene.addChild(_pointLight);
}
/**
* Init the away3d logo.
*/
private function initLogo():void
{
var logo:Sprite = new LogoAsset();
logo.y = stage.stageHeight;
addChild(logo);
logo.addEventListener(MouseEvent.MOUSE_DOWN, logoMouseDownHandler);
}
/**
* Logo on click.
*/
private function logoMouseDownHandler(evt:MouseEvent):void
{
navigateToURL(new URLRequest("http://www.away3d.com"), "_blank");
}
/**
* Init the stage settings.
*/
private function initStage():void
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
_width3d = stage.stageWidth;
_height3d = stage.stageHeight;
}
/**
* Load the assets swf to extract the fonts vector data.
* NOTE: Could be embedded also, just wanted to demonstrate another way to
* get vector stuff into 3d.
*/
private function loadFonts():void
{
_loader = new URLLoader();
_loader.dataFormat = URLLoaderDataFormat.BINARY;
_loader.addEventListener(Event.COMPLETE, onFontsLoadedHandler);
_loader.load(new URLRequest("assets/assets.swf"));
}
/**
* Continue initialization when fonts are ready.
*/
private function onFontsLoadedHandler(evt:Event):void
{
initFonts();
init3d();
init3dObjects();
initLogo();
initLights();
this.addEventListener(Event.ENTER_FRAME, render3d);
}
/**
* Use the swf binary data to extract the fonts.
* Wumedia's package at work.
*/
private function initFonts():void
{
VectorText.extractFont(_loader.data);
}
/**
* Initialize the main 3d elements.
*/
private function init3d():void
{
_scene = new Scene3D();
_camera = new Camera3D({x:0, y:0, z:-1000});
_view = new View3D({camera:_camera, scene:_scene});
_view.x = _width3d/2;
_view.y = _height3d/2;
_view.clipping = new RectangleClipping({minX:-_width3d/2, maxX:_width3d/2, minY:-_height3d/2, maxY:_height3d/2});
_view.addSourceURL("srcview/index.html");
addChild(_view);
}
/**
* Initiliaze the 3d objects in the scene.
*/
private function init3dObjects():void
{
var floor:Plane = new Plane();
floor.width = floor.height = 25000;
floor.segmentsW = floor.segmentsH = 12;
floor.y = -1500;
floor.material = new WireframeMaterial(0x333333);
_scene.addChild(floor);
var sphere:Sphere = new Sphere();
sphere.radius = 300;
sphere.segmentsW = sphere.segmentsH = 16;
sphere.material = new ShadingColorMaterial(0xFFFFFF);
_scene.addChild(sphere);
_textfield = new TextField3D("Helvetica", {text:"Warping text in Away3D", size:150, textWidth:2000});
_textfield.material = new ColorMaterial(0xFF0000);
_textWidth = _textfield.objectWidth;
_scene.addChild(_textfield);
var pathSource:ObjectContainer3D = Swf.parse(new SwfAsset(), {libraryClips:["Circle"], scaling:7});
var circleFace:Face = pathSource.children[0].faces[0];
for each(var vertex:Vertex in circleFace.vertices)
{
vertex.z = -vertex.y;
vertex.y = 0;
}
circleFace.material = new WireframeMaterial(0xFFFFFF, {alpha:0.5});
_aligner = new AlignToPath(_textfield, circleFace);
_aligner.arcLengthPrecision = 0.1;
updateText();
}
/**
* Simple camera-mouse motion.
*/
private function hoverCamera():void
{
var mX:Number = this.mouseX > 0 ? this.mouseX : 0;
var mY:Number = this.mouseY > 0 ? this.mouseY : 0;
var tarX:Number = 3*(mX - stage.stageWidth/2);
var tarY:Number = -3*(mY - stage.stageHeight/2);
var dX:Number = _camera.x - tarX;
var dY:Number = _camera.y - tarY;
_camera.x -= dX*0.1;
_camera.y -= dY*0.1;
_camera.lookAt(_center);
}
/**
* Update method for light position
* Follows camera.
*/
private function hoverLight():void
{
_pointLight.x = _camera.x;
_pointLight.y = _camera.y;
_pointLight.z = _camera.z;
}
/**
* Updates the alignment of the text with an incremental offset in x.
*/
private function updateText():void
{
_xOffset += _speed;
_xOffset = _xOffset < 0 ? _pathLength - _textWidth : _xOffset;
_xOffset = _xOffset > _pathLength - _textWidth ? 0: _xOffset;
_aligner.apply(-_xOffset, 75, true);
}
/**
* Enterframe.
*/
private function render3d(evt:Event):void
{
hoverCamera();
hoverLight();
_view.render();
updateText();
}
}
}