python 物理引擎_第十六章:物理引擎

物理引擎

物理引擎概述

物理引擎是一种用于模拟真实物理现象的中间件,可以用来创建虚拟的物理环境,并在其中运行来自物理世界的规则。物理引擎应用的最多的地方就是动画和游戏行业,例如3D游戏开发常用的三大物理引擎:

Havok引擎的授权则比较昂贵和严格,光环4、上古卷轴5等游戏大作使用的都是这款引擎。PhysX虽然现在不开源,但也实行免费推广政策,是Unity3D、CryEngine等游戏引擎的首选。Bullet物理引擎是一款开源、免费的物理引擎,jMonkeyEngine3 选择了与Bullet引擎集成。很多电影、游戏大作都选择使用这些物理引擎,网上有很多关于它们的介绍和对比,所以本文就不再赘述了,感兴趣的读者可以自行探索。

顺便提一下2D物理引擎,应用最广泛的2D物理引擎当属Box2D,以及它的衍生项目 Chipmunk。Cocos 2d、libGDX等2D游戏引擎中默认集成的就是Box2D。Java世界中也有一些比较出色的作品,比如Dyn4j。

除这些知名物理引擎以外,还有其他数不清的物理引擎,使用各种各样的编程语言进行开发(Java、C#、JavaScript、Python……)。我并不想一一介绍这些引擎,而是希望在学习具体的应用方法之前,能够对物理引擎背后的共性有所了解。我的思路是:首先大致了解物理引擎的理论基础,然后进一步分析各种引擎的基本设计思路,最后是探讨物理引擎在游戏引擎中的使用方法。在对物理引擎这个概念已经有所理解之后,再分别学习如何在 jMonkeyEngine 中集成3D物理引擎(Bullet)和2D物理引擎(Dyn4j),甚至自己集成任意物理引擎。

理论力学

如同3D图形引擎是建立在计算机图形学和光学建模的理论基础之上,现代物理引擎也有其理论根基,最主要的就是物理学的分支——理论力学。

理论力学(theoretical mechanics)是研究物体机械运动的基本规律的学科,是力学的一个分支。它是大部分工程技术科学的基础,也称经典力学。其理论基础是牛顿运动定律。20世纪初建立起来的量子力学和相对论,表明牛顿力学所表述的是相对论力学在物体速度远小于光速时的极限情况,也是量子力学在量子数为无限大时的极限情况。对于速度远小于光速的宏观物体的运动,包括超音速喷气飞机及宇宙飞行器的运动,都可以用经典力学进行分析 。

理论力学通常分为三个部分:静力学、运动学与动力学。**静力学(statics)研究作用于物体上的力系的简化理论及力系平衡条件;运动学(kinematics)只从几何角度研究物体机械运动特性而不涉及物体的受力;动力学(dynamics)则研究物体机械运动与受力的关系。动力学是理论力学的核心内容。理论力学的研究方法是从一些由经验或实验归纳出的反映客观规律的基本公理或定律出发,经过数学演绎得出物体机械运动在一般情况下的规律及具体问题中的特征。理论力学中的物体主要指质点、刚体及刚体系,当物体的变形不能忽略时,则成为变形体力学(如材料力学、弹性力学等)**的讨论对象。静力学与动力学是工程力学的主要部分。

质点和刚体的运动是游戏物理引擎中运用最多的技术,因为刚体在发生碰撞时可以忽略物体的形态变化。对于需要实时运算的游戏来说,这意味着只需要针对质点的运动进行模拟,可以极大得简化模拟过程。比刚体更为复杂的是软体,例如布娃娃、弹球、布料等物体,在发生碰撞后会导致模型变形。在游戏中,这种变形通常意味着需要实时计算成千上万个顶点的位置。

设计思路

架构

从架构设计的角度来看,物理引擎是一种中间件(Middleware)。如同汽车发动机一样,它从设计之初就没有打算单独存在,而是作为其它系统的一个组成部分。无论是制作电影还是游戏,都可以根据需要来使用物理引擎。

同时,物理引擎又是一种独立的系统软件或服务程序,它不依赖其他特定的软件或平台而存在。这就导致几乎每个物理引擎都会自己实现一套数据结构、数学库、内存管理、碰撞检测、物理模拟等。但是,没有可视化系统。虽然我们使用物理引擎是为了获得更加真实的游戏效果,但是物理引擎本身并不在乎你的游戏画面,它的作用只是近似模拟物理现象。正因为专注,所以才更加专业。关于这个问题,我曾在知乎上看到过一个相关讨论,刷新了我对物理引擎的认知。

很多人搞错了一点,以为数学库要效率高,这也是我刚开始写引擎和图形程序时候的错觉。后来发现,不是的,游戏引擎的数学库,不是全都要求效率高的,数学库最重要的是“稳定”。因为真正在跑的,AAA游戏,或者重度的MMORPG,最重要的,不是数学运算,而是“架构”。反而数学运算,需要稳。稳到什么程度?havok曾经推销他们的物理引擎,最引以为傲的的,并不是它有多快,而是它的所有物理运算在所有平台上的计算结果都完全一致(评论有朋友修正了这个说法,应该是同样的计算在同一平台上每次计算都一样)。这简直吊炸天啊有木有!!!如果你不明白这句话背后的意义,那么我想你没必要讨论数学库了。

注:这个答主的内容已经删掉了,不过此处还有一个备份,有兴趣的朋友可以去看看。

封装

下面,让我们把目光从宏观的架构设计转移到微观的类和对象设计。站在面向对象分析和设计(OOA & OOD)的视角,物理引擎对现实世界中的物理现象进行了封装。一般来说,物理引擎中总是有这样几类对象:

世界(World)或空间(Space)

物体(Body)

关节(Joint)

形状(Shape)或网格(Mesh)

质量(Mess)

速度(Velocity)

力(Force)

物理世界

在诸多物理引擎中,“世界(World)”是各种物理规则的载体,比如“重力(Gravity)”。与游戏引擎中的场景图类似,“世界”也需要管理场景中的物体。如果你希望模拟物理现象,那么你就得先创造一个世界,再把各种形状的物体添加到这个世界中,然后开动世界的马达,让物体在世界中运动、碰撞、相互作用。

通常我们只需要一个“世界”,但你也可以创造不同的世界。在多个世界中定义不同的物理规则,以此来模拟不同的物理现象,如地表、水下、太空等。除了物理规则以外,“世界”最常见的属性是“边界(Bound)”。这个属性的存在主要是考虑了程序的性能问题,用于剔除超出世界边缘的物体。毕竟我们的游戏画面就那么大,对那些超出玩家感知的物体进行运算可能没有太大的必要。<

你可能感兴趣的:(python,物理引擎)