package { import flash.display.Sprite; import flash.events.*; import flash.utils.getTimer; import flash.utils.Timer; import flash.text.TextField; import flash.text.TextFieldAutoSize; import flash.text.TextFieldType; // Cast3D dependencies import cast3d.core.Cast3d; import cast3d.core.events.LoadEvent; import cast3d.loader.Xc3Loader; import cast3d.utils.controls.*; import cast3d.utils.manipulators.Manipulator; import cast3d.utils.manipulators.sandy3d.TrackBall; // Sandy3D dependencies import sandy.core.Scene3D; import sandy.core.scenegraph.Camera3D; import sandy.core.scenegraph.Group; import sandy.core.light.Light3D; public class Sample extends Sprite { private var manipulator:TrackBall; private var animator:Cast3d; private var cp:ControlPanel; private var scene:Scene3D; private var camera:Camera3D; private var loader:Xc3Loader; private var loaded:Boolean; private var statusText:TextField; private var statusTimer:Timer; public function Sample() { setup3DScene(); } /** * Configures the 3D scene */ private function setup3DScene(): void { this.setupSandy(); this.setupCast3D(); this.setupControls(); this.loadData(); this.addEventListener(Event.ENTER_FRAME, this.handleEnterFrame); } /** * initial setup for Sandy3D. */ public function setupSandy(): void { // We create the camera camera = new Camera3D( 600, 400 ); camera.near = 1; // We create the "group" that is the tree of all the visible objects var root:Group = new Group(); // We create a Scene and we add the camera and the objects tree scene = new Scene3D( "scene", this, camera, root ); scene.light = new Light3D(new Vector(0,0,1),100); } /** * initial setup for Cast3D. */ public function setupCast3D(): void { this.loaded = false; this.animator = new Cast3d(this.scene, this.camera); this.animator.animationType = Cast3d.ANIMATION_TYPE_BYFRAME; // ANIMATION_TYPE_REAL; // this.animator.fps = 22; this.animator.autoRewind = false; } /** * Function setups visual animation control panel. */ public function setupControls(): void { cp = new ControlPanel(animator); this.stage.addChild(cp); // cp.visible = false; statusText = new TextField(); statusText.textColor = 0x00ff00; statusText.autoSize = TextFieldAutoSize.LEFT; statusText.type = TextFieldType.DYNAMIC; statusText.y = cp.height; this.stage.addChild(statusText); } /** * Function performs 3D data load from a X3c file. */ private function loadData(): void { /** stealth - simple model, no animation */ this.loader = new Xc3Loader("simple/stealth.x3c"); this.loader.resourcePath = "simple/data"; statusText.text = "loading file: " + loader.sourceURL; statusTimer = new Timer(1000, 0.2); // designates listeners for the interval and completion events statusTimer.addEventListener(TimerEvent.TIMER, onTick); statusTimer.addEventListener(TimerEvent.TIMER_COMPLETE, onTimerComplete); statusTimer.start(); // this.loader.preCalcMotion = true; this.loader.addEventListener(LoadEvent.LOAD_COMPLETE, this.cast3dLoadComplete); this.loader.addEventListener(LoadEvent.LOAD_ERROR, this.cast3dLoadError); this.loader.load(this.animator.source); } /** * Timer, updates current status */ private function onTick(event:TimerEvent):void { statusText.text = this.loader.loadstatus; } /** * Timer handler */ private function onTimerComplete(event:TimerEvent):void { trace("Time's Up!"); statusText.textColor = 0xff0000; statusText.text = "Loading time exceeded 20 nimutes!"; removeTimer(); } /** * At the end of load, removes timer */ private function removeTimer():void { statusTimer.stop(); statusTimer.removeEventListener(TimerEvent.TIMER,onTick); statusTimer.removeEventListener(TimerEvent.TIMER_COMPLETE,onTimerComplete); } /** * Handles the ENTER_FRAME event and updates the 3D scene. */ private function handleEnterFrame(event: Event): void { if (!this.loaded) return; var time:Number = getTimer(); // Update cast3D first this.animator.render(); // then render scene this.scene.render(); // Update stat data if (this.animator.source && cp) { var frame:int = this.animator.source.currentFrame; var kframe:int = this.animator.source.currentKeyFrame; cp.setCurrentFrame(kframe,frame); cp.setCurrentTime(animator.currentTime); cp.currentFps = 1000.0/(getTimer() - time); } } /** * Handles mouse event */ public function mouseClicked(e:Event):void { if (!this.animator.source) return; if (this.animator.isPlaying) { this.animator.pause(); } else { this.animator.play(); } } /** * Handles the load complete event */ private function cast3dLoadComplete(event: LoadEvent): void { trace("cast3dLoadComplete "); this.manipulator = new TrackBall(this.animator,this.stage, this.stage.stageWidth, this.stage.stageHeight, Manipulator.Y_UP); this.loaded = true; removeTimer(); if (loader.loaderror.length) { statusText.textColor = 0xff0000; statusText.text = loader.loaderror; } else { statusText.visible = false; } } /** * Handles the load Error event */ private function cast3dLoadError(event: LoadEvent): void { trace("cast3dLoadError ", event.message ); removeTimer(); statusText.textColor = 0xff0000; statusText.text = event.message; } } }