3d碰撞检测技术共30页文档

合集下载

碰撞检测算法

碰撞检测算法

碰撞检测算法
碰撞检测是指在计算机图形学中,用于检测当图形物体移动时是否会相互发生碰撞。

碰撞检测一般使用物理定义来判断物体当前位置是否与其他物体重叠,从而实现移动物体
间的物理相互作用。

通常情况下,碰撞检测涉及计算两个物体在当前空间状态下是否相交,碰撞的检测的两个物体一般是由它们的几何外型所表征的;因此,碰撞检测一般由对物体
几何外型的描述子对应的空间状态来判断是否存在碰撞;更进一步地,碰撞检测还需要判
断相交点在物体表面上的位置,以实现物体间的物理相互作用。

最常用的碰撞检测算法有以下几类:
1. 物体边界检测:这是指基于物体边界外形的一种检测方法,判断物体是否发生碰撞。

这种方法最简单,易于实现,以线段为例,只要计算两条线段的端点之间的距离是否
小于指定的阈值,就可以认定这两条线段是否发生碰撞。

2. 空间栅格化:这种检测方法是将物体的表面看作是一个由许多小空间格子所组成
的网格;当一个物体移动时,只要计算其占据的空间格子是否有交叉的部分,就可以认定
发生碰撞。

3. 形状比对算法:这是一种更加精确的碰撞检测方法,不仅判断物体移动是否发生
碰撞,而且还可以精确判断碰撞点所在位置,实现精确的物理交互模拟。

形状比对算法主
要利用多边形的凸多边形表示来做碰撞检测,以凸包算法为基础,将物体表面中的点多边
形分割成更小的多边形,依据凸多边形的几何关系,实现物体的准确碰撞检测。

上述三种碰撞检测方法都有它们的优缺点,应用时需要结合场景具体要求,根据精度
以及实现复杂度,灵活选择最佳检测算法。

虚拟现实中的碰撞检测技术word文档格式60

虚拟现实中的碰撞检测技术word文档格式60

虚拟现实中的碰撞检测技术word文档格式60摘要实时准确的碰撞检测关于提高虚拟环境的真实性、增强虚拟环境的沉溺感有着至关重要的作用。

该文对碰撞检测相关技术停止了深化的研讨,主要包括以下几个方面的内容:首先引见了虚拟理想技术的开展及现状、碰撞检测的研讨现状;然后复杂引见了碰撞检测一些基础实际知识,着重引见常用的碰撞检测算法。

紧接着,复杂引见了OpenGL编程的基础知识和面向对象编程的特点。

在碰撞检测算法的运用中,运用OBB包围盒层次树的碰撞检测算法,提出了一种普通多面体间碰撞检测的可行性方案,并用软件对该方案停止完成,同时指出该方案的优缺陷。

最后,对全文停止了总结,并指出今后的研讨方向。

关键词:虚拟理想碰撞检测包围盒层次树OBBSTUDY AND IMPLEMENTATION ON COLLISIONDETECTION TECNOLOGY OF VIRTUAL REALITYAbstractReal-time and accurate collision detection is very important to improve reality and enhance illusion of immersion for virtual environment.This paper studies the technique of collision detection deeply.It contains the following parts:Firstly,this paper reviews recent research on collision detection field.Then it introduces some basic knowledge and emphasizes on introduce of collision detection algorithm.Next,it introduces OpenGL and Oriented-object language program character.In collision detection implementation chapter,a scheme of collision detection between general polyhedron is presented by using bounding hierarchy volume algorithm.The method is implemented by vc6.0.And it analyses advantage and disadvantage of the method.Finally,the conclusion is drawn and the work of future research is presented.KEY WORDS: virtual reality collision detection bounding hierarchy volume OBB目录第一章绪论 (1)1.1虚拟理想技术开展及现状 (1)1.1.1 虚拟理想的特点 (1)1.1.2 国际外虚拟理想技术的研讨状况 (2)1.2碰撞检测的研讨现状 (3)1.2.1意义及特点 (3)1.2.2碰撞检测的研讨现状 (4)1.3论文的任务和组织结构 (6)第二章碰撞检测实际 (8)2.1碰撞的定义[3] (8)2.2碰撞检测的模型类别 (8)2.3碰撞检测的场景特征[2] (9)2.4碰撞检测技术的基本原理 (9)第三章碰撞检测算法 (11)3.1空间剖分法 (11)3.2包围盒层次树法 (12)3.2.1包围盒外形的设计准那么 (13)3.2.2包围盒类型 (13)3.3基于特征的距离计算增量算法 (17)3.3.1基本概念 (17)3.3.2 Lin-Canny算法概述 (19)3.3.3顺应性准那么 (20)第四章编程基础实际 (26)4.1O PEN GL编程基础 (26)4.1.1 OpenGL基本特点 (26)4.1.2 OpenGL完成 (28)4.1.3 OpenGL图形绘制 (29)4.1.4 OpenGL光照处置 (30)4.1.5 OpenGL纹理映射 (31)4.1.6深度测试 (33)4.2面向对象的编程 (33)4.3O PEN GL编程环境的设置 (34)第五章碰撞检测算法的运用 (36)5.1物体建模 (36)5.2场景绘制 (39)5.3碰撞检测算法的运用 (42)5.3. 1 基础实际 (42)5.3.2 碰撞检测的完成进程 (44)5.3.4用户交互 (51)5.4本顺序的优缺陷 (53)第六章总结与展望 (55)主要参考文献 (56)..................................................................................................................................................................................第一章绪论1.1虚拟理想技术开展及现状1.1.1 虚拟理想的特点自20世纪90年代初以来,虚拟理想技术不时是信息范围研讨、开发和运用的热点方向之一。

unity3d的碰撞检测及trigger

unity3d的碰撞检测及trigger

unity3d的碰撞检测及triggerA、基本概念  要产⽣碰撞必须为游戏对象添加刚体(Rigidbody)和碰撞器,刚体可以让物体在物理影响下运动。

碰撞体是物理组件的⼀类,它要与刚体⼀起添加到游戏对象上才能触发碰撞。

如果两个刚体相互撞在⼀起,除⾮两个对象有碰撞体时物理引擎才会计算碰撞,在物理模拟中,没有碰撞体的刚体会彼此相互穿过。

物体发⽣碰撞的必要条件: 两个物体都必须带有碰撞器(Collider),其中⼀个物体还必须带有Rigidbody刚体。

在unity3d中,能检测碰撞发⽣的⽅式有两种,⼀种是利⽤碰撞器,另⼀种则是利⽤触发器。

碰撞器:⼀群组件,它包含了很多种类,⽐如:Box Collider(盒碰撞体),Mesh Collider(⽹格碰撞体)等,这些碰撞器应⽤的场合不同,但都必须加到GameObjecet⾝上。

触发器,只需要在检视⾯板中的碰撞器组件中勾选IsTrigger属性选择框。

触发信息检测: 1.MonoBehaviour.OnTriggerEnter(Collider collider)当进⼊触发器 2.MonoBehaviour.OnTriggerExit(Collider collider)当退出触发器 3.MonoBehaviour.OnTriggerStay(Collider collider)当逗留触发器碰撞信息检测: 1.MonoBehaviour.OnCollisionEnter(Collision collision) 当进⼊碰撞器 2.MonoBehaviour.OnCollisionExit(Collision collision) 当退出碰撞器 3.MonoBehaviour.OnCollisionStay(Collision collision) 当逗留碰撞器B、何时触发?下⾯就是我做的测试情况,都是A物体去撞B物体。

⼀、A(碰撞体),B(没有碰撞体,⽆论有没有刚体),没有触发事件。

碰撞检测精华版

碰撞检测精华版

碰撞检测技术碰撞检测在计算机游戏中是用来保证真实世界的正确虚拟化,确保人物不能够穿越墙壁,防止人物坠落到地板以下等。

同时,碰撞检测在游戏中还可以通知敌人是否发现目标玩家,并对玩家发起相应的攻击。

碰撞检测在机器人模拟程序中用于路径规划使机器人避开障碍物,在虚拟样机技术中用于批量生产前物理模型的修正计算,还可用在工程仿真和碰撞测试中。

在游戏、物理引擎以及实时状态中,碰撞检测将耗用大量时间,拙劣的碰撞系统将会导致其瓶颈的产生。

碰撞检测即检测两个或者多个物体是否相交,确定两个物体是否、何处及何时形成碰撞。

“是否碰撞”是计算两个物体是否相交,“何处碰撞”将决定物体如何碰撞,“何时碰撞”将测定碰撞发生的时间。

文章中提出的碰撞检测方案不仅适用于碰撞检测系统,还可用以解决计算机图形学、光线跟踪系统以及地理信息系统等问题。

存在的问题尽管有关碰撞检测的研究成果已经比较丰富,一些算法也在实际中得到了应用,但随着虚拟现实新技术出现,实际应用系统对碰撞检测技术的要求越来越高"目前碰测领域仍然存在着以下问题亟需研究解决"碰撞检测的实时性与逼真性一直以来都是研究者们所追求的终极目标,但两者往往相互抵触"逼真性受两个因素影响:一是场景模型的精细程度,因为要准确仿真虚拟现实中的碰撞效果,就要求模型准确精细,相应的数据量就增大(某些场景存在几十万级以上的多边形,而这样的情况越来越多),碰撞检测的时间开销也更大,所以实时性就很难保证,甚至有些时候不能承受"第二个因素来自于人的视觉需求"目前碰撞检测的速度已能达到1秒钟24Hz以上,基本满足人们视觉的实时感知最低需要,但是要满足人对虚拟环境中力觉再现的真实感知,碰撞检测的速度至少要达到300Hz以上才能维持交互系统的稳定性"因此现有的碰撞检测算法还不能完全达到真正意义上的实时和精确,必须依据实际应用对实时性和真实性的具体要求,在准确性和实时性之间折衷,例如:随机检测算法!基于图像的碰撞检测算法等"所以未来的研究方向势必是研究出适应于复杂场景的高频率的碰撞检测方法,这个目标的实现也和计算机硬件的发展息息相关"。

碰撞检测算法范文

碰撞检测算法范文

碰撞检测算法范文碰撞检测算法是计算机图形学中的一个重要问题,它用于检测两个或多个物体是否发生碰撞。

在游戏开发、虚拟现实、物理仿真等领域中都有广泛的应用。

这个问题可以通过多种算法来解决,下面将介绍几种常用的碰撞检测算法。

1.矩形边界框碰撞检测算法(AABB碰撞检测算法):矩形边界框是一种简单的表示物体边界的方式。

这个算法利用矩形边界框的位置和尺寸信息来判断两个物体是否相交。

如果两个矩形边界框相交,那么可以认为物体发生了碰撞。

这个算法的时间复杂度较低,适用于处理大量物体,但是对于复杂形状的物体可能存在误判。

2.圆形碰撞检测算法:圆形碰撞检测算法适用于处理圆形物体之间的碰撞。

它利用圆心之间的距离与两个圆的半径之和进行比较,如果距离小于或等于半径和,则认为两个圆发生了碰撞。

这个算法较为简单,但是只适用于处理圆形物体。

3.分离轴定理(SAT碰撞检测算法):分离轴定理是一种用于判断多边形之间是否发生碰撞的算法。

它基于一个原理:如果两个多边形没有共用的分离轴,则它们一定发生了碰撞。

分离轴定理需要判断多个分离轴是否存在,对于复杂形状的物体,计算量较大。

4.基于包围体的碰撞检测算法:基于包围体的碰撞检测算法是一种将物体用较简单的几何形状包围起来,然后对包围体进行碰撞检测的方法。

常见的包围体形状有球体、盒子、球树等。

这种算法可以大大减少需要进行精确碰撞检测的物体数量,以提高性能。

5.网格碰撞检测算法:网格碰撞检测算法适用于处理三维物体之间的碰撞。

它将物体分解为离散的小三角形网格,然后通过对网格之间的关系进行遍历检测碰撞。

这个算法对于复杂的三维物体具有较高的准确性,但是计算量较大。

综上所述,碰撞检测算法在计算机图形学中是一个非常重要且复杂的问题。

不同的算法适用于不同的场景和物体形状,开发人员需要根据具体需求选择合适的算法。

同时,随着计算机硬件的不断升级和算法的不断改进,碰撞检测算法也在不断发展,相信未来会出现更加高效和准确的算法来解决这个问题。

三维引擎高效碰撞检测原理

三维引擎高效碰撞检测原理

三维引擎高效碰撞检测原理
嘿,朋友们!今天咱要聊一聊超级酷炫的三维引擎高效碰撞检测原理啦!就好像你在玩游戏,你的角色能那么丝滑地在场景里跑来跑去,还不会莫名其妙地穿透墙壁,这可都是碰撞检测的功劳呀!
你想想看,要是没有高效的碰撞检测,那会成啥样?比如说,你操控的
游戏角色说不定走着走着就直接陷到地里去了,或者能直接从房子中间穿过去,哇,那岂不是乱套啦!这就好比一辆汽车没有刹车系统,那得多危险啊!
三维引擎的碰撞检测就像是给整个虚拟世界安装了一个超级敏锐的“感应器”。

它能时刻察觉到物体之间是否发生了碰撞,而且要超级快速地做出反应。

比如在一个赛车游戏里,你的车要高速绕过其他车辆,如果碰撞检测不及时不准确,那“嘭”的一声,就撞车啦!
这其中的原理其实挺复杂的,涉及到好多数学和算法呢!但咱简单来说,就是要快速判断两个物体是否有重叠的部分。

这可不是随便看看就行的,得精确到每一个像素点呢!哎呀呀,这可真是个精细的活儿呀!
举个例子说吧,就像你搭积木,你得保证每一块积木都稳稳地放在该放的地方,不能歪七扭八的,要不整个“建筑”不就塌了嘛!在三维引擎里,就是要确保每一个物体的行动都符合规则。

三维引擎高效碰撞检测原理真的太重要啦!它让我们能在虚拟世界里尽情畅游,感受到真实的互动和乐趣。

没有它,那我们的虚拟体验可就要大打折扣咯!所以呀,大家一定要好好珍惜这个神奇的技术呀!。

高级碰撞检测及响应算法——碰撞检测

高级碰撞检测及响应算法——碰撞检测

高级碰撞检测及响应算法——碰撞检测2010-11-18 22:351.概述移动的物体可以由椭球体近似表达,这种椭球体更容易逼近类人和动物的形状,比如说人的头,就是一个X-Y-Z轴半径相等的椭球体,髋骨,盆骨等都可以较好地用椭球体体现出来。

多个椭球体组成的集合的形状也使它们易于在障碍物上平滑地移动,这一点在3D游戏中显得特别重要,因为玩家绝不希望在激烈的战斗中自己被卡在某个死角里不能动弹。

我们希望能在场景中来回移动我们的物体(或者角色)。

它可以由一个椭球体表现,其中椭球体的中心位置代表了角色的位置,半径向量则定义了椭球体沿三个轴向的尺寸。

见图3.1。

图3.1:椭球体的半径向量通过对角色施加某方向的力,他就能在场景世界中移动。

这个过程由速度向量(velocity vector)表示。

我们希望椭球体能够在场景世界中移动,那么它的新的位置等于它当前位置加上速度向量。

见图3.2。

图3.2:通过一个速度移动椭球体但是我们还不清楚我们是否能成功完成这个移动,因为可能在过程中会出现一些事情,例如组成场景世界的一个或者多个三角片挡住了椭球体的去路。

我们不可能事先准确地知道椭球体会撞上哪个三角片,所以我们应该检查所有的三角片(这里,可以将一个大的网格体化分成一个八叉树,这个八叉树被用来帮助我们检查那些靠近角色的三角片)。

同时,我们还不能在检测到一个可能碰撞的三角片后就立即停止检测,因为我们要检测出所有潜在的障碍,近而找出最近的那一个碰撞。

如果我们检测到了一个与三角片A发生的碰撞后就停止,而没有继续检测其它的三角片,例如三角片B,那么将发生如图3.3所示的情况,即三角片B比三角片A更先发生碰撞。

图3.3:必须检测所有的三角片碰撞检测过程应该为后继的响应阶段提供至少两个必要的信息:* 球体在场景中的碰撞位置。

* 球体发生碰撞之前,沿速度方向到碰撞点的距离。

所以,对于单个三角片的碰撞检测,我们首先要清楚是否会发生碰撞(这将产生一个bool值),如果发生了碰撞,算法应该能够为碰撞响应提供上述两个必要的信息。

碰撞检测

碰撞检测

二维碰撞检测算法碰撞检测(Collision Detection,CD)也称为干涉检测或者接触检测,用来检测不同对象之间是否发生了碰撞,它是计算机动画、系统仿真、计算机图形学、计算几何、机器人学、CAD\ CAM等研究领域的经典问题。

碰撞物体可以分为两类:面模型和体模型。

面模型是采用边界来表示物体,而体模型则是使用体元表示物体。

面模型又可根据碰撞后物体是否发生形变分为刚体和软体,刚体本身又可根据生成方式的不同分为曲面模型和非曲面模型。

目前对于碰撞的研究多集中于面模型的研究,因为体模型是一种三维描述方式,对它进行碰撞检测代价较高。

而在面模型的研究中,对刚体的研究技术更为成熟。

下面列举几种常用的碰撞检测技术:1:包围盒(bounding box)是由Clark提出的,基本思想是使用简单的几何形体包围虚拟场景中复杂的几何物体,当对两个物体进行碰撞检测时,首先检查两个物体最外层的包围盒是否相交,若不相交,则说明两个物体没有发生碰撞,否则再对两个物体进行检测。

基于这个原理,包围盒适合对远距离物体的碰撞检测,若距离很近,其物体之间的包围盒很容易相交,会产生大量的二次检测,这样就增大了计算量。

包围盒的类型主要有AABB(Aligned Axis Bounding Box)沿坐标轴的包围盒、包围球、OBB(Oriented Bounding Box)方向包围盒和k-DOP(k Discrete Orientation Polytopes)离散方向多面体等。

AABB是包含几何对象且各边平行于坐标轴的最小六面体,两个AABB包围盒相交当且仅当它们三个坐标轴上的投影均重叠,只要存在一个方向上的投影不重叠,那么它们就不相交。

AABB间的相交测试和包围体的更新速度比其他算法效率高,因此使用最广泛,尤其适用于多物体运动的大规模环境和变形体碰撞检测。

OBB包围盒的相交测试基于分离轴的理论的,它的构造关键在于包围盒最佳方向的确定,最佳方向必须保证在该方向上包围盒的尺寸最小。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第 1 页 核心提示:10.3 碰撞检测技术 到目前为止,构造的各种对象都是相互独立的,在场景中漫游各种物体,墙壁、树木对玩家(视点)好像是虚设,可以任意从其中穿越。为了使场景人物更加完善,还需要使用碰撞检测技术。 10.3.1 碰撞检测技术简介 无论是PC游戏,还是移动应用,

10.3 碰撞检测技术 到目前为止,构造的各种对象都是相互独立的,在场景中漫游各种物体,墙壁、树木对玩家(视点)好像是虚设,可以任意从其中穿越。为了使场景人物更加完善,还需要使用碰撞检测技术。

10.3.1 碰撞检测技术简介 无论是PC游戏,还是移动应用,碰撞检测始终是程序开发的难点,甚至可以用碰撞检测作为衡量游戏引擎是否完善的标准。

好的碰撞检测要求人物在场景中可以平滑移动,遇到一定高度的台阶可以自动上去,而过高的台阶则把人物挡住,遇到斜率较小的斜坡可以上去,斜率过大则会把人物挡住,在各种前进方向被挡住的情况下都要尽可能地让人物沿合理的方向滑动而不是被迫停下。

在满足这些要求的同时还要做到足够精确和稳定,防止人物在特殊情况下穿墙而掉出场景。 第 2 页

做碰撞检测时,该技术的重要性容易被人忽视,因为这符合日常生活中的常识。如果出现Bug,很容易被人发现,例如人物无缘无故被卡住不能前进或者人物穿越了障碍。所以,碰撞检测是让很多程序员头疼的算法,算法复杂,容易出错。

对于移动终端有限的运算能力,几乎不可能检测每个物体的多边形和顶点的穿透,那样的运算量对手机等设备来讲是不可完成的,所以移动游戏上使用的碰撞检测不可能使用太精确的检测,而且对于3D碰撞检测问题,还没有几乎完美的解决方案。目前只能根据需要来取舍运算速度和精确性。

目前成功商业3D游戏普遍采用的碰撞检测是BSP树及AABB(axially aligned bounding box)包装盒(球)方式。简单地讲,AABB检测法就是采用一个描述用的立方体或者球形体包裹住3D物体对象的整体(或者是主要部分),之后根据包装盒的距离、位置等信息来计算是否发生碰撞,如图10-24所示。

除了球体和正方体以外,其他形状也可以作包装盒,但是相比计算量和方便性来讲还是立方体和球体更方便些,所以其他形状的包装只用在一些特殊场合使用。BSP树是用来控制检测顺序和方向的数据描述。

在一个游戏场景中可能存在很多物体,它们之间大多属于较远位置或者相对无关的状态,一个物体的碰撞运算没必要遍历这些物体,同时还可以节省重要的时间。 第 3 页

如果使用单步碰撞检测,需要注意当时间步长较大时会发生两个物体完全穿透而算法却未检测出来的问题,如图10-25所示。其解决方案是产生一个4D空间,在物体运动的开始和结束时间之间产生一个4D超多面体,用于穿透测试。

图10-24 AABB包装盒 图10-25 碰撞检测的单步失控和4D测试

读者在程序开发初期有必要对碰撞检测有一个初步的估计,以免最后把大量精力消耗在碰撞检测问题上,从而降低了在基础的图形编程之上的注意力。

10.3.2 球体碰撞检测 真实的物理模拟系统需要非常精确的碰撞检测算法,但是游戏中常常只需要较为简单的碰撞检测,因为只需要知道物体什么时候发生碰撞,而不用知道模型的哪个多边形发生了碰撞,因此可以将不规则的物体投影成较规则的物体进行碰撞检测。

球体只有一个自由度,其碰撞检测是最简单的数学模型,我们只需要知道两个球体的球心和半径就能进行检测。

那么球体碰撞是如何工作的?主要过程如下。 n 计算两个物体中心之间的距离,并且将其与两个球体的半径和进行比较。 第 4 页

n 如果距离大于半径和,则没有发生碰撞。 n 否则,如果距离小于半径和,则发生了物体碰撞。 考虑由球心c1、c2和半径r1、r2定义的两个球,如图10-26所示。设d为球心间的距离。很明显,当d<r1+r2时相交,在实践中通过比较d2<(r1+r2)2,可以避免包括计算d在内的平方根运算。

对两个运动的球进行碰撞检测要麻烦一些,假设两个球的运动向量为d1和d2,球与位移向量是一一对应的,它们描述了所讨论时间段中的运动方式。

事实上,物体的运动是相对的,例如两列在两条平行轨道上相向行驶的火车,在其中一列中观察,对方的速度是两车速度之和。同样,也可以从第一个球的角度来简化问题,假设第一个球是“静止”的,另一个是“运动”的,那么该运动向量等于原向量d1和d2之差,如图10-27所示。

图10-27 动态球的检测过程 球体碰撞的优点是非常适用于需要快速检测的游戏,因为它不需要精确的碰撞检测算法。执行速度相对较快,不会给CPU带来过大的计算负担。

球体碰撞的另一个劣势是只适用于近似球形物体,如果物体非常窄或者非常宽,该碰撞检测算法将会失效,因为会在物体实际发生碰第 5 页

撞之前,碰撞检测系统就发出碰撞信号,如图10-28所示是球体碰撞检测中可能出现的坏情况,其解决方法是缩小检测半径,或者使用其他检测模型,如图10-29所示。

图10-28 球体碰撞的坏情况 图10-29 缩小检测半径

为了解决包容球精确度不高的问题,人们又提出了球体树的方法。 球体树实际上是一种表达3D物体的层次结构。对一个形状复杂的3D物体,先用一个大球体包容整个物体,然后对物体的各个主要部分用小一点的球体来表示,然后对更小的细节用更小的包容球体,这些球体和它们之间的层次关系就形成了一个球体树。

举例来说,对一个游戏中的人物角色,可以用一个大球来表示整个人,然后用中等大小的球体来表示四肢和躯干,然后用更小的球体来表示手脚等。这样在对两个物体进行碰撞检测时,先比较两个最大的球体。

如果有重叠,则沿树结构向下遍历,对小一点的球体进行比较,直到没有任何球体重叠,或者到了最小的球体,这个最小的球体所包含的部分就是碰撞的部分,如图10-30所示。

10.3.3 AABB立方体边界框检测 用球体去近似地代表物体运算量很小,但在游戏中的大多数物体是方的或者长条形的,应该用方盒来代表物体。另一种常见的检测模第 6 页

型是立方体边界框,如图10-31展示了一个AABB检测盒和它里面的物体。

坐标轴平行(Axially-aligned)不仅指盒体与世界坐标轴平行,同时也指盒体的每个面都和一条坐标轴垂直,这样一个基本信息就能减少转换盒体时操作的次数。AABB技术在当今的许多游戏中都得到了应用,开发者经常用它们作为模型的检测模型,再次指出,提高精度的同时也会降低速度。

因为AABB总是与坐标轴平行,不能在旋转物体时简单地旋转AABB,而是应该在每一帧都重新计算。如果知道每个对象的内容,这个计算就不算困难,也不会降低游戏的速度。然而,还面临着精度的问题。

假如有一个3D的细长刚性直棒,并且要在每一帧动画中都重建它的AABB。可以看到每一帧中的包装盒都不一样而且精度也会随之改变,如图10-32所示。

图10-31 3D模型与AABB检测盒 图10-32 不同方向的AABB

可以注意到AABB对物体的方向很敏感,同一物体的不同方向,AABB也可能不同(由于球体只有一个自由度,所以检测球对物体方向不敏感)。 第 7 页

当物体在场景中移动时,它的AABB也需要随之移动,当物体发生旋转时,有两种选择:用变换后的物体来重新计算AABB,或者对AABB做和物体同样的变换。

如果物体没有发生扭曲,可以通过“变换后的AABB”重新计算,因为该方法要比通过“变换后的物体”计算快得多,因为AABB只有8个顶点。变换AABB得出新的AABB要比变换物体的运算量小,但是也会带来一定的误差,如图10-33所示。

比较图中原AABB(灰色部分)和新AABB(右边比较大的方框),它是通过旋转后的AABB计算得到的,新AABB几乎是原来AABB的两倍,注意,如果从旋转后的物体而不是旋转后的AABB来计算新AABB,它的大小将和原来的AABB相同。

先介绍AABB的表达方法,AABB内的点满足以下条件: xmin≤x≤xmax

ymin≤y≤ymax

zmin≤z≤zmax

因此只需要知道两个特别重要的顶点(xmin,ymin,zmin)、(xmax,ymax,zmax),记作:

float[] min = new float []{0.0f,0.0f,0.0f}; float[] max = new float []{0.0f,0.0f,0.0f}; 第 8 页

中心点是两个顶点的中点,代表了包装盒的质点。 float[] center = new float []{0.0f,0.0f,0.0f}; 中心点的计算方法如下: float [] center(){ center[0] = (min[0] + max[0])*0.5f; center[1] = (min[1] + max[1])*0.5f; center[2] = (min[2] + max[2])*0.5f; return center; 通过这两个顶点可以知道以下属性。 float xSize() { return (max[0]-min[0]); } float ySize() { return (max[1]-min[1]); } float zSize() { return (max[2]-min[2]); } float size(){ return (max[0]-min[0])*(max[1]-min[1])*(max[2]-min[2]);}

当添加一个顶点到包装盒时,需要先与这两个顶点进行比较。 void add(float []p) { if (p[0] < min[0]) min[0] = p[0]; if (p[0] > max[0]) max[0] = p[0];

相关文档
最新文档