Havok Physics 2012(1)

Chapter 1. Introduction

目录
  • Chapter 1. Introduction
    • 1. What is a Physics Engine?
      • 1.1 介绍
      • 1.2 物理模拟
      • 1.3 物理引擎是做什么的?
      • 1.4 Simulating a Cannon Ball 模拟炮弹
      • 1.4.1 Iterations and Accuracy 迭代和准确性
      • 1.5. Linear Physical Units and Values(线性物理单位和值)
      • 1.6. Angular Physical Units and Values 角的物理单位和值
        • 1. Coordinate Systems & Reference Frames 坐标系和参考系
      • 1.7. Physical properties 物理性质
        • 1. Dynamic and Static Friction 动静摩擦
      • 1.8. Collision Detection 碰撞检测
        • 1. Multiphase Collision Detection 多相碰撞检测
          • 1. Midphase Collision Detection 中期碰撞检测
          • 2. Narrowphase Collision Detection 细测阶段碰撞检测
        • 2.Rigid Bodies and Collision Geometries 刚体和碰撞几何
        • 3. Inside and Outside 内部和外部
        • 4. Setting Position and Orientation Directly 直接设置位置和方向
        • 5. Setting the Scene
      • 1.9. Constrained Dynamics 约束动力学

​ 欢迎来到Havok Physics 2012 SDK,这是一种用于快速、实时刚体仿真的物理中间件技术。Havok可以用于对象需要在三维空间中进行实际交互的应用程序中。它已经被部署在300多个游戏中,跨越许多平台和许多游戏类型,包括动作冒险、角色扮演、第一和第三人称射击、体育和汽车游戏。完整的游戏列表可以在我们的网站上找到。

Havok Physics 2012(1)_第1张图片

​ 本章首先介绍了物理引擎,然后概述了Havok physics 2012 SDK以及如何在您的应用程序中使用它。您将在本手册的其余部分中找到关于这里介绍的概念和组件的更详细的信息。


1. What is a Physics Engine?

1.1 介绍

​ 本节旨在提供与物理引擎相关的术语、方法和行为的一般理解。了解了物理模拟的行为之后,让Havok在你的游戏中工作将会变得更加容易。


1.2 物理模拟

​ 物理模拟并不是一个新概念。自从计算机开始从装配线上脱落以来,科学家和程序员就用它们来模拟复杂的情况,如火箭轨迹(弹道运动)、液体流动(流体动力学)和其他复杂的项目。就所需的CPU资源而言,其中许多模拟非常昂贵。他们关心的是高水平的准确性,因此,计算需要以非常高的细节水平执行。游戏物理引擎有一个不同的目标:快速、可信的模拟在非常有限的条件下执行

​ 刚体动力学是电子游戏中最常见的物理仿真形式。出于性能原因,通常对环境做一些假设。

  • 每个对象的形状都是固定的。每个物体都是无限坚硬的。

    如果可以假定物体的形状不变,不管施加给它们的力有多大,将有许多好处。由于可以预先计算或简化大量关于物体如何移动的信息,因此可以实现较大的速度提升。

    在现实生活中,汽车仪表盘与墙壁相撞时,会根据撞击的强度而弯曲(甚至可能被撕掉)。在刚体模拟中,汽车面板将保持完整

    Havok Physics 2012(1)_第2张图片

  • 景观不会动态变化。

    模拟一个完全动态的环境(例如用手榴弹在地上炸洞)在计算上非常昂贵。在大多数游戏中,环境的基本水平是固定的,景观中的物体(如交通锥、行人、垃圾桶等)可以被建模为单独的物理物体,而不是景观的一部分。

    Havok Physics 2012(1)_第3张图片

    游戏环境中需要动态的部分(如水、可折叠的墙壁、可破坏的土地等)可以在基础静态环境之上分层。

  • 为了进行物理模拟,可以简化物体的形状。

    一个对象很少需要像它的图形表示那样多的物理细节。一个简化的表示形状通常被用来代替一个高度详细的游戏多边形网格且没有任何不利影响

    场景中的对象并非同时都是活动的。

    Havok Physics 2012(1)_第4张图片

  • 模拟静止的对象是非常有效的(零CPU时间)。只要在给定的时间内,只有合理数量的对象在移动,就可以创建具有许多对象的大型世界。在一个典型的游戏场景中,可能有许多潜在的活跃的环境对象,如椅子、板条箱、桶等。它们中的大多数在大多数时间里都处于静止状态。物理引擎将进行优化,只模拟当前需要的对象。


1.3 物理引擎是做什么的?

​ 物理引擎不知道也不关心它所模拟的对象在游戏中是如何图形化显示的。它基于对象的物理(而不是图形)描述来模拟对象的运动和交互,但是这些信息可以用来生成“跟踪”模拟的显示。

Havok Physics 2012(1)_第5张图片

​ 一个物理引擎在它的主模拟回路中有三个基本任务要完成(一旦它为给定的场景设置了初始条件):

  1. 确定哪些物体重叠或即将重叠(例如,一艘宇宙飞船与机库壁相撞,或与另一艘宇宙飞船相撞)。这一阶段通常分为三个阶段:宽相、中相和窄相。

  2. 解决作用于物体上的所有力。一些力的产生是由于碰撞检测(例如两艘宇宙飞船相撞),另一些力的产生是由于外部模拟输入(例如环境的引力或船舶发动机的驱动力)。

  3. 将所有力集合起来,通过仿真时间步长进行仿真,计算出物体的新状态(位置、方向、速度、加速度等)。然后使用此信息更新对象的相应显示表示。

    做所有其他的游戏逻辑和重复。


1.4 Simulating a Cannon Ball 模拟炮弹

​ 暂且不考虑碰撞,让我们考虑一下炮弹从火炮中发射后立即进行的模拟。我们知道球的当前位置,速度和加速度。我们知道它的重量和环境状态(即空气阻力、风力、重力)。有了这些知识,物理引擎就可以模拟它的飞行轨迹。

Havok Physics 2012(1)_第6张图片

​ 这幅图说明了我们想要实现的目标。在一段时间内,由于重力的作用,炮弹的上升速度会变慢,它最终会以经典的抛物线轨迹落到地面(假设没有空气阻力)。

Havok Physics 2012(1)_第7张图片
​ 在给定的时间点我们检查球的状态(其速度v和加速度)。了解外部力量作用于我们作出预测其变化位置运行一段时间后(我们称这一时期h秒),如上图所示。这一预测基于以下几个假设:

  1. 牛顿运动定律支配着球的运动。

  2. 在h时间段内,作用在球上的所有外力都是恒定的(即空气阻力、风和重力在这段时间内没有变化)。

  3. 用于计算新位置的数学是准确的(见下文)。

    一般来说,1)通常是一个很好的假设,但是2)和3)会引起问题,并且与计算执行的时间h密切相关

​ 想象一下如何规划从家里到办公室的路线。影响你旅行的因素从来都不是完全相同的,也没有一个简单的方程可以指导你通过交通。如果你把旅行分成更小的部分,并在每一步后重新计划,你的计划就会更准确。

​ 模拟数学也是如此。随着仿真变得越来越复杂,计算仿真中目标的新位置和速度所需的数学也变得越来越复杂。结果,随着时间步长增加,由数学产生的猜测产生的结果不那么准确。

​ 所采取的时间步长越小,在时间步长结束时的结果就越准确。要在时间上向前进一个大的时间步长h,最好把它分成n个连续的小时间间隔h/n的步骤。

Havok Physics 2012(1)_第8张图片


1.4.1 Iterations and Accuracy 迭代和准确性

​ 对于物理模拟,每个结果完全依赖于前面的模拟步骤。如果在一个步骤中产生了一个非常不准确的结果,那么下一个步骤很可能更不准确,导致精度不断下降,直到最终结果变成垃圾(模拟“变得不稳定”或简单地“爆炸”)。

​ 假设我们需要更新游戏中的几何图形,这样它就可以每1/60秒显示一次。为了仿真的准确性和稳定性,我们可能仍然需要在较高的频率下执行物理仿真步骤。我们将这些子时间步骤称为“迭代”。

​ 迭代是不与显示交互的内部物理模拟步骤。iteration参数指定物理引擎在更新显示之前所采取的步骤数。这使得物理仿真的粒度控制独立于显示更新频率。

Havok Physics 2012(1)_第9张图片

​ 在上图中,显示器以1/60秒的速度进行更新,但是物理仿真将以1/240秒的间隔进行。对于每4次迭代,显示只更新一次。通过设置迭代次数,可以独立于显示器控制物理仿真的精度。


1.5. Linear Physical Units and Values(线性物理单位和值)

​ 当使用物理引擎时,维护一致的单元系统是很重要的。不分青红皂白地混合不同的单元会导致不准确、不现实的结果和不一致的行为。使用一组一致的单元非常有价值。

​ 在任何给定的时间都有大量不同的度量方法在使用。尽管处理所有这些单元的复杂性显而易见,但在大多数情况下,您不需要担心它们。但是,知道您可以分析场景和用于确定实现预期目标所需的近似值的单位是很有用的。

​ 一般来说,下面的讨论使用公制。对于我们的目的,度量标准或SI单位表现得很好

  • m = Meters.
  • kg = Kilograms.
  • s = Seconds.
  • N = Newtons (measurement of force: 1 N = force required to change the speed of a 1kg object by 1 m/s in 1 s. This can be difficult to grasp but think of it using an example of a 1 kg weight sliding on 'perfect' ice. Imagine this weight slides at a speed of 1m/s (3.6 kph). It would take 1 N of force applied for 1 s in the opposite direction of the movement to bring the weight to a perfect stop).
  • rad = Radians. 1 rad = 57.2958 degrees = (180 / PI).

表1.1 单位和术语

Name Units, Metric Unit, Imperial Description
Position m ft A better description of this term is displacement or distance.
Velocity m/s ft/s Speed—how fast an object is traveling relative to some frame of reference.
Mass kg Slug A measure of the amount of matter in a body. How difficult it is to move a body.
Momentum kg m/s lb/ft2 速度乘以质量——这个性质决定了改变物体速度所需要的力的大小。例如,一辆卡车比小型摩托车更难停车,即使两辆车以相同的速度行驶,因为卡车的质量更大
Acceleration m/s2 ft/s2 速度随时间的变化率(即物体是在加速还是在减速)
Impulse kg m/s (or N s) lb s 动量变化的量度(通常以牛顿秒为单位)。要瞬间改变物体的速度,给它施加一个冲量。
Force kg m/s2 (or Newton N) lb 物理引擎的基本单位。这个量衡量改变一个物体的速度所需要的努力(即给一个物体一个加速度,或正或负)。

注:有时,为了区别于角速度(稍后讨论),速度、动量和加速度被定义为线速度、线动量和线速度。


1.6. Angular Physical Units and Values 角的物理单位和值

​ 方向通常是最难熟悉的量之一。大多数人(任何不花一整天时间从事太空项目或编写游戏的人)发现很难很好地直观地把握3D方向。请参阅关于方位、旋转和旋向的文章以获得详细的解释

​ 重要的是要记住方向需要一个参考系。旋转是从某处到另一处。你总是需要一个固定的参考系来计算你从哪里旋转。

1. Coordinate Systems & Reference Frames 坐标系和参考系

​ 物体通常的参考系是物体的质心(COM)。对象的COM不难形象化。这是需要支持的一点,以保持对象的平衡。例如,在一部电影中,一辆汽车摇摇晃晃地从悬崖上掉下来,悬崖的边缘在COM下面。施加在物体上的力会根据COM的位置产生不同的结果。

Havok Physics 2012(1)_第10张图片

​ 当一个力作用于或通过物体的COM时,物体的线性加速度发生变化,但没有引入旋转加速度。在左边的汽车在上面的图表蓝色的力量是适用于点的门板。力线穿过COM(绿色框),没有创建旋转。

​ 另一方面,当施加一个力使它不通过COM时,就会引入扭矩(或扭转)(正确的汽车例子)。这个力矩改变了物体的线性加速度和角加速度。在我们的例子中,这导致了从左到右的运动和逆时针旋转。力(或者更准确地说,力线)离COM越远,引入的扭转就越大。同样的道理也适用于冲动。

​ 当应用脉冲和力时,指定应用脉冲或力的点对物体的COM很重要。

表1.2 物理术语和描述

Name Units Description
Orientation Axis + Angle (radians) 物体相对于世界/游戏坐标系的方向.
Angular Velocity Axis + radians/s 物体旋转的速度:即物体每秒旋转的弧度数,通常用它旋转的轴来指定
Moment of Inertia 3 x 3 matrix, kg-m2 惯性质量的角当量。表示物体对其绕任意轴角速度变化的阻力
Angular Momentum kg-m2/s 动量的角等价物。这量化了在给定时间内停止物体旋转所需的扭矩。
Angular Acceleration rad/s2 加速度的角等价物。这是角速度的变化率。
Angular Impulse kg-m2/s or N-m-s 脉冲的角等价物。这是角动量随时间变化的一个度量。表示对物体角速度的瞬时变化的理想化。
Torque kg m2/s2 or N-m 这是力的角等价物。单位是牛顿米。

1.7. Physical properties 物理性质

这些特性依赖于对象的材料,并在物理模拟中影响其行为

表1.3 对象属性

Name Units Description
Friction Dimensionless 摩擦系数(通常为0到1之间的值),它指定一个物体有多“粘”或有多“粗糙”。请看下面更详细的解释。
Restitution Dimensionless 恢复系数(通常为0到1之间的值)指定了两个物体在碰撞中损失了多少动能,例如,当值为0时,所有的能量都损失了,物体在碰撞时似乎完全停止了运动。值为1时,没有能量损失,物体以相等但相反的速度相互反弹。对于0到1之间的值,每次碰撞都会损失一些能量,但不是全部。这是每个对象或每个对象/材质的属性。
Mass kg 测量物体对运动变化的阻力,或物体中物质的量。不要和重量混淆,重量是地球对某一质量的引力。
1. Dynamic and Static Friction 动静摩擦

​ 摩擦力是一种力,它能抵抗两个接触物体相互滑动的趋势。摩擦力是使物体稳定堆放的关键因素(即,在接触点的摩擦力作用下,使物体静止不动)。在所有的碰撞过程中,一定数量的能量由于摩擦而损失(在现实世界中大部分转化为热量)。

​ 摩擦表现为两种形式,静态和动态。静摩擦作用时物体处于静止状态;它是阻止物体移动或滑动的力。如果对一个大到足以克服静摩擦的物体施加一个力,这个物体就开始移动/滑动。此时,动摩擦开始起作用,只要物体与另一个物体或物体表面接触,动摩擦就是使物体减速的力。

Havok Physics 2012(1)_第11张图片

​ 上图显示,巨石被静摩擦固定在原地,直到施加足够的力来打破接触(即木板被提升到足够的高度,重力迫使它移动)。当巨石开始滑动时,动摩擦力开始起作用,与滑动作用相反,产生热量。


1.8. Collision Detection 碰撞检测

​ 碰撞检测是任何物理引擎的核心之一。如果不成熟地实现,它可能会占用游戏模拟所需的大部分CPU时间。我们想知道玩家何时与关卡发生碰撞,子弹何时与玩家发生碰撞,子弹何时与关卡发生碰撞等等。

ps: 关于碰撞检测和物理引擎

​ 物理引擎试图将每个模拟步骤必须测试的可能碰撞的数量最小化。将仿真框架中的每个对象与其他对象进行对比测试,将完全没有效率。物理引擎使用局域性和帧一致性来减少所需的测试数量。

​ 有很多方法可以加速碰撞检测过程:

  1. 减少需要生成详细碰撞结果的碰撞数量(例如,首先使用更简单的碰撞测试)

  2. 减少碰撞测试对象的复杂性

  3. 减少同时移动的物体的数量

​ 给定场景中活动的对象数量(第3点)是CPU负载的主要来源。如果某些对象可以忽略,这将加速仿真。在第2点的情况下,提供详细的碰撞结果的困难与对象的复杂性直接相关,并且总是鼓励使用物理形状的简化表示。首先,我们讨论Havok系统如何试图达到1),减少复杂碰撞的数量。

1. Multiphase Collision Detection 多相碰撞检测

​ 物理引擎使用了一系列的碰撞检测层,每一层都越来越复杂,返回的结果也越来越详细。在使用结果数据转移到下一个阶段之前,每个阶段从测试过程中筛选尽可能多的对象。

Havok Physics 2012(1)_第12张图片

​ 上面是一个碰撞系统的第一次传递的例子。汽车朝着一堆板条箱驶去。每个对象由一个轴向对齐的包围框(AABB)近似,它完全包围每个对象。

​ 底部的紫色线表示沿单个轴的不同边框之间的重叠。只有投影沿所有三个轴重叠的一对对象被传递到下一阶段的碰撞检测。这个过程称为三轴扫描和修剪,并返回所有AABB重叠的对象对。

​ 检测AABB之间的重叠是一个非常快的操作,它允许我们过滤掉大量潜在的冲突对。

​ 当我们考虑一个轴的潜在列表21碰撞对在我们的例子中((7 x6) / 2)我们发现只有5双有重叠的盒子(车和3离开最盒3双,盒子2和3形式另一双,和箱子4和5形式最后一对)。在这种情况下,我们可以忽略其他的对。这有时被称为琐碎的拒绝。

​ 虽然已经确定了可能发生碰撞的物体对,但这并不意味着它们实际上在碰撞,只是它们可能在碰撞。它们需要被一个更精确的碰撞检测层进一步检测。

1. Midphase Collision Detection 中期碰撞检测

​ 现在,潜在冲突对象的集合减少了,可以进行更复杂的测试来确定两个对象在最终将它们传递到细测阶段(NarrowPhase)之前是否存在潜在冲突。中期碰撞检测用于减少复杂对象(如景观)之间的碰撞对数量。

Havok Physics 2012(1)_第13张图片

​ 在上面的图中,我们看到日志将落在一个静态的风景上(风景包含1000个三角形)。粗测阶段(BroadPhase)将检测到所有的日志都重叠在景观的AABB上,并且都可能发生碰撞。通过识别地形中可能与日志发生冲突的三角形,中期可以减少这个问题。这大大减少了可能的碰撞集,现在适合通过到最后的细测阶段(NarrowPhase)。

2. Narrowphase Collision Detection 细测阶段碰撞检测

​ 最后一个阶段执行精确的碰撞测试,以确定物体是否真的碰撞。如果是,则计算相关的碰撞信息(如碰撞点、物体在碰撞点的法线等)。这些计算可能非常CPU密集型,这就是为什么前两个阶段用于修剪在此阶段处理的对象集。

​ 由于这三个步骤都是由物理引擎自动完成的,所以用户只能控制形状的碰撞表示的复杂性。下一节讨论可用于碰撞检测的各种类型的对象形状及其复杂性

2.Rigid Bodies and Collision Geometries 刚体和碰撞几何

​ 碰撞测试对象的形状对碰撞测试的速度有很大的影响。如果可以对物体的形状或碰撞测试的简化几何进行假设,就可以降低计算成本。

Havok Physics 2012(1)_第14张图片

​ 在物理引擎中,对象根据它们的形状进行分类,特定的形状具有特定的属性,这使得它们在碰撞检测时更容易处理。以下列表按复杂性的增加对对象形状进行分类:

  • spheres 球

  • planes 平面

  • boxes 盒

  • polygons 多边形

​ 对于简单形状,可以用物体的隐式数学表示对其进行碰撞测试。对于多边形表示,必须使用复杂表示。在这种情况下,按照复杂性的增加对对象进行分类,如下:

  1. 凸面:想象用玻璃纸包裹一个物体。如果玻璃纸接触到表面的每一个部分(即表面没有玻璃纸无法触及的空洞),那么物体就是凸的,例如沙滩球是凸的,海星不是。把一个物体看成凸面意味着它有内外两面。许多物体也可以近似为凸包(这极大地加快了碰撞测试)。

    近似值的数量代表了碰撞速度和精度之间的权衡。这通常是特定于上下文的;对于下面的汽车底盘,我们可以用一个简单的框表示。如果我们想看到我们的汽车在车顶上旋转和摇摆,那么凸包就能很好地近似于图形网格。

Havok Physics 2012(1)_第15张图片

  1. Polygon Soup:多边形的集合,不一定连接,所有的分组和分类为一个单一的对象。这是检测冲突最昂贵的格式,但也是最通用的。大多数固定级别的数据使用多边形汤格式存储

Havok Physics 2012(1)_第16张图片

3. Inside and Outside 内部和外部

​ 坚固性假设和相互渗透问题的一个主要结果是,你不能认为物体是空心的。一个常见的错误是为一个房间创建一个盒子,并开始在盒子里放置对象,认为这些对象被放置在房间里。任何放置在盒子里的物体都被标记为互相穿透的,当模拟开始时,它们将被简单地推出盒子(可能是以速度!)

​ 避免这种情况的一种方法是使用多边形集合几何体(非连通三角形)或一组框来表示房间/框。这将有一个空心的外壳的房间所期望的效果

4. Setting Position and Orientation Directly 直接设置位置和方向

​ 物理引擎仔细地存储场景中所有对象的状态,并将此状态从一个时间步骤更新到下一个步骤。如果外部系统对场景进行更改,物理引擎需要相应地更新其状态。这是可以的,除非对场景所做的更改违反了物理引擎试图维护的模拟稳定性或一致性。

​ 很容易看出,在物理场景中任意设置一个物体的位置可能会导致问题:

  • If an object is warped to a position that causes interpenetration, without additional information the physics engine must simply guess how to resolve the inconsistency. A physics engine is able to deal with interpenetrations better when it can plan for it.

    如果一个物体被扭曲到导致相互渗透的位置,没有额外的信息,物理引擎必须简单地猜测如何解决这种不一致。一个物理引擎能够更好地处理相互渗透,当它可以计划好它。

  • If other objects are resting or stacked above an object that is warped away while the stack is deactivated, the remainder of the stack will remain floating above the space vacated by the warped object.

    如果其他对象在堆栈停用时在被扭曲的对象之上休息或堆积,则堆栈的其余部分仍将漂浮在被扭曲的对象腾出的空间之上。

  • If other objects are attached to the moved object by springs or constraints, it can lead to huge instability problems. By moving the object abruptly, the connections to the other objects are stretched instantaneously and can cause the system to destabilize and the constraints to oscillate wildly.

    如果其他物体被弹簧或约束附加到移动的物体上,就会导致巨大的不稳定性问题。通过突然移动物体,与其他物体的连接瞬间被拉伸,可能导致系统不稳定,约束条件剧烈振荡

5. Setting the Scene

​ 任何物理模拟的第一阶段都是创建场景。这与构建一个没有物理的3D场景略有不同,您应该记住像避免相互渗透这样的要求。如果你用纯几何的方式构建一个场景,你可能会遇到放置物体的困难,这样它们就可以稳定地停留在其他物体上,同时避免碰撞问题。

Havok Physics 2012(1)_第17张图片

​ 以创建独立桥为例。如果石头互相渗透,所有的石头都将是活跃的,并立即被引擎移开。即使一切都稳定下来了,在最初的模拟步骤中,性能仍然会有很大的提升。

​ 最好的解决办法是先用一小段距离把石头隔开。然后简单地模拟一段时间的场景。这些石头会在很短的距离内落下,并稳定地堆积在一起。最终,当能量管理系统启动时,它们将停止工作。现在您有了一个稳定的堆栈,该堆栈已停用并准备保存。存储桥件的位置。现在你可以使用这些位置来创建你的桥梁,准备好进入你的游戏。


1.9. Constrained Dynamics 约束动力学

​ 在许多情况下,我们想要构造一个物理系统,在一个较大的组件的子部件之间有连接或附件。我们需要能够制造机器、机器人、陷阱和谜题。物理引擎将提供以下任意数量的功能(Havok提供了所有这些功能)。

  • 弹簧:施加在弹簧连接的物体上的力,试图使物体之间保持一定的固定距离(剩余长度)。
  • 阻尼器(一种更机械的弹簧;在现实生活中,防震罐中含有油,可以消除震动。
  • 机械接头:我们周围世界上常见的接头;移动关节(如机器上的活塞、推拉门)铰链关节(如门、幽灵酒馆上方晃动的招牌)、车轴(如车轮、齿轮)、人体关节(从铰链状的肘部到更复杂的身体部位,如肩膀和臀部)以及各种汽车部件。

Havok Physics 2012(1)_第18张图片
​ 约束是创建互连系统的必要条件。作用于一个物体的力同时作用于所有其他相连物体。在上面的例子中,当水转动桨叶时,轴转动,水平齿轮转动垂直齿轮,垂直齿轮转动垂直轴,磨石开始研磨。

*Havok Physics 2012的第一部分介绍到这里就结束了,这一部分是有关物理引擎的介绍,刚入坑havok,发现没有翻译以及教程较少,所以自己翻译之余发上来方便一起学习,若译文内容有不同意见请与我交流,
转载标明出处:作者AMzz 博客: https://www.cnblogs.com/AMzz/

你可能感兴趣的:(Havok Physics 2012(1))