提要

当物体在运动的时候。普通的每帧进行碰撞检測已经无法满足要求,比方子弹的运动

两帧的位置已经直接将中间的板子穿过了,所以 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 frame
void 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

碰撞检測之OBB-OBB的SweepTest的更多相关文章

  1. Cocos2d-x教程(34)-三维物体OBB碰撞检測算法

    欢迎增加Cocos2d-x 交流群:193411763 个中心点.1个旋转矩阵和3个1/2边长(注:一个旋转矩阵包括了三个旋转轴,若是二维的OBB包围盒则是一个中心点,两个旋转轴,两个1/2边长). ...

  2. Cocos2d-x教程(35)-三维拾取Ray-AABB碰撞检測算法

    欢迎增加Cocos2d-x 交流群:193411763 转载时请注明原文出处 :http://blog.csdn.net/u012945598/article/details/39927911 --- ...

  3. cocos2d-x ios游戏开发初认识(八) 触摸事件与碰撞检測

    玩过植物大战僵尸都知道,要在草坪里放一朵向日葵或者其他的植物仅仅需触摸那个植物将其拖入到想要摆放的位置,这事实上就是这节要写的触摸事件.还能够发现当我们的僵尸出来的时候,我们的小豌豆会发子弹攻击僵尸, ...

  4. Cocos2d-x 精灵碰撞检測(方法二)

    将"Cocos2d-x 精灵碰撞检測(方法一)" update函数改动一下. 使用精灵boundingBox函数获取直接精灵边界框, 不用自己计算精灵矩形大小了,还比較精确,然后调 ...

  5. cocos2d-x 旅程開始--(实现瓦片地图中的碰撞检測)

    转眼隔了一天了,昨天搞了整整一下午加一晚上,楞是没搞定小坦克跟砖头的碰撞检測,带着个问题睡觉甚是难受啊!还好今天弄成功了.只是感觉程序不怎么稳定啊.并且发现自己写的东西让我重写一遍的话我肯定写不出来. ...

  6. cocos2d-html5 碰撞检測的几种方法

    游戏中的碰撞还是比較多的,比方角色与角色的碰撞,角色与墙壁的碰撞,角色与怪物的碰撞等,都须要 进行碰撞的检測,来触发一定的事件 近期在尝试制作一个小游戏的时候须要用到碰撞检測,然后就查了下资料,并在论 ...

  7. Unity3D入门(二):碰撞检測

    碰撞器由来 1.系统默认会给每一个对象(GameObject)加入一个碰撞组件(ColliderComponent),一些背景对象则能够取消该组件. 2.在unity3d中,能检測碰撞发生的方式有两种 ...

  8. iOS 碰撞检測以及事件响应

    */ //碰撞检測 //碰撞检測de过程 //碰撞检測 //碰撞检測 //碰撞检測 //UIApplication-> UIWindow-> UIController-> 视图控制器 ...

  9. cocos2d-x游戏开发 跑酷(八) 对象管理 碰撞检測

    对象管理类的原理是这种: ObjectManager类是一个单例类,全局仅仅有一个对象实例存在.初始化的时候创建两个数组CCArray来保存金币和岩石.为什么要保存,由于在地图重载的时候.要销毁看不见 ...

随机推荐

  1. CPU 基础术语总结

    CPU CPU为 Central Processing Unit 的缩写.是一块超大规模的集成电路,是一台计算机的运算核心(Core)和控制核心( Control Unit).它的功能主要是解释计算机 ...

  2. 蓝牙学习(3) Linux kernel部分Bluetooth HCI分析

    在上文,https://blog.csdn.net/feiwatson/article/details/81712933中主要理解了在Kernel中USB adapter是如何实现USB设备驱动,以及 ...

  3. Controller View 模式

    参考:https://blog.andrewray.me/the-reactjs-controller-view-pattern/ Flux参考:http://www.cnblogs.com/hell ...

  4. axure笔记--内置变量

    部件变量: This:当前变量名称 Target:目标变量的名称 x,y表示组件左上角的位置 name:获取当前组件标签命名 Top:获取组件上边界到x轴的距离 bottom:获取组件下边界到x轴的距 ...

  5. (转)iOS完成学习路线

    转自 MJ大神博客 原文地址http://blog.csdn.net/q199109106q/article/details/8596506 晚特地花时间整理出了iOS的完整学习路线图,希望对大家有帮 ...

  6. (原)pat1007素数猜想

    ---恢复内容开始--- 1007. 素数对猜想 (20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 让我们 ...

  7. 电子邮件中的to、cc、bcc

    电子邮件中的to.cc(carbon copy)和bcc(blind carbon copy),分别是收件人.抄送.密送 to 收件人 你想要给其发邮件的人 cc 抄送人 cc和to是一样的,但是cc ...

  8. .net 操作Access数据库

    using System; using System.Collections.Generic; using System.Configuration; using System.Data; using ...

  9. kali2018 安装****

    1.安装需要的依赖包: apt-get install qt5-qmake qtbase5-dev libqrencode-dev libappindicator-dev libzbar-dev ro ...

  10. 【HTML/XML 2】XML基础知识点总结

    导读:刚开始看到这个名的时候,还以为会和HTML一样呢,结果看完了资料里的视频,才发现是各有千秋.现在,就对XML的基础知识,做一个总结. 一.总体概述 XML(Extensible Markup L ...