PageRenderTime 43ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/PanoSalado.as

http://universalmap.googlecode.com/
ActionScript | 1 lines | 1 code | 0 blank | 0 comment | 0 complexity | 7d37fb6fcfcdd9ef73921baaf9b2bf8e MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. package { import flash.net.*; import flash.system.ApplicationDomain; import br.com.stimuli.loading.BulkLoader; import br.com.stimuli.loading.BulkProgressEvent; import br.com.stimuli.loading.BulkErrorEvent; import flash.utils.Dictionary; import flash.display.*; import flash.text.TextField; import flash.text.TextFieldAutoSize; import flash.text.TextFormat; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.geom.Rectangle; import flash.events.TimerEvent; import flash.utils.Timer; import flash.geom.Point; import flash.events.KeyboardEvent; import flash.ui.Keyboard; import flash.display.Sprite; import flash.events.Event; import flash.events.ProgressEvent; import flash.events.MouseEvent; import mx.events.MetadataEvent; import mx.events.VideoEvent; //import org.papervision3d.cameras.Camera3D; import zephyr.cameras.PSCamera3D; import zephyr.objects.primitives.Cube; import zephyr.objects.primitives.Cylinder; import org.papervision3d.objects.primitives.Plane; import zephyr.objects.primitives.Sphere; //import org.papervision3d.render.BasicRenderEngine; import zephyr.render.PSRenderEngine; import org.papervision3d.scenes.Scene3D; import org.papervision3d.view.Viewport3D; import org.papervision3d.events.InteractiveScene3DEvent; import org.papervision3d.objects.DisplayObject3D; import org.papervision3d.materials.BitmapMaterial; import org.papervision3d.materials.utils.PrecisionMode; import org.papervision3d.materials.utils.MaterialsList; import org.papervision3d.core.proto.MaterialObject3D; import org.papervision3d.events.RendererEvent; import org.papervision3d.core.render.data.RenderStatistics; import org.papervision3d.core.math.Number3D; import org.papervision3d.view.layer.ViewportBaseLayer; import org.papervision3d.view.layer.ViewportLayer; import org.papervision3d.materials.MovieMaterial; import com.eyesee360.materials.VideoPlayerMaterial; import mx.core.Singleton; import mx.resources.ResourceManager; import com.eyesee360.VideoDisplaySprite; import flash.net.NetStream; import flash.net.NetConnection; import flash.system.Security; //import gs.TweenFilterLite; import gs.TweenLite; import gs.easing.*; import com.adobe.utils.StringUtil; import flash.utils.*; import zephyr.objects.StageAlignedSprite; import zephyr.objects.Hotspot; import zephyr.objects.primitives.GeodesicSphere; import zephyr.BroadcastEvent; import org.papervision3d.view.stats.StatsView; import zephyr.utils.StringTo; /** * The PanoSalado Class is used to display panoramas in cubic (or equirectangular, cylindrical, or QTVR format). * It is primarily meant to be used in conjunction with ModuleLoader.as, with ModulueLoader loading the XML descriptor file * and then loading the compiled PanoSalado.swf file and any other swfs to be loaded as specified in the XML descriptor. */ public class PanoSalado extends Sprite { /** * Bulkloader class that PanoSalado uses for loading assets (images) */ public var bulkLoader : BulkLoader; // public var ui:Sprite = new Sprite(); /** * Array of objects containing the basic PV3D objects for creating a "space", Scene, Camera, Renderer, etc */ public var spaces:Array = new Array(); /** * primary container for the viewports so that they can be isolated from the rest of the display list for easier access. */ public var viewports:Sprite = new Sprite(); /** * name of the currentSpace as specified in the XML. */ public var currentSpace:String = ""; /** * reference to the last space that was loaded. */ public var lastSpace:String = ""; /** * name of the space that is currently loading if applicable. */ public var loadingSpace:String = ""; /** * reference to the current VideoDisplaySprite. */ public var currentVideo:VideoDisplaySprite; /** * Object containing the string equivalents between XML event listener types and PanoSalado's type names. */ private var interactionEquivalents:Object = { mouseClick:"onClick", mouseOver:"onOver", mouseOut:"onOut", mousePress:"onPress", mouseRelease:"onRelease", mouseMove:"onMouseMove", mouseDown:"onPress", mouseUp:"onRelease", click:"onClick" }; /** * storage for assets that have been loaded before all assets are loaded and claimed. */ private var unclaimedMaterials:Dictionary = new Dictionary(true); /** * flag to control whether or not to render the scene. */ private var _worldDirty:Boolean = false; /** * reference to the XML object containing PanoSalado's XML layer node (layer id="PanoSalado") */ public var settings : XML; // public var loadMeter:Sprite = new Sprite(); /** * objects that need to have their placement changed on stage resize. */ public var resizeDict:Object = new Object(); /** * reference to the ModuleLoader singleton. */ private var moduleLoader:Object; // private var ModuleLoader:Class; // private var BroadcastEvent:Class; /** * junk. */ private var CustomActions:Class; /** * used to track QTVR loading. */ private var qtvrCount:int = 0; /************************************/ /************mstandio****************/ /************************************/ /**modification_start**/ private var cameraMovementState:String = ""; /**modification_end**/ /** * constructor */ public function PanoSalado() { // Workaround for Flex 3 framework bug. // var resourceManagerImpl:Object = // flash.system.ApplicationDomain.currentDomain.getDefinition("mx.resources::ResourceManagerImpl"); // mx.core.Singleton.registerClass("mx.resources::IResourceManager", // Class(resourceManagerImpl)); addEventListener(Event.ADDED_TO_STAGE, stageReady, false, 0, true); //add viewports sprite to display list. It will hold all the viewports so they can be iterated/isolated from other items addChild(viewports); addEventListener(Event.ENTER_FRAME, doRender, false, 0, true); //set up bulk loader bulkLoader = new BulkLoader("panoSaladoBulkLoader"); bulkLoader.addEventListener(BulkProgressEvent.PROGRESS, onAllProgress, false, 0, true); bulkLoader.addEventListener(BulkLoader.COMPLETE, onAllLoaded, false, 99, true); // addChild(ui); // ui.addEventListener(MouseEvent.CLICK, mouseEventHandler, false, 0, true); // ui.addEventListener(MouseEvent.MOUSE_OVER, mouseEventHandler, false, 0, true); // ui.addEventListener(MouseEvent.MOUSE_OUT, mouseEventHandler, false, 0, true); // ui.addEventListener(MouseEvent.MOUSE_DOWN, mouseEventHandler, false, 0, true); // ui.addEventListener(MouseEvent.MOUSE_UP, mouseEventHandler, false, 0, true); // ui.addEventListener(MouseEvent.MOUSE_MOVE, mouseEventHandler, false, 0, true); } /** * stage ready is called when ModuleLoader has added PanoSalado to the stage. * This is where PanoSalado sets stage properties: framerate quality and a resize event. */ public function stageReady(e:Event):void { stage.frameRate = 30; stage.quality = StageQuality.HIGH; stage.addEventListener(Event.RESIZE, onResize, false, 100, true); var doLoadSettings:Boolean = true; if (ApplicationDomain.currentDomain.hasDefinition("ModuleLoader")) { //ModuleLoader = ApplicationDomain.currentDomain.getDefinition("ModuleLoader") as Class; //trace(ModuleLoader); moduleLoader = ModuleLoader.moduleLoader; if (moduleLoader) { moduleLoader.addEventListener(BroadcastEvent.ALL_LAYERS_LOADED, allLayersLoaded, false, 0, true); if ( moduleLoader.xmlByName["PanoSalado"] ) { doLoadSettings = false; settings = moduleLoader.xmlByName["PanoSalado"]; onXMLLoaded(); } } } if ( doLoadSettings ) { var xmlLoader:URLLoader = new URLLoader(); xmlLoader.dataFormat = URLLoaderDataFormat.BINARY; xmlLoader.load( new URLRequest( loaderInfo.parameters.xml?loaderInfo.parameters.xml:"PanoSalado.xml" ) ); xmlLoader.addEventListener(Event.COMPLETE, onXMLLoaded, false, 0, true); } } /** * this should be triggered when ModuleLoader dispatched the allLayersLoaded event. */ private function allLayersLoaded(e:*):void { e = e as BroadcastEvent; if ( ApplicationDomain.currentDomain.hasDefinition("CustomActions") ) CustomActions = ApplicationDomain.currentDomain.getDefinition("CustomActions") as Class; } /** * used by an alternate setup whereby PanoSalado is used standalone and loads its own XML */ private function onXMLLoaded(e:Event=null):void { if (e) settings = XML(e.target.data); if (settings.spaces.@stageQuality.length != 0) { switch(settings.spaces.@stageQuality) { case "low": stage.quality = StageQuality.LOW; break; case "medium": stage.quality = StageQuality.MEDIUM; break; case "high": default: stage.quality = StageQuality.HIGH; break; case "best": stage.quality = StageQuality.BEST; break; } } initCameraController( true, int(settings.spaces.@autorotatorDelay) || 15000 ); refresh(); //onStart code hook, pass second arg false to NOT check for onStart in non-existent current scene node. XMLCodeHook("onStart", false); } /** * refreshes values that should usually only change each time a new space is loaded. * this avoids unnecessary XML access which is slow for frequently consulted vars like camera limits etc. */ private function refresh():void { sensitivity = findValueInXML("cameraSensitivity", Number, 60); friction = findValueInXML("cameraFriction", Number, 0.3); threshold = findValueInXML("cameraRestThreshold", Number, 0.0001); keyIncrement = findValueInXML("cameraKeyIncrement", Number, 75); zoomIncrement = findValueInXML("cameraZoomIncrement", Number, 0.2); maxTilt = findValueInXML("cameraMaximumTilt", Number, 9999); minTilt = findValueInXML("cameraMinimumTilt", Number, 9999); maxPan = findValueInXML("cameraMaximumPan", Number, 9999); minPan = findValueInXML("cameraMinimumPan", Number, 9999); minZoom = findValueInXML("cameraMinimumZoom", Number, 1); maxZoom = findValueInXML("cameraMaximumZoom", Number, 50); dqa = findValueInXML("dynamicQualityAdjustment", Boolean, true) ; accSmooth = findValueInXML("smoothOnAcceleration", Boolean, false ); accPrecise = findValueInXML("preciseOnAcceleration", Boolean, true ); accPrecision = findValueInXML("precisionOnAcceleration", int, 32); decSmooth = findValueInXML("smoothOnDeceleration", Boolean, true ); decPrecise = findValueInXML("preciseOnDeceleration", Boolean, true ); decPrecision = findValueInXML("precisionOnDeceleration", int, 8); stopSmooth = findValueInXML("smoothAtRest", Boolean, true) ; stopPrecise = findValueInXML("preciseAtRest", Boolean, true ); stopPrecision = findValueInXML("precisionAtRest", int, 1); aah = findValueInXML("autorotatorAutoHorizon", Boolean, true); da = findValueInXML("autorotatorIncrement", Number, 0.25); aaz = findValueInXML("autorotatorAutoZoom", Boolean, true); } /** * puts each asset as it has loaded into the unclaimedMaterials dictionary. */ private function onSingleItemLoaded(e:Event):void { var bm:BitmapMaterial = new BitmapMaterial( BitmapData(e.target._content.bitmapData) ); unclaimedMaterials[ e.target.url.url.toString() ] = bm ; } /** * prepares stream materials */ private function onStreamMaterialLoaded(e:Event):void { var vm:VideoPlayerMaterial = e.target.material; unclaimedMaterials[ e.target.source ] = vm; currentVideo = VideoDisplaySprite(e.target); onAllLoaded(); dispatchEvent(new Event("videoLoaded")); } /** * handles PHP QTVR parser script XML output */ private function qtvrXMLLoaded(e:Event):void { qtvrCount -= 1; for each (var mov:XML in findXMLNode(loadingSpace)..mov) { var id:String = e.target.url.url.toString(); if (mov == id ) { var target:XML = mov.parent(); var xml:XML = bulkLoader.getXML(id); if( StringTo.bool(target.@applyCameraSettingsFromThisQTVR) ) { target.parent().@cameraMinimumPan = xml.@cameraMinimumPan; target.parent().@cameraMaximumPan = xml.@cameraMaximumPan; target.parent().@cameraMinimumTilt = xml.@cameraMinimumTilt; target.parent().@cameraMaximumTilt = xml.@cameraMaximumTilt; target.parent().@cameraMinimumZoom = xml.@cameraMinimumZoom; target.parent().@cameraMaximumZoom = xml.@cameraMaximumZoom; target.parent().@cameraPan = xml.@cameraPan; target.parent().@cameraTilt = xml.@cameraTilt; target.parent().@cameraZoom = xml.@cameraZoom; } target.setChildren( xml.children() ); for each (var tile:XML in target.tile) { bulkLoader.add(tile.toString(), { type:"image", weight: (tile.@weight || 10) }); } bulkLoader.start(); } } } /** * bulkLoader's progress handler. dispatches progress events on ModuleLoader. */ private function onAllProgress(e : BulkProgressEvent) : void { //trace("progress event: loaded" , e.bytesLoaded," of ", e.bytesTotal); moduleLoader.dispatchEvent( new BroadcastEvent(BroadcastEvent.LOAD_PROGRESS, { id : bulkLoader.name, percentLoaded : e.weightPercent }) ); } /** * @private */ /************************************/ /************mstandio****************/ /*******autorotation*patch***********/ /************************************/ /**modification_start**/ //private var autorotatorFirstRun:Boolean = false; private var autorotatorFirstRun:Boolean = true; /**modification_end**/ /** * main function that handles setting up a new space */ private function onAllLoaded(e : BulkProgressEvent=null) : void { if ( qtvrCount != 0 ) return; trace("PS: initializing " + currentSpace ); lastSpace = currentSpace; currentSpace = loadingSpace; loadingSpace = ""; dispatchBroadcast(BroadcastEvent.SPACE_LOADED, "spaceLoaded="+currentSpace); refresh(); // create a new space (viewport, scene, and camera) var idx:int = instantiateNewSpace(); var thisSpace:Object = spaces[idx]; //set up viewport setupViewport( thisSpace.viewport ); //set-up camera setupCamera(thisSpace.camera, spaces[idx-1]); //iterate through all the objects in the scene (pano, hotspots, etc) var sceneObjects:XML = findXMLNode(currentSpace); if (sceneObjects) for each (var xml:XML in sceneObjects.children() ) { var nodeName:String = xml.name().localName.toString(); //create papervision primitive by calling the function bearing its name (cube, plane, sphere, etc) if ( hasOwnProperty(nodeName) ) var primitive:Object = this[ nodeName ].call(null, xml); else continue; // if ( nodeName != "stageAlignedSprite" ) // { primitive.name = xml.@id.toString(); //set position and rotation of primitive, using += so that it can be pre adjusted e.g. sphere primitive.x += int(xml.@x) || 0; primitive.y += int(xml.@y) || 0; primitive.z += int(xml.@z) || 0; primitive.rotationX += Number(xml.@rotationX) || 0; primitive.rotationY += Number(xml.@rotationY) || 0; primitive.rotationZ += Number(xml.@rotationZ) || 0; primitive.visible = StringTo.bool(xml.@visible || "true"); primitive.useOwnContainer = StringTo.bool(xml.@useOwnContainer || "false"); if ( primitive.useOwnContainer ) { primitive.alpha = Number(xml.@alpha) || 1 ; primitive.blendMode = xml.@blendMode.toString() || "normal"; //primitive.filters = ; } if ( xml.@onClick.toString() != "" ) { primitive.addEventListener(InteractiveScene3DEvent.OBJECT_CLICK, interactionScene3DEventHandler, false, 0, true); } if ( xml.@onOver.toString() != "" ) { primitive.addEventListener(InteractiveScene3DEvent.OBJECT_OVER, interactionScene3DEventHandler, false, 0, true); } if ( xml.@onOut.toString() != "" ) { primitive.addEventListener(InteractiveScene3DEvent.OBJECT_OUT, interactionScene3DEventHandler, false, 0, true); } if ( xml.@onPress.toString() != "" ) { primitive.addEventListener(InteractiveScene3DEvent.OBJECT_PRESS, interactionScene3DEventHandler, false, 0, true); } if ( xml.@onRelease.toString() != "" ) { primitive.addEventListener(InteractiveScene3DEvent.OBJECT_RELEASE, interactionScene3DEventHandler, false, 0, true); } if ( xml.@onOverMove.toString() != "" ) { primitive.addEventListener(InteractiveScene3DEvent.OBJECT_MOVE, interactionScene3DEventHandler, false, 0, true); } if (StringTo.bool( xml.@useHandCursor || "false") ) { primitive.addEventListener(InteractiveScene3DEvent.OBJECT_OVER, cursorHandler, false, 0, true); primitive.addEventListener(InteractiveScene3DEvent.OBJECT_OUT, cursorHandler, false, 0, true); } if ( xml.@toolTip.toString() != "" ) { primitive.addEventListener(InteractiveScene3DEvent.OBJECT_OVER, tooltipHandler, false, 0, true); primitive.addEventListener(InteractiveScene3DEvent.OBJECT_OUT, tooltipHandler, false, 0, true); } primitive.updateTransform(); thisSpace.scene.addChild( primitive, xml.@id.toString() ); // } // else // { // ui.addChild( StageAlignedSprite(primitive) ); // } } //onResize(); bulkLoader.removeAll(); // add viewport to the displaylist viewports.addChild( thisSpace["viewport"] ); //transitionStart code hook XMLCodeHook("onTransitionStart"); var trans:String = findValueInXML("transition", String, "tween:currentSpace.viewport.alpha from 0 over 1.5 seconds using Expo.easeIn"); // var idxThenDo:int = trans.indexOf("then do "); // // if ( idxThenDo == -1 ) // { // if ( trans.lastIndexOf(";")+1 == trans.length) // trans = trans.substr(0, trans.length-1) + " then do onTransitionEnd"; // else // trans = trans + " then do onTransitionEnd"; // } // else // { // if ( trans.lastIndexOf(";")+1 == trans.length) // trans = trans + " onTransitionEnd"; // else // trans = trans + "; onTransitionEnd"; // } execute( trans ); _worldDirty = true; //code hook XMLCodeHook("onDisplay"); //remove onDisplay so it doesn't trigger again settings.@onDisplay = ""; /************************************/ /************mstandio****************/ /*******autorotation*patch***********/ /************************************/ /**modification_start**/ if (isAutorotating) { isAutorotating = false; dispatchBroadcast(BroadcastEvent.AUTOROTATION_OFF); } /**modification_end**/ ///autorotator if ( findValueInXML("autorotator", Boolean, true)) { _autorotatorOn = true; if (autorotatorFirstRun) restartAutorotatorTimer( findValueInXML("autorotatorDelay", Number, 15000) ); else restartAutorotatorTimer( findValueInXML("autorotatorRestartDelay", Number, 15000) ); } else { _autorotatorOn = false; stopAutorotatorNow(); } } /** * helper function that handles setting up viewport properties with XML values. */ private function setupViewport(viewport:Viewport3D):void { viewport.interactive = findValueInXML("interactive", Boolean, true); viewport.autoScaleToStage = findValueInXML("viewportAutoScaleToStage", Boolean, true ); viewport.autoCulling = findValueInXML("viewportAutoCulling", Boolean, true ); viewport.autoClipping = findValueInXML("viewportAutoClipping", Boolean, true ); viewport.viewportWidth = findValueInXML("viewportWidth", Number, 640 ); viewport.viewportHeight = findValueInXML("viewportHeight", Number, 480 ); viewport.x = findValueInXML("viewportX", Number, 0 ); viewport.y = findValueInXML("viewportY", Number, 0 ); } /** * helper function that handles setting up the camera properties with XML values. */ private function setupCamera(camera:PSCamera3D, lastSpace:Object=null):void { // set up camera: var cameraContinuity:Boolean = findValueInXML("cameraRetainsLastValues", Boolean, false); var pan:Number = findValueInXML("cameraPan", Number, 0 ); var tilt:Number = findValueInXML("cameraTilt", Number, 0); var zoom:Number = findValueInXML("cameraZoom", Number, 12); var focus:Number = findValueInXML("cameraFocus", Number, 100); var camX:Number = findValueInXML("cameraX", Number, 0); var camY:Number = findValueInXML("cameraY", Number, 0); var camZ:Number = findValueInXML("cameraZ", Number, 0); // leash free or default unspecified leashing if (!cameraContinuity) { camera.rotationX = tilt; camera.rotationY = pan; camera.rotationZ = 0; camera.zoom = zoom; camera.focus = focus; camera.x = camX; camera.y = camY; camera.z = camZ; } else { //leash = lock camera.rotationX = lastSpace != null ? lastSpace["camera"].rotationX : tilt ; camera.rotationY = lastSpace != null ? lastSpace["camera"].rotationY : pan ; camera.rotationZ = lastSpace != null ? lastSpace["camera"].rotationZ : 0 ; camera.zoom = lastSpace != null ? lastSpace["camera"].zoom : zoom ; camera.focus = lastSpace != null ? lastSpace["camera"].focus : focus ; camera.x = lastSpace != null ? lastSpace["camera"].x : camX ; camera.y = lastSpace != null ? lastSpace["camera"].y : camY ; camera.z = lastSpace != null ? lastSpace["camera"].z : camZ ; } /************************************/ /************mstandio****************/ /************************************/ /**modification_start**/ dispatchBroadcast(BroadcastEvent.CAMERA_INIT,"pan=" + camera.rotationY, "tilt=" + camera.rotationX, "zoom=" + camera.zoom); /**modification_end**/ } /** * helper function that takes a loaded asset and converts it into a BitmapMaterial for PV3d */ private function createMaterial(xml:XML):* { var returnObject:*; var materials:MaterialsList = new MaterialsList(); if (xml.file != undefined) { // BitmapMaterial var numFileMaterials:int = xml.file.length(); for each (var file:XML in xml.file) { var material:BitmapMaterial = BitmapMaterial(unclaimedMaterials[file.toString()]); applyPropertiesToMaterial(material, xml); if ( numFileMaterials > 1 ) { materials.addMaterial( material, file.@face.toString() ); } } if ( numFileMaterials > 1 ) returnObject = materials; else returnObject = material; } if (xml.stream != undefined) { // VideoStreamMaterial var numStreamMaterials:int = xml.stream.length(); for each (var stream:XML in xml.stream) { var streamMaterial:VideoPlayerMaterial = VideoPlayerMaterial(unclaimedMaterials[stream.toString()]); applyPropertiesToMaterial(streamMaterial, xml); if ( numStreamMaterials > 1 ) { materials.addMaterial( streamMaterial, stream.@face.toString() ); } } if ( numFileMaterials > 1 ) returnObject = materials; else returnObject = streamMaterial; } return returnObject; } /** * helper function that applies properties to material from XML values. */ private function applyPropertiesToMaterial(material:BitmapMaterial, xml:XML):BitmapMaterial { if ( findValueInXML("dynamicQualityAdjustment", Boolean, true) ) { material.smooth = findValueInXML("smoothAtRest", Boolean, true ) ; material.precise = findValueInXML("preciseAtRest", Boolean, true ) ; material.precision = findValueInXML("precisionAtRest", int, 1) ; material.precisionMode = PrecisionMode.STABLE; } else { material.smooth = StringTo.bool( xml.@smooth || "false") ; material.precise = StringTo.bool( xml.@precise || "false") ; material.precision = int( xml.@precision) || 8 ; material.precisionMode = PrecisionMode.STABLE; } material.oneSide = StringTo.bool( xml.@oneSide || "true") ; material.interactive = StringTo.bool( xml.@interactive || "false") ; return material; } /** * creates a sphere. not to be called directly. in the descriptor XML, a 'sphere' node will cause this to be called. */ public function sphere(xml:XML):Object { var material:BitmapMaterial = createMaterial(xml) as BitmapMaterial; //var material:BitmapMaterial = BitmapMaterial(unclaimedMaterials[xml.file.toString()]); var segments:int = int( xml.@segments) || 9 ; var radius:int = int( xml.@radius ) || 50000; var reverse:Boolean = StringTo.bool(xml.@reverse || "true"); var minPan:Number = Number( xml.@minPan ) || 0.0; var panRange:Number = Number( xml.@panRange ) || 360.0; var minTilt:Number = Number( xml.@minTilt ) || -90.0; var tiltRange:Number = Number( xml.@tiltRange ) || 180.0; var sphere:Sphere = new Sphere(material, radius, segments, segments, reverse, minPan, panRange, minTilt, tiltRange ); sphere.rotationY = 90 - 360/segments; return sphere; } /** * creates a geosphere. not to be called directly. in the descriptor XML, a 'geodesicSphere' node will cause this to be called. */ public function geodesicSphere(xml:XML):Object { var material:BitmapMaterial = createMaterial(xml) as BitmapMaterial; //var material:BitmapMaterial = BitmapMaterial(unclaimedMaterials[xml.file.toString()]); var segments:int = int( xml.@segments) || 40 ; var radius:int = int( xml.@radius ) || 50000; var reverse:Boolean = StringTo.bool(xml.@reverse || "true"); //GeodesicSphere( material:MaterialObject3D=null, radius:Number=100, fractures:int=2, initObject:Object=null ) var geoSphere:GeodesicSphere = new GeodesicSphere(material, radius, segments, true ); geoSphere.rotationY = 90; return geoSphere; } /** * creates a cylinder. not to be called directly. in the descriptor XML, a 'cylinder' node will cause this to be called. */ public function cylinder(xml:XML):Cylinder { //Cylinder( material:MaterialObject3D=null, radius:Number=100, height:Number=100, segmentsW:int=8, segmentsH:int=6, topRadius:Number=-1, topFace:Boolean=true, bottomFace:Boolean=true ) var bmd:BitmapData = bulkLoader.getBitmapData(xml.file.toString(), false); /// THIS MAY NEED ADJUSTING var height:Number = (bmd.height/bmd.width)*50000*2*Math.PI; var material:BitmapMaterial = createMaterial(xml) as BitmapMaterial; var segments:int = int( xml.@segments) || 30 ; var radius:int = int( xml.@radius ) || 50000; var reverse:Boolean = StringTo.bool(xml.@reverse || "true"); var cyl:Cylinder = new Cylinder(material, radius, height, segments, segments, -1, false, false, reverse ); //var cyl:Cylinder = new Cylinder(material, radius, height, segments, segments, -1, false, false, reverse ); /// THIS MAY NEED ADJUSTING cyl.rotationY = -50; cyl.rotationZ = 0; if ( StringTo.bool(xml.@autoFOV) ) { var mt:Number = Math.atan( (height*0.5)/50000) * 180/Math.PI; minTilt = -mt; maxTilt = mt; } return cyl; } /** * creates a cube. not to be called directly. in the descriptor XML, a 'cube' node will cause this to be called. */ public function cube(xml:XML):Cube { var materials:MaterialsList = createMaterial(xml) as MaterialsList; var insideFaces : int; if ( ! StringTo.bool(xml.@reverse) ) insideFaces = Cube.ALL; else insideFaces = Cube.NONE; var excludeFaces :int = Cube.NONE; var segments:int = int( xml.@segments) || 9 ; var width:int = int( xml.@width ) || 100000 ; var normalCube:Cube = new Cube( materials, width, width, width, segments, segments, segments, insideFaces, excludeFaces ); return normalCube; } /** * creates a hotspot. not to be called directly. in the descriptor XML, a 'hotspot' node will cause this to be called. * note that a hotspot is only a special Plane which points toward the origin (where the camera is unless you move it). */ public function hotspot(xml:XML):Hotspot { var fileName:String = xml.file.toString(); if (fileName.search( /\.swf$/ ) == -1) return bitmapHotspot(xml); else return movieHotspot(xml); } /** * creates a bitmap hotspot. Will be called by hotspot if the asset url does not end with '.swf'. it can be used directly with a bitmapHotspot node in the XML * */ public function bitmapHotspot(xml:XML):Hotspot { var bmd:BitmapData = bulkLoader.getBitmapData(xml.file.toString(), false); var width:Number = bmd.width * 40; var height:Number = bmd.height * 40; width = int( xml.@width) * 40 || width ; height = int( xml.@height) * 40 || height ; var material:BitmapMaterial = createMaterial(xml) as BitmapMaterial; material.interactive = StringTo.bool( xml.@interactive) || true ; var segments:int = int( xml.@segments) || 3 ; var pan:Number = Number( xml.@pan) || 0 ; var tilt:Number = Number( xml.@tilt) || 0 ; var hs:Hotspot = new Hotspot(pan, tilt, material, width, height, segments, segments ); return hs; } /** * creates a movie hotsport. Will be called automatically by hotspot if the asset url ends in '.swf'. It can be called directly with a movieHotspot node in the XML. */ public function movieHotspot(xml:XML):Hotspot { var mc:MovieClip = bulkLoader.getMovieClip(xml.file.toString(), false); var width:Number = mc.width * 40; var height:Number = mc.height * 40; width = int( xml.@width) * 40 || width ; height = int( xml.@height) * 40 || height ; var material:MovieMaterial = new MovieMaterial(mc, true); material.interactive = StringTo.bool( xml.@interactive) || true ; material.animated = StringTo.bool( xml.@animated) || true ; var segments:int = int( xml.@segments) || 3 ; var pan:Number = Number( xml.@pan) || 0 ; var tilt:Number = Number( xml.@tilt) || 0 ; var hs:Hotspot = new Hotspot(pan, tilt, material, width, height, segments, segments ); return hs; } /** * creates a plane. not to be called directly. in the descriptor XML, a 'plane' node will cause this to be called. */ public function plane(xml:XML):Plane { var width:Number = int( xml.@width) || 100 ; var height:Number = int( xml.@height) || 100 ; var material:MaterialObject3D = createMaterial(xml) as MaterialObject3D; var segments:int = int( xml.@segments) || 3 ; var plane:Plane = new Plane( material, width, height, segments, segments ); return plane; } /** * creates a qtvr. not to be called directly. in the descriptor XML, a 'qtvr' node will cause this to be called. */ public function qtvr(xml:XML):Cube { var q:Cube = tiledCube(xml); return q; } /** * helper function for tiled QTVRs */ private function tiledCube(xml:XML):Cube { var bitmapDatasCreated:Boolean = false; var bmd:BitmapData; for each (var singleTile:XML in xml.tile) { bmd = bulkLoader.getBitmapData(singleTile.toString(), true) as BitmapData; var w:Number = bmd.width; var h:Number = bmd.height; if ( ! bitmapDatasCreated) { var wTotal:Number = bmd.width * Math.sqrt( int( xml.tile.(@face == "front").length() ) ) var hTotal:Number = bmd.height * Math.sqrt( int( xml.tile.(@face == "front").length() ) ) var ft:BitmapData = new BitmapData(wTotal, hTotal, false, 0xFF0000); var lt:BitmapData = new BitmapData(wTotal, hTotal, false, 0x00FF00); var rt:BitmapData = new BitmapData(wTotal, hTotal, false, 0x0000FF); var bk:BitmapData = new BitmapData(wTotal, hTotal, false, 0x888888); var up:BitmapData = new BitmapData(wTotal, hTotal, false, 0xFFFFFF); var dn:BitmapData = new BitmapData(wTotal, hTotal, false, 0x000000); bitmapDatasCreated = true; } var rect:Rectangle = new Rectangle(0,0,w,h); var pt:Point = new Point(w * int(singleTile.@x_offset), h * int(singleTile.@y_offset)); switch( singleTile.@face.toString() ) { case "front": ft.copyPixels(bmd,rect,pt); break; case "left": lt.copyPixels(bmd,rect,pt); break; case "right": rt.copyPixels(bmd,rect,pt); break; case "back": bk.copyPixels(bmd,rect,pt); break; case "up": up.copyPixels(bmd,rect,pt); break; case "down": dn.copyPixels(bmd,rect,pt); break; default: trace("invalid face value in " + xml.@id+ ", tile: "+ singleTile ); } } bmd.dispose(); var matsArray:Array = new Array(); matsArray.push( { id:"front", material:new BitmapMaterial(ft) } ); matsArray.push( { id:"left", material:new BitmapMaterial(lt) } ); matsArray.push( { id:"right", material:new BitmapMaterial(rt) } ); matsArray.push( { id:"back", material:new BitmapMaterial(bk) } ); matsArray.push( { id:"top", material:new BitmapMaterial(up) } ); matsArray.push( { id:"bottom", material:new BitmapMaterial(dn) } ); var materials:MaterialsList = new MaterialsList(); for each (var o:Object in matsArray) { if ( findValueInXML("dynamicQualityAdjustment", Boolean, true) ) { o.material.smooth = findValueInXML("smoothAtRest", Boolean, true ) ; o.material.precise = findValueInXML("preciseAtRest", Boolean, true ) ; o.material.precision = findValueInXML("precisionAtRest", int, 1) ; } else { o.material.smooth = StringTo.bool( xml.@smooth || "false") ; o.material.precise = StringTo.bool( xml.@precise || "false") ; o.material.precision = int( xml.@precision) || 8 ; } o.material.oneSide = StringTo.bool( xml.@oneSide || "true") ; o.material.interactive = StringTo.bool( xml.@interactive || "false") ; materials.addMaterial( o.material, o.id ); } var insideFaces : int; if ( ! StringTo.bool(xml.@reverse) ) insideFaces = Cube.ALL; else insideFaces = Cube.NONE; var excludeFaces :int = Cube.NONE; var segments:int = int( xml.@segments) || 9 ; var width:int = int( xml.@width ) || 100000 ; var cube:Cube = new Cube( materials, width, width, width, segments, segments, segments, insideFaces, excludeFaces ); return cube; } // private function stageAlignedSprite(xml:XML):StageAlignedSprite // { // var bm:BitmapData = bulkLoader.getBitmapData(xml.file.toString(), true); // // var sp:StageAlignedSprite = new StageAlignedSprite(); // // sp.graphics.beginBitmapFill(bm, null, false, false); // // sp.graphics.drawRect(0,0,bm.width,bm.height); // // sp.graphics.endFill(); // // sp.scaleX = Number(xml.@scaleX) || 1; // // sp.scaleY = Number(xml.@scaleY) || 1; // // sp.rotation = Number(xml.@rotation) || 0; // // sp.alpha = Number(xml.@alpha) || 1; // // sp.visible = StringTo.bool(xml.@visible || "true"); // // sp.cacheAsBitmap = StringTo.bool(xml.@cacheAsBitmap || "false"); // // sp.blendMode = String(xml.@blendMode) || "normal"; // // sp.name = String(xml.@id) || ""; // // sp.alignment = String(xml.@align) || "tl"; // // sp.offsetX = Number(xml.@offsetX) || 0; // // sp.offsetY = Number(xml.@offsetY) || 0; // //sp.align(); // return sp; // } protected var dqa:Boolean, accSmooth:Boolean, accPrecise:Boolean, accPrecision:int, decSmooth:Boolean, decPrecise:Boolean, decPrecision:int, stopSmooth:Boolean, stopPrecise:Boolean, stopPrecision:int; /** * handles changing the quality settings on the rendering based on mouse camera movement: accelerating, decelerating, stopped. */ private function changeQuality(type:String):void { /* change precise, smooth, and precision while moving camera for better fps loops through all the scenes in all the spaces, getting all the objects from each, and then pushing either the materials from the materialsList, or the material into an array, and then applies the changes to each item in the array. */ /************************************/ /************mstandio****************/ /************************************/ /**modification_start**/ this.cameraMovementState = type; /**modification_end**/ if ( dqa ) { var allmats:Array = getAllMaterials(); var bmToChange:BitmapMaterial, matToChange:MaterialObject3D; while ( matToChange = allmats.pop() ) { bmToChange = BitmapMaterial(matToChange); if (type == "accelerating") { bmToChange.smooth = accSmooth; bmToChange.precise = accPrecise; bmToChange.precision = accPrecision; } else if (type == "decelerating") { bmToChange.smooth = decSmooth; bmToChange.precise = decPrecise; bmToChange.precision = decPrecision; } else if (type == "resting") { bmToChange.smooth = stopSmooth; bmToChange.precise = stopPrecise; bmToChange.precision = stopPrecision; } } } //_worldDirty is set when camera or objects in scene have changed and need rendering. _worldDirty = true; } /** * gets all the materials used in a scene * @return Array */ private function getAllMaterials():Array { var matsToChange:Array = new Array(), matToChange:MaterialObject3D, objsToChange:Array, numObjsToChange:int, objToChange:DisplayObject3D; for (var i:int = 0; i < spaces.length; i++) { objsToChange = spaces[i].scene.objects as Array; numObjsToChange = objsToChange.length; for ( var j:int=0; j < numObjsToChange; j++ ) { objToChange = DisplayObject3D(objsToChange[ j ]); if (objToChange.materials) {/// obj.materials is the materialsList, if it is not null add them for each( matToChange in objToChange.materials.materialsByName ) { matsToChange.push(matToChange); } } else {// obj.material is the material, add it matsToChange.push( objToChange.material ); } } } return matsToChange; } protected var dp:Number, dt:Number, maxTilt:Number, minTilt:Number, maxPan:Number, minPan:Number, cam:PSCamera3D, newTilt:Number, newPan:Number, maxZoom:Number, minZoom:Number; /** * turns or zooms the camera the specified relative amount * @param delta pan * @param delta tilt * @param delta zoom */ private function moveCamera(dp:Number, dt:Number, dz:Number):void { dt *= -1; for (var i:int=0; i < spaces.length; i++) { var cam:PSCamera3D = PSCamera3D(spaces[i]["camera"]); if (maxTilt == 9999) maxTilt = 90 + cam.vfov*0.5; if (minTilt == 9999) minTilt = -90 - cam.vfov*0.5; if (dt >= 0) { newTilt = cam.rotationX + dt + cam.vfov*0.5; if (newTilt <= maxTilt) cam.rotationX += dt; } else { newTilt = cam.rotationX + dt - cam.vfov*0.5; if (newTilt >= minTilt) cam.rotationX += dt; } if (dp >= 0) { if (maxPan == 9999) { cam.rotationY += dp; } else { newPan = cam.rotationY + dp + cam.hfov*0.5; if (newPan <= maxPan) cam.rotationY += dp; } } else { if (minPan == 9999) { cam.rotationY += dp; } else { newPan = cam.rotationY + dp - cam.hfov*0.5; if (newPan >= minPan) cam.rotationY += dp; } } //zoom cam.zoom += dz; if (cam.zoom < minZoom) { cam.zoom = minZoom } if (cam.zoom > maxZoom) { cam.zoom = maxZoom } /************************************/ /************mstandio****************/ /************************************/ /**modification_start**/ if (dz != 0){ dispatchBroadcast(BroadcastEvent.CAMERA_ZOOM, "zoom=" + cam.zoom); } /**modification_end**/ } //_worldDirty is set when camera or objects in scene have changed and need rendering. _worldDirty = true; } protected var da:Number; // deltaAutorotate protected var aah:Boolean; protected var aaz:Boolean; /** * handles autorotating the camera */ private function autorotate():void { //da = findValueInXML("autorotatorIncrement", Number, 0.25); for (var i:int=0; i < spaces.length; i++) { var cam:PSCamera3D = PSCamera3D(spaces[i].camera); if (aah) { if (da > 0) { if (cam.rotationX > da ) { cam.rotationX -= da; } else if (cam.rotationX < -da ) { cam.rotationX += da; } } else { if (cam.rotationX < da ) { cam.rotationX -= da; } else if (cam.rotationX > -da ) { cam.rotationX += da; } } } cam.rotationY += da; if(aaz) { var zoom:Number = findValueInXML("cameraZoom", Number, 12); /************************************/ /************mstandio****************/ /************************************/ /**modification_start**/ if (cam.zoom != zoom){ dispatchBroadcast(BroadcastEvent.CAMERA_ZOOM, "zoom=" + cam.zoom); } /**modification_end**/ if (cam.zoom < zoom) { cam.zoom += zoomIncrement; if (cam.zoom > zoom) cam.zoom = zoom; } if (cam.zoom > zoom) { cam.zoom -= zoomIncrement; if (cam.zoom < zoom) cam.zoom = zoom; } } } _worldDirty = true; } /** * resize handler */ private function onResize(e:Event):void { _worldDirty = true; } /** * main render loop. will only render if the worldDirty has been set, or if there are any objects on the animated layer that need continuous re-rendering. */ private function doRender(e:Event=null):void { /* Check if any of the camera control flags are set and if so move the camera */ if (mouseIsDown || keyIsDown) { if (keyIsDown) { if ( up ) { startPoint.x = stage.mouseX, startPoint.y = stage.mouseY + keyIncrement ; } if ( down ) { startPoint.x = stage.mouseX, startPoint.y = stage.mouseY - keyIncrement ; } if ( left) { startPoint.x = stage.mouseX + keyIncrement, startPoint.y = stage.mouseY ; } if ( right ) { startPoint.x = stage.mouseX - keyIncrement, startPoint.y = stage.mouseY ; } if ( zoomin ) { moveCamera(0, 0, zoomIncrement); resting = false; } if ( zoomout ) { moveCamera(0, 0, -zoomIncrement); resting = false; } } if (mouseIsDown || up || down || left || right) { // calculate new position changes deltaPan = (deltaPan - (((startPoint.x - stage.mouseX) * sensitivity) * 0.00006)); deltaTilt = (deltaTilt + (((startPoint.y - stage.mouseY) * sensitivity) * 0.00006)); } } /************************************/ /************mstandio****************/ /************************************/ /**modification_start**/ if (!resting || isAutorotating) { dispatchBroadcast(BroadcastEvent.CAMERA_SPIN, "spin=" + getCameraRotation(), "movementState=" + this.cameraMovementState); if(this.cameraMovementState == "autorotating") this.cameraMovementState = "decelerating"; // ugly patch ugh } /**modification_end**/ // motion is still over the threshold, so apply friction /************************************/ /************mstandio****************/ /*******autorotation*patch***********/ /************************************/ /**modification_start**/ //if ( ( (deltaPan * deltaPan) + (deltaTilt * deltaTilt) ) > threshold ) if (( ( (deltaPan * deltaPan) + (deltaTilt * deltaTilt) ) > threshold ) || isAutorotating) /**modification_end**/ { // always apply friction so that motion slows AFTER mouse is up deltaPan = (deltaPan * (1 - friction) ); deltaTilt = (deltaTilt * (1 - friction) ); moveCamera( deltaPan, deltaTilt, 0); resting = false; } else { // motion is under threshold stop camera motion if ( !mouseIsDown && !keyIsDown && !resting) { // motion is under threshold, stop and remove enter frame listener deltaPan = 0; deltaTilt = 0; moveCamera(deltaPan, deltaTilt, 0) changeQuality("resting"); /************************************/ /************mstandio****************/ /*******autorotation*patch***********/ /************************************/ /**modification_start**/ //if (_autorotatorOn){ if (_autorotatorOn && !autorotatorFirstRun){ /**modification_end**/ restartAutorotatorTimer( findValueInXML("autorotatorRestartDelay", Number, 15000) ); } resting = true; } } if (isAutorotating) autorotate(); var i:int; // check if anything has set the _worldDirty flag and if so render if ( _worldDirty ) { for (i = 0; i < spaces.length; i++) { PSRenderEngine(spaces[i].renderer).renderScene ( Scene3D(spaces[i].scene), PSCamera3D(spaces[i].camera), Viewport3D(spaces[i].viewport) ); } _worldDirty = false; } else { // check if there are any animated materials that need continuous rendering. var animatedLayer:ViewportLayer; var animatedLayerCreated:Boolean = false; for (i = 0; i < spaces.length; i++) { var staticLayer:ViewportBaseLayer = spaces[i].viewport.containerSprite; var allObjects:Array = spaces[i].scene.objects as Array; var numObjects:int = allObjects.length; var allMaterials:Array = new Array(); for ( var j:int=0; j < numObjects; j++ ) { var object:DisplayObject3D = DisplayObject3D( allObjects[ j ] ); var material:MaterialObject3D; if (object.materials) {/// obj.materials is the materialsList for each( material in object.materials.materialsByName ) { if ( material is MovieMaterial && (material as MovieMaterial).animated ) { // put do3d in animated continuously rendering animatedLayer if ( ! animatedLayerCreated ) { animatedLayer = spaces[i].viewport.getChildLayer( object, true, false ); animatedLayerCreated = true; } else { animatedLayer.addDisplayObject3D( object, false); } if ( staticLayer.hasDisplayObject3D(object) ) { staticLayer.removeDisplayObject3D( object ); } } else { // put do3d in static layer which only renders with user input (camera motion) staticLayer.addDisplayObject3D( object, false); if (animatedLayer) { if ( animatedLayer.hasDisplayObject3D(object) ) { animatedLayer.removeDisplayObject3D( object ); } } } // break out of materials list loop break; } } else {// obj.material is the material material = object.material; if ( material is MovieMaterial && (material as MovieMaterial).animated ) { // put do3d in animated continuously rendering animatedLayer if ( ! animatedLayerCreated ) { animatedLayer = spaces[i].viewport.getChildLayer( object, true, false ); animatedLayerCreated = true; } else { animatedLayer.addDisplayObject3D( object, false); } if ( staticLayer.hasDisplayObject3D(object) ) { staticLayer.removeDisplayObject3D( object ); } } else { // put do3d in static layer which only renders with user input (camera motion) staticLayer.addDisplayObject3D( object, false); if (animatedLayer) { if ( animatedLayer.hasDisplayObject3D(object) ) { animatedLayer.removeDisplayObject3D( object ); } } } } } } if ( animatedLayer ) { // render the animated layer. for (i = 0; i < spaces.length; i++) { PSRenderEngine(spaces[i].renderer).renderLayers ( Scene3D(spaces[i].scene), PSCamera3D(spaces[i].camera), Viewport3D(spaces[i].viewport), [ animatedLayer ] ); } } // end else render animated objects } } /** * main interactiveScene3DEvent handler for all PV3D 'display objects'. action executed is set in the descriptor XML. */ private function interactionScene3DEventHandler(e:InteractiveScene3DEvent=null):void { var name:String = e.target.name; trace("PS:" + name + "." + interactionEquivalents[e.type] ); execute( settings..*.(hasOwnProperty("@id") && @id == name).attribute( interactionEquivalents[e.type] ).toSt…

Large files files are truncated, but you can click here to view the full file