Box2D(2.1a)引擎的群组筛选碰撞详解

本文详细探讨了Box2D物理引擎中的群组筛选功能,通过实验揭示了categoryBits和maskBits属性如何控制刚体之间的碰撞。碰撞发生受两刚体的categoryBits与maskBits按位运算结果制约,通过三个步骤判断是否发生碰撞。默认情况下,所有物体的maskBits为0xFFFF,意味着与其他所有物体碰撞。示例代码展示了如何通过设置这些属性来观察特定碰撞效果。
摘要由CSDN通过智能技术生成

关于box2d的群组筛选功能是怎么回事一直有点不明所以,现在经过一系列实验,终于明白box2d群组筛选的控制机制了。群组碰撞筛选的核心属性有2个,分别是b2FilterData的categoryBits属性以及maskBits属性;(b2FilterData作为b2FixtureDef的filter对象存在)categoryBits是刚体的所属群组id值域为0x0000-0xFFFF;而maskBits属性则是当前刚体接受碰撞的"掩码";测试结果显示,两个物体是否碰撞,受到两个条件的制约。分为3个步骤;这里举例刚体A和刚体B;
1:会对A的掩码和B的群组ID进行按位或运算,得到结果a1(这里简化为true/false);
2:对B的掩码和A的群组ID进行按位或运算,得到b1(true/false);
3:决定碰撞,对a1和b1进行与运算;得到结果为true则两物体进行碰撞;否则穿过;
所以,默认情况下所有的b2FilterData的maskBits属性为0xFFFF——与所有物体碰撞;
例如下面测试代码
矩形物体会从中间开始下落到静态体圆形上;从而观察碰撞效果;

import Box2D.Collision.Shapes.b2CircleShape;
import Box2D.Collision.Shapes.b2PolygonShape;
import Box2D.Dynamics.b2World;
import Box2D.Dynamics.b2Body;
import Box2D.Common.Math.b2Vec2;
import Box2D.Dynamics.b2Fixture;
import Box2D.Dynamics.b2FixtureDef;
import Box2D.Dynamics.b2BodyDef;
import Box2D.Dynamics.b2DebugDraw;
 
var world:b2World=new b2World(new b2Vec2(0,2),true);
var b2d:b2BodyDef=new b2BodyDef();
b2d.position.Set(200/30,100/30);
b2d.type=b2Body.b2_dynamicBody;
var bb:b2Body=world.CreateBody(b2d);
var fx:b2FixtureDef=new b2FixtureDef();
fx.friction=1;
fx.restitution=0.1;
fx.shape=b2PolygonShape.AsBox(400/30,7.5/30);
fx.density=1;
fx.filter.categoryBits=0x1100;//方形体群ID
fx.filter.maskBits=0x1101;//方形体掩码(对于碰撞对方的)因为是按位或运算所以每位的数字就不重要了;(过滤群ID为0x00X0)的ID
bb.CreateFixture(fx);
//完成方形创建 
fx.shape=new b2CircleShape(100/30);
fx.filter.categoryBits=0x0011;//圆形体群ID
fx.filter.maskBits=0x0111;//圆形体掩码(过滤群ID为0xX000)的群
//通过两轮过滤之后还要将结果进行与运算,得出最终是否可碰撞;
b2d.position.Set(400/30,300/30);
b2d.type=b2Body.b2_staticBody;
bb=world.CreateBody(b2d);
bb.CreateFixture(fx);
//完成圆形创建
var sp:Sprite=new Sprite();
addChild(sp);
var dbg:b2DebugDraw=new b2DebugDraw();
dbg.SetSprite(sp);
dbg.SetFlags(b2DebugDraw.e_shapeBit);
dbg.SetDrawScale(30);
dbg.SetLineThickness(0);
dbg.SetFillAlpha(0.5);
world.SetDebugDraw(dbg);
addEventListener(Event.ENTER_FRAME,run);
function run(e:Event){
	world.Step(1/30,10,10);
	world.ClearForces();
	world.DrawDebugData();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值