碰撞检測之OBB-OBB的SweepTest
提要
当物体在运动的时候。普通的每帧进行碰撞检測已经无法满足要求,比方子弹的运动
两帧的位置已经直接将中间的板子穿过了,所以 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的更多相关文章
- Cocos2d-x教程(34)-三维物体OBB碰撞检測算法
欢迎增加Cocos2d-x 交流群:193411763 个中心点.1个旋转矩阵和3个1/2边长(注:一个旋转矩阵包括了三个旋转轴,若是二维的OBB包围盒则是一个中心点,两个旋转轴,两个1/2边长). ...
- Cocos2d-x教程(35)-三维拾取Ray-AABB碰撞检測算法
欢迎增加Cocos2d-x 交流群:193411763 转载时请注明原文出处 :http://blog.csdn.net/u012945598/article/details/39927911 --- ...
- cocos2d-x ios游戏开发初认识(八) 触摸事件与碰撞检測
玩过植物大战僵尸都知道,要在草坪里放一朵向日葵或者其他的植物仅仅需触摸那个植物将其拖入到想要摆放的位置,这事实上就是这节要写的触摸事件.还能够发现当我们的僵尸出来的时候,我们的小豌豆会发子弹攻击僵尸, ...
- Cocos2d-x 精灵碰撞检測(方法二)
将"Cocos2d-x 精灵碰撞检測(方法一)" update函数改动一下. 使用精灵boundingBox函数获取直接精灵边界框, 不用自己计算精灵矩形大小了,还比較精确,然后调 ...
- cocos2d-x 旅程開始--(实现瓦片地图中的碰撞检測)
转眼隔了一天了,昨天搞了整整一下午加一晚上,楞是没搞定小坦克跟砖头的碰撞检測,带着个问题睡觉甚是难受啊!还好今天弄成功了.只是感觉程序不怎么稳定啊.并且发现自己写的东西让我重写一遍的话我肯定写不出来. ...
- cocos2d-html5 碰撞检測的几种方法
游戏中的碰撞还是比較多的,比方角色与角色的碰撞,角色与墙壁的碰撞,角色与怪物的碰撞等,都须要 进行碰撞的检測,来触发一定的事件 近期在尝试制作一个小游戏的时候须要用到碰撞检測,然后就查了下资料,并在论 ...
- Unity3D入门(二):碰撞检測
碰撞器由来 1.系统默认会给每一个对象(GameObject)加入一个碰撞组件(ColliderComponent),一些背景对象则能够取消该组件. 2.在unity3d中,能检測碰撞发生的方式有两种 ...
- iOS 碰撞检測以及事件响应
*/ //碰撞检測 //碰撞检測de过程 //碰撞检測 //碰撞检測 //碰撞检測 //UIApplication-> UIWindow-> UIController-> 视图控制器 ...
- cocos2d-x游戏开发 跑酷(八) 对象管理 碰撞检測
对象管理类的原理是这种: ObjectManager类是一个单例类,全局仅仅有一个对象实例存在.初始化的时候创建两个数组CCArray来保存金币和岩石.为什么要保存,由于在地图重载的时候.要销毁看不见 ...
随机推荐
- RESTful介绍
web框架的本质: socket服务端与浏览器的通信 socket(套接字):进程间的一种通信方式 socket服务端功能划分: a.负责与浏览器收发消息(socket通信) --- ...
- linux终端颜色控制
引言: 由于在c代码中看到过打印彩色字, 又对PS1 想进一步了解,才有了这篇博文.----------------------------------------Linux 终端控制台字体颜色 - ...
- failed to execute goal org.apache.maven.plugins:maven-archetype-plugin错误解决方法
使用maven创建project时碰到如下错误: D:\codes\JSF>mvn archetype:create -DgroupId=com.tutorialspoint.test -Dar ...
- centos 部署 自定义(succes)
安装前先检查一下有没有安装好了的JDK,Tomcat,MySQL,不过一般都没有. 1.安装JDK 1.1 下载jdk,可以到官网查看不同版本的下载地址 wget --no-check-certifi ...
- js根据银行卡号判断属于哪个银行,并返回银行缩写及银行卡类型
在做绑定银行卡,输入银行卡的时候,产品有这么一个需求,需要用户输入银行卡号的时候,显示对应的银行卡名称及简称.于是苦苦寻觅,终于找到了支付宝的开放API,银行卡校验接口 https://ccdca ...
- linux 安装SNV服务
1.安装vnc server[root@pxe ~]# yum install tigervnc-server -y 2.设置 vnc server 开机启动[root@pxe ~]# chkconf ...
- 九度oj 题目1537:买卖股票
题目描述: 给定一个大小为n的数组,数组的元素a[i]代表第i天的股票价格. 设计一个算法,计算在最多允许买卖k次(一买一卖记为一次)的条件下的最大收益. 需要注意的是,你不能同时拥有两份股票.也就是 ...
- 防火墙iptables介绍
防火墙: netfilter/iptables是集成在Linux2.4.X版本内核中的包过滤防火墙系统.该架构可以实现数据包过滤,网络地址转换以及数据包管理功能.linux中防火墙分为两部分:netf ...
- shell的brake和continue的用法
在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环,像大多数编程语言一样,Shell也使用 break 和 continue 来跳出循环. break命令 break命令允许跳出所有循环(终止 ...
- Ubuntu Flask安装与配置(待整理)
工作中开发需要用到python的flask框架,无奈网络上的资源很少,连基本的安装和配置都不全,在这做一下整理,方便以后用到. ———————————————————————————— 由于比较繁琐, ...