forked from: forked from: [Box2D][PV3D] Elevator
===================================================
Box2DAS3 and Papervision3D Demo
ドラッグで3Dを回転できます。
マウスホイールで拡大できます。
後ろ側の緑色のはBox2Dの2次元表示です。
rsakane さんの投稿から Folk させていただきました。
@author Yasu
@see http://clockmaker.jp/blog/
@since 2009.04.02
===================================================
// forked from hacker_waira's forked from: [Box2D][PV3D] Elevator
// forked from clockmaker's [Box2D][PV3D] Elevator
/*===================================================*//**
* Box2DAS3 and Papervision3D Demo
* ドラッグで3Dを回転できます。
* マウスホイールで拡大できます。
* 後ろ側の緑色のはBox2Dの2次元表示です。
*
* rsakane さんの投稿から Folk させていただきました。
*
* @author Yasu
* @see http://clockmaker.jp/blog/
* @since 2009.04.02
*//*===================================================*/
package
{
import Box2D.Collision.Shapes.*;
import Box2D.Collision.b2AABB;
import Box2D.Common.Math.b2Vec2;
import Box2D.Dynamics.Joints.*;
import Box2D.Dynamics.*;
import org.papervision3d.cameras.CameraType;
import org.papervision3d.materials.utils.MaterialsList;
import org.papervision3d.render.QuadrantRenderEngine;
import flash.display.*;
import flash.events.*;
import flash.geom.*;
import flash.net.*;
import flash.ui.*;
import flash.utils.getTimer;
import flash.utils.Timer;
import org.papervision3d.events.*;
import org.papervision3d.lights.*;
import org.papervision3d.materials.shadematerials.*;
import org.papervision3d.objects.*;
import org.papervision3d.view.*;
import org.papervision3d.objects.primitives.*;
import caurina.transitions.Tweener;
[SWF(width="465", height="465", frameRate="30", backgroundColor="0xFFFFFF")]
public class Main extends BasicView
{
static public const OBJ_SIZE : int = 20;
static public const OBJ_COLOR : uint = 0xff6666;
static private const CAMERA_DISTANCE : int = 900;
private var worldWidth : Number;
private var worldHeight : Number;
private var m_iterations : int;
private var m_wallWidth : Number;
private var m_wallHeight : Number;
private var m_timeStep : Number;
private var m_physScale : Number;
private var m_world : b2World;
private var m_mouseJoint : b2MouseJoint;
private var m_draggedBody : b2Body;
private var mouseXWorldPhys : Number;
private var mouseYWorldPhys : Number;
private var isMouseDown : Boolean;
private var arrayIndex : int;
private var pv3dObjsArr : Vector.<DisplayObject3D> = new Vector.<DisplayObject3D>();
private var box3dSpapesArr : Vector.<b2Body> = new Vector.<b2Body>();
private var light : PointLight3D;
private var mat : FlatShadeMaterial;
private var timerCnt : int = 0;
public function Main()
{
stage.quality = StageQuality.MEDIUM;
Mouse.cursor = MouseCursor.HAND;
super(stage.stageWidth, stage.stageHeight, false, false, CameraType.FREE);
createPaervision3dWorld();
createBox2dWorld()
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
createBackGround();
stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
stage.addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheel);
}
private function createPaervision3dWorld() : void
{
camera.x = 0;
camera.z = -CAMERA_DISTANCE;
light = new PointLight3D();
light.z = -100;
mat = new FlatShadeMaterial(light, OBJ_COLOR);
ballMat = new FlatShadeMaterial(light, 0xFFFF0F);
cameraTarget = new DisplayObject3D();
cameraTarget.x = -80;
cameraTarget.y = 60;
}
private function createBox2dWorld() : void
{
worldWidth = stage.stageWidth;
worldHeight = stage.stageHeight;
m_iterations = 10;
m_timeStep = 1 / stage.frameRate;
m_physScale = 60;
var worldAABB : b2AABB = new b2AABB();
worldAABB.lowerBound.Set( -1000, -1000);
worldAABB.upperBound.Set(1000, 1000);
var gravity : b2Vec2 = new b2Vec2(0, 50);
var doSleep : Boolean = true;
m_world = new b2World(worldAABB, gravity, doSleep);
var dbgDraw : b2DebugDraw = new b2DebugDraw();
dbgDraw.m_sprite = this;
dbgDraw.m_drawScale = SCALE;
dbgDraw.m_fillAlpha = 0.8;
dbgDraw.m_lineThickness = 0.3;
dbgDraw.m_alpha = 0.3;
dbgDraw.m_xformScale = 1.0
dbgDraw.m_drawFlags = b2DebugDraw.e_shapeBit;
//m_world.SetDebugDraw(dbgDraw);
createPolygon(stage.stageWidth / 2 / SCALE, 1.0, 354, 1.1, 0.1);
createPolygon(stage.stageWidth / 4 / SCALE, 2.1, 20, 1.2, 0.1);
createPolygon(stage.stageWidth / 2 / SCALE, 3.2, 354, 1.1, 0.1);
createPolygon(stage.stageWidth / 4 / SCALE, 4.0, 12, 2.3, 0.1);
createPolygon(0.5, 5.1, 0, 6, 0.5);
createPolygon(0, stage.stageHeight / 2 / SCALE, 90, stage.stageHeight / 2 / SCALE, 0.1);
createPolygon(3.32, stage.stageHeight / 2 / SCALE, 90, 1.5, 0.1);
createPolygon(4.58, stage.stageHeight / 2 / SCALE, 90, stage.stageHeight / SCALE, 0.1);
addCubeAtPv3dWorldNoSave(stage.stageWidth / 2 / SCALE, 1.0, 354, 1.1, 0.1);
addCubeAtPv3dWorldNoSave(stage.stageWidth / 4 / SCALE, 2.1, 20, 1.2, 0.1);
addCubeAtPv3dWorldNoSave(stage.stageWidth / 2 / SCALE, 3.2, 354, 1.1, 0.1);
addCubeAtPv3dWorldNoSave(stage.stageWidth / 4 / SCALE, 4.0, 12, 2.3, 0.1);
addCubeAtPv3dWorldNoSave(0.5, 5.1, 0, 6, 0.5);
addCubeAtPv3dWorldNoSave(0, stage.stageHeight / 2 / SCALE, 90, stage.stageHeight / 2 / SCALE, 0.1);
addCubeAtPv3dWorldNoSave(3.32, stage.stageHeight / 2 / SCALE, 90, 1.5, 0.1);
addCubeAtPv3dWorldNoSave(4.58, stage.stageHeight / 2 / SCALE, 90, stage.stageHeight / SCALE, 0.1);
for (var i : int = 0; i < 14; i++)
{
addCubeAtPv3dWorld(0.23, 0.1, true);
if (i % 2) addRectAtBox2dWorld(3.7, i * 0.4, 0, 0.23, 0.1, "elevator");
else addRectAtBox2dWorld(4.2, i * 0.4, 0, 0.23, 0.1, "elevator");
}
ballMat = new FlatShadeMaterial(light, 0xFFFFfF);
for (i = 0; i < 4; i++)
{
addSphereAtPv3dWorld(40, 30, OBJ_SIZE);
addCircleAtBox2dWorld(40, 30, OBJ_SIZE);
}
}
private function addCubeAtPv3dWorldNoSave(posX : Number, posY : Number, degree : Number, hx : Number, hy : Number, id : String = "", density : Number = 0.0, restitution : Number = 0.0, setMass : Boolean = false) : void
{
var obj3d : DisplayObject3D = scene.addChild(
new Cube(
new MaterialsList({all : mat}),
hx * m_physScale * 2,
30,
hy * m_physScale * 2));
obj3d.x = + posX * m_physScale - worldWidth / 2;
obj3d.y = - posY * m_physScale + worldHeight / 2;
obj3d.rotationZ = - degree
}
private function addSphereAtPv3dWorld(posX : Number, posY : Number, radius : Number) : void
{
var obj3d : DisplayObject3D = scene.addChild(new Sphere(ballMat, radius / 2, 6, 5));
pv3dObjsArr.push(obj3d);
}
private function addCubeAtPv3dWorld(hx : Number, hy : Number, isSaveArray : Boolean) : void
{
var obj3d : DisplayObject3D = scene.addChild(
new Cube(
new MaterialsList({all : mat}),
hx * m_physScale * 2,
hy * m_physScale * 2,
10));
if (isSaveArray) pv3dObjsArr.push(obj3d);
}
private function addCircleAtBox2dWorld(posX : Number, posY : Number, radius:Number):void
{
var obj3d : DisplayObject3D = pv3dObjsArr[pv3dObjsArr.length - 1];
var circleShape : b2CircleDef = new b2CircleDef();
circleShape.radius = radius / m_physScale / 2;
circleShape.density = 1;
circleShape.friction = 1;
circleShape.restitution = 0.6;
var bodyDef : b2BodyDef = new b2BodyDef();
bodyDef.position.Set((posX + worldWidth / 2) / m_physScale, (posY + worldHeight / 2) / m_physScale);
bodyDef.userData = {id : "", obj : obj3d};
var body : b2Body = m_world.CreateBody(bodyDef);
body.CreateShape(circleShape);
body.SetMassFromShapes();
box3dSpapesArr.push(body);
}
private function addRectAtBox2dWorld(posX : Number, posY : Number, degree : Number, hx : Number, hy : Number, id : String = "", density : Number = 0.0, restitution : Number = 0.0, setMass : Boolean = false) : void
{
var obj3d : DisplayObject3D = pv3dObjsArr[pv3dObjsArr.length - 1];
var bodyDef : b2BodyDef = new b2BodyDef();
bodyDef.position.Set(posX, posY);
bodyDef.angle = degree * Math.PI / 180;
if (id) bodyDef.userData = {id : id, obj : obj3d};
var blockShape : b2PolygonDef = new b2PolygonDef();
blockShape.SetAsBox(hx, hy);
blockShape.density = density;
blockShape.restitution = restitution;
var body : b2Body = m_world.CreateBody(bodyDef);
body.CreateShape(blockShape);
if (setMass) body.SetMassFromShapes();
}
private function enterFrameHandler(event : Event) : void
{
m_world.Step(m_timeStep, m_iterations);
for (var bb : b2Body = m_world.GetBodyList(); bb; bb = bb.GetNext())
{
if (bb.m_userData)
{
if (bb.m_userData.id == "elevator")
{
bb.SetXForm(new b2Vec2(bb.GetPosition().x, bb.GetPosition().y - 0.02), 0);
if (bb.GetPosition().y < -0.1) bb.SetXForm(new b2Vec2(bb.GetPosition().x, stage.stageHeight / SCALE + 1), 0);
if (bb.GetPosition().y < 0.8) bb.SetXForm(bb.GetPosition(), bb.GetAngle() - 0.2);
}
if (bb.m_userData.obj is DisplayObject3D)
{
var obj : DisplayObject3D = bb.m_userData.obj;
obj.x = bb.GetPosition().x * m_physScale - worldWidth / 2;
obj.y = -bb.GetPosition().y * m_physScale + worldHeight / 2;
obj.rotationZ = -bb.GetAngle() * (180 / Math.PI);
}
}
}
easePitch += (cameraPitch - easePitch) * 0.2
easeYaw += (cameraYaw - easeYaw) * 0.2
camera.orbit(easePitch, easeYaw, true, cameraTarget);
camera.zoom += (easeZoom - camera.zoom) * 0.1;
singleRender();
}
private function createBackGround():void
{
graphics.beginFill(0xFFFFFF);
graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
}
private const SCALE : uint = 100;
private function createPolygon(posX:Number, posY:Number, degree:Number, hx:Number, hy:Number, id:String = "", density:Number = 0.0, restitution:Number = 0.0,
setMass:Boolean = false):void
{
var blockBodyDef : b2BodyDef = new b2BodyDef();
blockBodyDef.position.Set(posX, posY);
blockBodyDef.angle = degree * Math.PI / 180;
if (id)
{
blockBodyDef.userData = new Object();
blockBodyDef.userData.id = id;
}
var blockShape : b2PolygonDef = new b2PolygonDef();
blockShape.SetAsBox(hx, hy);
blockShape.density = density;
blockShape.restitution = restitution;
var blockBody : b2Body = m_world.CreateBody(blockBodyDef);
blockBody.CreateShape(blockShape);
if (setMass) blockBody.SetMassFromShapes();
}
private var isOribiting : Boolean;
private var cameraPitch : Number = 50;
private var cameraYaw : Number = 300;
private var cameraTarget : DisplayObject3D = DisplayObject3D.ZERO;
private var previousMouseX : Number;
private var previousMouseY : Number;
private var easePitch : Number = 90;
private var easeYaw : Number = 270;
private var easeZoom : Number = 150;
private var ballMat : FlatShadeMaterial;
private function onMouseDown(event : MouseEvent) : void
{
isOribiting = true;
previousMouseX = event.stageX;
previousMouseY = event.stageY;
singleRender();
}
private function onMouseUp(event : MouseEvent) : void
{
isOribiting = false;
}
private function onMouseMove(event : MouseEvent) : void
{
var differenceX : Number = event.stageX - previousMouseX;
var differenceY : Number = event.stageY - previousMouseY;
if (isOribiting)
{
cameraPitch += differenceY * 0.25;
cameraYaw += differenceX * 0.25;
cameraPitch %= 360;
cameraPitch = cameraPitch > 0 ? cameraPitch : 0.0001;
cameraPitch = cameraPitch < 180 ? cameraPitch : 179.9999;
previousMouseX = event.stageX;
previousMouseY = event.stageY;
}
}
private function onMouseWheel(e : MouseEvent) : void
{
easeZoom += e.delta;
easeZoom = Math.max(1, easeZoom);
}
}
}