碰撞检测之OBB-OBB的SweepTest
来源:互联网 发布:公司取名软件注册码 编辑:程序博客网 时间:2024/05/18 06:22
提要
当物体在运动的时候,普通的每帧进行碰撞检测已经无法满足要求,比如子弹的运动
两帧的位置已经直接将中间的板子穿过了,所以 t 时刻和 t +1 时刻的检测都是失效的。这时候需要用到的就是sweep检测了。今天要处理的就是AABB的Sweep检测。
2D情况
如下图,当前位置是蓝色Box所在位置,目的位置是绿色框所在位置。
2D情况只用处理x,y方向的,利用SAP理论,分别在各个轴向计算可以移动的距离。代码如下
public static Vector2 SweepTest(OBB from, OBB other, Vector2 movement){ float deltaX = movement.x; float deltaY = movement.y; if (from.max.y > other.min.y && from.min.y < other.max.y) { float d1; if (deltaX > 0.0D && from.max.x <= other.min.x) { d1 = other.min.x - from.max.x; if (d1 < deltaX) { deltaX = d1; } } else if (deltaX < 0.0D && from.min.x >= other.max.x) { d1 = other.max.x - from.min.x; if (d1 > deltaX) { deltaX = d1; } } } if (from.max.x > other.min.x && from.min.x < other.max.x) { float d1; if (deltaY > 0f && from.max.y <= other.min.y) { d1 = other.min.y - from.max.y; if (d1 < deltaY) { deltaY = d1; } } else if (deltaY < 0f && from.min.y >= other.max.y) { d1 = other.max.y - from.min.y; if (d1 > deltaY) { deltaY = d1; } } } return Vector2(deltaX, deltaY);}
输入是两个OBB,from是要运动的OBB,movement是要进行的位移,返回的是最终的位移。
简单说一下X方向的判断,
首先
if (from.max.y > other.min.y && from.min.y < other.max.y)
要判断的是两个OBB在Y方向的投影是否有重叠,如果没有就直接返回movement 的x分量,因为在X方向不可能发生碰撞。
接下来判断的是如果from在other的左边,看是否有足够的空间给它运动,没有的话直接贴到other的边边上。from在other的右边的情况做同样的检测。
3D情况
只要简单的扩展到3D情况就可以了。
public static Vector3 SweepTest(Bounds from, Bounds other, Vector3 movement) { float deltaX = movement.x; float deltaY = movement.y; float deltaZ = movement.z; if (from.max.y > other.min.y && from.min.y < other.max.y && from.max.z > other.min.z && from.min.z < other.max.z) { float d1; if (deltaX > 0.0D && from.max.x <= other.min.x) { d1 = other.min.x - from.max.x; if (d1 < deltaX) { deltaX = d1; } } else if (deltaX < 0.0D && from.min.x >= other.max.x) { d1 = other.max.x - from.min.x; if (d1 > deltaX) { deltaX = d1; } } } if (from.max.x > other.min.x && from.min.x < other.max.x && from.max.z > other.min.z && from.min.z < other.max.z) { float d1; if (deltaY > 0f && from.max.y <= other.min.y) { d1 = other.min.y - from.max.y; if (d1 < deltaY) { deltaY = d1; } } else if (deltaY < 0f && from.min.y >= other.max.y) { d1 = other.max.y - from.min.y; if (d1 > deltaY) { deltaY = d1; } } } if (from.max.x > other.min.x && from.min.x < other.max.x && from.max.y > other.min.y && from.min.y < other.max.y) { float d1; if (deltaZ > 0.0D && from.max.z <= other.min.z) { d1 = other.min.z - from.max.z; if (d1 < deltaZ) { deltaZ = d1; } } else if (deltaZ < 0.0D && from.min.z >= other.max.z) { d1 = other.max.z - from.min.z; if (d1 > deltaZ) { deltaZ = d1; } } } return new Vector3(deltaX, deltaY, deltaZ); }
测试代码
using UnityEngine;using System.Collections;using NPhysX;public class BoxBoxSweepTester : MonoBehaviour { public Vector3 direction; public float speed; public GameObject box; public GameObject box1; Box _box; Box _box1; // Use this for initialization void Start() { _box = new Box(); _box1 = new Box(); direction = Vector3.one; }// Update is called once per framevoid Update () { Vector3 moveVector = speed * direction; Vector3 realMove = NSweepTests.SweepTest(box.GetComponent<BoxCollider>().bounds, box1.GetComponent<BoxCollider>().bounds, moveVector); box.transform.position += realMove; }}
测试结果
参考
Swept AABB Collision Detection and Response - http://www.gamedev.net/page/resources/_/technical/game-programming/swept-aabb-collision-detection-and-response-r3084
0 0
- 碰撞检测之OBB-OBB的SweepTest
- 碰撞检测之OBB-OBB检测
- OBB碰撞检测算法
- Ogre中基于蒙皮骨骼的OBB碰撞检测
- Ogre 中基于蒙皮骨骼的OBB碰撞检测
- cocos2d-x添加快速OBB碰撞检测
- Cocos2d-X添加快速OBB碰撞检测
- 三维物体OBB碰撞检测算法
- 算法与游戏之OBB碰撞算法
- AABB&OBB碰撞
- 基于cocos2d-x的2D空间中的OBB(Orient Bounding Box)碰撞检测算法
- 基于cocos2d-x的2D空间中的OBB(Orient Bounding Box)碰撞检测算法
- 为cocos2d-x添加快速OBB盒碰撞检测
- 《实时碰撞检测算法技术》读书笔记(四):OBB计算
- OBB包围盒及其碰撞检测算法(一)
- 游戏碰撞之OBB算法实现(java代码实现)
- 光线与盒体相交检测(Ray-OBB)可用于VR中Cursor与控件的碰撞检测
- Unity3d数学公式之 OBB vs OBB
- Leetcode 117. Populating Next Right Pointers in Each Node II
- PHP:微信公众号的红包发送功能
- 代码篇——DataGrid
- 观察观察观察
- SA模板
- 碰撞检测之OBB-OBB的SweepTest
- 重建二叉树
- 二、初学SpringMVC+Mybatis之Spring IOC
- RDD弹性分布式数据集(一)
- The effect of opinion clustering on disease outbreaeks
- Docker隔绝上传文件
- python中的函数式编程——apply, filter, map, reduce
- Python reverse order
- MapReduce处理多个不同的出入文件