提要

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

两帧的位置已经直接将中间的板子穿过了,所以 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. (32)zabbix分布式监控proxy vs nodes

    概述 zabbix为IT基础设施提供有效和可用的分布式监控,zabbix提供了两种解决方案,分别为:proxy和nodes.proxy代替zabbix server在本地检索数据,然后提交给zabbi ...

  2. 详解css媒体查询

    简介 媒体查询(Media Queries)早在在css2时代就存在,经过css3的洗礼后变得更加强大bootstrap的响应式特性就是从此而来的. 简单的来讲媒体查询是一种用于修饰css何时起作用的 ...

  3. Mac OS X下安装Vue脚手架(vue-cli)

    前言 Vue作为前端三大框架(Angular,React,Vue)之一,号称是最简单,最容易上手的框架,同时也是行内的大趋势,还可以用来开发最火的小程序.具有开发快,双向数据流等特点,有些人认为Vue ...

  4. php各种主流框架的优缺点总结

    ThinkPHP ThinkPHP(FCS)是一个轻量级的中型框架,是从Java的Struts结构移植过来的中文PHP开发框架.它使用面向对象的开发结构和MVC模式,并且模拟实现了Struts的标签库 ...

  5. mysql 慢查询日志 pt-query-digest 工具安装

    介绍:pt-query-digest是用于分析mysql慢查询的一个工具,它可以分析binlog.General log.slowlog,也可以通过SHOWPROCESSLIST或者通过tcpdump ...

  6. 快照、克隆,xshell优化,Linux历史

    目录 一.虚拟拍照功能 二.虚拟机克隆功能 三.Xshell的优化 四.介绍Linux历史 一.虚拟拍照功能 1.拍摄快照 关机状态拍照 关机命令:shutdown -h now 或者 init 0 ...

  7. Python9-day11-作业

    # 1.编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),# 要求登录成功一次,后续的函数都无需再输入用户名和密码 FLAG = False def login(func): def ...

  8. POJ-1061 青蛙的约会 (扩展欧几里得)

    [题目描述] 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件很重要的事情,既没有 ...

  9. ACM Changchun 2015 A. Too Rich

    You are a rich person, and you think your wallet is too heavy and full now. So you want to give me s ...

  10. VisionPro工业视觉的标定方法

    工业视觉常用的几种标定方式. 计算像素比 有些时候我们需要的检测数据并不需要特别准确,并且手边没有其它标定工具,可以使用这种方法大概算一算每个像素对应多大距离. 找一个知道距离的物体,测出它的像素距离 ...