示例#1
0
        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);
        }