package { import Box2D.Collision.*; import Box2D.Collision.Shapes.*; import Box2D.Common.*; import Box2D.Common.Math.*; import Box2D.Dynamics.*; import Box2D.Dynamics.Contacts.*; import Box2D.Dynamics.Joints.*; import flash.display.*; import flash.events.Event; import flash.events.MouseEvent; import org.papervision3d.core.data.UserData; import org.papervision3d.core.proto.MaterialObject3D; import org.papervision3d.events.InteractiveScene3DEvent; import org.papervision3d.lights.PointLight3D; import org.papervision3d.materials.*; import org.papervision3d.materials.shadematerials.FlatShadeMaterial; import org.papervision3d.materials.utils.MaterialsList; import org.papervision3d.objects.DisplayObject3D; import org.papervision3d.objects.primitives.*; import org.papervision3d.view.*; public class BlocksTest05 extends BasicView { // block public var BOX_W:Number = 19 / 3 * 2 * 3 public var BOX_H:Number = 19 / 5 * 2 * 3 public var COLORS:Array = [ 0xcc0000, // red 0x0066a7, // blue 0x006822, // green 0x02b535, // light green 0xfbe419] // yellow public var blocks:Array = [] public var plane_for_drug:Plane // papervision public var light:PointLight3D // box2d public var m_world:b2World; public var m_mouseJoint:b2MouseJoint; public var m_iterations:int = 10; public var m_timeStep:Number = 1/30; public var m_physScale:Number = 30; public function BlocksTest05() { viewport.interactive = true stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; stage.frameRate = 30; // event addEventListener(Event.ENTER_FRAME, update, false, 0, true); stage.addEventListener(MouseEvent.MOUSE_MOVE, change_camera_position); stage.addEventListener(MouseEvent.MOUSE_UP, released); init_papervision(); init_box2d() init_blocks() } public function init_papervision():void{ light = new PointLight3D() light.z = 600; light.x = -700; light.y = 800; camera.y = 100 camera.focus = 1000 var material_for_drug:MaterialObject3D = new WireframeMaterial() material_for_drug.interactive = true plane_for_drug = new Plane(material_for_drug, 300, 300, 10, 10) plane_for_drug.visible = false scene.addChild(plane_for_drug) plane_for_drug.addEventListener(MouseEvent.MOUSE_MOVE, moved); } public function init_box2d():void { var worldAABB:b2AABB = new b2AABB(); worldAABB.lowerBound.Set(-1000.0, -1000.0); worldAABB.upperBound.Set(1000.0, 1000.0); // Construct a world object m_world = new b2World(worldAABB, new b2Vec2(0.0, 10.0), true); } public function init_blocks():void{ var base_material:MaterialObject3D = new FlatShadeMaterial(light, 0xffffff, 0x808080) var base:Cube = create_box(base_material, 500, 20, 0, 0, 0, 2.0, false, 10, 1, 10, function():void {}, function():void {}) blocks.push(base) scene.addChild(base) for (var j:int = 0; j < 5; j++) { for (var i:int = 0; i < 5; i++) { var color:Number = COLORS[Math.floor(Math.random() * 5)] var material:MaterialObject3D = new FlatShadeMaterial(light, 0xffffff, color) material.interactive = true var block:Cube = create_box(material, BOX_W, BOX_H, BOX_W * 2 * (j - 2), -( BOX_H * 3 * (i + 2)), b2Math.b2RandomRange(-Math.PI, Math.PI), 2.0, true, 1, 1, 1, pressed, moved) blocks.push(block) scene.addChild(block) } } } public function create_box(material:MaterialObject3D, width:Number, height:Number, x:Number, y:Number, angle:Number, density:Number, dinamic:Boolean, segmentsS:Number, segmentsT:Number, segmentsH:Number, pressed:Function, moved:Function):Cube { // boc2d var pd:b2PolygonDef = new b2PolygonDef(); pd.SetAsOrientedBox(width/m_physScale, height/m_physScale) pd.density = density; var bd:b2BodyDef = new b2BodyDef(); bd.position.Set( x / m_physScale, y / m_physScale); bd.angle = angle; var body:b2Body if (dinamic) { body = m_world.CreateDynamicBody(bd); } else { body = m_world.CreateStaticBody(bd); } var shape:b2Shape = body.CreateShape(pd) body.SetMassFromShapes(); // papervision var block:Cube = new Cube(new MaterialsList({all:material}), width, width, height, segmentsS, segmentsT, segmentsH) block.addEventListener(InteractiveScene3DEvent.OBJECT_PRESS, pressed) block.addEventListener(InteractiveScene3DEvent.OBJECT_MOVE, moved) block.userData = new UserData() block.userData.data = shape return block } public function pressed(event:InteractiveScene3DEvent):void { plane_for_drug.x = event.renderHitData.x plane_for_drug.y = event.renderHitData.y plane_for_drug.z = event.renderHitData.z plane_for_drug.visible = true var lego:DisplayObject3D = event.displayObject3D var shape:b2Shape = lego.userData.data var x:Number = event.renderHitData.x var y:Number = event.renderHitData.y if (!m_mouseJoint) { var body:b2Body = shape.GetBody() var md:b2MouseJointDef = new b2MouseJointDef(); md.body1 = m_world.m_groundBody; md.body2 = body; md.target.Set(x / (m_physScale / 2), -y / (m_physScale / 2)); md.maxForce = 300.0 * body.m_mass; md.timeStep = m_timeStep; m_mouseJoint = m_world.CreateJoint(md) as b2MouseJoint; body.WakeUp(); } } public function moved(event:InteractiveScene3DEvent):void { plane_for_drug.x = event.renderHitData.x plane_for_drug.y = event.renderHitData.y //plane_for_drug.z = event.renderHitData.z var x:Number = event.renderHitData.x var y:Number = event.renderHitData.y if (m_mouseJoint) { m_mouseJoint.SetTarget(new b2Vec2(x / (m_physScale / 2), -y / (m_physScale / 2))); } } public function released(evt:MouseEvent):void { plane_for_drug.visible = false if (m_mouseJoint) { m_world.DestroyJoint(m_mouseJoint); m_mouseJoint = null; } } public function update(e:Event):void{ m_world.Step(m_timeStep, m_iterations); for (var i:Number = 0; i < blocks.length; i++) { var block:Cube = blocks[i] var shape:b2Shape = block.userData.data var body:b2Body = shape.GetBody() block.x = (body.GetPosition().x) * m_physScale / 2 block.y = -(body.GetPosition().y) * m_physScale / 2 block.z = 0 block.rotationZ = - (body.GetAngle() * 180) / Math.PI - 180 } onRenderTick() } public function change_camera_position(evt:MouseEvent):void{ camera.x = (mouseX - stage.stageWidth / 2) / 2 camera.y = mouseY / 2 camera.z = -500 } } }