package { import Box2D.Collision.Shapes.b2PolygonDef; import Box2D.Collision.Shapes.b2Shape; import Box2D.Collision.b2AABB; import Box2D.Common.Math.b2Vec2; import Box2D.Dynamics.Joints.b2MouseJoint; import Box2D.Dynamics.Joints.b2MouseJointDef; import Box2D.Dynamics.b2Body; import Box2D.Dynamics.b2BodyDef; import Box2D.Dynamics.b2World; import caurina.transitions.Tweener; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.Event; import flash.events.KeyboardEvent; import flash.events.MouseEvent; import org.papervision3d.core.data.UserData; import org.papervision3d.core.math.Number3D; import org.papervision3d.core.proto.MaterialObject3D; import org.papervision3d.events.InteractiveScene3DEvent; import org.papervision3d.lights.PointLight3D; import org.papervision3d.materials.BitmapMaterial; import org.papervision3d.materials.shadematerials.FlatShadeMaterial; import org.papervision3d.materials.special.CompositeMaterial; import org.papervision3d.materials.utils.MaterialsList; import org.papervision3d.objects.DisplayObject3D; import org.papervision3d.objects.primitives.Cube; import org.papervision3d.objects.primitives.Plane; import org.papervision3d.view.BasicView; [SWF(frameRate='10')] public class BlocksTest07 extends BasicView { [Embed (source="1.png")] private var picture1:Class; [Embed (source="2.png")] private var picture2:Class; [Embed (source="3.png")] private var picture3:Class; [Embed (source="4.png")] private var picture4:Class; [Embed (source="5.png")] private var picture5:Class; [Embed (source="6.png")] private var picture6:Class; [Embed (source="7.png")] private var picture7:Class; [Embed (source="8.png")] private var picture8:Class; // block public var BOX_W:Number = 19 / 3 * 2 * 3 * 2 public var BOX_H:Number = 19 / 5 * 2 * 3 * 2 public var BLOCKS_SETTING:Array = [ [0xcc0000, picture1, 1.1, 1], // red [0x006822, picture2, 0.8, 0], // green [0x02b535, picture3, 2.3, 1], // light green [0x02b535, picture4, 1.9, 0], // light green [0xfbe419, picture5, 3, 2], // yellow [0x0066a7, picture6, 3.3, 1], // blue [0x0066a7, picture7, 3, 0], // blue [0xff9500, picture8, 4.3, 0] // orange ] 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/10 public var m_physScale:Number = 30 // camera public var last_click_time:Date = new Date() public var view_presentation_mode:Boolean = false public var base:Cube public function BlocksTest07() { //stage.quality = StageQuality.LOW; viewport.interactive = true stage.align = StageAlign.TOP_LEFT stage.scaleMode = StageScaleMode.NO_SCALE //stage.frameRate = 5 // event stage.addEventListener(MouseEvent.MOUSE_UP, released) stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDown) init_papervision() init_box2d() init_base() init_blocks() startRendering() } protected override function onRenderTick(event:Event = null):void { loop() renderer.renderScene(scene, _camera, viewport) } public function loop():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 } if (!view_presentation_mode) { var p:Number3D = get_camera_position() camera.x = p.x camera.y = p.y camera.z = p.z } } public function get_camera_position():Number3D { var p:Number3D = new Number3D() var theta:Number = ((mouseX / stage.stageWidth) * 2 - 1) * Math.PI /8 p.x = Math.sin(theta) * 500 p.y = (mouseY + stage.stageWidth / 4) / 2 p.z = Math.cos(theta) * 500 return p } public function init_papervision():void{ light = new PointLight3D() light.z = 600 light.x = -700 light.y = 800 camera.x = (mouseX - stage.stageWidth / 2) / 2 camera.y = (mouseY + stage.stageWidth / 4) / 2 camera.z = -500 camera.focus = 1000 var material_for_drug:MaterialObject3D = new MaterialObject3D() material_for_drug.interactive = true plane_for_drug = new Plane(material_for_drug, 1000, 1000, 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_base():void{ // boc2d var pd:b2PolygonDef = new b2PolygonDef() pd.SetAsOrientedBox(500/m_physScale, 20/m_physScale) pd.density = 2.0 var bd:b2BodyDef = new b2BodyDef() bd.position.Set( 0 / m_physScale, 20 / m_physScale) bd.angle = 0 var body:b2Body body = m_world.CreateStaticBody(bd) var shape:b2Shape = body.CreateShape(pd) body.SetMassFromShapes() // papervision var base_material:MaterialObject3D = new FlatShadeMaterial(light, 0xffffff, 0x808080) base = new Cube(new MaterialsList({all:base_material}), 500, 500, 10 , 10, 10, 10) base.y = -5 scene.addChild(base) } public function init_blocks():void{ for each(var setting:Array in BLOCKS_SETTING) { var color:Number = setting[0] var picture:Class = setting[1] var x:Number = setting[2] var y:Number = setting[3] var material:MaterialObject3D = new FlatShadeMaterial(light, 0xffffff, color) material.interactive = true var block:Cube = create_block(material, picture, BOX_W, BOX_H, BOX_W * 2 * (- x + 2.5), -( BOX_H * 2 * (y + 1)), Math.PI, 2.0, true, 1, 1, 1, pressed, moved, clicked) blocks.push(block) scene.addChild(block) } } public function create_block(material:MaterialObject3D, picture:Class, width:Number, height:Number, x:Number, y:Number, angle:Number, density:Number, dinamic:Boolean, segmentsS:Number, segmentsT:Number, segmentsH:Number, pressed:Function, moved:Function, clicked: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) for each (var k:Number in [1, -1]){ // top var pdTop:b2PolygonDef = new b2PolygonDef() pdTop.SetAsOrientedBox((width / 4) / m_physScale, height / m_physScale, new b2Vec2((k * width / 4)/m_physScale, (height / 4)/m_physScale)) pdTop.density = 2.0 body.CreateShape(pdTop) } body.SetMassFromShapes() // papervision var material_front:CompositeMaterial = new CompositeMaterial() material_front.addMaterial(material) material_front.addMaterial(new BitmapMaterial(new picture().bitmapData)) material_front.interactive = true var mlist_body:MaterialsList = new MaterialsList({all:material, front:material_front}) var mlist_cylinder:MaterialsList = new MaterialsList({all:material}) var block:Cube = new Cube(mlist_body, width, width, height, segmentsS, segmentsT, segmentsH) for each (var i:Number in [1, -1]){ for each (var j:Number in [1, -1]){ var cylinder:Cube = new Cube(mlist_cylinder, width / 4, width / 4, height / 4) cylinder.x = i * width / 4 cylinder.z = j * width / 4 cylinder.y = height / 2 block.addChild(cylinder) } } block.addEventListener(InteractiveScene3DEvent.OBJECT_PRESS, pressed) block.addEventListener(InteractiveScene3DEvent.OBJECT_MOVE, moved) block.addEventListener(InteractiveScene3DEvent.OBJECT_CLICK, clicked) 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 clicked(event:InteractiveScene3DEvent):void { var click_time:Date = new Date() if (click_time.getTime() - last_click_time.getTime() < 300) { double_clicked(event) } last_click_time = click_time } public function double_clicked(event:InteractiveScene3DEvent):void { var params:Object if (view_presentation_mode) { view_presentation_mode = false //cameraAsCamera3D.target = base var p:Number3D = get_camera_position() params = { x:p.x, y:p.y, z:p.z, zoom:3, time:1 } Tweener.addTween(camera, params) } else { view_presentation_mode = true cameraAsCamera3D.target = event.displayObject3D params = { x:event.displayObject3D.x, y:event.displayObject3D.y, z:100, zoom:10, time:1 } Tweener.addTween(camera, params) } } public function released(evt:MouseEvent):void { plane_for_drug.visible = false if (m_mouseJoint) { m_world.DestroyJoint(m_mouseJoint) m_mouseJoint = null } } public function keyDown(event:KeyboardEvent):void { cameraAsCamera3D.target = base view_presentation_mode = false //cameraAsCamera3D.target = base var p:Number3D = get_camera_position() var params:Object = { x:p.x, y:p.y, z:p.z, zoom:3, time:1 } Tweener.addTween(camera, params) } } }