irrlicht圆球与三角形碰撞测试
看了irrlicht terrian例子,里面摄影机重力track中涉及一个球与三角形的碰撞函数:
CSceneCollisionManager::testTriangleIntersection
代码中注释较为简单,这里稍为补充一下,
主要是利用圆球半径为1这个条件建立二次方程求根,得到碰撞发生的时间点
椭圆标准化为半径为1的球(通过对三角形的三个顶点实施缩放实现)
case 1:
首先测试圆心与三角形所在平面的交点
如果交点在三角形之内,则认为碰撞发生,并根速度求出t
case 2:
测试三角形的顶点是否与圆碰撞
假设速度向量为Vx Vy Vz,
初始圆心所在位置为 Bx By Bz
碰撞点自然为Px Py Pz
新的圆心为
B(new)x = t*Vx
B(new)y = t*Vy
B(new)z = t*Vz
根据圆的特点有
(Px - B(new)x)^2 + (Py - B(new)y)^2 + (Pz - B(new)z)^2 = 1
将B(new)的分量分别用t代入,可以得到一个二次方程,求根,就可以得到t
case 3:
与三角形的边相碰撞
同样,求出新圆心与三角形某个顶点P的向量D1的长度平方:
leng_sqrt(D1) = (Px - B(new)x)^2 + (Py - B(new)y)^2 + (Pz - B(new)z)^2
其中B(new)向量如case2所示
同时,向量D1某在三角形某个边上V投影成一个向量D2,
根据圆球
有D1^2 + D2^2 = 1 ---- 式1
同时D2的长度可以直接用向量点乘算出
V归一化后,与D1进行点乘,就可以得到D2
D2算法如下
length(D2) = dot(normalise(V), D1);
将lenght(D2)代入式1,就是CSceneCollisionManager::testTriangleIntersection 最后一部分的二次方程的由来
滑动处理:
设一个滑动值 sliding_vel
根据碰撞点,以及相应切平面的法线,得到一个向量v
物体在碰撞检测前的目的点dest,与向量v相减
就会得到沿着碰撞切面滑动的点p,
p与dest重新进行一轮碰撞检测,直到p与dest之间的距离小于某个阀值,停止递归