碰撞检測之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来保存金币和岩石.为什么要保存,由于在地图重载的时候.要销毁看不见 ...
随机推荐
- Lex与Yacc学习(二)之第一个Lex程序
用lex识别单词 构建一个识别不同类型英语单词的简单程序.先识别词性(名词,动词等),然后再扩展到处理符合简单英语语法的多个单词的句子. 先列出要识别的一组动词: is am are w ...
- JavaScript注释
JavaScript注释有两种方式: 1.单行注释. 2.多行注释. 单行注释 单行注释以“//”开头. <script type="text/javascript"> ...
- cs229_part4
又到了一节很重要的课,因为这个学习理论是从统计角度为机器学习算法提供了一个理论基础. 学习理论 问题背景 先回顾一下我们第一节课提到的机器学习的组成: 第一节课只是简单的提了一下,现在我们要真正来分析 ...
- Webstrom卡顿问题解决
1.设置node_modules 打开项目,新建node_modules空文件夹,然后右击选择Mark Directory as,选择Excluded. 2.设置ingore文件 files-> ...
- 【LeetCode】String to Integer (atoi)(字符串转换整数 (atoi))
这道题是LeetCode里的第8道题. 题目要求: 请你来实现一个 atoi 函数,使其能将字符串转换成整数. 首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止. 当我们 ...
- [uiautomator篇] bluetooth---接口来做
package com.softwinner.performance.frameratetest; import android.Manifest; import android.bluetooth. ...
- 【Kubernetes】离线业务:Job与CronJob
Deployment.StatefulSet和DaemonSet这三个编排概念编排的对象主要都是在线业务(Long Running Task,这些应用一旦运行起来,除非出错或者停止,它的容器进程会一直 ...
- 防火墙iptables介绍
防火墙: netfilter/iptables是集成在Linux2.4.X版本内核中的包过滤防火墙系统.该架构可以实现数据包过滤,网络地址转换以及数据包管理功能.linux中防火墙分为两部分:netf ...
- 2013 年 acm 长春现场赛
A - Hard Code Hdu 4813 题目大意:给你一坨字符串,让你输出其栅栏密码的解码形式 思路:水题模拟 #include<iostream> #include<cstd ...
- 使用反射获取类中的属性(可用于动态返回PO类的列,当做表格的表头)
//利用反射取类中的属性字段 try { Class clazz = Class.forName("houji.bean.model.TaskModel"); Field[] fi ...