转自:http://www.ityran.com/thread-650-1-1.html
第六章 fixture
6.1关于
记得,shape不了解body,并且shape可以在物理模拟中被单独使用。因此Box2D
提供了b2Fixture类将shape附属到body上,fixture持有以下:
单个外形a singleshape
·broad-phaseproxies
·密度,摩擦,和恢复
·碰撞过滤旗帜
·返回父辈body的指针
·用户数据user data
·传感器旗帜sensorflag
具体将在以下章节中描述
6.2创建Fixture
fixture是通过初始化fixture定义并把定义传递给父辈body创建的。
b2FixtureDeffixtureDef;
fixtureDef.shape=&myShape;
fixtureDef.density=1.0f;
b2Fixture*myFixture =myBody->CreateFixture(&fixtureDef);
这创建了fixture,并把它附属到body上。你没必要存储fixture指针,因为
当父辈body被破坏时,fixture会自动被破坏。
你可以在父辈body上破坏fixture,你可以用这种方法来创建一个易碎的对象。
否则
youcanjustleavethefixture andletthebodydestructiontakecare
of destroyingthe attachedfixtures.
myBody->DestroyFixture(myFixture);
密度
Fixture的密度可以用来计算父辈body的质量性能。密度可以为零或者为正数。
对所有的fixture,你应该使用相似的密度,这样可以提高堆的稳定性。
当你设置密度时,Body的质量是不可改变的。你需要访问ResetMassData才能
改变。
fixture->SetDensity(5.0f);
body->ResetMassData();
摩擦
摩擦用来保证对象像现实生活中一样移动。Box2D提供了静态和动态摩擦,但都
需要使用相同的参数。 在Box2D模拟中,摩擦需要非常准确,摩擦强度与正常
力量成正比(这就是所谓的库仑摩擦)。
摩擦参数通常是设置在0和1之间,但也可以是任何非负价值。将值设为0,摩擦关
掉。值为1,摩擦增强。当计算两个shape之间的摩擦力的时候,Box2D必须结
合两个父辈夹具的摩擦参数。
This isdonewith thegeometricmean:
float32friction;
friction=sqrtf(shape1->friction*shape2->friction);
如果一个夹具含有零摩擦,那么接触也会有零摩擦。
恢复Restitution
恢复用来使对象弹回。恢复值通常设置在0和1之间。考虑将一个球坠到桌子上,
9值意味着这个球不能返回。这就是所谓的一个非弹性碰撞。1值意味着这个球会
准确快速的反弹。这就是所谓的“完全弹性碰撞”。恢复则是组合使用下列公式:
float32restitution;
restitution=b2Max(shape1->restitution,shape2->restitution);
夹具通过携带碰撞过滤器的信息来帮助你阻止游戏对象之间的碰撞。
当一个形状发展多种接触时候,恢复会被近似模拟.这是因为Box2D使用一个迭
代求解器进行求解。当碰撞速度小的时候,Box2D也采用弹性碰撞。这是为了防
止抖动。
过滤
碰撞过滤可以帮助你防止fixture之间的碰撞。例如,你创建一个骑着自行车的
角色,你像让这个自行车和角色与地形碰撞,但是你不想让自行车与角色碰撞(因
为他们必须重叠), Box2D通过类别和分组支持这样的过滤碰撞。
Box2D支持16种碰撞类别,对于每一个夹具,你都能制定其属于哪一个类别。你
也可以制定这个夹具可以与哪种类型碰撞。例如,
你可以在一个多人游戏中指定,所有玩家之间不能互相碰撞,怪物与怪物之间不
能碰撞,但是玩家与怪物之间可以碰撞。Thisis donewith maskingbits.例
如:
playerFixtureDef.filter.categoryBits=0x0002;
monsterFixtureDef.filter.categoryBits=0x0004;
playerFixtureDef.filter.maskBits=0x0004;
monsterFixtureDef.filter.maskBits=0x0002;
这是碰撞规则:
uint16catA =fixtureA.filter.categoryBits;
uint16maskA =fixtureA.filter.maskBits;
uint16catB =fixtureB.filter.categoryBits;
uint16maskB =fixtureB.filter.maskBits;
if((catA &maskB)!=0&&(catB&maskA) !=0)
{
//fixtures cancollide
}
碰撞组让你指定一个整体分类指标。你可以让所有包含相同群指标的夹具永
远碰撞或者从不碰撞(negative index).集团指标通常用于一些相关的东西,像
自行车的一部分,在下面的例子中,夹具1和夹具2一直互相碰撞,但是夹具3和
夹具4却始终不碰撞。
fixture1Def.filter.groupIndex=2;
fixture2Def.filter.groupIndex=2;
fixture3Def.filter.groupIndex=-8;
fixture4Def.filter.groupIndex=-8;
不同的群指标(groupindex)夹具之间的碰撞,会根据类别和屏蔽位(mask
bits)而被过滤。换句话说,集团过滤优先级高于类别过滤。
注意在Box2D中的额外碰撞过滤,清单如下:
静态body上的夹具只能与动态body上的夹具碰撞
运动的body上的夹具只能与动态body上的夹具碰撞
相同body上的夹具永远不能互相碰撞
Youcanoptionallyenable/disablecollisionbetweenfixtureson
bodiesconnectedby ajoint.
有时候当一个fixture被创建的时候,你可能需要修改它的碰撞过滤。你可以用
b2Fixture::GetFilterData和b2Fixture::SetFilterData获取和设置一个已经
存在的fixture的b2Filter结构。要注意过滤数据不会增加或删除接触,直到
下一个时间步。
6.3 传感器
有些时候,游戏逻辑需要知道,什么时候两个fixture相交但不会碰撞。这将通
过传感器实现。传感器可以检测碰撞但不会产生碰撞反应。
你可以将任一shape标记为传感器,传感器可以是静态或动态的。记得,每个物
体上可以有多个shape,并且传感器和实体shape是可以混合的。传感器可以
是静态的或者动态的。记住每个body都可以有多个fixture并且也可以有任何
的混合传感器,和固体fixture。
传感器器不会产生触点,有两种方式获得感应器的状态;
1. b2Contact::IsTouching
2. b2ContactListener::BeginContactandEndContact
另外,有下边一些概念要记住:
1,钢体
2,形状
3,约束
4,接触约束
5,关节
6,关节限制
7,关节马达
8,世界
一、创建一个世界的步骤:
1.先创建世界的AABB盒子:
b2AABB worldAABB;
worldAABB.lowerBound.Set(-100.0f,-100.0f);
worldAABB.upperBound.Set(100.0f,100.0f);
2.再设置世界的重力失量
b2Vec2 gravity(0.0f,-10.0f);
3.再设置是否使能世界体眠功能
bool doSleep = true;
4.创建世界
b2World World(worldAABB,gravity,doSleep);
二、创建一个物体的步骤:
1.创建物体定义
b2BodyDef groundBodyDef;
2.设置定义物体的初始坐标
groundBodyDef.position.Set(0.0f,10.0f);
3.使用世界创建这个物体
b2Body *groundbody = world.CreatBody(&groundBodyDef);
4.创建物体定义形状
b2PolygonDef groundShapeDef;
groundShapeDef.SetAsBox(50.0f, 10.0f);
5.将形状绑定到物体
groundBody->CreateShape(&groundShapeDef);
三、创建活动物体
1.先使用世界创建一个物体
b2BodyDef bodyDef;
bodyDef.position.Set(0.0f, 4.0f);
b2Body* body = world.CreateBody(&bodyDef);
2.设置形状,并设定物体密度和摩擦系数
b2PolygonDef shapeDef;
shapeDef.SetAsBox(1.0f, 1.0f);
shapeDef.density = 1.0f; //密码,如果密度为0说明物体是固定物体
shapeDef.friction = 0.3f; //摩擦系数
body->CreateShape(&shapeDef);
body->SetMassFromShapes(); //通过物体形状和密度设置物体质量
四、模拟
float32 timeStep = 1.0f / 60.0f;
int32 iterations = 10;
for (int32 i = 0; i < 60; ++i)
{
world.Step(timeStep, iterations);
b2Vec2 position = body->GetPosition();
float32 angle = body->GetAngle();
printf("%4.2f %4.2f %4.2f\n", position.x, position.y, angle);
}
说明一下,以上的代码是box2D的2.0版的,2.2.0版好像形状这一块改了一些东西,我这里找到的是2.0版的说明文档