Contains information about a ray cast hit.
예제 #1
0
        /// <summary>
        /// Determines whether there is a cliff nearby.
        /// </summary>
        /// <param name="position">Position to look from.</param>
        /// <param name="facingDirection">Direction to check in.</param>
        /// <param name="filter">Anonymous function to filter out unwanted objects.</param>
        /// <param name="space">The space to check for a cliff in.</param>
        /// <param name="distance">The distance to check at.</param>
        /// <returns>True if a cliff was detected, false otherwise.</returns>
        public static bool FindCliff(Vector3 position, Vector3 facingDirection, Func<BroadPhaseEntry, bool> filter, Space space, float distance)
        {
            // If there is a wall before the requested distance assume there is no cliff.
            Ray forwardRay = new Ray(position, new Vector3(facingDirection.X, 0, facingDirection.Z));
            RayCastResult forwardResult = new RayCastResult();
            space.RayCast(forwardRay, filter, out forwardResult);
            if ((forwardResult.HitData.Location - position).Length() < distance)
            {
                return false;
            }

            facingDirection.Normalize();
            Ray futureDownRay = new Ray(position + new Vector3(facingDirection.X * distance, 0, facingDirection.Z * distance), Vector3.Down);
            RayCastResult result = new RayCastResult();
            space.RayCast(futureDownRay, filter, out result);

            Vector3 drop = result.HitData.Location - futureDownRay.Position;
            if (drop.Y < -6.0f)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
예제 #2
0
        /// <summary>
        /// <para>Casts a convex shape against the space.</para>
        /// <para>Convex casts are sensitive to length; avoid extremely long convex casts for better stability and performance.</para>
        /// </summary>
        /// <param name="castShape">Shape to cast.</param>
        /// <param name="startingTransform">Initial transform of the shape.</param>
        /// <param name="sweep">Sweep to apply to the shape. Avoid extremely long convex casts for better stability and performance.</param>
        /// <param name="filter">Delegate to prune out hit candidates before performing a cast against them. Return true from the filter to process an entry or false to ignore the entry.</param>
        /// <param name="castResult">Hit data, if any.</param>
        /// <returns>Whether or not the cast hit anything.</returns>
        public bool ConvexCast(ConvexShape castShape, ref RigidTransform startingTransform, ref Vector3 sweep, Func <BroadPhaseEntry, bool> filter, out RayCastResult castResult)
        {
            var  castResults = PhysicsResources.GetRayCastResultList();
            bool didHit      = ConvexCast(castShape, ref startingTransform, ref sweep, filter, castResults);

            castResult = castResults.Elements[0];
            for (int i = 1; i < castResults.Count; i++)
            {
                RayCastResult candidate = castResults.Elements[i];
                if (candidate.HitData.T < castResult.HitData.T)
                {
                    castResult = candidate;
                }
            }
            PhysicsResources.GiveBack(castResults);
            return(didHit);
        }
예제 #3
0
 public bool SpecialCaseConvexTrace(ConvexShape shape, Location start, Location dir, double len, MaterialSolidity considerSolid, Func<BroadPhaseEntry, bool> filter, out RayCastResult rayHit)
 {
     RigidTransform rt = new RigidTransform(start.ToBVector(), BEPUutilities.Quaternion.Identity);
     BEPUutilities.Vector3 sweep = (dir * len).ToBVector();
     RayCastResult best = new RayCastResult(new RayHit() { T = len }, null);
     bool hA = false;
     if (considerSolid.HasFlag(MaterialSolidity.FULLSOLID))
     {
         RayCastResult rcr;
         if (PhysicsWorld.ConvexCast(shape, ref rt, ref sweep, filter, out rcr))
         {
             best = rcr;
             hA = true;
         }
     }
     sweep = dir.ToBVector();
     AABB box = new AABB();
     box.Min = start;
     box.Max = start;
     box.Include(start + dir * len);
     foreach (KeyValuePair<Vector3i, Chunk> chunk in LoadedChunks)
     {
         if (chunk.Value == null || chunk.Value.FCO == null)
         {
             continue;
         }
         if (!box.Intersects(new AABB() { Min = chunk.Value.WorldPosition.ToLocation() * Chunk.CHUNK_SIZE,
             Max = chunk.Value.WorldPosition.ToLocation() * Chunk.CHUNK_SIZE + new Location(Chunk.CHUNK_SIZE, Chunk.CHUNK_SIZE, Chunk.CHUNK_SIZE) }))
         {
             continue;
         }
         RayHit temp;
         if (chunk.Value.FCO.ConvexCast(shape, ref rt, ref sweep, len, considerSolid, out temp))
         {
             hA = true;
             if (temp.T < best.HitData.T)
             {
                 best.HitData = temp;
                 best.HitObject = chunk.Value.FCO;
             }
         }
     }
     rayHit = best;
     return hA;
 }
예제 #4
0
        /// <summary>
        /// Determines whether there is a wall nearby.
        /// </summary>
        /// <param name="position">Position to look from.</param>
        /// <param name="facingDirection">Direction to check in.</param>
        /// <param name="filter">Anonymous function to filter out unwanted objects.</param>
        /// <param name="space">The space to check for a wall in.</param>
        /// <param name="distance">The distance to check within.</param>
        /// <returns>True if a wall was detected, false otherwise.</returns>
        public static bool FindWall(Vector3 position, Vector3 facingDirection, Func<BroadPhaseEntry, bool> filter, Space space, float distance, out RayCastResult result)
        {
            Ray forwardRay = new Ray(position, new Vector3(facingDirection.X, 0, facingDirection.Z));
            result = new RayCastResult();
            space.RayCast(forwardRay, filter, out result);

            Vector3 flatNormal = new Vector3(result.HitData.Normal.X, 0, result.HitData.Normal.Z);
            float normalDot = Vector3.Dot(result.HitData.Normal, flatNormal);
            float minDot = (float)Math.Cos(MathHelper.PiOver4) * flatNormal.Length() * result.HitData.Normal.Length();
            if ((result.HitData.Location - forwardRay.Position).Length() < distance && normalDot > minDot)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
예제 #5
0
        /// <summary>
        /// Tests a ray against the space.
        /// </summary>
        /// <param name="ray">Ray to test.</param>
        /// <param name="maximumLength">Maximum length of the ray in units of the ray direction's length.</param>
        /// <param name="filter">Delegate to prune out hit candidates before performing a ray cast against them.</param>
        /// <param name="result">Hit data of the ray, if any.</param>
        /// <returns>Whether or not the ray hit anything.</returns>
        public bool RayCast(Ray ray, float maximumLength, Func <BroadPhaseEntry, bool> filter, out RayCastResult result)
        {
            var  resultsList = Resources.GetRayCastResultList();
            bool didHit      = RayCast(ray, maximumLength, filter, resultsList);

            result = resultsList.Elements[0];
            for (int i = 1; i < resultsList.count; i++)
            {
                RayCastResult candidate = resultsList.Elements[i];
                if (candidate.HitData.T < result.HitData.T)
                {
                    result = candidate;
                }
            }
            Resources.GiveBack(resultsList);

            return(didHit);
        }
예제 #6
0
        /// <summary>
        /// Tests a ray against the space.
        /// </summary>
        /// <param name="ray">Ray to test.</param>
        /// <param name="maximumLength">Maximum length of the ray in units of the ray direction's length.</param>
        /// <param name="result">Hit data of the ray, if any.</param>
        /// <returns>Whether or not the ray hit anything.</returns>
        public bool RayCast(Ray ray, float maximumLength, out RayCastResult result)
        {
            var  resultsList = PhysicsResources.GetRayCastResultList();
            bool didHit      = RayCast(ray, maximumLength, resultsList);

            result = resultsList.Elements[0];
            for (int i = 1; i < resultsList.Count; i++)
            {
                RayCastResult candidate = resultsList.Elements[i];
                if (candidate.HitData.T < result.HitData.T)
                {
                    result = candidate;
                }
            }
            PhysicsResources.GiveBack(resultsList);

            return(didHit);
        }
예제 #7
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <param name="normal"></param>
        /// <param name="pos"></param>
        /// <returns></returns>
        public bool RayCastAgainstAll( Vector3 from, Vector3 to, out Vector3 normal, out Vector3 pos, out Entity hitEntity, Entity skipEntity = null )
        {
            hitEntity	=	null;
            var dir		=	to - from;
            var dist	=	dir.Length();
            var ndir	=	dir.Normalized();
            Ray ray		=	new Ray( from, ndir );

            normal	= Vector3.Zero;
            pos		= to;

            Func<BroadPhaseEntry, bool> filterFunc = delegate(BroadPhaseEntry bpe)
            {
                if (skipEntity==null) return true;

                ConvexCollidable cc = bpe as ConvexCollidable;
                if (cc==null) return true;

                Entity ent = cc.Entity.Tag as Entity;
                if (ent==null) return true;

                if (ent==skipEntity) return false;

                return true;
            };

            var rcr		= new RayCastResult();
            var bRay	= MathConverter.Convert( ray );

            bool result = physSpace.RayCast( bRay, dist, filterFunc, out rcr );

            if (!result) {
                return false;
            }

            var convex	=	rcr.HitObject as ConvexCollidable;
            normal		=	MathConverter.Convert( rcr.HitData.Normal ).Normalized();
            pos			=	MathConverter.Convert( rcr.HitData.Location );
            hitEntity	=	(convex == null) ? null : convex.Entity.Tag as Entity;

            return true;
        }
예제 #8
0
        protected override void UsePartUpdate(GameTime time)
        {
            bool onGround = mCreature.CharacterController.SupportFinder.HasTraction;

            if (!onGround && State == AIState.FollowCreature && WithinStompRange(mTargetCreature))
            {
                Vector3 downVector = mTargetCreature.Position - mCreature.Position;
                Ray downRay = new Ray(mCreature.Position, downVector);
                Func<BroadPhaseEntry, bool> filter = (bfe) => (!(bfe.Tag is Sensor) && bfe.Tag != mCreature);
                RayCastResult result = new RayCastResult();
                mCreature.World.Space.RayCast(downRay, filter, out result);
                if (result.HitObject.Tag is CharacterSynchronizer)
                {
                    if ((result.HitObject.Tag as CharacterSynchronizer).body.Tag == mTargetCreature)
                    {
                        int part = ChoosePartSlot();
                        mCreature.UsePart(part, downVector);
                        mCreature.FinishUsePart(ChoosePartSlot(), downVector);
                        return;
                    }
                }
                else if (result.HitObject.Tag == mTargetCreature)
                {
                    int part = ChoosePartSlot();
                    mCreature.UsePart(part, downVector);
                    mCreature.FinishUsePart(part, downVector);
                    return;
                }
                ////Console.WriteLine("Ray fail");
            }
            else if (mUsingPart && mTargetCreature == null)
            {
                mCreature.FinishUsePart(ChoosePartSlot(), mCreature.Forward);
                mUsingPart = false;
            }
            else if (mUsingPart && onGround)
            {
                Vector3 targetDirection;
                if (State == AIState.FollowCreature)
                {
                    targetDirection = mTargetCreature.Position - mCreature.Position;
                }
                else if (State == AIState.FleeCreature)
                {
                    targetDirection = mCreature.Position - mTargetCreature.Position;
                }
                else
                {
                    return;
                }

                int part = ChoosePartSlot();
                KangarooLegs kLegs = (mCreature.PartAttachments[part].Part as KangarooLegs);
                if (mJumpTimer < kLegs.FullJumpTime)
                {
                    mJumpTimer += time.ElapsedGameTime.TotalSeconds;
                    if (mJumpTimer / kLegs.FullJumpTime > targetDirection.Length() / mCreature.Sensor.Radius)
                    {
                        mCreature.FinishUsePart(part, targetDirection);
                        mUsingPart = false;
                        mJumpTimer = double.MaxValue;
                    }
                }
                else
                {
                    mCreature.UsePart(ChoosePartSlot(), targetDirection);
                    mJumpTimer = 0.0f;
                }
            }
        }
예제 #9
0
 /// <summary>
 /// Tests a ray against the space.
 /// </summary>
 /// <param name="ray">Ray to test.</param>
 /// <param name="filter">Delegate to prune out hit candidates before performing a ray cast against them.</param>
 /// <param name="result">Hit data of the ray, if any.</param>
 /// <returns>Whether or not the ray hit anything.</returns>
 public bool RayCast(Ray ray, Func <BroadPhaseEntry, bool> filter, out RayCastResult result)
 {
     return(RayCast(ray, float.MaxValue, filter, out result));
 }
예제 #10
0
 /// <summary>
 /// Tests a ray against the space.
 /// </summary>
 /// <param name="ray">Ray to test.</param>
 /// <param name="result">Hit data of the ray, if any.</param>
 /// <returns>Whether or not the ray hit anything.</returns>
 public bool RayCast(Ray ray, out RayCastResult result)
 {
     return(RayCast(ray, float.MaxValue, out result));
 }
예제 #11
0
 public bool RayCast(BEPUutilities.Ray ray, out RayCastResult result)
 {
     return space.RayCast(ray, out result);
 }
예제 #12
0
파일: Space.cs 프로젝트: d3x0r/Voxelarium
 /// <summary>
 /// <para>Casts a convex shape against the space.</para>
 /// <para>Convex casts are sensitive to length; avoid extremely long convex casts for better stability and performance.</para>
 /// </summary>
 /// <param name="castShape">Shape to cast.</param>
 /// <param name="startingTransform">Initial transform of the shape.</param>
 /// <param name="sweep">Sweep to apply to the shape. Avoid extremely long convex casts for better stability and performance.</param>
 /// <param name="filter">Delegate to prune out hit candidates before performing a cast against them. Return true from the filter to process an entry or false to ignore the entry.</param>
 /// <param name="castResult">Hit data, if any.</param>
 /// <returns>Whether or not the cast hit anything.</returns>
 public bool ConvexCast(ConvexShape castShape, ref RigidTransform startingTransform, ref Vector3 sweep, Func<BroadPhaseEntry, bool> filter, out RayCastResult castResult)
 {
     var castResults = PhysicsResources.GetRayCastResultList();
     bool didHit = ConvexCast(castShape, ref startingTransform, ref sweep, filter, castResults);
     castResult = castResults.Elements[0];
     for (int i = 1; i < castResults.Count; i++)
     {
         RayCastResult candidate = castResults.Elements[i];
         if (candidate.HitData.T < castResult.HitData.T)
             castResult = candidate;
     }
     PhysicsResources.GiveBack(castResults);
     return didHit;
 }
예제 #13
0
파일: Space.cs 프로젝트: d3x0r/Voxelarium
        /// <summary>
        /// Tests a ray against the space.
        /// </summary>
        /// <param name="ray">Ray to test.</param>
        /// <param name="maximumLength">Maximum length of the ray in units of the ray direction's length.</param>
        /// <param name="filter">Delegate to prune out hit candidates before performing a ray cast against them. Return true from the filter to process an entry or false to ignore the entry.</param>
        /// <param name="result">Hit data of the ray, if any.</param>
        /// <returns>Whether or not the ray hit anything.</returns>
        public bool RayCast(Ray ray, float maximumLength, Func<BroadPhaseEntry, bool> filter, out RayCastResult result)
        {
            var resultsList = PhysicsResources.GetRayCastResultList();
            bool didHit = RayCast(ray, maximumLength, filter, resultsList);
            result = resultsList.Elements[0];
            for (int i = 1; i < resultsList.Count; i++)
            {
                RayCastResult candidate = resultsList.Elements[i];
                if (candidate.HitData.T < result.HitData.T)
                    result = candidate;
            }
            PhysicsResources.GiveBack(resultsList);

            return didHit;
        }
예제 #14
0
파일: Space.cs 프로젝트: d3x0r/Voxelarium
 /// <summary>
 /// Tests a ray against the space.
 /// </summary>
 /// <param name="ray">Ray to test.</param>
 /// <param name="filter">Delegate to prune out hit candidates before performing a ray cast against them. Return true from the filter to process an entry or false to ignore the entry.</param>
 /// <param name="result">Hit data of the ray, if any.</param>
 /// <returns>Whether or not the ray hit anything.</returns>
 public bool RayCast(Ray ray, Func<BroadPhaseEntry, bool> filter, out RayCastResult result)
 {
     return RayCast(ray, float.MaxValue, filter, out result);
 }
예제 #15
0
파일: Space.cs 프로젝트: d3x0r/Voxelarium
 /// <summary>
 /// Tests a ray against the space.
 /// </summary>
 /// <param name="ray">Ray to test.</param>
 /// <param name="result">Hit data of the ray, if any.</param>
 /// <returns>Whether or not the ray hit anything.</returns>
 public bool RayCast(Ray ray, out RayCastResult result)
 {
     return RayCast(ray, float.MaxValue, out result);
 }
예제 #16
0
파일: Region.cs 프로젝트: Morphan1/Voxalia
 public bool SpecialCaseRayTrace(Location start, Location dir, float len, MaterialSolidity considerSolid, Func<BroadPhaseEntry, bool> filter, out RayCastResult rayHit)
 {
     Ray ray = new Ray(start.ToBVector(), dir.ToBVector());
     RayCastResult best = new RayCastResult(new RayHit() { T = len }, null);
     bool hA = false;
     if (considerSolid.HasFlag(MaterialSolidity.FULLSOLID))
     {
         RayCastResult rcr;
         if (PhysicsWorld.RayCast(ray, len, filter, out rcr))
         {
             best = rcr;
             hA = true;
         }
     }
     AABB box = new AABB();
     box.Min = start;
     box.Max = start;
     box.Include(start + dir * len);
     foreach (KeyValuePair<Vector3i, Chunk> chunk in LoadedChunks)
     {
         if (chunk.Value == null || chunk.Value.FCO == null)
         {
             continue;
         }
         if (!box.Intersects(new AABB() { Min = chunk.Value.WorldPosition.ToLocation() * Chunk.CHUNK_SIZE, Max = chunk.Value.WorldPosition.ToLocation() * Chunk.CHUNK_SIZE + new Location(Chunk.CHUNK_SIZE) }))
         {
             continue;
         }
         RayHit temp;
         if (chunk.Value.FCO.RayCast(ray, len, null, considerSolid, out temp))
         {
             hA = true;
             //temp.T *= len;
             if (temp.T < best.HitData.T)
             {
                 best.HitData = temp;
                 best.HitObject = chunk.Value.FCO;
             }
         }
     }
     rayHit = best;
     return hA;
 }
예제 #17
0
        /// <summary>
        /// Tests a ray against the space.
        /// </summary>
        /// <param name="ray">Ray to test.</param>
        /// <param name="maximumLength">Maximum length of the ray in units of the ray direction's length.</param>
        /// <param name="result">Hit data of the ray, if any.</param>
        /// <returns>Whether or not the ray hit anything.</returns>
        public bool RayCast(Ray ray, float maximumLength, out RayCastResult result)
        {
            var resultsList = Resources.GetRayCastResultList();
            bool didHit = RayCast(ray, maximumLength, resultsList);
            result = resultsList.Elements[0];
            for (int i = 1; i < resultsList.count; i++)
            {
                RayCastResult candidate = resultsList.Elements[i];
                if (candidate.HitData.T < result.HitData.T)
                    result = candidate;
            }
            Resources.GiveBack(resultsList);

            return didHit;
        }
예제 #18
0
        /// <summary>
        /// Find the position and object in a ray.
        /// </summary>
        /// <param name="ray">The ray.</param>
        /// <param name="maximumDistance">The maximum distance to look from the ray origin.</param>
        /// <param name="castResult">Tuple containing the rayHit result and the DummyObject if any (can be null).</param>
        /// <returns>Whether the ray hit anything.</returns>
        public bool RayCast(Ray ray, float maximumDistance, out Tuple<RayHit, DummyObject> castResult)
        {
            // Fill out default failed hit data
            castResult = new Tuple<RayHit, DummyObject>(new RayHit(), null);

            DummyObject selectedObject = GetDummyObjectFromID(GraphicsManager.GetPickingObject(ray));
            RayHit rayHit = new RayHit();

            if (selectedObject == null || !selectedObject.RayCast(ray, maximumDistance, out rayHit))
            {
                RayCastResult rayResult = new RayCastResult();
                if (!Space.RayCast(ray, maximumDistance, out rayResult))
                {
                    return false;
                }
                rayHit = rayResult.HitData;
            }

            castResult = new Tuple<RayHit, DummyObject>(rayHit, selectedObject);
            return true;
        }