package { import com.thirdavedesign.utils.StatsView; import flash.display.*; import flash.events.Event; import flash.events.MouseEvent; import flash.events.ProgressEvent; import flash.geom.Point; import flash.text.TextField; import flash.text.TextFormat; import fr.seraf.wow.constraint.WSpringConstraint; import fr.seraf.wow.core.WOWEngine; import fr.seraf.wow.core.data.WVector; import fr.seraf.wow.primitive.WParticle; import org.papervision3d.cameras.Camera3D; import org.papervision3d.core.geom.renderables.Vertex3D; import org.papervision3d.core.proto.LightObject3D; import org.papervision3d.events.FileLoadEvent; import org.papervision3d.events.InteractiveScene3DEvent; import org.papervision3d.materials.BitmapFileMaterial; import org.papervision3d.materials.shadematerials.FlatShadeMaterial; import org.papervision3d.objects.DisplayObject3D; import org.papervision3d.objects.primitives.Plane; import org.papervision3d.render.BasicRenderEngine; import org.papervision3d.scenes.Scene3D; import org.papervision3d.view.Viewport3D; public class wowDraggable extends Sprite { //pv3d vars private var viewport:Viewport3D; private var camera:Camera3D; private var scene:Scene3D; private var renderer:BasicRenderEngine; private var p:Plane; private var universe:DisplayObject3D; private var rugBitmap:BitmapFileMaterial; private var pVerts:Array; private var vertexDragged:Vertex3D; //wow vars private var wowEngine:WOWEngine; private var wowParticles:Array; private var beingDragged:Boolean = false; private var fixedVerts:Array = new Array(); private var tf:TextField; private var segW:int = 8; private var segH:int = 4; private var i:int; public function wowDraggable():void { stage.frameRate = 31; stage.scaleMode = "noScale"; stage.align = "TOP_LEFT"; stage.quality = "LOW"; init(); } private function init():void { addStats(); loadRug(); } private function loadRug():void { rugBitmap = new BitmapFileMaterial("assets/rug.jpg"); rugBitmap.doubleSided = true; rugBitmap.precise = true; rugBitmap.interactive = true; rugBitmap.addEventListener(FileLoadEvent.LOAD_COMPLETE, handleRugComplete); } private function handleRugProgress(event:ProgressEvent):void { trace("rug is "+Math.floor(event.target.bytesLoaded/event.target.bytesTotal*100)); } private function handleRugComplete(event:Event):void { setUpPapervision(); tf.text = "click a part of the cloth to drag it around. the upper right hand corner will remain fixed"; } private function addStats():void { var stats:StatsView = new StatsView(); this.addChild(stats); tf = new TextField(); tf.width = 500; var tFormat:TextFormat = new TextFormat("Arial", 12, 0xffffff, false, false, false); tf.defaultTextFormat = tFormat; tf.text = "please wait for the cloth to load"; tf.x = 200; tf.y = 50; this.addChild(tf); } private function setUpPapervision():void { viewport = new Viewport3D(stage.stageWidth, stage.stageHeight, false, true); viewport.containerSprite.buttonMode = true; this.addChild(viewport); camera = new Camera3D(); camera.z = -100; camera.x = 0; camera.zoom = 3; scene = new Scene3D(); renderer = new BasicRenderEngine(); //create the bitmap plane p = new Plane(rugBitmap, 200, 100, segW, segH); p.addEventListener(InteractiveScene3DEvent.OBJECT_PRESS, handlePlaneDown); pVerts = p.geometry.vertices; scene.addChild(p); setUpWow(); } private function setUpWow():void { //set up wow engine wowEngine = new WOWEngine(.3); //add gravity wowEngine.addMasslessForce(new WVector(0, 30, 0)); //create array for particles wowParticles = new Array(); //create the wow particles; for(i = 0; i< pVerts.length; i++) { var wp:WParticle = new WParticle(pVerts[i].x, -pVerts[i].y, pVerts[i].z, false, 10); wp.elasticity = 0; wp.friction = 0; wowEngine.addParticle(wp); wowParticles.push(wp); } wowParticles.reverse(); //make the top left and right corners fixed; wowParticles[0].fixed = true; fixedVerts.push(wowParticles[0]); wowParticles[(segH+1)*segW].fixed = true; fixedVerts.push(wowParticles[(segH+1)*segW]); for(i = 0; i(segH+1)) wowEngine.addConstraint(new WSpringConstraint(wowParticles[i], wowParticles[i-segH-1], .8)); // for every particle that is not on the bottom edge // add a constraint between it and the particle below it //put in a different way: // if it is on the bottom edge... //or, mathematically- if((i+1)%(segH+1) == 0) trace("don't add constraint"+i); //then don't add a constraint //but if it is.. // you'd better add that constraint to the particle below it else wowEngine.addConstraint(new WSpringConstraint(wowParticles[i], wowParticles[i+1], .8)); // same for the top if(i % (segH+1) == 0) trace("dont add contstraint"); else wowEngine.addConstraint(new WSpringConstraint(wowParticles[i], wowParticles[i-1], .8)); } // start rendering this scene. addEventListener(Event.ENTER_FRAME, handleFrame); this.stage.addEventListener(MouseEvent.MOUSE_UP, handleRelease); } private function handlePlaneDown(event:InteractiveScene3DEvent):void { //remove handleDown listener p.removeEventListener(InteractiveScene3DEvent.OBJECT_PRESS, handlePlaneDown); // toggle fixed vertices for(i = 1; i