/// <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; } }
/// <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); }
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; }
/// <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; } }
/// <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); }
/// <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); }
/// <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; }
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; } } }
/// <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)); }
/// <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)); }
public bool RayCast(BEPUutilities.Ray ray, out RayCastResult result) { return space.RayCast(ray, out result); }
/// <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; }
/// <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; }
/// <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); }
/// <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); }
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; }
/// <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; }
/// <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; }