ImageVerifierCode 换一换
格式:DOCX , 页数:24 ,大小:234.39KB ,
资源ID:3050484      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bingdoc.com/d-3050484.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(整理3d碰撞检测技术文档格式.docx)为本站会员(b****2)主动上传,冰点文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰点文库(发送邮件至service@bingdoc.com或直接QQ联系客服),我们立即给予删除!

整理3d碰撞检测技术文档格式.docx

1、10.3.2 球体碰撞检测真实的物理模拟系统需要非常精确的碰撞检测算法,但是游戏中常常只需要较为简单的碰撞检测,因为只需要知道物体什么时候发生碰撞,而不用知道模型的哪个多边形发生了碰撞,因此可以将不规则的物体投影成较规则的物体进行碰撞检测。球体只有一个自由度,其碰撞检测是最简单的数学模型,我们只需要知道两个球体的球心和半径就能进行检测。那么球体碰撞是如何工作的?主要过程如下。n 计算两个物体中心之间的距离,并且将其与两个球体的半径和进行比较。 如果距离大于半径和,则没有发生碰撞。 否则,如果距离小于半径和,则发生了物体碰撞。考虑由球心c1、c2和半径r1、r2定义的两个球,如图10-26所示。

2、设d为球心间的距离。很明显,当dr1+r2时相交,在实践中通过比较d2(r1+r2)2,可以避免包括计算d在内的平方根运算。对两个运动的球进行碰撞检测要麻烦一些,假设两个球的运动向量为d1和d2,球与位移向量是一一对应的,它们描述了所讨论时间段中的运动方式。事实上,物体的运动是相对的,例如两列在两条平行轨道上相向行驶的火车,在其中一列中观察,对方的速度是两车速度之和。同样,也可以从第一个球的角度来简化问题,假设第一个球是“静止”的,另一个是“运动”的,那么该运动向量等于原向量d1和d2之差,如图10-27所示。图10-27 动态球的检测过程球体碰撞的优点是非常适用于需要快速检测的游戏,因为它不

3、需要精确的碰撞检测算法。执行速度相对较快,不会给CPU带来过大的计算负担。球体碰撞的另一个劣势是只适用于近似球形物体,如果物体非常窄或者非常宽,该碰撞检测算法将会失效,因为会在物体实际发生碰撞之前,碰撞检测系统就发出碰撞信号,如图10-28所示是球体碰撞检测中可能出现的坏情况,其解决方法是缩小检测半径,或者使用其他检测模型,如图10-29所示。 图10-28 球体碰撞的坏情况 图10-29 缩小检测半径为了解决包容球精确度不高的问题,人们又提出了球体树的方法。球体树实际上是一种表达3D物体的层次结构。对一个形状复杂的3D物体,先用一个大球体包容整个物体,然后对物体的各个主要部分用小一点的球体来

4、表示,然后对更小的细节用更小的包容球体,这些球体和它们之间的层次关系就形成了一个球体树。举例来说,对一个游戏中的人物角色,可以用一个大球来表示整个人,然后用中等大小的球体来表示四肢和躯干,然后用更小的球体来表示手脚等。这样在对两个物体进行碰撞检测时,先比较两个最大的球体。如果有重叠,则沿树结构向下遍历,对小一点的球体进行比较,直到没有任何球体重叠,或者到了最小的球体,这个最小的球体所包含的部分就是碰撞的部分,如图10-30所示。10.3.3 AABB立方体边界框检测用球体去近似地代表物体运算量很小,但在游戏中的大多数物体是方的或者长条形的,应该用方盒来代表物体。另一种常见的检测模型是立方体边界

5、框,如图10-31展示了一个AABB检测盒和它里面的物体。坐标轴平行(Axially-aligned)不仅指盒体与世界坐标轴平行,同时也指盒体的每个面都和一条坐标轴垂直,这样一个基本信息就能减少转换盒体时操作的次数。AABB技术在当今的许多游戏中都得到了应用,开发者经常用它们作为模型的检测模型,再次指出,提高精度的同时也会降低速度。因为AABB总是与坐标轴平行,不能在旋转物体时简单地旋转AABB,而是应该在每一帧都重新计算。如果知道每个对象的内容,这个计算就不算困难,也不会降低游戏的速度。然而,还面临着精度的问题。假如有一个3D的细长刚性直棒,并且要在每一帧动画中都重建它的AABB。可以看到每

6、一帧中的包装盒都不一样而且精度也会随之改变,如图10-32所示。 图10-31 3D模型与AABB检测盒 图10-32 不同方向的AABB可以注意到AABB对物体的方向很敏感,同一物体的不同方向,AABB也可能不同(由于球体只有一个自由度,所以检测球对物体方向不敏感)。当物体在场景中移动时,它的AABB也需要随之移动,当物体发生旋转时,有两种选择:用变换后的物体来重新计算AABB,或者对AABB做和物体同样的变换。如果物体没有发生扭曲,可以通过“变换后的AABB”重新计算,因为该方法要比通过“变换后的物体”计算快得多,因为AABB只有8个顶点。变换AABB得出新的AABB要比变换物体的运算量小

7、,但是也会带来一定的误差,如图10-33所示。比较图中原AABB(灰色部分)和新AABB(右边比较大的方框),它是通过旋转后的AABB计算得到的,新AABB几乎是原来AABB的两倍,注意,如果从旋转后的物体而不是旋转后的AABB来计算新AABB,它的大小将和原来的AABB相同。先介绍AABB的表达方法,AABB内的点满足以下条件:xminxxmaxyminyymaxzminzzmax因此只需要知道两个特别重要的顶点(xmin,ymin,zmin)、(xmax,ymax,zmax),记作:float min = new float 0.0f,0.0f,0.0f;float max = new f

8、loat 0.0f,0.0f,0.0f;中心点是两个顶点的中点,代表了包装盒的质点。float center = new float 0.0f,0.0f,0.0f;中心点的计算方法如下:float center() center0 = (min0 + max0)*0.5f; center1 = (min1 + max1)*0.5f; center2 = (min2 + max2)*0.5f; return center;通过这两个顶点可以知道以下属性。float xSize() return (max0-min0); float ySize() return (max1-min1);float

9、 zSize() return (max2-min2);float size() return (max0-min0)*(max1-min1)*(max2-min2);当添加一个顶点到包装盒时,需要先与这两个顶点进行比较。void add(float p) if (p0 max0) max0 = p0; if (p1 max1) max1 = p1; if (p2 max2) max2 = p2;检测包装盒是否为空,可以将这两个顶点进行比较。boolean isEmpty() return (min0 max0) | (min1 max1) | (min2 max2);检测某个点是否属于AAB

10、B范围之内的代码如下:boolean contains(float p) return(p0 = min0) & (p0 = min1) & (p1 = min2) & (p2 box2_max0) return false; if (max0 box2_max1) return false; if (max1 box2_max2) return false; if (max2 0.0f) minx += m0 * min0; maxx += m0 * max0; else minx += m0 * max0; maxx += m0 * min0; if (m1 minx += m1 * mi

11、n1; maxx += m1 * max1; minx += m1 * max1; maxx += m1 * min1; if (m2 minx += m2 * min2; maxx += m2 * max2; minx += m2 * max2; maxx += m2 * min2; if (m4 miny += m4 * min0; maxy += m4 * max0; miny += m4 * max0; maxy += m4 * min0; if (m5 miny += m5 * min1; maxy += m5 * max1; miny += m5 * max1; maxy += m

12、5 * min1; if (m6 miny += m6 * min2; maxy += m6 * max2; miny += m6 * max2; maxy += m6 * min2; if (m8 minz += m8 * min0; maxz += m8 * max0; minz += m8 * max0; maxz += m8 * min0; if (m9 minz += m9 * min1; maxz += m9 * max1; minz += m9 * max1; maxz += m9 * min1; if (m10 minz += m10 * min2; maxz += m10 *

13、 max2; minz += m10 * max2; maxz += m10 * min2; min0 = minx; min1 = miny; min2 = minz; /用新的AABB坐标替换原有坐标 max0 = maxx; max1 = maxy; max2 = maxz;为了使用AABB包装盒进行碰撞检测,将这些方法和属性封装为AABB类,代码如下:import java.lang.Math;import javax.microedition.m3g.Transform;class AABB public AABB() float getMin()return min; float

14、getMax()return max; void setMin(float x,float y,float z)min0=x;min1=y;min2=z; void setMax(float x,float y,float z)max0=x;max1=y;max2=z; void reset()for(int i =0;i3;i+) mini=0;maxi=0; /其他方法同上为了检验碰撞检测的使用构造了两个立方体,并各自绑定了一个包装盒。/*立方体1*/mesh1 = createCube(); /创建立方体1mesh1.setTranslation(1.0f, 0.0f,0.0f) ; /

15、平移mesh1.setOrientation(90,0.0f,1.0f,0.0f); /旋转mesh1.setScale(0.5f,0.5f,0.5f); /缩放box1 = new AABB(); /包装盒box1.setMin(-1.0f,-1.0f,-1.0f); /设置包装盒1的最小顶点box1.setMax(1.0f,1.0f,1.0f); /设置包装盒1的最大顶点mesh1.getCompositeTransform(cubeTransform); /获取立方体1的混合矩阵box1.setToTransformedBox(cubeTransform); /将变换矩阵应用到包装盒中w

16、orld.addChild(mesh1); /将立方体1添加到场景中/*立方体2*/mesh2 = createCube(); /创建立方体2mesh2.setTranslation(-0.5f, 0.0f,0.0f) ;mesh2.setScale(0.5f,0.5f,0.5f);box2 = new AABB();box2.setMin(-1.0f,-1.0f,-1.0f); /设置包装盒2的最小顶点box2.setMax(1.0f,1.0f,1.0f); /设置包装盒2的最大顶点mesh2.getCompositeTransform(cubeTransform); /获取立方体2的混合矩阵box2.setToTransformedBox(cubeTransform); /将变换矩阵应用到包装盒2中

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2