[笔记]物理碰撞整合

碰撞总结
点积:两个向量之间的夹角,投影
叉积:两向量组成的平行四边形的面积,两向量的前后关系(方向)

dot(a,a)得到a的长度平方
行列式:体积,行列式转为矩阵公式用克莱姆公式求解
叉积转点积:拉格朗日公式
多边形划分:v域,质心划分,边延长线划分
判断点是否在三角形内,可以判断点是否在所有的面的左边
质心:三个点的为面积比,四个点的为体积比
射线相交:
    以时间t代入求解
    以一元二次方程的思想求解,判断是否有根已经是否合法

1.直线运动的AABB,原则上是进行8条射线的碰撞检测,这个算法主要应用于角色的高速移动
3,子弹用射线检测
3.圆和直线的碰撞可以转变为=>直线和圆的并集得到一个胶囊体,圆只取圆心点,求圆心点和胶囊体的碰撞,也可以看成点和线段的碰撞判定
4.2个任意形状的物体求是否相交,可以将2个物体的点集进行差集计算,若结果集合中有(0,0,0)点代表相交(因为相交则一点有点重合,相交点的差为0)
5.AABB数据结构记录方法:
    最小点,最大点
    最小点,各个轴长度
    中心点,各个轴半径
6.碰撞穿透问题
    扫掠形状,两帧之间物理的位置连接形成的形状
    连续检测,使用位置插值,前后两个位置间,使用时间插值,可以增加精度
7.胶囊体和球-》线段和球
8.球和线段是否相交,可以看成是球心在线段上的投影,投影值大于0且投影终点和球心距离小于球半径则相交
9.比较平方,避免开方
10.线段和平面最近点:
11.求点到obb的距离
    显示求出最近点:先将点转换到obb的本地坐标上,之后就转变为了求点到AABB的最近点,之后再求点到最近点的距离
    不显示求出最近点:用voronoi域,若点落在顶点域,则距离为点到点的距离。若落在边域,则距离为点到线段的距离。若落在面域,则距离为点到面的距离
12.线段和直线的距离
    线段和直线之间最近点构成的线段一定垂直于原来的直线和线段
13.判断点是否在凸多边形内
    点对凸多边形每个顶点之间建立一个线段2D向量,该向量与其对应的顶点的边进行叉乘,得到一个叉积值。
    若每个叉积值的符号都一样(都是正数/都是负数),则证明点在凸多边形内。
    否则,则证明点不再凸多边形内
14.判断点在平面前后算法:平面的法向量为(A,B,C),则平面方程为:Ax+By+Cz+D=0
    将点(x0,y0,z0)代入方程,得distance=Ax0+By0+Cz0+D
    若distance<0,则在平面背后
    若distance=0,则在平面中
    若distance>0,则在平面前方
AABB,OOBB 最近点
直线和线段最近点
最近点问题-三角形和拉格朗日公式优化
    点到三角形最近点可以用v域去判断落在哪个域,同时用拉格朗日算法优化叉积
最近点问题-三角形&线段,三角形和三角形分析
分离轴算法应用:obb和obb碰撞
    检测面与面相交用面的法线做为分离轴,检测边与边相交用边与边的叉积做为分离轴
分离轴算法应用:面与球,面与AABB,AABB&三角形判定,AABB的特殊优化
    面和圆,以面的法线为轴
三角形和三角形碰撞检测3种方式
射线检测:球和平面。AABB OBB。ray和三角形碰撞检测4种方式
运动物体的碰撞检测区间半分法
    扫掠法
    两个物体之间的距离减半,做2个圆,判断是否碰撞,再减半递归,知道检测的半径达到阀值则跳出
运动物体碰撞检测的更多算法
    2个运动向量相加后得到相对运动的向量
    以这个向量作为轴,进行投影,可得到初始时的距离,2物体之间的最小距离和最大距离分别除以运动分量,会分别得到相应轴上最先碰撞的时间和最后碰撞时间,这两个时间看做区间,再求其他轴的区间,区间的交集的最小值就是实际碰撞时间

检测凸碰撞,GJK算法。GJK算法可以高效地检测任意凸多胞形(polytope)。GJK算法依赖于闵可夫斯基差(Minkowski difference):把A图形中的所有点,与B图形中的所有点成对相减,得出的集合便是闵可夫斯基差。用处在于,当两个形状相交,闵可夫斯基差会包含原点。

连续碰撞检测: 球形扫掠体检测(子弹穿过纸张问题) Swept Volume,在开始顶点和当前顶点之间做射线检测(一般会有多个顶点)

通过点积的计算我们可以简单粗略的判断当前物体是否朝向另外一个物体: 只需要计算当前物体的transform.forward向量与 (otherObj.transform.position – transform.position)的点积即可, 大于0则面对,否则则背对着

高效的碰撞检测    
    1.快速找出潜在的碰撞物体对列表,只对这个列表进行碰撞检测,通常做法是收集上一次发生碰撞的对象,这一帧中状态有改变的对象
    2.准确找出会发生碰撞的对象列表,通常做法是用空间划分管理去实现Chunk内对象和Chunk内对象的碰撞检测
    3.碰撞掩码及碰撞层。为碰撞体分类,指明哪些碰撞体之间可以发生碰撞
    4.算法为松散八叉树,BVH,SAT(分离轴算法),GJK(计算两个凸体之间的距离)[SAT和GJK只对凸多边形有效]
    5.室内物件数量过多,用BSP分割空间
    6.室外一般用四叉树

扩展
    甚至于可以添加碰撞材质的概念(collision material)。把每个碰撞表面关联至一组属性。可以是音效、粒子效果、物理属性


松散四叉树
    比四叉树多了入口边界(也就是四叉树的边界)和出口边界(比四叉树边界大的边界)
    如何判定一个物体现在在哪个节点
        若物体还没添加进四叉树/八叉树,则检测现在位于哪个节点的入口边界内;
        若物体先前已经存在于某个节点,则先检测现在是否越出该节点的出口边界,若越出再检测位于哪个节点的入口边界内
    应用场景:
        感知检测的过滤,碰撞检测过滤,光线追踪过滤不必要的区域
    注意:
        出口边界大小是入口边界大小的2倍时表现最好
        在某个节点下没有物体时,可以回收/合并这个节点下的所有子节点
    
层次包围盒BVH
    同一个父节点包围和下的元素尽可能的紧凑,但同时最好不要有重叠
    三种构造方法:
        1.自顶向下(适用于知道场景中具体有哪些元素的时候)
        2.自底向上(递归)
        3.插入法(4叉树,适用于游戏中元素增删的情况,单个空间中元素达到一定程度时,需要再次划分)
    三种划分:
        1.折半划分
        2.不看空间,只看元素个数,保证划分后2个子空间元素个数平衡
        3.带权值的划分,比如体积大的权值大,或者计算复杂度高的权值大,然后划分后确保2个子空间权值平衡(启发式 )
    应用场景
        碰撞检测
            Bullet、Havok等物理引擎的碰撞粗测阶段,使用一种叫做 动态层次AABB包围盒树(Dynamic Bounding Volume Hierarchy Based On AABB Tree) 的结构来存储动态的AABB形状。
            然后通过该包围盒树的性质(不同父包围盒必定不会碰撞),快速过滤大量不可能发生碰撞的形状对。
        射线检测/挑选几何体
            射线检测从层次包围盒树自顶向下检测是否射线通过包围盒,若不通过则无需检测其子包围盒。
            这种剪裁可让每次射线检测平均只需检测O(logN)数量的形状。
            通过一个点位置快速挑选该点的几何体也是类似的原理。
        视锥剔除
            对BVH树进行中序遍历的视锥测试,如果一个节点所代表的包围盒不在视锥范围内,那么其所有子节点所代表的包围盒都不会在视锥范围内,则可以跳过测试其子节点。在这个遍历过程中,通过测试的节点所代表的几何体才可以发送渲染命令。
        辅助BSP树构建
            在BSP树的构建中,利用球体树辅助,可以将复杂度从O(Nlog²N)下降为O(NlogN)的复杂度。

二叉空间分割(BSP)
    一般用于编辑器状态,场景变化时需要重新生成
    3d空间就是依次按xyz轴进行平面划分
    2d空间就是依次按xz轴进行线段划分
    当平面有交叉时,需要将交叉的平面再次进行拆分
    可利用BVH加速BSP的构建
    应用:
        BSP 适合结构比较紧凑的互相遮挡多的场景
        fps室内,portal系统(看着挺复杂的)

kd树
    一种特殊形式的BSP树(轴对齐的BSP树)
    每一层都在不同的轴
    适合于最近的静态目标的查找,构造比较耗时,一般不动态刷新
    查询点均落在划分轴上
    每次划分前都计算这个块中中间位置的点,穿过这个点进行轴划分
    应用:
        最近邻静态目标查找,例如上百的单位找最近的建筑,用kd树代替遍历+距离判断


几种结构的比较
    四叉树最适合二维数据,例如导航系统中的地图渲染。在这种情况下,它比八叉树更快,因为它可以更好地适应几何形状并保持节点结构较小。
    如果数据是三维的,则用八叉树和BVH
    BSP旨在优化大型静态几何体,不爱适合需要大量动态增加物体的场合中,自带排序属性
    BVH多用于光线追踪(bvh 做 pvs(潜在可视集合)并不算特别有效率。bvh 做线段求交很快)
    碰撞检测,潜在碰撞集是关键,所以会使用更加优化邻近搜索的策略譬如 kdtree 或者 rtree
    kd树是平衡的,很难动态更新。octree比较容易更新


点是否在多边形内
    点向一条边的中点引射线,检测这个射线和多边形其他边的交点有几个,奇数个则代表点在多边形内,偶数个则代表点在多边形外
点是否在三角形内
    1是用之前的射线判断交点的奇偶数
    2是将三角形ABC三个边(AB,BC,CA)分别与比较点判断差乘,如果这3个差乘结果表示的方向一致,说明就在三角形内
圆和扇形的相交
点至三角形的最近点
射线与圆的相交
点和扇形的相交
点到AABB,点到OBB的最近点和距离
圆与AABB,OBB的相交
两条线段是否相交
    线段1为 AB,线段2为CD。则AB与AC,AB与AD进行cross判断CD两点是否同侧,再CD与CA,CD与CB进行cross检测同侧,如果都不同侧则相交
求线段与圆的交点
求两圆的交点
凸多边形和凸多边形相交,OBB和AABB相交,OBB和OBB相交
    分离轴
凸多边形和凹多边形相交
    将凹多边形拆分成多个凸多边形,再进行分离轴检测
点到线段的最短距离
    与点到直线的最短距离的求法有些差别,求点到线段最短距离时需要考虑参考点在沿线段方向的投影点是否在线段上
扇形和圆相交
    先检测扇形和圆心的距离是否小于两半径和,小于则再根据扇形前方和扇形圆形指向圆形的向量计算角度是否小于扇形的半角,大于则再判断扇形两线段和圆是否有交点
点是否在胶囊体内
    胶囊体本质是与胶囊体竖直方向的线段AB距离小于一定值V的所有点的集合,判断点是否在胶囊内则可简化为点到AB是否小于V

https://www.cnblogs.com/KillerAery/p/10878367.html
空间划分的数据结构(四叉树/八叉树/BVH树/BSP树/k-d树)

https://blog.csdn.net/silangquan/article/details/17481717
Real-Time Rendering (9) - 碰撞检测(Collision Detection)

https://www.cnblogs.com/hont/p/9470781.html
https://www.cnblogs.com/hont/category/682916.html
2D空间中求两圆的交点
2D空间中求线段与圆的交点
线段与非无限平面相交检测
一种3D空间的柱状多边形检测实现
胶囊体边界点的计算及获取

https://blog.csdn.net/qq_37043683/article/details/80375691
相交检测(必看)

https://blog.csdn.net/heyuchang666/article/details/55192932
GJK

http://www.dyn4j.org/2010/01/sat/#sat-convex
SAT分离轴

https://www.cnblogs.com/hont/p/5340044.html
Unity胶囊体的碰撞检测实现


作者:Wyman
链接:https://www.zhihu.com/question/266499219/answer/308829529
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

IDG_Game_One
https://github.com/phenomLi/Blog
n个碰撞检测的博文

https://www.bilibili.com/video/av31359405/?spm_id_from=333.788.videocard.11
https://github.com/QinZhuo/Client_IDG_YISHI 
GJK碰撞检测算法

http://ma-yidong.com/2018/11/10/construct-bvh-with-unity-job-system/
https://www.cnblogs.com/lookof/p/3546320.html
BVH

https://zhuanlan.zhihu.com/p/78315557
游戏编程算法与技巧读书笔记第七章·物理(超级赞)

Q.行列式怎么转为矩阵
Q.克朗姆公式怎么用
https://gameinstitute.qq.com/community/detail/117137
Real-Rime Rendering (9) - 碰撞检测(Collision Detection)

https://groups.google.com/d/topic/gamedevtop/WXOgxBK7Nk8


https://wuzhiwei.net/kdtree/
kdTree

r-tree


https://www.cnblogs.com/tekkaman/p/3645073.html
碰撞检测系统
https://www.cnblogs.com/tekkaman/p/3647566.html
刚体动力学
https://so.cger.com/tag/d3/2033.html
动力学模拟


https://zhuanlan.zhihu.com/p/86981378
多边形碰撞检测(好文)
http://www.idivecat.com/archives/category/tx/pzxg
碰撞相关(好文)
https://www.cnblogs.com/wangchengfeng/p/3495954.html
3D游戏引擎中常见的三维场景管理方法(好文)
https://www.cnblogs.com/lookof/p/3546320.html
BVH的分析和解释(好文)
https://zhuanlan.zhihu.com/p/41742755
Unity3D-游戏中的技能碰撞检测
https://blog.csdn.net/lkysyzxz/category_6524451.html
扇形等表示和相交
https://blog.csdn.net/zaffix/article/details/25339837
圆与扇形碰撞检测
https://www.zhihu.com/question/48905832?sort=created
BVH和四叉树对比
https://blog.csdn.net/a1047120490/article/details/104925253
点乘和叉乘
https://www.zhihu.com/question/266499219
3D游戏的碰撞检测是如何实现的?
https://zhuanlan.zhihu.com/p/33529865
UE4的移动碰撞
https://www.qiujiawei.com/collision-detection/
碰撞检测算法
https://www.zhihu.com/question/29739023
BSP树与八叉树各有什么优劣,分别有什么应用场合?
https://zhuanlan.zhihu.com/p/28760549
unity涨姿势知识(技术题一)
https://blog.csdn.net/heyuchang666/article/details/55192932
引擎开发_ 碰撞检测_GJK 算法详细介绍
https://blog.csdn.net/qq_17347313/article/details/99947084
游戏碰撞表示以及检测的原理

Q.碰撞后怎么平滑的运动
Q.圆和AABB在尖角处碰撞时怎么消除尖叫的抖动感觉

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页