public static bool IntersectRayOBB(LVector3 o, LVector3 d, OBB obb, out LFloat tmin, out LVector3 p) { var fo = o - obb.c; var fd = obb.u.WorldToLocal(d); return(Utils.IntersectRayAABB(fo, fd, obb.ToAABB(), out tmin, out p)); }
public static bool TestOBBCapsule(OBB obb, Capsule capsule) { //-1.确认两个包围球是否 碰撞 如果未曾碰撞 加速返回 var cc = capsule.GetBoundSphereCenter(); var rc = capsule.GetBoundsSphereRadius(); var diffr = obb.e.magnitude + rc; if ((obb.c - cc).sqrMagnitude > diffr * diffr) { return(false); } //0.检测端点距离 var maxDist = capsule.r * capsule.r; var sqDistA = Utils.SqDistPointOBB(capsule.a, obb); if (sqDistA <= maxDist) { return(true); } var sqDistB = Utils.SqDistPointOBB(capsule.b, obb); if (sqDistB <= maxDist) { return(true); } //0.Capsule 转换到OBB坐标 空间转换为Capsule VS AABB //1 将capsule 变成一个射线 var lrayd = obb.u.WorldToLocal(capsule.b - capsule.a); var lraydn = lrayd.normalized; var lcapa = obb.u.WorldToLocal(capsule.a); var cap2obb = (/*obb.lc == LVector3.zero*/ -lcapa); var aabb = obb.ToAABB(); //2.将射线沿着AABB 中心靠近capsule.r 距离 var orthDir = (cap2obb - Dot(lraydn, cap2obb) * lraydn).normalized; var finalRayC = lcapa + (orthDir * capsule.r); //3.碰撞转换为ray AABB碰撞 if (Utils.IntersectRayAABB(finalRayC, lrayd, aabb, out LFloat tmin, out LVector3 q)) { //4.检测碰撞点时间 确认碰撞是否发生 return(tmin <= LFloat.one); } return(false); }