游戏物理引擎之静态碰撞

  最近在编写一些简单的物理引擎,在编写静态碰撞的时候遇到了小问题,经人指点后终于弄懂了,现在写出来分享下。

  物理引擎主要是用来模拟大自然的力的作用。在我看来,物理引擎主要有两个机制:

  • 作用力发生器。就是来模拟诸如重力、阻力、弹簧弹力等常见的牛顿力。
  • 碰撞。这里的碰撞是非常广义的,基本上作用力发生器模拟不了的情况都能用碰撞模拟。


  这里扯一个题外话,在计算机动画里,特别是物理引擎中主要处理的是质点的位置和速度,很多大自然的物理都是近似看成由多个质点组成的。所以,碰撞主要解决的是三类问题:

  • 碰撞过程中质点的速度变化,这个很简单,由动量守恒公式(即m1v1+m2v2=m1‘v1‘+m2‘v2‘)就可以模拟出来。
  • 碰撞过程中质点的位置变化,这个属于碰撞检测问题,有许多成熟的算法,这里不做详述。
  • 静态碰撞问题。就是如何利用碰撞来模拟物理静止的过程。我们今天就来讨论一下这个问题。


  在计算机图形学中,我们可以利用OpenGL等图形API在三维场景中绘制一些三维图形,比如地面、桌子、小球等。但是计算机本身不知道什么是地面,什么是桌子,所以在当我们给地面上添加一个受重力作用的静止小球,我们看到的只会是小球一直下落,而不是静止在地面上。当然我们可以加一些几何约束(y<0时,y=0),强行让小球在地面上,但是我们用物理引擎模拟显然不能做,我们可以将这种情况模拟成碰撞,这一类的碰撞都称为静态碰撞。如图1,可以看第2帧的时候小球位于地面下面,我们可以认为这时小球是与地面相交的,生成碰撞。

图1

  我们肯定不希望我们的程序中物体没有静止在地面上,反而穿过地面继续下坠。我们需要对碰撞行为进行检测。如上图,我们可以看出在第1帧状态下,小球的位置是没有问题,但到了第2帧,小球与地面相交了。所以我们要寻找一个通过两帧的碰撞信息就能判断出第1帧状态下小球是否是静止的。我们结合上图分析,因为小球只受到重力作用,即小球的速度仅由其重力引发,对此,可简单的将多用力乘以第1帧和第2帧之间的时间间隔(duration),进而得到基于当前作用力下的速度数据,这个速度我们写作Vg。由于我们将小球作碰撞处理,所以由碰撞机制可以得到小球在第2帧的真实速度V。我们比较Vg和V,如果实际速度V小于Vg,则可知小球在第1帧中处于静止状态。



  那么问题来了,为什么比较这两个速度就可以确定小球在前一帧就是静止状态?我们结合图2来分析一下。在小球第1帧静止在在地面V=0,但是我们计算一下如果按碰撞处理的话,小球肯定会产生一个方向向上的速度V‘。这时我们再跟Vg进行比较,V‘<Vg,说明小球并没有向上运动的趋势,所以小球的初始前一帧状态要么是静止要么是速度非常非常小,都可以近似作静态碰撞处理。

图2

  最后贴一段处理这个过程的代码。

double newSepVelocity = -separatingVelocity * restitution;

CVector3 accCausedVelocity = particle[0]->GetAcceleration();
if (particle[1]) accCausedVelocity -= particle[1]->GetAcceleration();
double accCausedSepVelocity = accCausedVelocity * contactNormal * duration;

/*比较合外力产生的速度和碰撞后物体的速度*/
if (accCausedSepVelocity < 0)
{
  /*newSepVelocity为正值*/
  newSepVelocity += restitution * accCausedSepVelocity;

  if (newSepVelocity < 0)
    newSepVelocity = 0;
}

  

时间: 2024-11-05 14:41:47

游戏物理引擎之静态碰撞的相关文章

Unity2D游戏物理引擎演示

原文地址:https://www.cnblogs.com/linhongquan/p/8324756.html

Unity的物理引擎是如何实现碰撞的呢?

物理引擎不允许两个碰撞器重叠,当两个或多个物体碰撞时,Unity会根 据他们的旋转速度计算碰撞效果.计算主要根据物体的碰撞器是静止的还 是动态的.物体是不移动的,例如,墙,地面,院子里的喷池等.动态物 体是移动的,例如玩家控制的球,汽车.当计算碰撞时,静态物体不会被 影响,而动态物体会被影响.例如动态的球碰到“静态”的方块时球被弹 开,而方块不受影响.物理引擎有“碰撞器”重叠发生时,物理引擎孩子 计算碰撞器体积,并追踪碰撞器重叠,但不会在碰撞重叠的物体上体现出 来,因为这不叫碰撞.我们把碰撞器放

COCOS2DX学习之box2d物理引擎在VS2012中的配置

因为vs中并没有继承box2dz游戏物理引擎,所以在开发有关box2d的游戏的时候,要自己将这个引擎添加进去.首先在解决方案中添加一个已经存在的项目,这个项目的路径就是你创建的cocos2dx项目的目录里面cocos2d\external\Box2D\proj.win32这个文件夹下面的一个vs工程,把它添加进去编译好,就会看到proj.win32\Debug.win32中有了Box2d的库. 之后,将生成的box2d的库添加到项目属性的连接器中即可 tool是我创建的coocs2dx项目 CO

【Unity笔记】静态碰撞体的陷阱

概念 静态碰撞体(Static Collider):物体勾选为静态Static,有Collider组件,无Rigidbody组件. 静态碰撞体的陷阱 Unity在游戏初始化时,会把所有的静态碰撞体合并为一个很大的Collider,Unity会认为这些物体在游戏中是不能移动的.但是若在游戏中不小心移动了这些静态碰撞体的位置(它们是可以被移动的),那么会导致一个严重的性能问题,所有那些与被移动的静态碰撞体合并到一起的其他静态碰撞体重新被计算. 所以在游戏中不要对静态碰撞体进行移动.禁用disable

unity2D物理引擎之-Rigidbody 2D

虽然Rigidbody 2D大致上可以看成是Rigidbody的2D化,大部分功能也是一致的,但是还是有一些细节问题. 一些事项: 1.任何添加到同一个 GameObject身上或者其子物体身上的 2D Collider组件都隐式的 附属于 那个 Rigidbody 2D. 2.当一个Collider 2D组件附属到一个Rigidbody 2D身上时,它就跟随Rigidbody 2D移动.这时不应该通过直接设置Transform 或者 Collider的偏移量来 移动. 3.附属于同一个 Rig

【Unity 3D】学习笔记三十七:物理引擎——碰撞与休眠

碰撞与休眠 上一篇笔记说过,当给予游戏对象刚体这个组件以后,那么这个组件将存在碰撞的可能性.一旦刚体开始运动,那么系统方法便会监视刚体的碰撞状态.一般刚体的碰撞分为三种:进入碰撞,碰撞中,和碰撞结束.关于休眠可以理解成为让游戏对象变成静止状态.如果给某个游戏对象休眠的状态,那么这个物体将立马静止,不再运动. 碰撞 首先学习下碰撞几个重要的方法: OnCollisionEnter(  ):刚体开始接触的时候,立即调用. OnCollisionStay(  ):碰撞过程中,每帧都会调用此方法,直到撞

Quick-Cocos2d-x初学者游戏教程(八)----------------- 物理引擎和角色

Quick-Cocos2d-x初学者游戏教程(八) 续上章载入 TiledMap 背景后,接下来的这章我们将开始引入物理引擎相关的东西,并且会开始创建我们的游戏角色.游戏地图中各类障碍物和奖励品的创建则会留到下一章. 构建物理世界 首先,物理引擎是干什么的应该不用我说吧?好吧,还是说一下(百度的):物理引擎通过为刚性物体赋予真实的物理属性的方式来计算运动.旋转和碰撞反映.所以用它来模拟真实世界的飞行.掉落等功能是具有得天独厚的优势的,这也是为什么我们的游戏要使用它的原因. 然后,我们要怎样使用物

不使用物理引擎,自己动手做真实物理的模拟投篮游戏

最近打算做一个2D投篮游戏,由于对于BOX2D等物理引擎并不熟悉,加之一开始低估了游戏所需要的碰撞检测复杂度,认为仅仅涉及4面墙,篮球,篮板,篮筐,篮网的碰撞检测并不复杂.因此决定自己实现所需要的碰撞检测.结果实际开始做时磕磕碰碰遇到了许多问题. 1.如何实现像素级碰撞检测. as3原生的hitTestObject只能检测矩形,对于圆形等其他形状就不适用了:打算用hitTestPoint来检测篮球与篮板四个边角,篮筐前后框点,在实践尝试中发现是有问题的,在涉及物体旋转的情况下检测就不精确了.因此

UIDynamic仿物理引擎-浮动碰撞效果-b

最近产品提了个需求(电商的APP-两鲜),需要在APP背景加上几个水果图案在那里无规则缓慢游荡...模仿 天天果园 APP的.好吧,那我就在网上找了很多文章,总结一下写个demo.效果如下: Mou icon 这里用到的是UIDynamic这个类. UIDynamic简介 一.简介 注意:UIKit动力学的引入,并不是为了替代CA或者UIView动画,在绝大多数情况下CA或者UIView动画仍然是最有方案,只有在需要引入逼真的交互设计的时候,才需要使用UIKit动力学它是作为现有交互设计和实现的