/// <summary> /// Performs a 2d physical raycast in world coordinates. /// </summary> /// <param name="start">The starting point in world coordinates.</param> /// <param name="end">The desired end point in world coordinates.</param> /// <param name="callback"> /// The callback that is invoked for each hit on the raycast. Note that the order in which each hit occurs isn't deterministic /// and may appear random. Return -1 to ignore the curret shape, 0 to terminate the raycast, data.Fraction to clip the ray for current hit, or 1 to continue. /// </param> /// <param name="firstHit">Returns the first hit that occurs, i.e. the one with the highest proximity to the starting point.</param> /// <returns>Returns whether anything has been hit.</returns> public bool RayCast(Vector2 start, Vector2 end, RayCastCallback callback, out RayCastData firstHit) { if (callback == null) { callback = RayCast_DefaultCallback; } Vector2 fsWorldCoordA = PhysicsUnit.LengthToPhysical * start; Vector2 fsWorldCoordB = PhysicsUnit.LengthToPhysical * end; float firstHitFraction = float.MaxValue; RayCastData firstHitLocal = default(RayCastData); this.native.RayCast(delegate(Fixture fixture, Vector2 pos, Vector2 normal, float fraction) { RayCastData data = new RayCastData( fixture.UserData as ShapeInfo, PhysicsUnit.LengthToDuality * pos, normal, fraction); float result = callback(data); if (result >= 0.0f && data.Fraction < firstHitFraction) { firstHitLocal = data; firstHitFraction = data.Fraction; } return(result); }, fsWorldCoordA, fsWorldCoordB); firstHit = firstHitLocal; return(firstHitFraction != float.MaxValue); }
/// <summary> /// Performs a 2d physical raycast in world coordinates. /// </summary> /// <param name="start">The starting point in world coordinates.</param> /// <param name="end">The desired end point in world coordinates.</param> /// <param name="callback"> /// The callback that is invoked for each hit on the raycast. Note that the order in which each hit occurs isn't deterministic /// and may appear random. Return -1 to ignore the curret shape, 0 to terminate the raycast, data.Fraction to clip the ray for current hit, or 1 to continue. /// </param> /// <param name="hits"> /// A list that will be filled with all hits that were registered, ordered by their Fraction value. /// The list will not be cleared before adding items. /// </param> /// <returns>Returns whether any new hit was registered.</returns> public bool RayCast(Vector2 start, Vector2 end, RayCastCallback callback, RawList <RayCastData> hits) { if (callback == null) { callback = RayCast_DefaultCallback; } Vector2 fsWorldCoordA = PhysicsUnit.LengthToPhysical * start; Vector2 fsWorldCoordB = PhysicsUnit.LengthToPhysical * end; int oldResultCount = hits.Count; this.native.RayCast(delegate(Fixture fixture, Vector2 pos, Vector2 normal, float fraction) { int index = hits.Count++; RayCastData[] data = hits.Data; data[index] = new RayCastData( fixture.UserData as ShapeInfo, PhysicsUnit.LengthToDuality * pos, normal, fraction); float result = callback(data[index]); if (result < 0.0f) { hits.Count--; } return(result); }, fsWorldCoordA, fsWorldCoordB); hits.Data.StableSort( 0, hits.Count, (d1, d2) => (int)(1000000.0f * (d1.Fraction - d2.Fraction))); return(hits.Count > oldResultCount); }
private static float Raycast_DefaultCallback(RayCastData data) { return 1.0f; }
/// <summary> /// Performs a 2d physical raycast in world coordinates. /// </summary> /// <param name="start">The starting point in world coordinates.</param> /// <param name="end">The desired end point in world coordinates.</param> /// <param name="callback"> /// The callback that is invoked for each hit on the raycast. Note that the order in which each hit occurs isn't deterministic /// and may appear random. Return -1 to ignore the curret shape, 0 to terminate the raycast, data.Fraction to clip the ray for current hit, or 1 to continue. /// </param> /// <param name="firstHit">Returns the first hit that occurs, i.e. the one with the highest proximity to the starting point.</param> /// <returns>Returns whether anything has been hit.</returns> public static bool RayCast(Vector2 start, Vector2 end, RayCastCallback callback, out RayCastData firstHit) { if (callback == null) callback = Raycast_DefaultCallback; Vector2 fsWorldCoordA = PhysicsUnit.LengthToPhysical * start; Vector2 fsWorldCoordB = PhysicsUnit.LengthToPhysical * end; float firstHitFraction = float.MaxValue; RayCastData firstHitLocal = default(RayCastData); Scene.PhysicsWorld.RayCast(delegate(Fixture fixture, Vector2 pos, Vector2 normal, float fraction) { RayCastData data = new RayCastData( fixture.UserData as ShapeInfo, PhysicsUnit.LengthToDuality * pos, normal, fraction); float result = callback(data); if (result >= 0.0f && data.Fraction < firstHitFraction) { firstHitLocal = data; firstHitFraction = data.Fraction; } return result; }, fsWorldCoordA, fsWorldCoordB); firstHit = firstHitLocal; return firstHitFraction != float.MaxValue; }
/// <summary> /// Performs a 2d physical raycast in world coordinates. /// </summary> /// <param name="start">The starting point in world coordinates.</param> /// <param name="end">The desired end point in world coordinates.</param> /// <param name="callback"> /// The callback that is invoked for each hit on the raycast. Note that the order in which each hit occurs isn't deterministic /// and may appear random. Return -1 to ignore the curret shape, 0 to terminate the raycast, data.Fraction to clip the ray for current hit, or 1 to continue. /// </param> /// <param name="hits">Returns a list of all occurred hits, ordered by their Fraction value.</param> public static void RayCast(Vector2 start, Vector2 end, RayCastCallback callback, out RawList<RayCastData> hits) { if (callback == null) callback = Raycast_DefaultCallback; Vector2 fsWorldCoordA = PhysicsUnit.LengthToPhysical * start; Vector2 fsWorldCoordB = PhysicsUnit.LengthToPhysical * end; RawList<RayCastData> localHits = new RawList<RayCastData>(); Scene.PhysicsWorld.RayCast(delegate(Fixture fixture, Vector2 pos, Vector2 normal, float fraction) { int oldCount = localHits.Count++; RayCastData[] data = localHits.Data; data[oldCount] = new RayCastData( fixture.UserData as ShapeInfo, PhysicsUnit.LengthToDuality * pos, normal, fraction); float result = callback(data[oldCount]); if (result < 0.0f) localHits.Count--; return result; }, fsWorldCoordA, fsWorldCoordB); localHits.Data.StableSort(0, localHits.Count, (d1, d2) => (int)(1000000.0f * (d1.Fraction - d2.Fraction))); hits = localHits; }
/// <summary> /// Performs a 2d physical raycast in world coordinates. /// </summary> /// <param name="worldCoordA">The starting point.</param> /// <param name="worldCoordB">The desired end point.</param> /// <param name="callback"> /// The callback that is invoked for each hit on the raycast. Note that the order in which each hit occurs isn't deterministic /// and may appear random. Return -1 to ignore the curret shape, 0 to terminate the raycast, data.Fraction to clip the ray for current hit, or 1 to continue. /// </param> /// <returns>Returns a list of all occurred hits, ordered by their Fraction value.</returns> public static List<RayCastData> RayCast(Vector2 worldCoordA, Vector2 worldCoordB, RayCastCallback callback = null) { if (callback == null) callback = Raycast_DefaultCallback; Vector2 fsWorldCoordA = PhysicsConvert.ToPhysicalUnit(worldCoordA); Vector2 fsWorldCoordB = PhysicsConvert.ToPhysicalUnit(worldCoordB); List<RayCastData> hitData = new List<RayCastData>(); Scene.PhysicsWorld.RayCast(delegate(Fixture fixture, Vector2 pos, Vector2 normal, float fraction) { RayCastData data = new RayCastData( fixture.UserData as ShapeInfo, PhysicsConvert.ToDualityUnit(pos), normal, fraction); float result = callback(data); if (result >= 0.0f) hitData.Add(data); return result; }, fsWorldCoordA, fsWorldCoordB); hitData.StableSort((d1, d2) => (int)(1000000.0f * (d1.Fraction - d2.Fraction))); return hitData; }
private static float RayCast_DefaultCallback(RayCastData data) { return(1.0f); }