예제 #1
0
        public static bool Intersect(BoundingBox aabb, Ray2 ray)
        {
            Vector3 min = GetMinimum(aabb), max = GetMaximum(aabb);
            double ix = ray.x.X;
            double iy = ray.x.Y;
            double iz = ray.x.Z;
            double t, u, v;
            bool hit = false;

            ray.tNear = Double.MaxValue;

            t = (min.X - ix) / ray.d.X;
            if (t < ray.tNear && t > -Ray2.EPSILON)
            {
                u = iz + ray.d.Z * t;
                v = iy + ray.d.Y * t;
                if (u >= min.Z && u <= max.Z &&
                    v >= min.Y && v <= max.Y)
                {
                    hit = true;
                    ray.tNear = t;
                    ray.u = u;
                    ray.v = v;
                    ray.n.X = -1;
                    ray.n.Y = 0;
                    ray.n.Z = 0;
                }
            }
            t = (max.X - ix) / ray.d.X;
            if (t < ray.tNear && t > -Ray2.EPSILON)
            {
                u = iz + ray.d.Z * t;
                v = iy + ray.d.Y * t;
                if (u >= min.Z && u <= max.Z &&
                    v >= min.Y && v <= max.Y)
                {
                    hit = true;
                    ray.tNear = t;
                    ray.u = 1 - u;
                    ray.v = v;
                    ray.n.X = 1;
                    ray.n.Y = 0;
                    ray.n.Z = 0;
                }
            }
            t = (min.Y - iy) / ray.d.Y;
            if (t < ray.tNear && t > -Ray2.EPSILON)
            {
                u = ix + ray.d.X * t;
                v = iz + ray.d.Z * t;
                if (u >= min.X && u <= max.X &&
                    v >= min.Z && v <= max.Z)
                {
                    hit = true;
                    ray.tNear = t;
                    ray.u = u;
                    ray.v = v;
                    ray.n.X = 0;
                    ray.n.Y = -1;
                    ray.n.Z = 0;
                }
            }
            t = (max.Y - iy) / ray.d.Y;
            if (t < ray.tNear && t > -Ray2.EPSILON)
            {
                u = ix + ray.d.X * t;
                v = iz + ray.d.Z * t;
                if (u >= min.X && u <= max.X &&
                    v >= min.Z && v <= max.Z)
                {
                    hit = true;
                    ray.tNear = t;
                    ray.u = u;
                    ray.v = v;
                    ray.n.X = 0;
                    ray.n.Y = 1;
                    ray.n.Z = 0;
                }
            }
            t = (min.Z - iz) / ray.d.Z;
            if (t < ray.tNear && t > -Ray2.EPSILON)
            {
                u = ix + ray.d.X * t;
                v = iy + ray.d.Y * t;
                if (u >= min.X && u <= max.X &&
                    v >= min.Y && v <= max.Y)
                {
                    hit = true;
                    ray.tNear = t;
                    ray.u = 1 - u;
                    ray.v = v;
                    ray.n.X = 0;
                    ray.n.Y = 0;
                    ray.n.Z = -1;
                }
            }
            t = (max.Z - iz) / ray.d.Z;
            if (t < ray.tNear && t > -Ray2.EPSILON)
            {
                u = ix + ray.d.X * t;
                v = iy + ray.d.Y * t;
                if (u >= min.X && u <= max.X &&
                    v >= min.Y && v <= max.Y)
                {
                    hit = true;
                    ray.tNear = t;
                    ray.u = u;
                    ray.v = v;
                    ray.n.X = 0;
                    ray.n.Y = 0;
                    ray.n.Z = 1;
                }
            }
            return hit;
        }
예제 #2
0
        private Entity CheckEntityCollide(Vector3 position, Vector3 direction)
        {
            var players = Level.GetOnlinePlayers.OrderBy(player => position.DistanceTo(player.KnownPosition.ToVector3()));
            Ray2 ray = new Ray2
            {
                x = position,
                d = direction.Normalize()
            };

            foreach (var entity in players)
            {
                if (entity == Shooter) continue;

                if (Intersect(entity.GetBoundingBox(), ray))
                {
                    if (ray.tNear < direction.Distance) break;

                    Vector3 p = ray.x + ray.tNear * ray.d;
                    KnownPosition = new PlayerLocation((float)p.X, (float)p.Y, (float)p.Z);
                    return entity;
                }
            }

            var entities = Level.Entities.OrderBy(entity => position.DistanceTo(entity.KnownPosition.ToVector3()));
            foreach (var entity in entities)
            {
                if (entity == Shooter) continue;
                if (entity == this) continue;

                if (Intersect(entity.GetBoundingBox(), ray))
                {
                    if (ray.tNear < direction.Distance) break;

                    Vector3 p = ray.x + ray.tNear * ray.d;
                    KnownPosition = new PlayerLocation((float)p.X, (float)p.Y, (float)p.Z);
                    return entity;
                }
            }

            return null;
        }