/// <summary>
        /// Project a point into 2D space
        /// </summary>
        public static Vector2 Project(BoundingFrustum VisibleArea, Vector3 Point)
        {
            //Acquires the frustum of the area of the screen in view.
            //Then it stores the corners of the area.
            Vector3[] corners = VisibleArea.GetCorners();
            Ray ray = new Ray(Point, Point - Manager.CameraFocus - Manager.CameraLocation);

            float? DistanceToFar = ray.Intersects(VisibleArea.Far);
            float? DistanceToNear = ray.Intersects(VisibleArea.Near);
            Vector3 ScreenCoord;
            if (DistanceToFar.HasValue)
            {
                ScreenCoord = ray.Position + ray.Direction * DistanceToFar.Value;
                ScreenCoord = new Vector3(
                    Vector3.Dot(
                        Vector3.Normalize(corners[5] - corners[4])
                        , ScreenCoord - corners[4])
                    / (corners[5] - corners[4]).Length()
                    , Vector3.Dot(
                        Vector3.Normalize(corners[7] - corners[4])
                        , ScreenCoord - corners[4])
                    / (corners[7] - corners[4]).Length()
                    , 0);
            }
            else
            {
                //Make sure this is off the screen
                return Vector2.One * (Manager.GameWindow.Width + Manager.GameWindow.Height);
            }
            return new Vector2(ScreenCoord.X * Manager.GameWindow.Width, ScreenCoord.Y * Manager.GameWindow.Height);
        }
Beispiel #2
0
        public static VoxLocation? GetOuter(Ray camRay, VoxState state)
        {
            camRay.Position -= new Vector3(state.World.worldMin.X * Region.WIDTH, 0, state.World.worldMin.Y * Region.DEPTH);
            VRay vr = new VRay(camRay.Position, camRay.Direction);
            Vector3I loc = vr.GetNextLocation();

            // Check For World Intersect
            BoundingBox bb = new BoundingBox(Vector3.Zero, new Vector3(VoxWorld.WIDTH * Region.WIDTH, Region.HEIGHT, VoxWorld.DEPTH * Region.DEPTH));
            if(!camRay.Intersects(bb).HasValue) return null;

            // Move In World
            while(!IsInBounds(loc))
                loc = vr.GetNextLocation();

            // Move Through World
            VoxLocation pvl = new VoxLocation(loc);
            while(IsInBounds(loc)) {
                VoxLocation vl = new VoxLocation(loc);
                Region region = state.World.regions[vl.RegionIndex];
                if(region != null) {
                    ushort id = region.voxels[vl.VoxelIndex].ID;
                    if(id != 0) return pvl;
                }
                loc = vr.GetNextLocation();
                pvl = vl;
            }
            return null;
        }
        public Vector3? GetCollisionPosition()
        {
            MouseState mouseState = Mouse.GetState();

            Vector3 nearSource = new Vector3(mouseState.X, mouseState.Y, 0f);
            Vector3 farSource = new Vector3(mouseState.X, mouseState.Y, 1f);

            Vector3 nearPoint = device.Viewport.Unproject(
                nearSource,
                camera.projection,
                camera.view,
                Matrix.Identity);

            Vector3 farPoint = device.Viewport.Unproject(
                farSource,
                camera.projection,
                camera.view,
                Matrix.Identity);

            Vector3 direction = farPoint - nearPoint;
            direction.Normalize();

            Ray pickRay = new Ray(nearPoint, direction);

            Nullable<float> result = pickRay.Intersects(new Plane(Vector3.Up, 0f));
            Vector3? resultVector = direction * result;
            Vector3? collisionPoint = resultVector + nearPoint;

            return collisionPoint;
        }
        public void BoundingCylinder_Ray_Test()
        {
            BoundingCylinder cyl = new BoundingCylinder (sideA: Vector3.Zero, sideB: Vector3.Up * 100, radius: 100f);
            Ray ray;
            ray = new Ray (position: new Vector3 (0, 0, 0), direction: Vector3.Up);
            Assert.IsNotNull (ray.Intersects (cyl));
            ray = new Ray (position: new Vector3 (0, 0, 0), direction: Vector3.Down);
            Assert.IsNotNull (ray.Intersects (cyl));

            ray = new Ray (position: new Vector3 (0, 0, 0), direction: Vector3.Forward);
            Assert.IsNotNull (ray.Intersects (cyl));
            ray = new Ray (position: new Vector3 (0, 0, 0), direction: Vector3.Left);
            Assert.IsNotNull (ray.Intersects (cyl));
            ray = new Ray (position: new Vector3 (0, -1, 0), direction: Vector3.Forward);
            Assert.IsNull (ray.Intersects (cyl));
            ray = new Ray (position: new Vector3 (0, -1, 0), direction: Vector3.Left);
            Assert.IsNull (ray.Intersects (cyl));

            // hier sollte eigentlich (0,100,0) auch noch drin sein, nicht nur (0,99,0),
            // also wie bei SideA!
            ray = new Ray (position: new Vector3 (0, 99, 0), direction: Vector3.Forward);
            Assert.IsNotNull (ray.Intersects (cyl));
            ray = new Ray (position: new Vector3 (0, 99, 0), direction: Vector3.Left);
            Assert.IsNotNull (ray.Intersects (cyl));
            ray = new Ray (position: new Vector3 (0, 101, 0), direction: Vector3.Forward);
            Assert.IsNull (ray.Intersects (cyl));
            ray = new Ray (position: new Vector3 (0, 101, 0), direction: Vector3.Left);
            Assert.IsNull (ray.Intersects (cyl));
        }
Beispiel #5
0
        /// <summary>
        /// Defines the closest obstacle
        /// </summary>
        public void DetectClosestObstacle()
        {
            float closestObstacleDistance = float.MaxValue;
            _closestObstacle = null;

            var localAgentMatrix = Matrix.Invert(AutonomousAgent.ParentObject.World);

            foreach (SceneEntity obstacle in Context.Keys)
            {
                Vector3 localPos = Vector3.Transform(obstacle.World.Translation, localAgentMatrix);

                if (UseLineOfSight)
                {
                    if (localPos.Z > 0f)
                        continue;
                }

                float expandedRadius = obstacle.WorldBoundingSphere.Radius + AutonomousAgent.ParentObject.WorldBoundingSphere.Radius - AllowedPenetration;

                var ray = new Ray(Vector3.Zero, Vector3.Forward);
                float? result = ray.Intersects(new BoundingSphere(localPos, expandedRadius));
                if (result.HasValue && result.Value < closestObstacleDistance)
                {
                    closestObstacleDistance = result.Value;

                    _closestObstacle = obstacle;
                    _closestObstacleLocalPosition = localPos;
                }
            }
        }
Beispiel #6
0
        public override void CalculateLocalMouse(Ray mouseRay, Action<VertexPositionColor, VertexPositionColor> debug)
        {
            MouseHover = false;

            var verts = new Vector3[3];
            verts[0] = new Vector3(-0.5f, -0.5f, 0);
            verts[1] = new Vector3(0.5f, -0.5f, 0);
            verts[2] = new Vector3(-0.5f, 0.5f, 0);

            for (int i = 0; i < 3; ++i)
                verts[i] = Vector3.Transform(verts[i], localTransformation);

            debug(new VertexPositionColor(verts[0], Color.Red), new VertexPositionColor(verts[1], Color.Red));
            debug(new VertexPositionColor(verts[0], Color.Green), new VertexPositionColor(verts[2], Color.Green));

            var distance = mouseRay.Intersects(new Plane(verts[0], verts[1], verts[2]));
            if (distance == null || !distance.HasValue) return;
            if (distance.Value < 0) return; //GUI plane is behind camera
            var interesectionPoint = mouseRay.Position + (mouseRay.Direction * distance.Value);

            debug(new VertexPositionColor(verts[0], Color.Blue), new VertexPositionColor(interesectionPoint, Color.Blue));

            var x = ScalarProjection(interesectionPoint - verts[0], verts[1] - verts[0]) / (verts[1] - verts[0]).Length();
            var y = ScalarProjection(interesectionPoint - verts[0], verts[2] - verts[0]) / (verts[2] - verts[0]).Length();

            LocalMouseX = (int)(x * uiCamera.viewportDimensions.X);
            LocalMouseY = (int)(y * uiCamera.viewportDimensions.Y);

            MouseHover = true;
        }
Beispiel #7
0
        private void GenerateRect()
        {
            int minX = int.MaxValue;
            int minZ = int.MaxValue;
            int maxX = int.MinValue;
            int maxZ = int.MinValue;
            var corners = Frustum.GetCorners();

            Plane plane = new Plane(new Vector4(0, 1, 0, 0));
            for (int i = 4; i < corners.Length; i++)
            {
                Ray ray = new Ray(corners[i - 4], corners[i]);
                var distance = ray.Intersects(plane);
                if (distance.HasValue)
                {
                    var pos2 = ray.Position + ray.Direction * distance.Value;
                    if ((int)pos2.X > maxX)
                        maxX = (int)pos2.X;
                    if ((int)pos2.X < minX)
                        minX = (int)pos2.X;
                    if ((int)pos2.Z > maxZ)
                        maxZ = (int)pos2.Z;
                    if ((int)pos2.Z < minZ)
                        minZ = (int)pos2.Z;
                }
                // Console.WriteLine("distance[{0}]: {1} pos2:{2}", i, distance, pos2.ToString());
            }
            quadRect = new Rectangle(minX, minZ, Math.Abs(maxX - minX), Math.Abs(maxZ - minZ));
            // Console.WriteLine("X: {0},{1} Z:{2},{3}", minX, maxX, minZ, maxZ);
        }
        public static void CalculateMouse3DPosition()
        {
            Plane GroundPlane = new Plane(0, 1, 0, 0); // x - lewo prawo Z- gora dol
               int mouseX =    mouseState.X;
               int mouseY =    mouseState.Y;
               Vector3 nearsource = new Vector3((float)mouseX, (float)mouseY, 0f);
               Vector3 farsource = new Vector3((float)mouseX, (float)mouseY, 1f);

               Matrix world = Matrix.CreateTranslation(0, 0, 0);

               Vector3 nearPoint = device.Viewport.Unproject(nearsource,
               Projection, View, Matrix.Identity);

               Vector3 farPoint = device.Viewport.Unproject(farsource,
               Projection, View, Matrix.Identity);

               Vector3 direction = farPoint - nearPoint;
               direction.Normalize();
               Ray pickRay = new Ray(nearPoint, direction);
               float? position = pickRay.Intersects(GroundPlane);

               if (position != null)
               {
               MousePosition = pickRay.Position + pickRay.Direction * position.Value;
               MousePosition.Y = 30f;
               }
               else
               MousePosition = new Vector3(0, 0, 0);
        }
Beispiel #9
0
        public static List<IPickable> GetPickables(Point a_clickPoint)
        {
            var camera = CameraManager.ActiveCamera;

               Vector3 nearSource = camera.Viewport.Unproject(new Vector3(a_clickPoint.X, a_clickPoint.Y, camera.Viewport.MinDepth), camera.Projection, camera.View, Matrix.Identity);
               Vector3 farSource = camera.Viewport.Unproject(new Vector3(a_clickPoint.X, a_clickPoint.Y, camera.Viewport.MaxDepth), camera.Projection, camera.View, Matrix.Identity);
               Vector3 direction = farSource - nearSource;

               direction.Normalize();

               var ray = new Ray(nearSource, direction);

               var pickables = new List<IPickable>();
               var rays = new List<Ray>();
               var map = new Dictionary<float?, IPickable>();

               foreach (var pickable in ComponentManager.Pickables.Values)
               {
               BoundingBox boundingBox = pickable.GetBoundingBox();
               float? distance;
               ray.Intersects(ref boundingBox, out distance);
               if (distance != null)
               {
                   map[distance] = pickable;
                   pickables.Add(pickable);
               }
               }

               return pickables;
        }
        public float? checkCollisionAgainstEnvironment(Ray ray)
        {
            float? collided = null;
            foreach (Collidable c in stationaryCollidables)
            {
                if (c.type == CollisionType.environment && collided == null)
                {
                    Vector3[] points = new Vector3[2];
                    points[0] = Vector3.Transform(c.boundingBox.Min, c.getComponent<Spatial>().transform);
                    points[1] = Vector3.Transform(c.boundingBox.Max, c.getComponent<Spatial>().transform);
                    BoundingBox bb = BoundingBox.CreateFromPoints(points);
                    if (ray.Intersects(bb) != null)
                    {
                        if (c.children.Count > 0)
                        {
                            collided = checkAgainstChildren(c, ray);
                        }
                        else
                        {
                            collided = checkAgainstMesh(c.getComponent<Drawable3D>(), ray);
                        }
                    }
                }
            }

            return collided;
        }
Beispiel #11
0
 public static Vector3? GetRayPlaneIntersectionPoint(Ray ray, Plane plane)
 {
     float? distance = ray.Intersects(plane);
     if (distance.HasValue)
         return ray.Position + ray.Direction * distance.Value;
     else
         return null;
 }
        // überprüft, ob ein Strahl ein Dreieck schneidet
        protected float? FindIntersection(Ray ray, ITriangle triangle)
        {
            // überprüfen, ob der Strahl die vom Dreieck aufgespannte Ebene schneidet
            float? f = ray.Intersects(new Plane(triangle.P0, triangle.P1, triangle.P2));

            // wenn ja, überprüfen ob Schnittpunkt im Dreieck liegt
            if (f != null && IsInsideTriangle(triangle, ray.Position + ray.Direction * f.Value))
                return f;

            return null;
        }
        public static float? CastBulletRay(Entity targetEntity, GraphicsDevice GraphicsDevice)
        {
            Vector3 near = new Vector3(GraphicsDevice.Viewport.Width * 0.5f, GraphicsDevice.Viewport.Height * 0.5f, 0.0f);
            Vector3 far = new Vector3(GraphicsDevice.Viewport.Width * 0.5f, GraphicsDevice.Viewport.Height * 0.5f, 1.0f);

            near = GraphicsDevice.Viewport.Unproject(near, Projection(GraphicsDevice), LookAt(), Matrix.Identity);
            far = GraphicsDevice.Viewport.Unproject(far, Projection(GraphicsDevice), LookAt(), Matrix.Identity);

            Ray ray = new Ray(near, Vector3.Normalize(far - near));
            return ray.Intersects(targetEntity.model.boundingbox);
        }
Beispiel #14
0
 public bool CheckRayIntersection(Ray ray, BoundingSphere sphere)
 {
     if (ray.Intersects(sphere) != null)
     {
         drawSpheres = sphere;
         return true;
     }
     else
     {
         return false;
     }
 }
        public static Vector3 getIntersectedQuadNode(Ray intersected)
        {
            Vector3 v = Vector3.Zero;
            BoundingBox tmp;
            foreach(QuadNode q in QuadNodeController.QuadNodeList)
            {
                if((intersected.Intersects(q.Bounds))!=null)
                {

                    // prezri vsetky bunky terenu v patchi a zisti ktoru malu bunku pretina
                    int minX = (int)q.Bounds.Min.X;
                    int minZ = (int)q.Bounds.Min.Z;
                    int maxX = (int)q.Bounds.Max.X;
                    int maxZ = (int)q.Bounds.Max.Z;

                    for (int j = minX; j < maxX; j++)
                    {
                        for (int k = minZ; k < maxZ; k++)
                        {
                            v.X = j;
                            v.Y = StaticHelpers.StaticHelper.GetHeightAt(k, j);
                            v.Z = k;

                            tmp.Min = v;
                            tmp.Max = v + new Vector3(1);

                            if (intersected.Intersects(tmp) != null)
                            {
                                return v;
                            }
                        }
                    }

                    return q.Bounds.Min + (q.Bounds.Max - q.Bounds.Min) /2;

                }
            }

            return Vector3.Zero;
        }
Beispiel #16
0
 public override GameObjectDistance Intersects(Ray ray)
 {
     foreach (BoundingSphere sphere in Bounds) {
         float? distance = ray.Intersects (sphere);
         if (distance != null) {
             GameObjectDistance intersection = new GameObjectDistance () {
                 Object=this, Distance=distance.Value
             };
             return intersection;
         }
     }
     return null;
 }
        public static Node getNodeIntersected(Ray mouseRay)
        {
            foreach (Node q in tileList)
            {
                if ((mouseRay.Intersects(q.Box)) != null)
                {
                    //return q.Box.Min + (q.Box.Max - q.Box.Min) / 2;
                    return q;
                }

            }
            return PathFinderManager.tileList[0, 0];
        }
Beispiel #18
0
        public static Vector3 GetPosition(Ray ray)
        {
            Plane plane = new Plane(new Vector3(0, 1, 0), 0);
            float? distance = ray.Intersects(plane);

            //ripped from http://xboxforums.create.msdn.com/forums/p/10441/212094.aspx
            //how the f**k does this work?
            double denominator = Vector3.Dot(plane.Normal, ray.Direction);
            double numerator = Vector3.Dot(plane.Normal, ray.Position) + plane.D;
            double t = -(numerator / denominator);

            return ray.Position + ray.Direction * (float)t;
        }
        public Vector3? GetCollisionTest()
        {
            Vector3 direction = camera.cameraDirection; //farPoint - nearPoint;
            direction.Normalize();

            Ray pickRay = new Ray(camera.cameraPosition, direction);

            Nullable<float> result = pickRay.Intersects(new Plane(Vector3.Up, -1f));
            Vector3? resultVector = direction * result;
            Vector3? collisionPoint = resultVector + camera.cameraPosition;

            return collisionPoint;
        }
Beispiel #20
0
        public Entity CheckEntity(Vector3 start, Vector3 direction, Entity sender)
        {
            Ray ray = new Ray(start, direction);

            foreach (var ent in Entities)
            {
                if (ent == sender)
                    continue;

                if (ray.Intersects(ent.CollisionBox) != null)
                    return ent;
            }
            return null;
        }
Beispiel #21
0
        public void CheckHits(Player player, OtherPlayer[] players)
        {
            if (players[id] != null)
            {

                Vector3 shooterPos = players[id].GetPosition();

                BoundingSphere b = new BoundingSphere(player.GetPosition(), Constants.BOLLRADIE);
                Ray r = new Ray(shooterPos, dir);
                if (r.Intersects(b) != null)
                {
                    player.ChangeLifeStatus(false);
                }
            }
        }
Beispiel #22
0
        /// <summary>
        /// Mira si un objeto es intersecado por el rayo.
        /// </summary>
        /// <param name="objeto">Objeto que se desea mirar</param>
        /// <param name="r">Rayo del mouse.</param>
        /// <param name="intersectionDistance">Out: Distancia donde se intersecto el objeto.</param>
        /// <returns>True si el objeto es intersectado por el rayo, de lo contrario false.</returns>
        public static bool intersectObject(GameObject objeto, Ray r, out float intersectionDistance)
        {
            //Posiciona el bounding box del objeto en coordenadas del mundo.
            Matrix world = Matrix.CreateScale(objeto.Size) * Matrix.CreateTranslation(objeto.Position);
            BoundingBox box = new BoundingBox();
            box.Max = Vector3.Transform(objeto.BoundingBox.Max, world);
            box.Min = Vector3.Transform(objeto.BoundingBox.Min, world);

            float? d;
            if ((d = r.Intersects(box)).HasValue == false)
            {
                intersectionDistance = 0f;
                return false;
            }
            intersectionDistance = d.Value;
            return true;
        }
Beispiel #23
0
        public static Vector3 MouseToWorld(MouseState ms, Matrix view, Matrix projection, Matrix world)
        {
            Vector3 nearsource = new Vector3((float)ms.X, (float)ms.Y, 0f);
            Vector3 farsource = new Vector3((float)ms.X, (float)ms.Y, 1f);

            Vector3 nearPoint = GameContainer.Graphics.GraphicsDevice.Viewport.Unproject(nearsource, projection, view, world);
            Vector3 farPoint = GameContainer.Graphics.GraphicsDevice.Viewport.Unproject(farsource, projection, view, world);

            Vector3 direction = Vector3.Normalize(farPoint - nearPoint);

            Ray pickRay = new Ray(nearPoint, direction);

            float? distance = pickRay.Intersects(new Plane(Vector3.Backward, -4)); // hack

            if (distance.HasValue) {
                return pickRay.Position + (pickRay.Direction * distance.Value);
            } else {
                return Vector3.Zero;
            }
        }
        public Vector3? GetCollisionPosition()
        {
            MouseState mousestate = Mouse.GetState();
            Vector3 near = new Vector3(mousestate.X,mousestate.Y,0f);
            Vector3 far = new Vector3(mousestate.X,mousestate.Y,1f);

            Vector3 nearPoint = graphicDevice.Viewport.Unproject(near,camera.projection,camera.view,Matrix.Identity);
            Vector3 farPoint = graphicDevice.Viewport.Unproject(far,camera.projection,camera.view,Matrix.Identity);

            Vector3 Direction = farPoint - nearPoint;
            Direction.Normalize();

            Ray pickRay = new Ray(nearPoint,Direction);
            Nullable<float> result = pickRay.Intersects(new Plane(Vector3.Up, 0f));

            Vector3? ResultVector = Direction * result;
            Vector3? Collision = ResultVector + nearPoint;

            return Collision;
        }
Beispiel #25
0
        public void interact()
        {
            bool v = false;
            foreach (GameObject go in Tools.Quick.game.Oom.onMapObject)
            {
                if(Vector3.Distance(go.getposition(),position)<Tools.Quick.distInteract)
                {

                Ray r = new Ray(position, Tools.Quick.game.camera.lookat);
                foreach (BoundingSphere bsph in go.getHitSphere())
                {
                    if(Convert.ToBoolean(r.Intersects(bsph)))
                    {
                        v = true;
                    }
                }
                if (v) go.action();
                }

            }
        }
Beispiel #26
0
        public RayIntersectionResult RayIntersection(Ray ray)
        {
            var closestIntersection = new RayIntersectionResult{ distance = float.PositiveInfinity, face = null };

            foreach (var face in Faces)
            {
                var plane = ConstructPlane(face);
                var intersectionDistance = ray.Intersects(plane);
                if (intersectionDistance.HasValue && intersectionDistance.Value < closestIntersection.distance)
                {
                    var intersectionPoint = ray.Position + (ray.Direction * intersectionDistance.Value);
                    if (IsPointOnFace(intersectionPoint, face))
                    {
                        closestIntersection.distance = intersectionDistance.Value;
                        closestIntersection.face = face;
                    }
                }
            }

            if (closestIntersection.face == null) return null;
            return closestIntersection;
        }
        /// <summary>
        /// Computes the intersection, if any, between a ray and the objects in the character's bounding box.
        /// </summary>
        /// <param name="ray">Ray to test.</param>
        /// <param name="length">Length of the ray to use in units of the ray's length.</param>
        /// <param name="earliestHit">Earliest intersection location and information.</param>
        /// <returns>Whether or not the ray hit anything.</returns>
        public bool RayCast(Ray ray, float length, out RayHit earliestHit)
        {
            earliestHit = new RayHit();
            earliestHit.T = float.MaxValue;
            foreach (var collidable in character.Body.CollisionInformation.OverlappedCollidables)
            {
                //Check to see if the collidable is hit by the ray.
                float? t = ray.Intersects(collidable.BoundingBox);
                if (t != null && t < length)
                {
                    //Is it an earlier hit than the current earliest?
                    RayHit hit;
                    if (collidable.RayCast(ray, length, SupportRayFilter, out hit) && hit.T < earliestHit.T)
                    {
                        earliestHit = hit;
                    }
                }
            }
            if (earliestHit.T == float.MaxValue)
                return false;
            return true;

        }
        public float? IntersectDistance(BoundingSphere sphere, Vector2 mouseLocation)
        {
            Matrix view = Global.view;
            Matrix projection = Global.projection;
            Viewport viewport = Global.GraphicsDevice.Viewport;
            Vector3 nearPoint = viewport.Unproject(new Vector3(mouseLocation.X,
            mouseLocation.Y, 0.0f),
            projection,
            view,
            Matrix.Identity);

            Vector3 farPoint = viewport.Unproject(new Vector3(mouseLocation.X,
            mouseLocation.Y, 1.0f),
            projection,
            view,
            Matrix.Identity);

            Vector3 direction = farPoint - nearPoint;
            direction.Normalize();

            Ray mouseRay = new Ray(nearPoint, direction);
            return mouseRay.Intersects(sphere);
            //bounding box or frustum?
        }
Beispiel #29
0
        public static VoxLocation? GetLevel(Ray camRay, VoxState state, int h)
        {
            camRay.Position -= new Vector3(state.World.worldMin.X * Region.WIDTH, 0, state.World.worldMin.Y * Region.DEPTH);
            VRay vr = new VRay(camRay.Position, camRay.Direction);
            Vector3I loc = vr.GetNextLocation();

            // Check For World Intersect
            BoundingBox bb = new BoundingBox(new Vector3(0, h - 1, 0), new Vector3(VoxWorld.WIDTH * Region.WIDTH, h, VoxWorld.DEPTH * Region.DEPTH));
            if(!camRay.Intersects(bb).HasValue) return null;

            // Move In World
            while(!IsInBounds(loc))
                loc = vr.GetNextLocation();

            // Move Through World
            while(IsInBounds(loc)) {
                VoxLocation vl = new VoxLocation(loc);
                Region region = state.World.regions[vl.RegionIndex];
                ushort id = region.voxels[vl.VoxelIndex].ID;
                if(loc.Y == h) return vl;
                loc = vr.GetNextLocation();
            }
            return null;
        }
Beispiel #30
0
        public RayIntersectionResult RayIntersection(Ray ray)
        {
            var closestIntersection = new RayIntersectionResult { Distance = float.PositiveInfinity, Intersects = false };

            for (int vindex = 0; vindex < indicies.Length; vindex += 3)
            {
                var p = indicies.Skip(vindex).Take(3).Select(i => verticies[i].Position).ToArray();
                var plane = new Plane(p[0], p[1], p[2]);
                var intersectionDistance = ray.Intersects(plane);
                if (intersectionDistance.HasValue && intersectionDistance.Value < closestIntersection.Distance)
                {
                    var intersectionPoint = ray.Position + (ray.Direction * intersectionDistance.Value);
                    if (IsPointOnFace(intersectionPoint, p))
                    {
                        closestIntersection.Distance = intersectionDistance.Value;
                        closestIntersection.Intersects = true;

                        var tc = indicies.Skip(vindex).Take(3).Select(i => verticies[i].TextureCoordinate).ToArray();

                        var bv = p.Select(v => v - intersectionPoint).ToArray();
                        var area = Vector3.Cross(p[0] - p[1], p[0] - p[2]).Length();
                        var baryArea = new float[] {
                            Vector3.Cross(bv[1], bv[2]).Length() / area,
                            Vector3.Cross(bv[2], bv[0]).Length() / area,
                            Vector3.Cross(bv[0], bv[1]).Length() / area
                        };

                        var uv = (tc[0] * baryArea[0]) + (tc[1] * baryArea[1]) + (tc[2] * baryArea[2]);

                        closestIntersection.UV = uv;
                    }
                }
            }

            return closestIntersection;
        }
Beispiel #31
0
        // Algorithm copied from: http://www.cs.utah.edu/~awilliam/box/box.pdf
        // This is the non-optimized version of:

        /*
         * Ray-box intersection using IEEE numerical properties to ensure that the
         * test is both robust and efficient, as described in:
         *
         *      Amy Williams, Steve Barrus, R. Keith Morley, and Peter Shirley
         *      "An Efficient and Robust Ray-Box Intersection Algorithm"
         *      Journal of graphics tools, 10(1):49-54, 2005
         *
         */
        private bool ComputeEntryAndExitSignedDistances(Ray rtRay, out float tMin, out float tMax)
        {
            float yMin = float.MaxValue, zMin = float.MaxValue;
            float yMax = float.MinValue, zMax = float.MinValue;

            tMin = float.MaxValue;
            tMax = float.MinValue;
            if (rtRay.Direction.X > 0)
            {
                tMin = (Bounds.Min.X - rtRay.Origin.X) / rtRay.Direction.X;
                tMax = (Bounds.Max.X - rtRay.Origin.X) / rtRay.Direction.X;
            }
            else if (rtRay.Direction.X < 0)
            {
                tMin = (Bounds.Max.X - rtRay.Origin.X) / rtRay.Direction.X;
                tMax = (Bounds.Min.X - rtRay.Origin.X) / rtRay.Direction.X;
            }
            if (rtRay.Direction.Y > 0)
            {
                yMin = (Bounds.Min.Y - rtRay.Origin.Y) / rtRay.Direction.Y;
                yMax = (Bounds.Max.Y - rtRay.Origin.Y) / rtRay.Direction.Y;
            }
            else if (rtRay.Direction.Y < 0)
            {
                yMin = (Bounds.Max.Y - rtRay.Origin.Y) / rtRay.Direction.Y;
                yMax = (Bounds.Min.Y - rtRay.Origin.Y) / rtRay.Direction.Y;
            }

            if ((tMin > yMax) || (yMin > tMax))
            {
                return(false);
            }
            if (yMin > tMin)
            {
                tMin = yMin;
            }
            if (yMax < tMax)
            {
                tMax = yMax;
            }

            if (rtRay.Direction.Z > 0)
            {
                zMin = (Bounds.Min.Z - rtRay.Origin.Z) / rtRay.Direction.Z;
                zMax = (Bounds.Max.Z - rtRay.Origin.Z) / rtRay.Direction.Z;
            }
            else if (rtRay.Direction.Z < 0)
            {
                zMin = (Bounds.Max.Z - rtRay.Origin.Z) / rtRay.Direction.Z;
                zMax = (Bounds.Min.Z - rtRay.Origin.Z) / rtRay.Direction.Z;
            }

            if ((tMin > zMax) || (zMin > tMax))
            {
                return(false);
            }
            if (zMin > tMin)
            {
                tMin = zMin;
            }
            if (zMax < tMax)
            {
                tMax = zMax;
            }

            return(true);

#if THIS_IS_USELESS
            // apparantly ray/BoundingBox returns _one_ of the intersection positions, but not always the closest one!!
            // USELESS!!
            Microsoft.Xna.Framework.Ray r = new Microsoft.Xna.Framework.Ray(rtRay.Origin, rtRay.Direction);

            float?dist = r.Intersects(Bounds);
            if (null == dist)
            {
                return(null);
            }

            float[] distances = new float[2];
            if (Bounds.Contains(rtRay.Origin) == ContainmentType.Contains)
            { // originated from inside, let's find the back-end existing position
                Microsoft.Xna.Framework.Ray backRay = new Microsoft.Xna.Framework.Ray(rtRay.Origin, -rtRay.Direction);
                float?backDist = backRay.Intersects(Bounds);
                distances[0] = (float)-backDist; // this will be a negative value
                distances[1] = (float)dist;
            }
            else
            {
                // dist is the entry position, now find the exist position
                distances[0] = (float)dist;
                // advance the ray position without going out of this node
                r.Position = r.Position + (distances[0] + float.Epsilon) * r.Direction;
                if (Bounds.Contains(r.Position) == ContainmentType.Contains)
                {
                    distances[1] = (float)r.Intersects(Bounds);
                }
                else
                {
                    distances[1] = distances[0] + float.Epsilon;
                }
            }
            return(distances);
#endif
        }
Beispiel #32
0
        public bool RayCast(Microsoft.Xna.Framework.Ray ray, float maximumLength, IList <BroadPhaseEntry> outputIntersections)
        {
            if (maximumLength == float.MaxValue)
            {
                throw new NotSupportedException("The Grid2DSortAndSweep broad phase cannot accelerate infinite ray casts.  Consider specifying a maximum length or using a broad phase which supports infinite ray casts.");
            }

            //Use 2d line rasterization.
            //Compute the exit location in the cell.
            //Test against each bounding box up until the exit value is reached.
            float   length = 0;
            Int2    cellIndex;
            Vector3 currentPosition = ray.Position;

            Grid2DSortAndSweep.ComputeCell(ref currentPosition, out cellIndex);
            while (true)
            {
                float cellWidth = 1 / Grid2DSortAndSweep.cellSizeInverse;
                float nextT;  //Distance along ray to next boundary.
                float nextTy; //Distance along ray to next boundary along y axis.
                float nextTz; //Distance along ray to next boundary along z axis.
                //Find the next cell.
                if (ray.Direction.Y > 0)
                {
                    nextTy = ((cellIndex.Y + 1) * cellWidth - currentPosition.Y) / ray.Direction.Y;
                }
                else if (ray.Direction.Y < 0)
                {
                    nextTy = ((cellIndex.Y) * cellWidth - currentPosition.Y) / ray.Direction.Y;
                }
                else
                {
                    nextTy = 10e10f;
                }
                if (ray.Direction.Z > 0)
                {
                    nextTz = ((cellIndex.Z + 1) * cellWidth - currentPosition.Z) / ray.Direction.Z;
                }
                else if (ray.Direction.Z < 0)
                {
                    nextTz = ((cellIndex.Z) * cellWidth - currentPosition.Z) / ray.Direction.Z;
                }
                else
                {
                    nextTz = 10e10f;
                }

                bool yIsMinimum = nextTy < nextTz;
                nextT = yIsMinimum ? nextTy : nextTz;



                //Grab the cell that we are currently in.
                GridCell2D cell;
                if (owner.cellSet.TryGetCell(ref cellIndex, out cell))
                {
                    float endingX;
                    if (ray.Direction.X < 0)
                    {
                        endingX = currentPosition.X;
                    }
                    else
                    {
                        endingX = currentPosition.X + ray.Direction.X * nextT;
                    }

                    //To fully accelerate this, the entries list would need to contain both min and max interval markers.
                    //Since it only contains the sorted min intervals, we can't just start at a point in the middle of the list.
                    //Consider some giant bounding box that spans the entire list.
                    for (int i = 0; i < cell.entries.count &&
                         cell.entries.Elements[i].item.boundingBox.Min.X <= endingX; i++)   //TODO: Try additional x axis pruning?
                    {
                        float?intersects;
                        var   item = cell.entries.Elements[i].item;
                        ray.Intersects(ref item.boundingBox, out intersects);
                        if (intersects != null && intersects < maximumLength && !outputIntersections.Contains(item))
                        {
                            outputIntersections.Add(item);
                        }
                    }
                }

                //Move the position forward.
                length += nextT;
                if (length > maximumLength) //Note that this catches the case in which the ray is pointing right down the middle of a row (resulting in a nextT of 10e10f).
                {
                    break;
                }
                Vector3 offset;
                Vector3.Multiply(ref ray.Direction, nextT, out offset);
                Vector3.Add(ref offset, ref currentPosition, out currentPosition);
                if (yIsMinimum)
                {
                    if (ray.Direction.Y < 0)
                    {
                        cellIndex.Y -= 1;
                    }
                    else
                    {
                        cellIndex.Y += 1;
                    }
                }
                else
                if (ray.Direction.Z < 0)
                {
                    cellIndex.Z -= 1;
                }
                else
                {
                    cellIndex.Z += 1;
                }
            }
            return(outputIntersections.Count > 0);
        }
Beispiel #33
0
 public Nullable <float> Intersects(Ray ray)
 {
     return(ray.Intersects(this));
 }