Box2D欠点?
単に設定が悪いだけなのかもしれませんが
Box2Dは単一のFixtureの中では
凹部分があるとだめで
そういう複雑な形状を作りたいときは
どうやらBodyに複数のFixtureをいれて
組み合わせてやらなきゃならないらしいです
あと、これはドキュメンテーションでも
かいてくれているのですがb2Vec2の配列から
b2PolygonShapeを作るときは
基本右回りの頂点の配列じゃないとダメなので
DXFで読み込む用の形状を作るにしても
反転のような操作はNGになります
しかし凹部分がNGというのは想定外
DXFクラスはグループ状態とかは覚えるように
つくっていないので凹部分のない形状に
分解して同じBodyに入れるようにするにしても
DXFクラスの書き換えからしなきゃならないようです
というかグループ状態がDXFで
どう記録されてるのかをまず調べてないので
まずはそこからですね
Box2Dは単一のFixtureの中では
凹部分があるとだめで
そういう複雑な形状を作りたいときは
どうやらBodyに複数のFixtureをいれて
組み合わせてやらなきゃならないらしいです
あと、これはドキュメンテーションでも
かいてくれているのですがb2Vec2の配列から
b2PolygonShapeを作るときは
基本右回りの頂点の配列じゃないとダメなので
DXFで読み込む用の形状を作るにしても
反転のような操作はNGになります
しかし凹部分がNGというのは想定外
DXFクラスはグループ状態とかは覚えるように
つくっていないので凹部分のない形状に
分解して同じBodyに入れるようにするにしても
DXFクラスの書き換えからしなきゃならないようです
というかグループ状態がDXFで
どう記録されてるのかをまず調べてないので
まずはそこからですね
Illustratorの形状をBox2Dに…
そういえば
先に作ったDXFからPointオブジェクトの配列を
生成するDXFクラスはすごくBox2Dと相性がいいですね
Pointをb2Vec2に置き換える関数ひとつ用意すれば
イラレで描いた形状を簡単にBox2Dに持って行けそうです
また明日にでも試してみます
この記事更新って形でやっていきます
Pictクラスとかがないと役に立たないクラスとか
言ってましたが役に立つところがあったようです
DXFクラスの記事
DXFから読み込みする形状にはいろいろと制約があって
特に凹面NGというのが想定外でまだ対応してないですし
曲線を読み込むということはできませんが
とりあえず簡単なものなら読み込めるようにできました
"shapes.dxf"という名前のDXFを読み込み
赤色(0xFF00000)の色の形状は動き
それ以外は動かないというようなカンジにしてます
b2PolygonShape.AsArrayの第二引数に
必須で頂点数を求めてくる意味が分からない
部分的にやってもらいたいならsliceするし
なんで全部処理すること前提じゃないのだろう?
先に作ったDXFからPointオブジェクトの配列を
生成するDXFクラスはすごくBox2Dと相性がいいですね
Pointをb2Vec2に置き換える関数ひとつ用意すれば
イラレで描いた形状を簡単にBox2Dに持って行けそうです
また明日にでも試してみます
この記事更新って形でやっていきます
Pictクラスとかがないと役に立たないクラスとか
言ってましたが役に立つところがあったようです
DXFクラスの記事
DXFから読み込みする形状にはいろいろと制約があって
特に凹面NGというのが想定外でまだ対応してないですし
曲線を読み込むということはできませんが
とりあえず簡単なものなら読み込めるようにできました
"shapes.dxf"という名前のDXFを読み込み
赤色(0xFF00000)の色の形状は動き
それ以外は動かないというようなカンジにしてます
import Box2D.Dynamics.*;
import Box2D.Collision.*;
import Box2D.Collision.Shapes.*;
import Box2D.Dynamics.Joints.*;
import Box2D.Dynamics.Contacts.*;
import Box2D.Common.*;
import Box2D.Common.Math.*;
import simplizer.graphic.DXF
//縮小率
var scl=1/5
//ワールドオブジェクト生成
var worldAABB:b2AABB
var wld:b2World
worldAABB= new b2AABB();
worldAABB.lowerBound.Set(-1000.0, -1000.0);
worldAABB.upperBound.Set(1000.0, 1000.0);
wld= new b2World(new b2Vec2(0.0, 10.0),false);
//デバッグ用に可視化
var dbgDraw:b2DebugDraw
dbgDraw= new b2DebugDraw();
dbgDraw.SetSprite(addChild(new Sprite())as Sprite);
dbgDraw.SetDrawScale(1/scl);
dbgDraw.SetFillAlpha(0.3);
dbgDraw.SetLineThickness(1.0);
dbgDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);
wld.SetDebugDraw(dbgDraw);
//壁作り
for(var i=0;i<4;i++){
var bdDef=new b2BodyDef()
bdDef.position.Set([5,275,545,275][i]*scl,[200,5,200,395][i]*scl)
var bd=wld.CreateBody(bdDef)
bd.CreateFixture2(b2PolygonShape.AsBox([5,275][i%2]*scl,[200,5][i%2]*scl))
}
//DXF読み込み
var dxf=new DXF("shapes.dxf")
dxf.addEventListener(Event.COMPLETE,onComp)
function onComp(e){
for each(var obj in dxf.objects){
bdDef=new b2BodyDef()
bdDef.position.Set(0,0)
if(obj.task.color==0xFF0000)bdDef.type=b2Body.b2_dynamicBody
wld.CreateBody(bdDef).CreateFixture2(pointsToShape(obj.verts),1)
}
function pointsToShape(pnts:Array):b2PolygonShape{
var verts:Array=new Array()
for each(var pnt in pnts){
verts.push(new b2Vec2(pnt.x*scl,pnt.y*scl))
}
return b2PolygonShape.AsArray(verts,verts.length-1)
}
}
//フレーム毎にb2WorldにStep、DrawDebugDataさせる
addEventListener(Event.ENTER_FRAME,function(e){wld.Step(0.1,10,10);wld.DrawDebugData();})
b2PolygonShape.AsArrayの第二引数に
必須で頂点数を求めてくる意味が分からない
部分的にやってもらいたいならsliceするし
なんで全部処理すること前提じゃないのだろう?




