package com.dare.labs.physics3d.core { import flash.events.TimerEvent; import org.papervision3d.objects.DisplayObject3D; import org.papervision3d.materials.WireframeMaterial; import org.papervision3d.view.BasicView; import flash.events.Event; import org.papervision3d.objects.primitives.Cube; import org.papervision3d.materials.utils.MaterialsList; import org.papervision3d.objects.primitives.Sphere; import org.papervision3d.core.proto.CameraObject3D; import org.papervision3d.core.proto.SceneObject3D; import fr.seraf.wow.core.WOWEngine; import fr.seraf.wow.core.data.WVector; import fr.seraf.wow.primitive.WSphere; import fr.seraf.wow.primitive.WBoundArea; import fr.seraf.wow.primitive.WParticle; import flash.utils.Timer; /** * @author wijnand.warren */ public class Main extends BasicView { private var wow:WOWEngine; private var resetTimer:Timer; private static const BOUND_SIDE:int = 1000; /** * CONSTRUCTOR */ public function Main(viewportWidth : Number = 640, viewportHeight : Number = 480, scaleToStage : Boolean = true, interactive : Boolean = false, cameraType : String = "Target") { super(viewportWidth, viewportHeight, scaleToStage, interactive, cameraType); init(); } // ============================ // PRIVATE // ============================ /** * */ private function init():void { // create the worlds create3DWorld(); createPhysicsWorldFrom3D(); // start rendering startRendering(); // auto reset resetTimer = new Timer(6000); resetTimer.addEventListener(TimerEvent.TIMER, resetHandler); resetTimer.start(); } /** * Creates the 3D world */ private function create3DWorld() : void { trace("Main.create3DWorld()"); var mat : WireframeMaterial = new WireframeMaterial(0x00ff00); var obj3D : DisplayObject3D; obj3D = new Cube( new MaterialsList( {all: mat} ), BOUND_SIDE, BOUND_SIDE, BOUND_SIDE ); obj3D.name = "bound_worldBounds"; scene.addChild(obj3D); for(var i:int = 0; i < 20; i++) { obj3D = new Sphere(mat, 50); obj3D.name = "sphere_" + i; // make sure all spheres are located within the bounding box? /*obj3D.x = 500 / i - 250; obj3D.y = 150; obj3D.z = 250 / i - 50;*/ //obj3D.z = -40 * i + BOUND_SIDE * 0.5; obj3D.x = Math.random() * 1000 - 500; obj3D.z = Math.random() * 1000 - 500; obj3D.y = Math.random() * 500 - 450; trace("obj3D: " + obj3D.x + ", " + obj3D.y + ", " + obj3D.z); scene.addChild(obj3D); } camera.x = camera.y = 1000; camera.z = -2000; camera.zoom = 80; trace("Camera pos: " + camera.x + ", " + camera.y + ", " + camera.z ); trace("Camera zoom: " + camera.zoom); } /** * Creates the physics world based on an existing 3D world */ private function createPhysicsWorldFrom3D() : void { trace("Main.createPhysicsWorldFrom3D()"); // init physics wow = new WOWEngine(); wow.collisionResponseMode = wow.SELECTIVE; wow.addMasslessForce(new WVector(0, 9.8, 0)); // find all 3D object and create an object in the physics world. var sphere:WSphere; for each ( var obj3D:DisplayObject3D in scene.objects ) { trace(obj3D.name); // TODO: replace with switch if(obj3D.name.indexOf("bound") > -1){ var bound:WBoundArea = new WBoundArea(BOUND_SIDE, BOUND_SIDE, BOUND_SIDE); bound.setPosition(obj3D.x, obj3D.y, obj3D.z); bound.elasticity = 0.1; bound.friction = 0.05; bound.name = obj3D.name; wow.setBoundArea(bound); trace("- added bounding box"); } else if(obj3D.name.indexOf("sphere") > -1) { sphere = new WSphere(obj3D.x, obj3D.y, obj3D.z, 50, false); sphere.name = obj3D.name; sphere.elasticity = 0.5; wow.addParticle(sphere); trace("- added sphere: " + obj3D.name); } } } /** * Resets the sphere positions */ function resetSpheres():void { trace("Main.resetSpheres()"); for each ( var pObj:WParticle in wow.getAllParticles() ) { if( pObj != null && pObj.name != null ) { if( pObj.name.indexOf("sphere") > -1 ) { //trace("pObj.name: " + pObj.name); pObj.px = Math.random() * 1000 - 500; pObj.py = Math.random() * 1000 - 500; pObj.pz = Math.random() * 500 - 450; trace("pObj: " + pObj.px + ", " + pObj.py + ", " + pObj.pz); } } } } // ============================ // OVERRRIDES // ============================ override protected function onRenderTick(event:Event = null):void { //trace("Main.onRenderTick(event)"); // update physics wow.step(); // sync 3d world with physics var obj3D:DisplayObject3D; for each ( var pObj:WParticle in wow.getAllParticles() ) { obj3D = scene.getChildByName(pObj.name); if(obj3D != null) { obj3D.x = pObj.px; obj3D.y = -pObj.py; obj3D.z = pObj.pz; //trace("pObj: " + pObj.px + ", " + pObj.py + ", " + pObj.pz); } } // update graphics super.onRenderTick(event); } // ============================ // EVENT HANDLERS // ============================ /** * Called every 6 seconds by the reset timer. */ private function resetHandler(e:TimerEvent) : void { resetSpheres(); } } }