碰撞检測之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来保存金币和岩石.为什么要保存,由于在地图重载的时候.要销毁看不见 ...
随机推荐
- 无法连接Elasticsearch解决方案
前言 最近还是在弄ELK,并且在测试Logstash从kafka消费日志(最后输出到Elasticsearch). 测试完毕后,在kibana中,并没有发现Elasticsearch中的数据. 后来装 ...
- link与@import导入css样式区别
XML/HTML代码<link rel="stylesheet" rev="stylesheet" href="CSS文件" type ...
- RHEL6.5上升级OpenSSH7.4p1
由于升级OpenSSH涉及到安全性问题,为保险起见,在升级前最好安装telnet服务作为备用方案,然后在升级成功后再停止telnet即可. 一.OpenSSH升级相关源码包下载地址 zlib htt ...
- 3,bool值之间的转换,和str的各个功能属性。
bool值之间的转换 and 空字符串即为False 字符串内有内容即为True. a = 11 c = str(a) #int转换成str print(type(c)) a = ' b = in ...
- 四、harbor实践之初识harbor
1 什么是Harbor harbor是VMware公司开源的企业级Registry项目,其的目标是帮助用户迅速搭建一个企业级的Docker registry 服务. 2 什么是Registry Reg ...
- Matplotlib绘图属性(1)
[matplotlib颜色.形状.线型等详细配置方法] #1.颜色(三种方法)-color 八种内置颜色及其缩写: b:blue <蓝色> c:cyan <青色> g:gree ...
- [android开发篇]elicpse安装教程
http://www.runoob.com/eclipse/eclipse-install.html Eclipse 安装(Neon 版本) Eclipse 最新版本 Eclipse Neon,这个首 ...
- 九度oj 题目1096:日期差值
题目描述: 有两个日期,求两个日期之间的天数,如果两个日期是连续的我们规定他们之间的天数为两天 输入: 有多组数据,每组数据有两行,分别表示两个日期,形式为YYYYMMDD 输出: 每组数据输出一行, ...
- 30分钟学会如何使用Shiro(转自:http://www.cnblogs.com/learnhow/p/5694876.html)
本篇内容大多总结自张开涛的<跟我学Shiro>原文地址:http://jinnianshilongnian.iteye.com/blog/2018936 我并没有全部看完,只是选择了一部分 ...
- 【Luogu】P3195玩具装箱(斜率优化DP)
这题还是比较炫的 题目链接 我们设f[i]是已经装了前i个玩具,且第i个玩具是某箱子里装的最后一个东西(废话) 那我们很轻松可以想到一个转移方程 ;i<=n;++i) ;j<i;++j) ...