package { import Box2D.Collision.Shapes.b2PolygonDef; import Box2D.Collision.Shapes.b2Shape; import Box2D.Collision.b2AABB; import Box2D.Common.Math.b2Math; 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 flash.display.Bitmap; import flash.display.BitmapData; import flash.display.BitmapDataChannel; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.Event; import flash.events.MouseEvent; import flash.filters.ColorMatrixFilter; import flash.geom.Matrix; import flash.geom.Point; import org.papervision3d.cameras.Camera3D; 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.ColorMaterial; import org.papervision3d.materials.shadematerials.FlatShadeMaterial; import org.papervision3d.materials.utils.MaterialsList; import org.papervision3d.objects.DisplayObject3D; import org.papervision3d.objects.primitives.Cube; import org.papervision3d.objects.primitives.Cylinder; import org.papervision3d.objects.primitives.Plane; import org.papervision3d.scenes.Scene3D; import org.papervision3d.view.BasicView; import org.papervision3d.view.BitmapViewport3D; [SWF(frameRate='5', width=640, height=480)] public class BlocksTest06 extends BasicView { // mirror public var camera_mirror:Camera3D public var viewport_mirror:BitmapViewport3D private var background:Bitmap public var viewport_mask:BitmapViewport3D public var scene_mask:Scene3D = new Scene3D() // block public var BOX_W:Number = 19 / 3 * 2 * 3 * 2 public var BOX_H:Number = 19 / 5 * 2 * 3 * 2 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 // camera public var theta:Number = 0 public function BlocksTest06() { viewport.interactive = true stage.align = StageAlign.TOP_LEFT stage.scaleMode = StageScaleMode.NO_SCALE stage.frameRate = 5 // event addEventListener(Event.ENTER_FRAME, update, false, 0, true) stage.addEventListener(MouseEvent.MOUSE_UP, released) init3D() init_papervision() init_box2d() init_mirror() init_blocks() startRendering() } protected override function onRenderTick(event:Event = null):void { loop() renderer.renderScene(scene, _camera, viewport) } public function init3D():void { viewport_mask = new BitmapViewport3D(640, 480, false, true) camera_mirror = new Camera3D() viewport_mirror = new BitmapViewport3D(640, 480, false, true) background = new Bitmap(new BitmapData(640, 480, true, 0x00000000)) addChild(background) addChild(viewport) } 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 //camera_mirror.y = 100 camera_mirror.focus = 1000 var material_for_drug:MaterialObject3D = new MaterialObject3D() 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_mirror():void{ var base_material:MaterialObject3D = new ColorMaterial(0xffffff) // 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:Plane = new Plane(base_material, 500, 500, 10, 10) base.rotationX = -90 scene_mask.addChild(base) } public function init_blocks():void{ for (var j:int = 0; j < 3; j++) { for (var i:int = 0; i < 2; 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_block(material, BOX_W, BOX_H, BOX_W * 2 * (j - 1), -( 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_block(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) 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 mlist:MaterialsList = new MaterialsList({all:material}) var block:Cube = new Cube(mlist, width, width, height, segmentsS, segmentsT, segmentsH) for each (var i:Number in [1, -1]){ for each (var j:Number in [1, -1]){ var cylinder:Cylinder = new Cylinder(material, width / 8, height / 4) //var cylinder:Cube = new Cube(mlist, 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.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 loop():void{ theta += (mouseX - stage.stageWidth / 2) / stage.stageWidth * Math.PI * 2 camera.x = Math.cos(theta/100) * 500 camera.y = (mouseY + stage.stageWidth / 4) / 2 camera.z = Math.sin(theta/100) * 500 // render mirror camera_mirror.x = camera.x camera_mirror.y = -camera.y camera_mirror.z = camera.z renderer.renderScene(scene, camera_mirror, viewport_mirror) // render mask renderer.renderScene(scene_mask, camera, viewport_mask) // render background var mirrorReverseBitmap:BitmapData = viewport_mirror.bitmapData var mirrorBitmap:BitmapData = new BitmapData(mirrorReverseBitmap.width, mirrorReverseBitmap.height, true) var reverseMatrix:Matrix = new Matrix() reverseMatrix.scale(1, -1) // reverse reverseMatrix.translate(0, mirrorReverseBitmap.height) mirrorBitmap.draw(mirrorReverseBitmap, reverseMatrix) var maskBitmap:BitmapData = viewport_mask.bitmapData var red:uint = BitmapDataChannel.RED var blue:uint = BitmapDataChannel.BLUE var green:uint = BitmapDataChannel.GREEN maskBitmap.copyChannel(mirrorBitmap, mirrorBitmap.rect, new Point(), 1, 1) maskBitmap.copyChannel(mirrorBitmap, mirrorBitmap.rect, new Point(), 2, 2) maskBitmap.copyChannel(mirrorBitmap, mirrorBitmap.rect, new Point(), 4, 4) var matrix:Array = new Array() matrix = matrix.concat([1, 0, 0, 0, 0]) // red matrix = matrix.concat([0, 1, 0, 0, 0]) // green matrix = matrix.concat([0, 0, 1, 0, 0]) // blue matrix = matrix.concat([0, 0, 0, 0.8, 0]) // alpha maskBitmap.applyFilter(maskBitmap, maskBitmap.rect, new Point(), new ColorMatrixFilter(matrix)) background.bitmapData.fillRect(maskBitmap.rect, 0xffffff) background.bitmapData.draw(maskBitmap) } } }