《游戏引擎架构》笔记十二

碰撞及刚体动力学

一些碰撞/物理系统:http://www.gamedev.net/community/forums/topic.asp?topic_id=463024

  • I-Collide:http://cs.unc.edu/I-COLLIDE
  • SWIFT:
  • ODE:http://www.ode.org
  • Bullet:http://code.google.com/p/bullet/
  • TrueAxis:http://trueaxis.com/
  • PhysX:
  • Havok:
  • PAL:http://www.adrianboeing.com/pal/index.ht ml
  • DMM:

碰撞检测系统
物理世界
形状

  • 相交、
  • 接触(分离矢量,沿该矢量运动就能高效脱离碰撞妆容)、
  • 凸(由形状内发射的光线不会穿越形状两次以上)

原型

  • 球体、
  • 胶囊体、
  • 轴对其包围盒AABB、
  • 定向包围盒OBB、
  • 离散定向多胞形discrete oriented polytope DOP、
  • 任意凸体积、
  • 多边形汤(碰撞引擎必须和每个三角形测试)、
  • 复合形状

碰撞测试

  • 点和球体相交
  • 球体和球体相交
  • 分离轴定理:凸形状于该轴(分离轴)上的投影不重叠,能确定两个形状不相交。分离两个物体的轴/面称为分离线/面。三维空间中,分离轴仍然是个轴,分离线变成分离面。可以把形状逐一投影到各个潜在分离轴,并检查投影区间是否相交
  • AABB相交:分离轴定理。三个轴x,y,z。只有在三个轴都重叠,才是相交的。
  • 检测凸碰撞:GJK算法。依赖闵可夫斯基差:把A中的所有点与B中的所有点都成对相减,得到的集合就是闵可夫斯基差。当且仅当两个形状相交,闵可夫斯基差包含原点。GJK尝试在闵科夫斯基的凸包内,尝试找出一个包含原点的四面体。若找到,则相交。
  • 运动物体间的碰撞:
    • 离散的静态碰撞;
    • sweep shape扫琼形状做静态测试(结果不准确);
    • 连续碰撞检测continuous collision detection CCD,求出最早的冲击时间TOI

性能优化

  • 利用时间一致性避免每帧重新计算一些类型的信息
  • 空间划分:八叉树、二元空间分割树、kd树等
  • 粗略阶段,中间阶段,精确阶段:先AABB测试哪些物体会碰撞;再用符合形状的逼近包围体检测;最终测试碰撞体中个别碰撞原形是否相交。
  • 扫琼裁剪:sweep and prune,对各个膨胀提的AABB的最小,最大坐标再三个主轴上排序,然后通过遍历改有序表检测AABB之间是否重叠

碰撞查询

  • 光线投射:投射的物体并不存在于碰撞世界,不会影响其他物体。返回一个t值,P = P0(起点) + td(矢量增量)
struct RayCastContact{
    F32     m_t;//此接触点的t值
    U32    m_collidableId;//击中哪个可碰撞体?
    Vector m_normal;//接触点的法向量
    //其他信息
};
  • 形状投射:传回的接触信息比光线投射更复杂,且必须返回多个接触点。
struct RayCastContact{
    F32     m_t;//此接触点的t值
    U32    m_collidableId;//击中哪个可碰撞体?
    Point   m_contactPoint;//实际接触点的位置
    Vector m_normal;//接触点的法向量
    //其他信息
};
  • Phantom:查询碰撞体是否在其他指定体积里。对于其他碰撞体是透明的,也不参与动力学模拟。phantom会持续在碰撞世界里存在。

碰撞过滤:决定碰撞体之间的接触是否成立

  • 碰撞掩码及碰撞层:对世界中物体分类,然后用一个查找表判断某类碰撞物体能否与另一些分类碰撞。
  • 碰撞回调:当碰撞库检测到碰撞时调用回调函数。回调函数可以检查碰撞的具体信息,然后按自己的条件决定接受或拒绝碰撞。
  • 碰撞材质:每个碰撞表面关联一组属性,它定义了某种表面在物理上和碰撞上的行为。包含碰撞属性,如音效,粒子效果,摩擦系数等等。

刚体动力学

无约束刚体指可以在3个笛卡尔轴上自由移动,并绕3个轴自由旋转,因此它含6个自由度(degree of freedom ,DOF)。

无约束刚体的运动分为两个部分:

  • 线性动力学:刚体除旋转以外的运动
  • 旋转动力学:刚体的旋转性运动

对于均匀密度的刚体,其质心位于刚体的几何中心;若刚体的密度不均匀,那么就要令每个小块以其质量为权值,求加权平均值作为整个刚体的质心

  其中,r表示半径或位置矢量,即从世界空间原点到该点的矢量。

线性动力学(质点)

  • 线性速度&加速度
  • 力&动量

运动方程求解

  • 力作为函数:位置、速度、时间等的函数(常微分方程(ordinary differential equation ODE))。F(t,r(t),v(t),...) = ma(t)
  • 解析解:找到闭合式函数,描述所有可能的时间值t的刚体位置(例如抛物线),但是游戏中几乎不可能。
  • 数值积分:游戏引擎使用数值积分求解运动方程
    • 显示欧拉:一阶近似,用切线逼近。
    • 距离近似方程:r(t2) = r(t1) + v(t1)Δt
    • 速度近似方程:v(t2) = v(t1) + a(t1)Δt
  • 常微分方程的数值解的特性:
    • 收敛性:Δt趋近于0的时候,近似解趋近真实解?
    • 阶数:误差是O(t^?)
    • 稳定性:数值解是否会稳定下来?

其他的数值积分方法

  • 向后欧拉法
  • 中点欧拉法
  • Runge-Kutta方法族
  • 韦尔莱积分

韦尔莱积分是三阶方法,它需要已知待求时间点的前两个Δt的位置信息或速度信息。实际上是通过泰勒展开消去重复项。

待求时间点是t1 + Δt,已知t1和t1 - Δt的位置信息。则:

  相减得到:

速度韦尔莱积分

  • 计算r(t + Δt) = r(t1) + v(t1)Δt + 0.5a(t1)*Δt2
  • 计算v(t1 + 0.5Δt) = v(t1) + 0.5a(t1)Δt
  • a(t1 + Δt)  (假设a仅仅依赖位置,如果依赖速度,则需要先计算速度近似值)a(t1 + Δt)  = a(t2) = m-1F(t2,r(t2),v(t2))
  • 计算v(t + Δt) = v(t1 + 0.5Δt) + 0.5a(t1 + Δt)Δt

旋转动力学(刚体)

  • 二维:

    • 定向:角度θ(t)(绕z轴旋转)
    • 角速率&加速度:

    • 转动惯量moment of inertia:改变角速率的难易程度。用I表示
    • 力矩torque:用N表示:= x F

二维中力矩必然和z轴平行

二维旋转方程求解

  • 显示欧拉逼近解:

速度韦尔莱积分

三维旋转动力学

  • 惯性张量:inertia tensor,标记为I。刚体的旋转质量由3x3矩阵表示。如果3个主轴对称,则主对角线以外的元素(也叫惯量积)就是0。物理引擎中惯性张量简化为三元素矢量[Ixx, Iyy, Izz]

刚体的定向可以用四元数q表示:

三维中的角速度

三维旋转动力学中,一个刚体在无外力的情况下旋转,其角速度ω(t)可能不是常量,因为旋转轴方向可能会不断改变。因此角速度不守恒,但是角动量(angular momentum,表示为L)守恒。

由于ω不守恒,所以不会像线性速度一般,视角速度为一个基本的量。角速度是第二级别的量,在确定了角动量L后才计算出ω

三维力矩:N = r x F =  = I dω(t)/dt = d(Iω(t))/dt = dL/dt

三维旋转求解

需要直接对L求解

将角速度转化成四元数:ω = [ωx, ωy, ωz, 0]

且:dq(t)/dt = ?ω(t))q(t)

显示欧拉:

需要定期把定向q(t)重新归一化,以消除浮点小数累计无法避免的误差。

碰撞响应

冲量碰撞响应

完全弹性碰撞无任何能量损失;完全非弹性碰撞,两个刚体一起损失动能。

  • 根据动量守恒+动能守恒,得到公式:

  • 无摩擦力下瞬时碰撞的牛顿恢复定律:假设接触点没有摩擦力,冲量必然垂直于表面法线

恢复系数:v2‘-v1‘=ε(v2 - v1)

将两者求解得

若恢复系数ε为1,刚体2的有效质量无穷大,则1/m2 = 0、v2 = 0;则:

其他碰撞响应方法

  • 惩罚性力:力会在短但有限的时间内产生所需的碰撞响应。就类似一个坚硬的阻尼弹簧。它容易实现及理解,适合低速撞击,但不适合高速移动的物体。
  • 约束

摩擦力

  • 静摩擦力
  • 滑动摩擦力
  • 滚动摩擦力
  • 碰撞摩擦力

5. 休眠

将休眠物体移除模拟之外,但是仍然参与碰撞检测

条件:

  • 刚体受到支持
  • 刚体的线性和角动量低于阈值
  • 线性和角动量的移动平均低于阈值
  • 总动能(0.5p·v+0.5L·ω)低于阈值
  • 逐渐减慢其运动,使其平滑的停止

Havok中有模拟岛:潜在近期会互动的物体组成。模拟岛能独立于其他岛模拟,并以整个岛为单位进入休眠。

6.约束

  • 点对点约束:刚体中某个点和其他刚体的指定点对齐
  • 弹簧约束:与点对点约束不同的是,它的两个点会分开一段距离
  • 铰链约束:只能绕铰链旋转。
  • 活塞约束:滑移铰,类似活塞一样的移动。
  • 平面约束

轮子:无限旋转的铰链+阻尼弹簧加入某种形式的垂直悬挂系统

约束链:特殊群组,内含供求解程序使用的物体连接信息。模拟一长串的刚体信息。

布娃娃:刚体用约束互相链接,通常使用约束链提高模拟的稳定性。是由物理系统驱动的程序式动画。

富动力约束(powered constraint):外部引擎间接控制布娃娃的平移和定向。力+动

画,力改变动画

控制刚体的运动

  • 引力
  • 施加力:多数引擎设计为每帧调用一次,力的影响也在该帧内
  • 施加力矩:改变速度&角速度;力偶:一样大,方向相反,离质心距离相同的对点上施加。
  • 施加冲量:速度瞬间改变,无穷短时间内的施力

8.游戏对象和刚体

物理驱动的刚体

游戏驱动的刚体(动画、玩家驱动):可当作含有无穷质量,力和力矩无法改变游戏驱动刚的速度

固定刚体:不参加动力学模拟,只有碰撞的刚体。

9.更新模拟

  • 更新游戏驱动刚体
  • 更新phantom
  • 施以力,冲量并调整约束
  • 步进模拟:
    • 对运动方程数值积分,求出次帧物理状态
    • 碰撞检测
    • 碰撞决议
    • 实行约束
  • 更新物理驱动的游戏对象
  • 执行phantom碰撞投射查询(以回调方式异步查询or使用上一帧的结果同步查询)
  • 渲染
时间: 2024-11-08 06:41:26

《游戏引擎架构》笔记十二的相关文章

游戏引擎架构笔记之基础

此书获誉无数,第一版没看过,直接看的第二版,然后大致看了一眼作者提到的和第一版的区别: 1.C++语言方面的最新进展,也就是C++ 11的标准:第八代主机游戏的架构,XBOX ONE和PS4 2.鉴于音效机制的巨大作用,作者增加了几章关于音效方面的内容. 3.修复了第一版中的一些错误. 我室友才买这本英文书没多长时间,就出新版本了,不知道杂说好,只能说好贵. 作者期望这本书能包括以下内容 1.工业级的游戏引擎是如何架构出来的? 2.游戏开发团队是如何被组织起来的,如何运转的. 3.世间有无数的游

游戏引擎架构笔记之逐层设计

软件设计最底层是什么?当然是硬件平台了.书里其实有点迷惑,说硬件呢,为啥要说Microsoft Windows, Linux and MacOS-based PCs这种系统呢?其实目前的PC,应该可以安装各种系统吧.我想这一层是硬件设备.包括桌面计算机(PC,当然也包括笔记本吧),手持设备包括各种的phone,pad,主机游戏设备XBOX,PS,WII等.这一层能考虑什么呢,首先手持设备的特性,尤其像wii之类特殊的,还有屏幕分辨率等都是要考虑的,另外设备升级,比如增加了方向盘,或者头盔显示器,

《游戏引擎架构》读书笔记1-游戏引擎中的C++

3月底,我暂时结束了北京的工作,从原来的公司离职,主要是为了学习游戏开发的底层知识和3D引擎相关的内容,并进行技术转型,为了鞭策自己的学习,未来博客更新会比较频繁,现阶段主要是<游戏引擎架构>读书笔记系列和unity学习笔记系列. <游戏引擎架构>在两年前就买了,而且自己也大体的看过一遍,因为自己想学习引擎的底层知识,所以重新又找出了这本书再读一遍,并把根据自己的理解写一些读书笔记在这里与大家交流,另外因为想有一个新的开始,近期都会在博客园这里写技术博客了,前些日子搞了个自己的网站

游戏引擎架构.pdf高清版免费下载

下载地址:网盘下载 备用地址:网盘下载 内容简介编辑[1]  <游戏引擎架构>同时涵盖游戏引擎软件开发的理论及实践,并对多方面的题目进行探讨.本书讨论到的概念及技巧实际应用于现实中的游戏工作室,如艺电及顽皮狗.虽然书中采用的例子通常依据一些专门的技术,但是讨论范围远超于某个引擎或API.文中的参考及引用也非常有用,可让读者继续深入游戏开发过程的任何特定方向.<游戏引擎架构>为一个大学程度的游戏编程课程而编写,但也适合软件工程师.业余爱好者.自学游戏程序员,以及游戏产业的从业人员.通

MySQL技术内幕-InnoDB存储引擎-读书笔记(二)

MySQL技术内幕-InnoDB存储引擎-读书笔记(二) 作为php开发,使用mysql总是少不了的 系列文章博客链接 http://itsong.net/articles/466.html 第三章 文件 mysql与innodb几个类型的文件 参数文件,配置路径.初始化参数.内存大小等 日志文件,包括错误日志,二进制日志,慢查询日志,查询日志 socket文件,用unix域套接字,unix domain socket来进行连接时需要的文件,这一般是本机连接,比通常tcp快 pid文件,进程id

Swift学习笔记十二:下标脚本(subscript)

下标脚本就是对一个东西通过索引,快速取值的一种语法,例如数组的a[0].这就是一个下标脚本.通过索引0来快速取值.在Swift中,我们可以对类(Class).结构体(structure)和枚举(enumeration)中自己定义下标脚本的语法 一.常规定义 class Student{ var scores:Int[] = Array(count:5,repeatedValue:0) subscript(index:Int) -> Int{ get{ return scores[index];

虚拟机VMWare学习笔记十二 - 将物理机抓取成虚拟机

1. 安装VMware vCenter Converter Standalone Client 运行虚拟机,File -- Virtualize a Physical Machine 这时如果电脑中没有VMware vCenter Converter Standalone Client ,则会进行安装. 安装过程 之后图标会出现在桌面上,双击运行 选择连接到本地服务器,登陆 点击转换计算机 这个,可以将本地计算机抓取成虚拟机,也可以将其他可以访问的计算机(需知道管理员用户名及密码)抓取成虚拟机.

swift 笔记 (十二) —— 下标

下标 swift允许我们为 类,结构体,枚举 定义下标,以更便捷的方式访问一大堆属性.比如Array和Dictionary都是结构体,swift的工程师已经为这两个类型提供好了下标操作的代码,所以,我们才可以通过 myArray[2]这种方式,读取和改写这个struct中保存的数据.而且,一个类型中可以定义多种下标访问方式(重载,关于重载,在后面的笔记中会提到,这里先不用太在意) 下标可以定义为"读写"型的,也可以定义为"只读"型,这种行为,是通过定义一组操作完成的

游戏引擎架构读书心得(一)

最近在读<游戏引擎架构>这本书,虽然感觉理论颇多,而且很多很多东西都看不懂,不过还是简单的把一些感觉很好的思想和方法或者概念记录下来. 1.      关于各个部件初始化,一个最简单粗暴的办法就是将各个部件按顺序排列起来,不但可以方便的看到初始化顺序,而且修改也十分容易. 2.      关于内存分配: a)        游戏中最常见的法则是-维持最低限度的堆分配,并且永远不在紧凑的循环中使用堆分配. b)        定制的内存分配器,先预先申请一大块内存,然后构建自己的内存分配器(st

《Hibernate学习笔记十二》学生、课程、分数关系的设计与实现

<Hibernate学习笔记十二>学生.课程.分数关系的设计与实现 这个马士兵老师的Hibernate视频学习的一个题目,这里面要用到多对多.多对一的关联关系以及联合主键,因此觉得挺好的,自己写篇博文来记录下. 先考虑数据库表 1.学生表:为简单起见,只考虑了学生id和学生姓名,其中id为主键 2.课程表:为简单起见,只考虑了课程id和课程名称,其中id为主键 3.分数表 分数表有两种解决方案 3.1 第一种为:使用联合主键:student_id 和 course_id 3.2 第二种:不使用