Home > Flash | WEB > Box2D と PaperVision3D を連携させてみる

Box2D と PaperVision3D を連携させてみる

Box2Dをちょっと勉強してみて、
このライブラリでは、
「物理演算させた結果を数値パラメータとして取り出して使う」、
ということがわかってきた。

Box2Dで遊んでいる人の多くがそうであるように、
このパラメータを何で使ったらおもしろいかというひとつの行き先として、3D表示がある。
Flashには3D表現のライブラリとしては、PaperVision3Dが有名です。

というわけで、3D表現とか未経験なので、勉強もかねて、
技術評論社の簡単なBox2Dサンプルの動作を、
Papervision3Dライブラリを使って3D表示させてみた。

↑ 画面クリックで、箱が落ちます。
Box2D部分はほぼ技術評論社のものと変更ありません。

Box2Dは、2次元の物理演算ライブラリなので、
PaperVision3Dを用いても、表示されている領域内では、2Dの動作しかしません。

Box2Dで、毎フレームごとのX座標、Y座標、傾きなどの値を取り出して、
PaperVision3Dの世界に落とし込んでいます。

というわけで、とりあえずPaperVision3Dの初体験ができましたw
がんばればもうちょっと面白いことできそうだなー。

↓ソース全部。

使用したPaperVision3Dライブラリのバージョンは
「Public Alpha 2.0 - Great White (24.03.08)」です。

メインのPaperVisionTestクラス

ACTIONSCRIPT:
  1. package src {
  2.     import Box2D.Collision.b2AABB;
  3.     import Box2D.Collision.Shapes.b2PolygonDef;
  4.     import Box2D.Common.Math.b2Vec2;
  5.     import Box2D.Dynamics.b2Body;
  6.     import Box2D.Dynamics.b2BodyDef;
  7.     import Box2D.Dynamics.b2DebugDraw;
  8.     import Box2D.Dynamics.b2World;
  9.     import flash.display.Sprite;
  10.     import flash.events.Event;
  11.     import flash.events.MouseEvent;
  12.    
  13.     /**
  14.     * ...
  15.     * @author Default
  16.     */
  17.     public class PaperVisionTest extends Sprite {
  18.         private var world:b2World;
  19.         private var boxBody:b2Body;
  20.         private var pvView:PVView;
  21.        
  22.         public function PaperVisionTest() {
  23.             // イベントハンドラを登録する
  24.             stage.addEventListener(MouseEvent.CLICK, clickHandler);
  25.             addEventListener(Event.ENTER_FRAME, enterFrameHandler)
  26.            
  27.             pvView = new PVView;
  28.             pvView.x = -100;
  29.             pvView.y = -100;
  30.             addChild(pvView);
  31.         }
  32.        
  33.         private function clickHandler(event:MouseEvent):void {
  34.             ////////////////////////////////////////
  35.             // 物理エンジンのセットアップ
  36.            
  37.             // 外枠を定義する
  38.             var worldAABB:b2AABB = new b2AABB();
  39.             worldAABB.lowerBound.Set(-100, -100);
  40.             worldAABB.upperBound.Set(100, 100);
  41.            
  42.             // 重力を下方向に10m/s^2とする
  43.             var gravity:b2Vec2 = new b2Vec2(0, 10);
  44.            
  45.             // 外枠と重力を指定して、物理エンジン全体をセットアップする
  46.             world = new b2World(worldAABB, gravity, true);
  47.            
  48.             ////////////////////////////////////////
  49.             // 床の設置
  50.             // 床は画面の下のほうに設置します
  51.            
  52.             // 床の位置を左から2.1m、上から3mとする
  53.             var floorBodyDef:b2BodyDef = new b2BodyDef();
  54.             floorBodyDef.position.Set(2.15, 3);
  55.            
  56.             // 床の形を、幅4m、厚さ20cmとする
  57.             // 指定するのはその半分の値
  58.             var floorShapeDef:b2PolygonDef = new b2PolygonDef();
  59.             floorShapeDef.SetAsBox(2, 0.1);
  60.            
  61.             // 床を動かない物体として作る
  62.             var floor:b2Body = world.CreateBody(floorBodyDef);
  63.             floor.CreateShape(floorShapeDef);
  64.            
  65.             ////////////////////////////////////////
  66.             // 箱の設置
  67.             // 箱は床の上から落として、少しはねるようにします
  68.            
  69.             // 箱の位置を左から2.5m、上から1mとする
  70.             var boxBodyDef:b2BodyDef = new b2BodyDef();
  71.             boxBodyDef.position.Set(2.5, 1);
  72.            
  73.             // 箱の形を、幅60cm、高さ40cmとして45度ぐらい右に回す
  74.             var boxShapeDef:b2PolygonDef= new b2PolygonDef();
  75.             boxShapeDef.SetAsOrientedBox(0.3, 0.2, new b2Vec2(0, 0), 0.9);
  76.             boxShapeDef.density = 1;        // 密度 [kg/m^2]
  77.             boxShapeDef.restitution = 0.75// 反発係数、通常は0~1
  78.            
  79.             // 箱を動く物体として作る
  80.             boxBody = world.CreateBody(boxBodyDef);
  81.             boxBody.CreateShape(boxShapeDef);
  82.             boxBody.SetMassFromShapes();
  83.            
  84.             ////////////////////////////////////////
  85.             // 描画設定
  86.            
  87.             var debugDraw:b2DebugDraw = new b2DebugDraw();
  88.             debugDraw.m_sprite = this;
  89.             debugDraw.m_drawScale = 100; // 1mを100ピクセルにする
  90.             debugDraw.m_fillAlpha = 0.6; // 不透明度
  91.             debugDraw.m_lineThickness = 1; // 線の太さ
  92.             debugDraw.m_drawFlags = b2DebugDraw.e_shapeBit;
  93.             world.SetDebugDraw(debugDraw);
  94.         }
  95.        
  96.         private function enterFrameHandler(event:Event):void {
  97.             if (world == null) {
  98.                 return;
  99.             }
  100.             // Flashはデフォルトで秒間24フレームなので、
  101.             // 物理シミュレーションを1/24秒進める
  102.             world.Step(1 / 24, 10);
  103.            
  104.             // 箱の座標、傾きを3D世界に適用する。
  105.             var b2vec:b2Vec2 = boxBody.GetPosition();
  106.             pvView.setCubePosition(b2vec.x * 100, b2vec.y * 100, boxBody.GetAngle());
  107.         }
  108.     }
  109. }

3D表示用PVViewクラス

ACTIONSCRIPT:
  1. package src {
  2.     import Box2D.Dynamics.b2Body;
  3.     import org.papervision3d.lights.PointLight3D;
  4.     import org.papervision3d.materials.ColorMaterial;
  5.     import org.papervision3d.materials.shadematerials.PhongMaterial;
  6.     import org.papervision3d.materials.special.CompositeMaterial;
  7.     import org.papervision3d.materials.utils.MaterialsList;
  8.     import org.papervision3d.materials.WireframeMaterial;
  9.     import org.papervision3d.objects.primitives.Cube;
  10.     import org.papervision3d.view.BasicView;
  11.    
  12.     /**
  13.     * ...
  14.     * @author Default
  15.     */
  16.     public class PVView extends BasicView{
  17.         private var b2BodyList:Array;
  18.         private var _light:PointLight3D;
  19.         private var cube:Cube;
  20.        
  21.         public function PVView(){
  22.             b2BodyList = new Array();
  23.             camera.z = -50;
  24.             camera.x = -40;
  25.             camera.y = -40;
  26.            
  27.             _light = new PointLight3D;
  28.             _light.x = 0;
  29.             _light.y = 0;
  30.             _light.z = 40;
  31.            
  32.             var colorMaterial:ColorMaterial = new ColorMaterial(0x77FF77, 1);
  33.             var wireMaterial:WireframeMaterial = new WireframeMaterial(0x66FF66, 1);
  34.             var phongMaterial:PhongMaterial = new PhongMaterial( _light, 0xCCDDCC, 0xDDEEDD, 1 );
  35.             var compositeMaterial:CompositeMaterial = new CompositeMaterial();
  36.             compositeMaterial.addMaterial(colorMaterial);
  37.             compositeMaterial.addMaterial(phongMaterial);
  38.             compositeMaterial.addMaterial(wireMaterial);
  39.            
  40.             var materialsList:MaterialsList = new MaterialsList;
  41.            
  42.             materialsList.addMaterial(compositeMaterial, "all");
  43.             cube = new Cube(materialsList, 60, 40, 40);
  44.             cube.x = 2.5 * 100;
  45.             cube.y = 1 * 100;
  46.             scene.addChild(cube);
  47.             startRendering()
  48.         }
  49.        
  50.         public function setCubePosition(x:Number, y:Number, rotationY) {
  51.             cube.x = x;
  52.             cube.z = y;
  53.             rotationY = rotationY * 180;
  54.             cube.rotationY = rotationY;
  55.         }
  56.     }
  57. }

Comments:2

とおりすがり 09-02-03 (火) 10:22

うまく回転ができてないみたいですね。

boxBodyDef.position.Set(2.5, 1);
の次の行に
boxBodyDef.angle = 0.9;
を追加

boxShapeDef.SetAsOrientedBox(0.3, 0.2, new b2Vec2(0, 0), 0.9);

boxShapeDef.SetAsOrientedBox(0.3, 0.2, new b2Vec2(0, 0), 0);

rotationY = rotationY * 180;

rotationY = rotationY * (180/Math.PI)

でなおると思います。

admin 09-02-19 (木) 11:59

お、どうもありがとうございます。
直してテストしてみます

Comment Form
Remember personal info

Trackbacks:1

Trackback URL for this entry
http://parpue.net/web/138/trackback
Listed below are links to weblogs that reference
Box2D と PaperVision3D を連携させてみる from parpue.net
pingback from parpue.net - Box2D,Papervision3Dでフリースローゲームを3D表示 08-08-01 (金) 1:35

[...] 前々回のエントリでBox2DとPapervision3dを連携させてみて、 前のフリースローも似たようなことできるんじゃないかと思ってやってみた。 [...]

Home > Flash | WEB > Box2D と PaperVision3D を連携させてみる

リンク
chocolataste-planner
millon

サーチ
Feeds
Meta
blog ranking ブログランキング・にほんブログ村へ
にほんブログ村 テクノラティのお気に入りに追加する

Return to page top