注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

风的驿站

一徐清风,半指烛光,觥筹已净,只余茶香。残卷一章,妙趣非常,忽闻帘响,愿闻其详?

 
 
 

日志

 
 
关于我

喜欢写生 编程 音乐 设计 喜欢把自己的想法变成实实在在的东西 喜欢安静的做一些事情 CSDN博客:http://blog.csdn.net/qwertyupoiuytr

网易考拉推荐

【原创】Box2D v2.3.0 用户指南(第七章)  

2014-05-25 18:44:15|  分类: Box2D |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
Box2D v2.3.0 用户指南(第七章) - 远行的风 - 风的驿站

第七章 装置(fixture

7.1 简介

回想一下,我们曾经说过形状并不知道它依附于的物体的存在,它们能够在物理模拟中独立使用。因此Box2D提供了b2Fixture类来讲形状附加到物体上。一个物体可以没有装置,也可以由多个装置,一个有一个以上装置的物体通常称为一个组合体(compound body)。

装置有以下组成元素:

· 一个单独的形状

· broad-phase代理(可以有多个)

· 密度(density),摩擦力(friction)和弹力(restitution

· 碰撞过滤标记(collision filtering flags

· 指回父物体的指针

· 用户数据(user data

· 传感器标记(sensor flag

 

7.2 创建装置

要创建一个装置,首先需要初始化一个装置定义(fixture definition),然后将装置定义作为参数传给父物体的方法:

b2FxitureDef fixtureDef;

fixtureDef.shape = &myShape;

fixtureDef.density = 1.0f;

b2Fixture* myFixture = myBody->CreateFixture(&fixtureDef);

这段代码创建好一个装置,并且将这个装置附加到物体上。你不需要去保存这个装置的指针,因为当父物体被析构的时候,这个附加到物体上的装置也会被自动析构。你可以创建多个装置附加到物体上。

你可能需要析构一个物体上的装置,以此来模拟一个可分裂的对象,否则的话,你不需要去管它们,让物体的析构函数来替你处理掉附加的装置就可以了。

myBody->DestoryFixture(myFixture);

 

密度

装置的密度是用来计算父物体的质量的,密度可以是0甚至是负数,你应该为所有的装置使用相似的密度,这样做可以提高堆叠的稳定性。

当你设置密度时,物体的质量并不会随之发生改变,你必须要手动调用ResetMassData方法来重新计算物体的质量。

fixture->SetDensity(5.0f);

body->ResetMassData();

 

摩擦力

摩擦力用来让物体更真实的沿着其他对象滑动,Box2D支持静摩擦力(static friction)和动摩擦力(dynamic friction),但是二者使用同一个属性值进行设置。摩擦力在Box2D中能够被精确模拟,摩擦力的大小等于接触面的压力(normal force)乘以摩擦系数,这种称为Coulomb friction(库伦摩擦)。摩擦系数通常在01之间,但是任何非负数都是有效的。当摩擦系数为0时,物体表面没有摩擦力,当摩擦系数为1时,物体表面会具有很大的摩擦力。在计算两个形状之间的摩擦力时,Box2D会结合两个形状的父装置的摩擦系数,通过计算他们的几何平均值得出:

float32 friction;

friction = sqrtf(fixtureA->friction * fixtureB->friction);

因此当其中一个装置具有大小为0的摩擦系数时,整个接触面上就不会有摩擦力存在(摩擦力为0)。

你可以重写b2Contact::SetFriction方法来使用不同的计算方程,这通常实在b2ContactListener的回调函数中完成的。

 

弹性

物体的弹性用来使物体在接触后反弹。弹性系数通常在01之间。我们考虑下面的情形:将一个小球坠落在一张桌子上,当弹性系数为0时,小球完全不会弹起(直接就砸到桌子上不动了),这种情况称为(完全)非弹性碰撞;当弹性系数为1时,小球会以完全相同的速度向上弹起(这意味着小球会达到坠落的初始高度,没有能量损失),这称为完全弹性碰撞。两个物体间的弹性系数通过下面的方程来计算:

float32 restitution;

restitution = b2Max(fixtureA->restitution, fixtureB->restitution);

弹性系数通过这样的方式来计算,这样你就可以有一个非常有弹力的小球,而不需要有一个非常有弹力的地面了。(注:因为是取二者的较大值,所以小球具有弹力就可以解决问题了)

你可以重写b2Contact::SetRestitution方法来使用不同的计算方程,这通常实在b2ContactListener的回调函数中完成的。

当一个形状执行多次碰撞时,弹性会被近似的模拟,这是由于Box2D使用迭代解析器的缘故。当碰撞的入射速度非常小的时候,Box2D会使用(完全)非弹性碰撞进行模拟,这是为了防止抖动。入射速度的阈值请参考定义在b2Settings.h文件中的b2_velocityThreshold常量。

 

过滤(filtering

碰撞过滤允许你避免装置间的碰撞。例如:假设你有一个骑自行车的角色,你希望自行车和地形发生碰撞,角色也和地形发生碰撞,但是你不希望你的角色和自行车发生碰撞(因为显然他们彼此重叠),这时你就需要设置过滤标记。Box2D中通过分类(category)和组(group)来支持这种碰撞过滤。

Box2D支持16种碰撞分类,对于每一个装置,你都可以指定它属于某一个碰撞分类,同时你可以指定那些碰撞分类可以与当前装置发生碰撞。举例来说,在一个多人游戏中,你可以指定所有的玩家彼此之间不发生碰撞,所有的怪兽彼此间不发生碰撞,但是玩家和怪兽之间可以发生碰撞。通过指定蒙版标记(masking bits),例如:

playerFixtureDef.filter.categoryBits = 0x0002;

monsterFixtureDef.filter.categoryBits = 0x0004;

playerFixtureDef.filter.maskBits = 0x0004;

monsterFixtureDef.filter.maskBits = 0x0002;

下面是当碰撞能够发生时的判断条件:

uint16 catA = fixtureA.filter.categoryBits;

uint16 maskA = fixtureA.filter.maskBits;

uint16 catB = fixtureB.filter.categoryBits;

uint16 maskB = fixtureB.filter.maskBits;

if ((catA & maskB) != 0 && (catB & maskA) != 0)

{

// fixtures can collide

}

碰撞组(collision group)允许你指定一个整数的组索引值,你可以设置具有相同组索引值的装置发生碰撞(正索引),也可以设置所有具有相同组索引值的装置不会彼此碰撞(负索引),组索引值通常用于以某种方式相关联的物体之间,比如自行车的部件。在下面的例子中,fixture1fixture2会发生碰撞,fixture3fixture4不发生碰撞:

fixture1Def.filter.groupIndex = 2;

fixture2Def.filter.groupIndex = 2;

fixture3Def.filter.groupIndex = -8;

fixture4Def.filter.groupIndex = -8;

具有不同组索引值的装置在发生接触的时候,通过categoryBitsmaskBits来判断是否发生碰撞,也就是说,组索引值相比于蒙版标记具有更高的优先级(higher precedence)。

注意,除了上述过滤规则,Box2D中还有下面的过滤规则:

· 静态物体(static)上的装置只能和动态物体发生碰撞

· 运动物体(kinematic)上的装置只能和动态物体发生碰撞

· 同一个物体上的装置之间不会发生碰撞

· 你可以选择“启用/禁用“关节绑定的物体上面的装置的碰撞

有时候你需要为已经创建出来的装置指定碰撞过滤条件,你可以通过调用b2Fixture::GetFilterDatab2Fixture::SetFilterData方法来获取(get)和设置(set)装置的b2Filter结构。需要注意的一点是,修改过滤条件不会在当前时间间隔(time step)生效,下一个时间间隔才会起作用(参考世界类)。

 

7.3 传感器(sensor

有时候游戏逻辑需要知道两个装置重叠在了一起,尽管此时没有发生任何碰撞,这可以通过传感器来实现。传感器是一种能够察觉到碰撞的装置,但是传感器不会响应这个碰撞。

你可以将任何一个装置标记为传感器,传感器可以使静态的(static),运动的(kinematic),或者动态的(dynamic),我们知道一个物体上可以附加多个装置,所以在物体上传感器和真正的装置(非传感器)可以混合存在。此外,当接触的两个物体之中至少有一个动态物体时,传感器才会感知到物体彼此接触,所以传感器无法够捕获这几种物体之间的接触:运动物体-运动物体,运动物体-静态物体,静态物体-静态物体。

传感器不会生成接触点,有两种方法可以得到传感器的状态:

1.    b2Contact::IsTouching

2.    b2ContactListener::BeginContact and EndContact


  评论这张
 
阅读(303)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017