Ejemplo n.º 1
0
        private List<RaycastHitResult> RaycastAllInternal(Ray ray)
        {
            if (Map == null)
                throw new InvalidOperationException("Cannot raycast against an unloaded map!");

            List<RaycastHitResult> returnResults = new List<RaycastHitResult>();
            foreach (Room room in Map.Rooms)
            {
                foreach (var entity in room.Entities)
                {
                    if (!Map.LayerIsVisible(entity.Layer))
                        continue;

                    SceneComponent sceneEntity = entity as SceneComponent;
                    if (sceneEntity == null)
                        continue;

                    Vector3 aabbMin, aabbMax;
                    sceneEntity.GetAABB(out aabbMin, out aabbMax);

                    float intersectionDist;
                    if (RayIntersectsAABB(ray, aabbMin, aabbMax, out intersectionDist))
                    {
                        RaycastHitResult result = new RaycastHitResult();
                        result.Distance = intersectionDist;
                        result.Entity = entity;
                        returnResults.Add(result);
                    }
                }
            }

            // Sort the results - nearest to furthest.
            returnResults = returnResults.OrderBy(x => x.Distance).ToList();
            return returnResults;
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Returns all results (sorted in closest to furthest) order which intersect the <see cref="Ray"/>, or an 
        /// empty list if there are no results.
        /// </summary>
        /// <param name="ray"></param>
        /// <returns></returns>
        public List<MapEntity> RaycastAll(Ray ray)
        {
            var allResults = RaycastAllInternal(ray);
            List<MapEntity> outputList = new List<MapEntity>();
            foreach (var result in allResults)
                outputList.Add(result.Entity);

            return outputList;
        }
Ejemplo n.º 3
0
        private static bool RayIntersectsAABB(Ray ray, Vector3 aabbMin, Vector3 aabbMax, out float intersectionDistance)
        {
            Vector3 t_1 = new Vector3(), t_2 = new Vector3();

            float tNear = float.MinValue;
            float tFar = float.MaxValue;

            // Test infinite planes in each directin.
            for (int i = 0; i < 3; i++)
            {
                // Ray is parallel to planes in this direction.
                if (ray.Direction[i] == 0)
                {
                    if ((ray.Origin[i] < aabbMin[i]) || (ray.Origin[i] > aabbMax[i]))
                    {
                        // Parallel and outside of the box, thus no intersection is possible.
                        intersectionDistance = float.MinValue;
                        return false;
                    }
                }
                else
                {
                    t_1[i] = (aabbMin[i] - ray.Origin[i]) / ray.Direction[i];
                    t_2[i] = (aabbMax[i] - ray.Origin[i]) / ray.Direction[i];

                    // Ensure T_1 holds values for intersection with near plane.
                    if (t_1[i] > t_2[i])
                    {
                        Vector3 temp = t_2;
                        t_2 = t_1;
                        t_1 = temp;
                    }

                    if (t_1[i] > tNear)
                        tNear = t_1[i];

                    if (t_2[i] < tFar)
                        tFar = t_2[i];

                    if ((tNear > tFar) || (tFar < 0))
                    {
                        intersectionDistance = float.MinValue;
                        return false;
                    }
                }
            }

            intersectionDistance = tNear;
            return true;
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Returns the closest result which intersects the Ray, or null if there is nothing.
        /// </summary>
        /// <param name="ray">Ray along which to check for intersections.</param>
        /// <returns>Closest MapEntity, or null if none.</returns>
        public MapEntity Raycast(Ray ray)
        {
            var allEnts = RaycastAllInternal(ray);
            if (allEnts.Count > 0)
                return allEnts[0].Entity;

            return null;
        }