Thanks for sharing man.It is going to be really helpful! On Sun, May 29, 2011 at 4:11 PM, Sazz Somewhere <jackthef...@hana-arashi.de>wrote:
> Hi, > > I have written Away3DCanvas which helps to integrate molehill/ > broomstick engine into flex applications. It's actually an enhanced > version of some previous away3d components. > > Because the 3d content gets rendered behind the flex applications > display list it's a little bit tricky to get the broomstick content > into place. > > My approach was to mask the unwanted areas of the 3d content with four > BorderContainer objects for each side (top,left,bottom,right). The > objects gets added to the bottom of the display list so that the > molehill areas are seperated from the flex displayed objects. > Therefore only one Away3DCanvas per application is possible. > > All properties are data binded so if you move the Away3DCanvas the > BorderContainer objects reconfigurate themselves around the canvas > giving the illusion of an embedded 3d content. > > The canvas can be configured with the following properties (changes to > the properties are reflected at runtime): > Away3DCanvas.view: View3D object > Away3DCanvas.scene: Scene3D object of the view > Away3DCanvas.stats: Boolean to toggle Away3DStats > Away3DCanvas.flightMode: Boolean - added the FlightController from the > Away3D examples > Away3DCanvas.cameraX: Number - x position of the camera > Away3DCanvas.cameraY: Number - y position of the camera > Away3DCanvas.cameraZ: Number - z position of the camera > Away3DCanvas.cameraRotationX: Number - rotationX position of the > camera > Away3DCanvas.cameraRotationY: Number - rotationY position of the > camera > Away3DCanvas.cameraRotationZ: Number - rotationZ position of the > camera > Away3DCanvas.appBackgroundColor: String - the color of the application > background (used by the BorderContainers) > > Here's the code for the Away3DCanvas: > > <?xml version="1.0" encoding="utf-8"?> > <mx:UIComponent xmlns:fx="http://ns.adobe.com/mxml/2009" > xmlns:s="library://ns.adobe.com/flex/spark" > xmlns:mx="library://ns.adobe.com/flex/mx" > enterFrame="handleEnterFrame(event)" > addedToStage="addedToStage(event)" > removedFromStage="removedFromStage(event)"> > <fx:Declarations> > <s:BorderContainer id="m_topCanvas" > borderColor="{appBackgroundColor}" borderWeight="0" > backgroundColor="{appBackgroundColor}"/> > <s:BorderContainer id="m_bottomCanvas" > borderColor="{appBackgroundColor}" borderWeight="0" > backgroundColor="{appBackgroundColor}"/> > <s:BorderContainer id="m_leftCanvas" > borderColor="{appBackgroundColor}" borderWeight="0" > backgroundColor="{appBackgroundColor}"/> > <s:BorderContainer id="m_rightCanvas" > borderColor="{appBackgroundColor}" borderWeight="0" > backgroundColor="{appBackgroundColor}"/> > </fx:Declarations> > <fx:Script> > <![CDATA[ > import away3d.containers.Scene3D; > import away3d.containers.View3D; > import away3d.debug.AwayStats; > import away3d.materials.ColorMaterial; > > import mx.binding.utils.BindingUtils; > import mx.binding.utils.ChangeWatcher; > import mx.collections.ArrayCollection; > import mx.core.FlexGlobals; > import mx.core.UIComponent; > import mx.events.PropertyChangeEvent; > > [Bindable] public var view:View3D; > [Bindable] public var stats:Boolean; > [Bindable] public var flightMode:Boolean; > [Bindable] public var cameraX:Number = 0; > [Bindable] public var cameraY:Number = 0; > [Bindable] public var cameraZ:Number = 0; > [Bindable] public var cameraRotationX:Number = 0; > [Bindable] public var cameraRotationY:Number = 0; > [Bindable] public var cameraRotationZ:Number = 0; > [Bindable] public var appBackgroundColor:String = "0xFFFFFF"; > > private var m_xWatcherArray:ArrayCollection = new > ArrayCollection(); > private var m_yWatcherArray:ArrayCollection = new > ArrayCollection(); > private var m_widthWatcher:ChangeWatcher; > private var m_heightWatcher:ChangeWatcher; > > private var m_application:Object; > private var m_statsObject:AwayStats; > private var m_flightController:FlightController; > > public function get scene():Scene3D { > return this.view.scene; > } > > protected function addedToStage(event:Event):void { > m_application = FlexGlobals.topLevelApplication; > m_application.addElementAt(m_topCanvas, 0); > m_application.addElementAt(m_bottomCanvas, 0); > m_application.addElementAt(m_leftCanvas, 0); > m_application.addElementAt(m_rightCanvas, 0); > init(); > } > > protected function removedFromStage(event:Event):void { > } > > /** > * Global initialise function > */ > private function init():void { > this.view = new View3D(); > createObjectWatch(this); > m_widthWatcher = ChangeWatcher.watch(this, "width", > handleViewChange); > m_heightWatcher = ChangeWatcher.watch(this, "height", > handleViewChange); > addChild(this.view); > ChangeWatcher.watch(this, "stats", updateStats); > ChangeWatcher.watch(this, "flightMode", updateFlightMode); > BindingUtils.bindProperty(view.camera, "x", this, "cameraX"); > BindingUtils.bindProperty(view.camera, "y", this, "cameraY"); > BindingUtils.bindProperty(view.camera, "z", this, "cameraZ"); > BindingUtils.bindProperty(view.camera, "rotationX", this, > "cameraRotationX"); > BindingUtils.bindProperty(view.camera, "rotationY", this, > "cameraRotationY"); > BindingUtils.bindProperty(view.camera, "rotationZ", this, > "cameraRotationZ"); > updateStats(null); > updateFlightMode(null); > handleViewChange(null); > } > > private function updateStats(event:PropertyChangeEvent):void { > if ((this.stats == true) && (m_statsObject == null)) { > m_statsObject = new AwayStats(view); > addChild(m_statsObject); > } > if ((this.stats == false) && (m_statsObject != null)) { > removeChild(m_statsObject); > m_statsObject = null; > } > } > > private function > updateFlightMode(event:PropertyChangeEvent):void { > if ((this.flightMode == true) && (m_flightController == null)) > { > m_flightController = new FlightController(view.camera, > this.stage); > } > if ((this.flightMode == false) && (m_flightController != > null)) { > m_flightController.destroy(); > m_flightController = null; > } > } > > private function > createObjectWatch(component:DisplayObjectContainer):void { > m_xWatcherArray.addItem(ChangeWatcher.watch(component, "x", > handleViewChange)); > m_yWatcherArray.addItem(ChangeWatcher.watch(component, "y", > handleViewChange)); > if (component.parent != null) { > createObjectWatch(component.parent); > } > } > > private function handleViewChange(event:Event):void { > var globalPoint:Point = this.localToGlobal(new Point(0, 0)); > var viewWidth:int = this.width; > var viewHeight:int = this.height; > var viewX:int = globalPoint.x; > var viewY:int = globalPoint.y; > > updatePosition(this.view, viewX, viewY, viewWidth, > viewHeight); > updatePosition(m_leftCanvas, 0, 0, viewX, > m_application.height); > updatePosition(m_rightCanvas, viewX + viewWidth, 0, > m_application.width - viewX - viewWidth, m_application.height); > updatePosition(m_topCanvas, viewX, 0, viewWidth, this.view.y); > updatePosition(m_bottomCanvas, viewX, viewY + viewHeight, > viewWidth, m_application.height - viewY - viewHeight); > } > > private function updatePosition(object:Object, x:int, y:int, > width:int, height:int):void { > object.x = x; > object.y = y; > object.width = width; > object.height = height; > } > > private function dispose():void { > for each(var xWatcher:ChangeWatcher in m_xWatcherArray) { > xWatcher.unwatch(); > } > for each (var yWatcher:ChangeWatcher in m_yWatcherArray) { > yWatcher.unwatch(); > } > m_xWatcherArray.removeAll(); > m_yWatcherArray.removeAll(); > m_widthWatcher = unwatch(m_widthWatcher); > m_heightWatcher = unwatch(m_heightWatcher); > } > > private function unwatch(watcher:ChangeWatcher):ChangeWatcher { > if (watcher != null) { > watcher.unwatch(); > } > return null; > } > > /** > * Render loop > */ > private function handleEnterFrame(event:Event):void { > if (this.view != null) { > this.view.render(); > } > } > > override protected function > updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void { > super.updateDisplayList(unscaledWidth, unscaledHeight); > > if (!this.view) > return; > > if (width * .5 != this.view.x) > this.view.x = width * .5; > if (height * .5 != this.view.y) > this.view.y = height * .5; > } > > ]]> > </fx:Script> > </mx:UIComponent> > > Here's a little example: > > <?xml version="1.0" encoding="utf-8"?> > <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" > xmlns:s="library://ns.adobe.com/flex/spark" > xmlns:mx="library://ns.adobe.com/flex/mx" > xmlns:ns1="*" backgroundAlpha="0" > minWidth="955" minHeight="600" > applicationComplete="creationComplete()"> > <fx:Declarations> > </fx:Declarations> > <fx:Script> > <![CDATA[ > import away3d.materials.ColorMaterial; > import away3d.primitives.Cube; > > public function creationComplete():void { > m_canvas.scene.addChild(new Cube(new > ColorMaterial(0x003988))); > addEventListener(Event.ENTER_FRAME, handleEnterFrame); > } > > public function handleEnterFrame(event:Event):void { > m_canvas.scene.getChildAt(0).rotationY++; > } > ]]> > </fx:Script> > <ns1:A3DCanvas id="m_canvas" x="148" y="113" width="546" > height="298" stats="true" flightMode="true" cameraZ="-150" > cameraY="-60"/> > <s:HSlider x="148" y="419" width="546" maximum="300" minimum="-300" > value="@{m_canvas.cameraX}"/> > <s:VSlider x="702" y="113" height="298" maximum="300" minimum="-300" > value="@{m_canvas.cameraY}"/> > <s:VSlider x="129" y="113" height="298" maximum="300" minimum="-300" > value="@{m_canvas.cameraZ}"/> > </s:Application> > > The FlightController class can be found at away3d/broomstick/Examples/ > as/src/FlightController.as > > And don't forget to set the backgroundAlpha of your flex application > to 0 (otherwise the 3d content won't be visible) > > Thanks to all the people providing little snippets to help finish this > component. > > Have fun :) > > Sazz > -- Michael Ivanov ,Programmer Neurotech Solutions Ltd. Flex|Air |3D|Unity| www.neurotechresearch.com http://blog.alladvanced.net Tel:054-4962254 mich...@neurotech.co.il t...@neurotech.co.il