[翻译]XNA开发之Farseer Physics 2.1 开源2D物理模拟引擎one

转载请著明出处,谢谢

原文:http://www.physicspoweredgames.com/FarseerPhysics/Manual2.1.htm#_Toc213068484

导言

      该Farseer物理引擎是一种易于使用的2D物理引擎。它支持广泛的平台,如微软的XNA , Silverlight的,粮食计划署,和香草。网。 Farseer物理引擎的重点简单,实用的功能,使创造的乐趣,充满活力的游戏。
概览

     使用权的难解问题, Farseer物理引擎的目的是随着时间的推移控制的地位和轮换游戏实体。

     在现实世界中,移动和旋转的东西,由于适用于外加力和扭矩。在Farseer ,情况也是如此。对象称为“机构”代表了现实世界的东西。作为外加力和扭矩被使用,该机构的反应依法二维物理。这些机构的位置和旋转,随后用来更新游戏实体。

在非常简单的概述它的运作方式如:

      1.创建“身体”对象

      2.添加"身体"对象到模拟器

      3.开始游戏的循环

           1.适用于施加力和扭矩,以身体。

           2.更新模拟器

       4.结束游戏循环

    机构设计,没有几何中的二维世界,因此没有任何碰撞的概念

    碰撞, Farseer的“几何”的对象。几何物体的代表作为二维多边形可以是凹或凸。他们是由一组顶点。一个或多个几何连接到一个机构,以便使该机构得到几何意识。这使得机构参加碰撞与其他机构(实际上其他几何重视其他机构,但你得到的图片。 )

Body

  body的核心是物理对象Farseer 。施加力,扭矩和推动力,适用于机构和机构作出反应,因此移动。机构自身不包含任何形式的碰撞意识。如果要建立一个机构,通常使用BodyFactory ,但首先,这里是你如何手动建立一个机构:

ContractedBlock.gifExpandedBlockStart.gifCode
1 int mass = 1;
2 float width = 128
;
3 float height = 128
;
4 Body rectBody = new
 Body();
5 rectBody.Mass =
 mass;
6 rectBody.MomentOfInertia = mass * (width * width + height * height) / 12
;
7 rectBody.Position = new Vector2(100200
);
8 

正如你所见的,计算MOI(转动惯量)为以下的矩形:

 不是每一个记忆MOI形状, Farseer物理为你计算的MOI。所有您需要做的就是使用BodyFactory类中所描述的“Body Factory”一章。
需要注意的是有关机构的立场是相对的中心机构

 

前副图片是正常位置,而后面一副图片是中心位置

这关系到您的定位和绘图代码。当你的位置你的Body,你需要它的相对中心的Body位置。此外,当你想在屏幕上画Body,请务必z注意相对中心。

Body Factory

您创建了一个Body工厂这样的:

Body rectBody  =  BodyFactory.Instance.CreateRectangleBody(PhysicsSimulator,  128 128 1 );

 这个BODY有一个大小为128宽度,高度128的质量1。MOI(转动惯量)帮助你计算。注意PhysicsSimulator做为参数立刻被添加到

Body中。您可以创建所有这些类型的Body工厂:

矩形,圆形,多边形,Body,

最后一个项目(Body)是当您想建立一个Body,没有Farseer计算MOI帮助你。您也可以使用它来创建克隆Bodies.

还有一些超载的每个BodyFactory方法。一个需要PhysicsSimulator对象和另外一个不需要。如果您提供了PhysicsSimulator对象,您创建的机构将被添加到模拟器中。

 Geometry

几何形状(Farseer中的几何 )是碰撞检测的中心。几何需要一个Body和一套顶点(规定为逆时针) ,界定形状的边缘。
虽然该Body是可以被力量,扭矩,和推动力所控制,几何在控制碰撞检测和计算推动力与其他几何图形碰撞。
您通常使用GeomFactory来创建一个几何 ,但首先,这里是你如何手动创建一个几何:

ContractedBlock.gif ExpandedBlockStart.gif Code
1 Body rectBody = BodyFactory.Instance.CreateRectangleBody(1281281);
2 Vertices vertices = new Vertices();
3 vertices.Add(new Vector2(-64-64));
4 vertices.Add(new Vector2(64-64));
5 vertices.Add(new Vector2(6464));
6 vertices.Add(new Vector2(-6464));
7 Geom rectGeom = new Geom(rectBody, vertices, 11);

这将创建一个矩形体,这是一套顶点,它们代表了一个矩形外形(相对于0 , 0 )和一个新的几何形状的定义顶点。 11作为参数插入几何构造的网格单元尺寸。
我们将有一个深入的观察网格单元尺寸的Grid章

GeomFactory

 另一种更容易的方式,并建立一个几何是使用GeomFactory 。该GeomFactory可以创
建一个简单的顶点集合形状如矩形和圆形。所有你需要的是宽度,高度为矩形或半径为界。
这里是一个利用GeomFactory创建几何的例子

1  Body rectBody  =  BodyFactory.Instance.CreateRectangleBody( 128 64 1 );
2  Geom rectGeom  =  GeomFactory.Instance.CreateRectangleGeom(PhysicsSimulator, rectBody,  128 64 );

请注意,您不必提供任何顶点或网格单元尺寸。该GeomFactory为您创造了顶点,计算网格单元尺寸
在某种情况下您想控制的网格单元尺寸。这也对GeomFactory很容易 ,只需使用重载方法,考虑一个网格单元尺寸:

1  Geom rectGeom  =  GeomFactory.Instance.CreateRectangleGeom(PhysicsSimulator, rectBody,  128 64 6.4f );

现在我们有一个网格单元尺寸为6.4 。 (之后的F数显示在C#中,它是一个浮点型)
如果您设置0到网格单元的尺寸,它会为你计算。他们这样的计算是通过寻找几何最短的一侧(64在这种情况下)和乘以它的
默认网格单元尺寸的因式0.1 。这将yeld 6.4 。
您可以调整预设的网格单元的尺寸设定GridCellSizeAABBFactor的GeomFactory对象。
Physics Simulator View

 物理仿真系统认为是用于联合调试,Body的位置,几何调整和碰撞。当您同意这看法,您会
看到锚,碰撞,联络点,中心,小麦的,还有许多其他的信息可能是必不可少Farseer物理相关的问题调试。
物理仿真系统仅用于XNA。在未来调试将用于其他平台。

解释述说明:

有许多配置的调试见解。以下列出的可能发生的:

性能面板
     显示关于时间引擎的信息和目前的机构数量,尺寸,接头,弹簧,控制器和判优器。
     整理:在过去更新所花费的时间来添加和删除几何,机构,接头,控制器和弹簧。
     广泛相碰撞:所花费的时间做了广泛的碰撞检测阶段。
     狭义相碰撞:所花费的时间做的狭隘相碰撞检测。
     适用于施加力:所花费的时间适用于施加力所有弹力,控制器和机构。
     适用于推动力:所花费的时间适用推动力到接头和判优器。
     最新位置:所花费的时间来更新的所有bodies位置

顶点
    显示了顶点拼接成几何形状。他们被视为黑色小像素周围的几何学
AABB
    显示了排列装订盒子的轴(更多关于AABB的在AABB章) 。
联系
    显示了有联系的顶点。显示为红色的小像素。
坐标轴
   显示机构的中心。表现出一个黑色交叉
网格
   显示网格的几何距离缩小阶段用于碰撞检测。就不可能有很多的网格点,
   所以这个选项可能会拖慢。显示为黑色圆圈。 (未启用调试查看图片段)
边缘
   显示几何形状的轮廓边缘。显示为黑色的边缘。
Joints
   旋转,销和滑块关节有可视化

弹簧
   线性弹簧(包括固定和正常)显示黑线之间的两端点。 3圈的位置显示收缩和扩张的路线。

Joints

Farseer物理引擎为您提供一些基本的Joints。您可以用这些节点创建几乎任何相结合动态行为:
      旋转联合*
     角联合*
     角度限制联合*
     引脚联合
    滑块联合

*有一个“固定”版本。固定版本意味着联合为基础的世界,而不是另一个机构作为非固定的版本。
所有joints的重要提示
   有些关节需要锚相对机构的位置和一些需要世界定位点。因此,要注意类型的联合的使用。
   关节附属于机构。
   所有关节共享一些变量和方法。
   锚不必重视内部机构几何。
   当关节打破,他们将被禁用。
如果Joints不能按预期方式工作
  1.请检查您的anchors是正确的。使用PhysicsSimulatorView找到它们(现在这意味着XNA) 。
  2.不改变性能急剧下降。调整缓慢,重新检查您的模拟器。
  3.不必重视锚的内部机构几何。
    不要让您的几何限制你克服困难能力。请记住游戏是50%假的。做什么才能使最终结果是'看'的权利。
开发者注意:

所有的关节都来源于基类联合,如果你有认识,以添加您自己的约束一定要获得你的更好的联合(请与团队共享) 。
共享变量- (这些适用于所有的关节)
  启用-只要让引擎知道是否执行限制
  IsDisposed -让您和PhysicsSimulator知道联合是否已处置
  JointError -获取错误的联合。请注意,并非所有关节产生错误
  断点-定义最大允许值,JointError可以达到前联合被打破了。默认是牢不可破(最高浮点数) 。
  柔软度-这系数用来允许柔软联合。应该在0.0f和1.0f之间 ,一切未定义。这是真的只是用来调整您想要的模
          拟器。一些需要注意的是所有关节会有一些柔软度即使柔软设置为0.0f 。
  BiasFactor -这个系数确定如何顽固的错误将得到纠正。应该在0.0f和1.0f之间 ,一切未定义。默认为0.2f 。
             请注意,设置过高或低会造成很大的不稳定,所以用小递增来改变。
  突破-这事件处理联合破裂时释放资源。这里为你提供一个方法,否则,什么都不会发生。
  标记-一种通用的对象,按您喜好设定任何事情共同的方法- (这些适用于所有的关节)
  验证-确定是否所有机构参与不处置。如果有联合不处置。
  PreStep -运用数学需要更新的联合。只应该用于您编写自己的联合。
  Update-运用数学需要更新的联合。只应该用于您编写自己的联合。
  处置-处置联合

Revolute Joint

这种类型的联合主要添加耦合或多个对象连接在一起。这个联合接受世界向量除存储连接的位置作为两个本地在内向量。联合错误决心找到两名当地载体之间的距离
。这个联合机构是在机构和机构适合的类型。一些值得注意的是,当使用的机构机
构类型,机构仍然可以线性的移动,并在使用固定式机构,该机构只能旋转。
属性
   Body1 -获取/设置的第一个机构的联合。这个属性被命名机构固定旋转接头。
   Body2 -获取/设置第二个机构的联合。这个属性不存在固定的旋转接头。
   -获取/设置锚联合。这是在世界坐标。
   CurrentAnchor -获取世界的坐标联合后的仿真已经开始。有益的借鉴联合。
   SetInitialAnchor -在设置锚之前已经开始的模拟
演示说明:
   黄色的长方形寄托在一个旋转的联合。它可以不动,只转动。使用鼠标来旋转矩形。固定旋转联合是用来实现这一目标。
   旁边的矩形,您将看到一个绿色钉死的长方形,一个红色的长方形。他们可以在世界坐标里移动,但他们无法移动相对对方,
   只有旋转。正常转动的联合是用来实现这一目标

Angle Joint
这个接缝主要是为连接两个Body的同样的角度或者得到目标夹角。简单固定版本用一个目标夹角保持。
他们的主要作用是程序改变Body的角度时不会造成角度猛烈的改变。
如果你改变了角,团体或机构将迅速作出反应,以实现这个角度。
属性
     TargetAngle -获取/设置的该机构/机构将努力实现弧度角。
     MaxImpulse -获取/设置身体/机构将的最大扭矩以利用在试图实现TargetAngle 。默认为高浮点数
     Body1 -获取/设置的第一个机构的联合。这个属性被命名身体关节固定角。
     Body2 -获取/设置第二个机构的联合。此属性并不存在于关节固定角。
事例说明
     左边你看到一个绿色的长方形一直保持在特定的角度。它不能转动,只有移动。固定角度被用来实现这一目标。
     右边看到2黄色矩形共享同一角/旋转。如果您旋转其中之一,另外一个将旋转同样的位移。正常的角度被用来实现这一目标

Angle Limit Joint

同样作为一个角度的联合,但限制,没有目标的夹角,没有扭矩推动力。
属性
   LowerLimit -获取/设置最低的角度,弧度,Body
   UpperLimit-获取/设置最大的角度,弧度,Body。
   Slop-获取/设置在过去的最小/最大限额之间的允许溢出。
   Body1 -获取/设置的第一个Body的联合。这个属性被命名体Body极限固定角。
   Body2 -获取/设置第二个Body的联合。此属性并不存在于Body固定极限角。
演示说明:
   绿色矩形的左边一直在定义的区域保持不断旋转。最低15度,最高50度。一个固定的角度限制的joint是用来实现这一目标。
   这两个黄色矩形正处在一个总是相对彼此在一个特定的角度限制。尝试把他们两个放到在地面上,您将会看到,它不可能让双方稳定地站在地面上。
   最低15度,最高50度。正常角度限制的joint是用来实现这一目标。

Pin Joint

这项联合或许应该被称为导管接头。这两个Body保持一定的距离同时使他们能够旋转
属性
   TargetDistance -获取/设置两个锚点之间的理想距离。如果没有距离的规定,两机构之间偏移量将是目标的距离。
   Body1 -获取/设置联合的第一个Body。在不重新计算TargetDistance的情况下改变它可能导致不稳定。
   Body2 -获取/设置联合的第二个Body。在不重新计算TargetDistance的情况下改变它可能导致不稳定。
   Anchor1 -为Body1获取/设置本地的锚
   Anchor2 -为Body2获取/设置本地的锚
   WorldAnchor1 -为Body1设置世界锚,对绘制连接非常有用。
   WorldAnchor2 -为Body2设置世界锚,对绘制连接非常有用。
演示说明
   两个红色矩形使用结合链共同保持对方与目标之间距离。他们不能移动的很远或者互相靠近。这两个机构还是可以旋转。
   这两个黄色矩形使用滑块联合(如下所示) ,以保持最低和最高之间的对方距离。与结合链联合他们可以进一步远离和彼此更加接近相比。

Slider Joint

这项联合就像一个带有最小/最大的距离限制引脚的联合,这两个Bodies将保持一系列的最低,最高的距离,同时使他们能够旋转。
属性
    TargetDistance -获取/设置两个锚点的理想之间的距离
    Body1 -获取/设置联合的第一个Body。在不重新计算TargetDistance的情况下改变它可能导致不稳定。
    Body2 -获取/设置联合的第二个Body。在不重新计算TargetDistance的情况下改变它可能导致不稳定
    Anchor1 -为Body1获取/设置本地的锚
    Anchor2 -为Body2获取/设置本地的锚
    WorldAnchor1 -为Body1设置世界锚,对绘制连接非常有用。
    WorldAnchor2 -为Body2设置世界锚,对绘制连接非常有用。
    Min-获取/设置锚点可连接在一起的最短距离的。
    Max-获取/设置锚点之间分开的最大距离的。
    Slop-获取/设置在过去最小/最大限额的允许溢出。

Joint Factories

 Joint Factories允许您使用很多相同的方式创建连接,您可以用fatory创建一个body。因为所有的参数都被描述为各种连接,我将只列出了各种使用过的方法。请注意,工厂并不总是设置所有联合所需要的参数。
旋转 Joint Factory

1  CreateRevoluteJoint(PhysicsSimulator physicsSimulator, Body body1, Body body2, Vector2 initialAnchorPosition)
2  CreateRevoluteJoint(Body body1, Body body2, Vector2 initialAnchorPosition)
3 

固定旋转Joint Factory

1  CreateFixedRevoluteJoint(PhysicsSimulator physicsSimulator, Body body, Vector2 anchor)
2  CreateFixedRevoluteJoint(Body body, Vector2 anchor)

铰链结合 Joint Factory

1  CreatePinJoint(PhysicsSimulator physicsSimulator, Body body1, Vector2 anchor1, Body body2, Vector2 anchor2)
2  CreatePinJoint(Body body1, Vector2 anchor1, Body body2, Vector2 anchor2)

滑块 Joint Factory

ContractedBlock.gif ExpandedBlockStart.gif Code
1 CreateSliderJoint(PhysicsSimulator physicsSimulator, Body body1, Vector2 anchor1, Body body2, Vector2 anchor2, float min, float max)
2 CreateSliderJoint(Body body1, Vector2 anchor1, Body body2, Vector2 anchor2, float min, float max)

角度 Joint Factory

ContractedBlock.gif ExpandedBlockStart.gif Code
1 CreateAngleJoint(PhysicsSimulator physicsSimulator, Body body1, Body body2)
2 CreateAngleJoint(Body body1, Body body2)
3 CreateAngleJoint(PhysicsSimulator physicsSimulator, Body body1, Body body2, float softness, float biasFactor)
4 CreateAngleJoint(Body body1, Body body2, float softness, float biasFactor)

固定角度 Joint Factory

1  CreateFixedAngleJoint(PhysicsSimulator physicsSimulator, Body body)
2  CreateFixedAngleJoint(Body body)

限制角度 Joint Factory

1  CreateAngleLimitJoint (PhysicsSimulator physicsSimulator, Body body1, Body body2,  float  min,  float  max)
2  CreateAngleLimitJoint (Body body1, Body body2,  float  min,  float  max)

限制固定角度 Joint Factory

1 CreateFixedAngleLimitJoint (PhysicsSimulator physicsSimulator, Body body, float min, float  max)
2 CreateFixedAngleLimitJoint (Body body, float min, float max)

Springs

Farseer物理引擎为您提供一些基本的弹簧。您几乎可以用组合的弹簧创建任何动力学的行为:
   线形弹簧
   角度弹簧
有一个“固定”版本。固定版本意味着弹簧立足世界,而不是另一个作为非固定的版本的Body。
所有弹簧的重要说明
    有些弹簧需要锚相对于机构的位置和一些需要世界定位点。因此,要注意您使用的弹簧的类型。
    弹簧属于Bodies
    所有弹簧共享一些变量和方法
    锚不必重视几何内部机构。
    当弹簧打破,他们将被禁用。
如果弹簧没有按预期般运动
    请检查您的锚是正确的。使用PhysicsSimulatorView找到它们(现在只能用于XNA) 。
    不能太快的改变属性。缓慢调整和重新检查您的模拟器。
    锚不必重视内部机构几何。不要让您的几何限制你有克服困难能力。请记住游戏是50 %假的。
    做什么才能使最终结果是'看'的权利。
开发者注意:
    所有的弹簧都来源于弹簧基类,如果你有意识可以添加您自己的确保从Spring获得更好的约束(与团队共享)
共享变量- (使用于所有弹簧)
    Enabled-
只要让引擎知道是否强制执行约束没有。
    IsDisposed -让您和PhysicsSimulator知道弹簧已经释放。
    DampningConstant -获取/设置的抑制弹簧。这种行为就像减震器。
    SpringConstant -获取/设置下拉/推动弹簧。可考虑的弹簧的力量。
    SpringError -获取弹簧的错误。请注意,并非所有弹簧产生错误。
    断点-定义允许最大值,可以达到SpringError春季之前被打破了。默认是牢不可破(最高浮点数) 。
    突破-这事件激烈处理时弹簧破裂。这里为你们提供一个方法,否则,什么都不会发生。
    标记-一种通用的对象,您可以设定任何你喜欢的
共享的方法- (这些适用于所有的Joints)
    验证-
确保弹簧的身体/机构仍然存在。如果有任何释放然后弹簧也释放。
    更新-执行数学需要弹簧的更新。只应该用于您编写自己的弹簧。
    释放-释放弹簧。

Linear Spring

 弹簧提供了一个拉/推Body/机构。这些可以在各种工作方式推动以及拉。如果添加正确的连接件任何事件都可以模拟。
属性
     Body1 -获取/设置的第一个连接件的Body。这个属性被命名机构固定线性弹簧。
     Body2 -获取/设置第二个连接件的Body。这个属性不存在固定的线性弹簧。
     Anchor1 -获取/设置Body1的地方支柱 。这个属性被命名机构固定线性弹簧。
     Anchor2 -获取/设置Body2的地方支柱 。这个属性不存在固定的线性弹簧。
     RestLength -弹簧的在不拉或推下的长度。注意:当使用的是Factory,其余长度计算公式为锚之间的距离。如果你想有一个弹簧开始拉或推后,
     作为它是建立属性。更大的价值将导致大长度的弹簧推动机构/机构之外,规模较小的值会导致身体/机构拉到一起。
代码说明
     这两个黄色机构用线性弹簧保持一起。在足够的力量下他们两可以分开。这就像他们用橡皮筋绑着一样。一个普通的线性弹簧用于演示。
     所有演示本手册中使用固定线性弹簧移动/使用外力的机构。用黑线表示弹簧。

Angle Spring

弹簧就像是扭杆
属性
      Body1 -获取/设置的第一个连接件的Body。这个属性被命名机构固定角弹簧。
      Body2 -获取/设置第二个连接件的Body。这个属性不存在固定角弹簧。
      Anchor1 -获取/设置Body1的地方支柱。这个属性被命名体角线性弹簧
      Anchor2 -获取/设置Body2的地方支柱。这个属性不存在固定角弹簧
      TargetAngle -这是角弧度在弹簧的中心,并提供任不加外力。
      MaxTorque -这是最大扭矩,将适用于试图达到TargetAngle 。
      TorqueMultiplier -扭矩乘以此值。使用1.0f使用正常的扭矩。这默认为1.0f 。
代码演示:
      白色物件在中间的功能就像一个跳板。弹簧的角度是固定的类型。这意味着,这是依附在“世界” 。旋转联合用于弹簧的引脚会向世界
      ,使之保持在同样的位置,但仍然允许它围绕旋转的支点。

Spring Factories
弹簧factories允许您创建弹簧在许多相同的方式您可以创建一个机构,一个工厂。因为所有的参数都被描述为各种弹簧,
我将只列出了各种方法。请注意,工厂并不总是设置所需的所有弹簧的参数。

线形弹簧Factory

ContractedBlock.gifExpandedBlockStart.gifCode
1 CreateLinearSpring(PhysicsSimulator physicsSimulator, Body body1, Vector2 anchor1, Body body2, Vector2 anchor2, float springConstant, float dampningConstant)
2 CreateLinearSpring(Body body1, Vector2 anchor1, Body body2, Vector2 anchor2, float springConstant, float dampningConstant)

固定线形弹簧Factory

ContractedBlock.gifExpandedBlockStart.gifCode
CreateFixedLinearSpring(PhysicsSimulator physicsSimulator, Body body, Vector2 anchor1, Vector2 anchor2, float springConstant, float dampningConstant)
CreateFixedLinearSpring(Body body, Vector2 anchor1, Vector2 anchor2, 
float springConstant, float dampningConstant)

角度弹簧Factory

ContractedBlock.gifExpandedBlockStart.gifCode
CreateAngleSpring(PhysicsSimulator physicsSimulator, Body body1, Body body2, float springConstant, float dampningConstant)
CreateAngleSpring(Body body1, Body body2, 
float springConstant, float dampningConstant)

固定角度弹簧Factory

1 CreateFixedAngleSpring(PhysicsSimulator physicsSimulator, Body body, float springConstant, float  dampningConstant)
2 CreateFixedAngleSpring(Body body, float springConstant, float dampningConstant)

Collision detection

 Farseer物理引擎为您提供了一个简便易用的碰撞系统含有2个不同的部分,每个部分有一个或一个以上的算法:
1.广泛相碰撞检测

     a)      AABB

2.窄相碰撞检测  

a)                   Distance Grid

b)               SAT (Separation of Axis Theorem)

每个系统介绍如下:

Broad phase

广泛相碰撞检测依靠先进的算法,以加快碰撞检测,减少了引擎的工作需要做。 我们目前有三种广泛相碰撞检测算法:
     1 。扫描和删除(所谓的SAP )
     2 。选择性扫描
     3 。强力
在扫描和删除算法框架一致,这意味着,如果屏幕上有非常多的物体,这可能是一个坏的选择。这也意味着,如果您的对象在附近的位置有是是最后时限,该算法是好的。
还注意到,在SAP算法不喜欢或teleporting物体以非常高速移动的物体,如同一颗来自末日的子弹。它可能打破它造成不可靠碰撞。
更多信息在SAP可以在这里找到和这里(称为排序和扫描) 。
选择性扫描算法开发了BioSlayer 。SS算法是默认一个Farseer物理引擎。SS最初建于扫描和删除,但有一些变化,使之更好的效果超过SAP公司。
更多SS信息可以在这里找到。
强力算法是最简单的,同时也是最后执行的 。在世界上它遍历所有的几何形状并比较其AABB。强力算法为O ( n ^ 2 )复杂性,但仍然是非常快的低几何计算。

AABB

AABB主张轴包围盒和不结盟的名称说,这是一个包围盒使自己排列成一个轴。所有的几何形状有AABB是每个更新计算,AABB的价格相对低廉,
用于快速测试,如果2几何形状接近对方(或什至触摸)在广泛的碰撞测试阶段。
您可以这样做测试是否2几何形状接近对方:

1  if  (AABB.Intersect(_circleGeom.AABB,_rectangleGeom.AABB))
2  {
3       // The 2 AABB's intersect
4  }

请记住,因为AABB不旋转,它们是几何轮廓的矩形,当您测试2AABB之间的交叉关系的,实际上可能的几何构型并没有触及。看看这些照片。
在AABB是黑色的几何轮廓。正如所看到的,他们不旋转,但轴对齐。如果你仔细的看,您可以看到,接触时产生碰撞是红色。

Narrow phase

狭窄的阶段,我们采取一切对撞机所产生的广泛的阶段,并做进一步的检查他们。
下面是一个简短地概括发生的事情的狭隘阶段:
我们认为,广泛的阶段为我们提供了一个对碰撞几何中的判优器对象。
   1 )用第一几何迭代世界上所有顶点
   2 )如果目前的载体与第二几何交织在一起
      a )如果错误:继续下一个载体顶点列表
      b )如果真正的:创建一个接触和插入的联络名单
   3 )做1和2关于第二个几何
   4 )如果有任何接触的联系人名单,火灾事件的OnCollision提供2几何和联系列表。
判优器类也用来计算推动力,适用于几何形状,当他们碰撞-靠使用接触来发现。
自Farseer物理2.1 ,我们有2个不同的狭窄相碰撞检测算法:
   1 。远程网
   2 。SAT(独立轴定理)
你可以阅读更多关于这些在下列网页中的。

Distance Grid

所有几何形状包含一个网格对象。这是用狭隘的相碰撞检测,并使用“Distance Grid” 。Distance Grid格是一种预先计算网格,每个网格点中包含的距离最近的点的几
何形状和正常在这一点。 (更多正规内容看到物理章)
所有的网格点的距离,属于几何形状内部是否定的。图片的网格,它的要点如下:

一旦距离网格是预先计算的距离和正常的范围内任何一点的网格可以计算的插值网格之间的已知点值。
网格所提供的计算网格单元尺寸的几何构造或使用时GeomFactory 。一个小网格单元尺寸使网格更加精确,因此也使碰撞检测更加准确。
计算网格可以相当费时,因此它可能是一个好主意预先初始化所有的几何尺寸和事先选择一个完美的几何形状网格单元尺寸。更多关于这方面的“Performance”一章。

SAT

SAT或单独轴定理是一个算法附带Farseer物理2.1 。相对于Distance Grid,它仅支持凸多边形的性质。这是一个比距离网格更快的算法,因为它充分利用了凸只有多边形。
作为SAT是根据不同的原则然后远程网格的一些变化需要考虑。
  SAT支持凸只有碰撞检测,但如果凹几何创建它会自动分解(打破)到一套凸多边形。
  SAT不需要任何细分和事实,将创造一个巨大的性能,如果使用性能。SAT处理边缘任何长度只有2个顶点。注: Vertices.CreateRectangle创建一个矩形的16个顶点只有4个是必要的。使用CreateSimpleRectangle而不是每个角落只创造了4一个。
  SAT提供出色的分离重叠几何形状,而距离往往重叠网格的几何构型的顶部,并建立彼此额外不必要的碰撞。这是说,SAT,您可以在同一地点创建若干几何,他们将单独(98 %的情况下) 。
  SAT没有预先计算时间(除非您使用凹几何) 。
  SAT允许动态变化的几何形状。 IE浏览器,您可以将顶点的实时定义几何
使用SAT的狭隘阶段算法,只需切换到它这样做:

PhysicsSimulator.NarrowPhaseCollider  =   new  SAT(PhysicsSimulator);

Collision group and categories

 Farseer为您提供了一种不同的碰撞团体和更先进的碰撞类别。
在默认的情况下所有几何都在碰撞组0里 ,这意味着它与所有其他几何图形碰撞。如果两个几何在同一碰撞集团,他们不会互相碰撞,碰撞的0组是一个例外
以下是如何设定的碰撞组几何:

 

ContractedBlock.gif ExpandedBlockStart.gif Code
1 Body rectBody = BodyFactory.Instance.CreateRectangleBody(PhysicsSimulator, 1281281);
2 rectBody.Position = new Vector2(250400);
3 Geom rectGeom = GeomFactory.Instance.CreateRectangleGeom(PhysicsSimulator, rectBody, 128128);
4 rectGeom.CollisionGroup = 10;
5 Body circleBody = BodyFactory.Instance.CreateCircleBody(PhysicsSimulator, 641); 
6 circleBody.Position = new Vector2(300400);
7 Geom circleGeom = GeomFactory.Instance.CreateCircleGeom(PhysicsSimulator, circleBody, 6420);
8 circleGeom.CollisionGroup = 10;

 即使rectGeom和circleGeom是互相重叠,他们将不与对方冲突。虽然碰撞群体易于使用,他们可以是非常有限的,所以也存在碰撞类别。
有两种性质的利益碰撞时,使用类别
  1 ) CollisionCategories
       a)默认值为CollisionCategory.All
       b )用于确定几何类的一个成员。
  2 ) CollidesWith
       a)默认值为CollisionCategory.All
       b )用于确定类几何碰撞的。
碰撞类别使用所谓CollisionCategory枚举这具有特殊的标志上启用它,所以它能够做到更明智的操作。 (更多信息在这里)

示例:

ContractedBlock.gif ExpandedBlockStart.gif Code
 1 Body rectBody = BodyFactory.Instance.CreateRectangleBody(PhysicsSimulator, 1281281);
 2 rectBody.Position = new Vector2(250400);
 3 Geom rectGeom = GeomFactory.Instance.CreateRectangleGeom(PhysicsSimulator, rectBody, 128128);
 4 rectGeom.CollisionCategory = CollisionCategories.Cat5;
 5 rectGeom.CollidesWith = CollisionCategories.All & ~CollisionCategories.Cat4;
 6 Body circleBody = BodyFactory.Instance.CreateCircleBody(PhysicsSimulator, 641); 
 7 circleBody.Position = new Vector2(300400);
 8 Geom circleGeom = GeomFactory.Instance.CreateCircleGeom(PhysicsSimulator, circleBody, 6420);
 9 circleGeom.CollisionCategory = CollisionCategories.Cat4;
10 circleGeom.CollidesWith = CollisionCategories.All & ~CollisionCategories.Cat5;

 只是为了澄清的运营商是指:
1 。 |这一个或运算
2 。&这是一个与运算
3 。 ~|这是异或运算,
是的rectGeom成员的Cat5 ( 5类) ,并与所有的碰撞,但Cat4 。
是的circleGeom成员Cat4和碰撞,但是与所有的Cat5 。
这意味着,这两个几何不会互相碰撞。

Collision Events

这里有3个不同的碰撞事件
   1 。 OnCollision (以几何级)
   2 。 OnSeparation (以几何级)
   3 。 OnBroadPhaseCollision (在IBroadPhaseCollider接口)
该OnCollision事件触发时,几何访问另一个几何。如果你想显示的碰撞发生与否您将需要返回一个布尔型内活动的方法。
该OnSeparation事件触发时,几何与另一几何碰撞后是分离的。
该OnBroadPhaseCollision事件就像OnCollision事件,但执行已在广泛的阶段。从正在兴建结构从放弃这个事件防止判优器,这意味着,没有冲动的,
没有狭隘的碰撞阶段完成后,几何参与碰撞。
注册事件,做到以下几点:

ContractedBlock.gif ExpandedBlockStart.gif Code
1 Body circleBody = BodyFactory.Instance.CreateCircleBody(PhysicsSimulator, 641); 
2 Geom circleGeom = GeomFactory.Instance.CreateCircleGeom(PhysicsSimulator, circleBody, 6420);
3 circleGeom.OnSeparation += OnSeperation;
4 circleGeom.OnCollision += OnCollision;
5 PhysicsSimulator.BroadPhaseCollider.OnBroadPhaseCollision += OnBroadPhaseCollision;
请注意, OnBroadPhaseCollision活动是BroadPhaseCollider注册的PhysicsSimulator 。
时间发生执行该方法:
ContractedBlock.gif ExpandedBlockStart.gif Code
 1 private bool OnCollision(Geom geom1, Geom geom2, ContactList contactList)
 2 {
 3     return true;
 4 }
 5 private void OnSeperation(Geom geom1, Geom geom2)
 6 {
 7 }
 8 private bool OnBroadPhaseCollision(Geom geom1, Geom geom2)
 9 {
10     return true;
11 }

Impulses

有2个系统的推动力:
     1 。碰撞反应
     2 。手动推力
碰撞反应时所发生的2几何互相碰撞。判优器类中描述的“窄阶段”一章负责计算冲动发生时碰撞。
如果我们得到更多一点的技术,实际结果是,接触计算在狭窄相碰撞检测得到的推动力的应用,使几何形状像真正的物理学。
碰撞反应可以停用设定几何CollisionResponseEnabled为false ,就像这样:

1  Geom circleGeom  =  GeomFactory.Instance.CreateCircleGeom(PhysicsSimulator, circleBody,  64 20 );
2  circleGeom.CollisionResponseEnabled  =   false ;

禁用碰撞响应的意思是它将通过其他所有几何。它仍将启动撞机事件中所描述的“碰撞事件”章。
您也可以将手动推动力施加于Body上。 (记住,这是机构控制的几何动力学和控制碰撞,但判优器控制与几何相关的推动力)您可以申请三种力量/推动一个body。他们的力量和方法,列举如下:

        1.      Force

1.      ApplyForce

2.      ApplyForceAtLocalPoint

3.      ApplyForceAtWorldPoint

4.      ClearForce

2.      Impulse

1.      ApplyImpulse

2.      ClearImpulse

3.      ApplyAngularImpulse

3.      Torque

1.      ApplyTorque

2.      ClearTorque

推力是用来accellerate一个body。您可以将它应用于整个机构或在某一特定点上的机构。您可以使用此添加jetpack的性质作为jetpack加速一段时间。
推动力是用来制造一种推动力到一个body。推动力是更新body的速度而不是象有外力一样使body加速。
您可以使用此,让您的游戏性质跳转。跳涨是一个即时变化的时刻,不加速。
扭矩是用来应用扭矩(roation)到您的身体。您可以打开或将大石头运上山。

Physics Properties

Farseer具有出色的界面改变物理属性的机构和几何形状。大多数属性不工作,而物理引擎正在运行,这使得有可能创造充满活力的行为。
以下列出的物理性能和简短说明他们做了什么:
内部机构类别:
AngularVelocity
     角速度是比率,一个body是旋转。这是衡量弧度每秒。更大的速度,更快的body旋转。
LinearVelocity
    速率是定义为位置变化的率。它也可以被定义为一个body在单位时间位移。这是一个载体,这意味着它不仅告诉你的数量变化,而且还有方向变化。
LinearDragCoefficient
    阻力抗拒的力量,一个机构通过液体或气体(空气)流动的 。在空中如果你有一个body快速移动,由于阻力它会逐渐减慢。在Farseer物理我们没有介质(液体或气体) ,该机构可以移动的,所以你将不得不手动设置机构的阻力系数。
风阻系数越高,就越是需要推力移动身体,将放慢速度。
RotationalDragCoefficient
    正如线性风阻系数,也有一些阻力时,旋转。如果您旋转机构,旋转阻力系数为0 ,它会永远旋转。更高的转动阻力系数,更快的旋转机构将放慢。
转动惯量(MOI)
    转动惯量的一个机构在2D是一个标量值,代表多么困难(或并不难)是旋转体的中心。
内部几何级:
RestitutionCoefficient
   恢复系数是速度之间的比率之前和之后的影响力。如果您设置了恢复系数为1 ,这将创造一个完美的反弹(图像球与地面的影响) ,如果你将其设置为0 ,将不会退回。
FrictionCoefficient
   摩擦本质上是一种力量,阻止两个表面互相接触的材料的相对运动。接触的越密切就越难相对的运动。
一个例子是冰钢,他们有一个非常小的摩擦系数。可以互相之间快速的滑动。另一方面橡胶路面,有一个非常高的摩擦系数,很难滑动。
事情需要注意的是Farseer物理有2个不同的方法来处理摩擦。您可以设置FrictionType的PhysicsSimulator对象有两个中的一个设置:
    平均
    如果其中的一个几何(材料)有摩擦5和其他有摩擦3 ,平均摩擦系数将由4 。
    最低
    它选择从一两个几何(材料)最小的摩擦 。如果2几何有摩擦的5和3 ,最低将3 。
Farseer物理默认平均摩擦类型。

Physics Properties

转载于:https://www.cnblogs.com/315358525/archive/2009/07/01/1514987.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值