原文Digital Library地址
pdf地址
稍微梳理一下这篇文章的内容,主要讲的是3D CCD的检测(不涉及处理)
第一遍看下来只看到了一堆点是不是在体内点是不是在面内的检测……
假设
或者说是公认的一些常识吧……
在3D CCD中,最基础的两个碰撞检测是
- 点和三角面片
- 线段和线段
这两者传入参数都是八个点,把时间归一化到
t∈[0,1]
t
∈
[
0
,
1
]
,这样一个点在这一段时间内的运动是
xi(t)=(1−t)xi+tx^i
x
i
(
t
)
=
(
1
−
t
)
x
i
+
t
x
^
i
但是这种线性插值对旋转情况的适应性相对会差一点。
点和三角面片
三角面片上的点可以表示为
x(u,v)=(1−u−v)x1+ux2+vx3
x
(
u
,
v
)
=
(
1
−
u
−
v
)
x
1
+
u
x
2
+
v
x
3
,
u,v∈[0,1],u+v<=1
u
,
v
∈
[
0
,
1
]
,
u
+
v
<=
1
假设传入的点的index为0,

这种情况下定义域是一个
Ω=[0,1]×{u,v≥0|u+v≤1} Ω = [ 0 , 1 ] × { u , v ≥ 0 | u + v ≤ 1 } 的三棱柱
线段和线段
索引01是同一条,23是同一条
这种情况下定义域是一个 [0,1]3 [ 0 , 1 ] 3 的立方体
after that
在定义域内,当
F=O
F
=
O
的时候,说明在这个点上发生了碰撞。(原文应该是0,反正对于每个tuv的集合,对应的是一个三维的坐标,相当于原点)
然后检测的方式就是从原点
O
O
引一条射线看是不是有奇数个交点。感觉是一种比较常见的检测点是不是在区域内的方法。
具体操作
Ray-Bilinear-Patch Crossing Parity Testing
Bilinear patch大概长这样
作者给出了求解射线和这样一个Bilinear的平面是否相交的处理办法。
【】在这里的问题是如果这个四个点落在同一个平面上的时候采用的是把它分为两个三角形,但是实际上如果两个线段的运动轨迹发生过交叉的话形成的图案不是简单的分为两个三角形可以处理的。
点在三角形内
https://www.cnblogs.com/graphics/archive/2010/08/05/1793393.html
这里的重心法
这个还会用在下面的Cubic Solver上,当P不位于三角形上的时候……看起来求的是投影是不是落在这个三角形内。
射线穿透三角形
https://lisabug.github.io/2015/05/01/Ray-tracer-triangle-intersection/
后面
最后的完整布料的码https://github.com/brickmaker/SimpleClothSimulation/tree/master/collision_detect
算一下碰撞检测这部分大概写了五六个钟头吧?。但是折腾布料还是很久的(可能最后为了跑出效果都不止五六个钟头)
一开始写完之后用随机数测试,和原文附带的代码比较。结果是edge-edge在一些比较扭曲的情况下有不同(但是因为感觉比较扭曲就没理它……)
然后具体做布料碰撞的时候,发现最容易检测出错的都在临界状态。
包括原文的代码在所有的点不运动的时候会崩溃。
还有一定要注意(不是这个模块但是在写弹簧质点模型的时候)注意对于,比如除以0以及零向量的normalize的时候可能会炸出来Nan然后布就会迷幻消失。
分享一个写错摩擦力之后炸裂的布
人生还有什么过不去的!
最后实现的效果大概是这样的(人生中第一个Youtube视频)。
效果还不是非常的好。而且运行效率不高,如果做一下并行或者GPU加速会好一点。
顺便BVH在另一篇博里
https://blog.youkuaiyun.com/birdy_/article/details/80589097
弹簧质点模型是小哥哥写的就不放了233
其他
Cubic Solver
这是比较常用的连续碰撞检测方法。也是这篇论文想要改进的方法。
需要解一个一元三次方程,我看起来好像常用的是牛顿法。然后得到具体的碰撞时间之后,再判断那个位置是不是真的发生了碰撞。但是它能够得到具体的碰撞点,而原文不行。
该论文对这个方法的评价↓
The standard method involving a cubic polynomial solver is vulnerable to rounding error, requiring the use of ad hoc tolerances, and nevertheless is particularly fragile in (near-)planar cases. Even with per-simulation tuning, it may still cause problems by missing collisions or erroneously flagging non-collisions.
https://github.com/sglab/OpenCCD.git
这个有BVH和连续的碰撞检测、
点和三角面片
(据说这个符号叫做楔积)
这个方程我如何都不知道怎么求导——啊——
如果看这个模块的可以参考了上面的OpenCCD