public void Initialize(LSAgent agent) { Agent = agent; Body = agent.Body; LocatedNode = GridManager.GetNode (Body.Position.x, Body.Position.y); LocatedNode.Add (this); }
public override void Initialize(LSAgent agent) { Body = agent.Body; timescaledTurnRate = TurnRate * LockstepManager.Timestep >> FixedMath.SHIFT_AMOUNT; TargetReached = true; TargetRotation = Vector2d.up; }
public static int Assimilate(LSBody body) { if (CachedIDs.Count > 0) { id = CachedIDs.Pop (); } else { id = PeakCount; PeakCount++; } SimObjectExists [id] = true; SimObjects [id] = body; for (i = 0; i < id; i++) { other = SimObjects [i]; if (RequireCollisionPair (body, other)) { CreatePair (other, body, i * MaxSimObjects + id); } } for (j = id + 1; j < PeakCount; j++) { other = SimObjects [j]; if (RequireCollisionPair (body, other)) { CreatePair (body, other, id * MaxSimObjects + j); } } AssimilatedCount++; return id; }
public static bool CheckBox_Poly(LSBody box, LSBody poly) { bool Right = poly.Position.x > box.Position.x; bool Top = poly.Position.y > box.Position.y; bool xPassed = false; bool yPassed = false; int vertCount = poly.RealPoints.Length; for (int i = 0; i < vertCount; i++) { if (!xPassed) { if (Right) { if (poly.RealPoints [i].x <= box.XMax) xPassed = true; } else { if (poly.RealPoints [i].x >= box.XMin) xPassed = true; } } if (!yPassed) { if (Top) { if (poly.RealPoints [i].y <= box.YMax) yPassed = true; } else { if (poly.RealPoints [i].y >= box.YMin) yPassed = true; } } if (xPassed && yPassed) return true; } return false; }
public override void Initialize(LSAgent agent) { MyMovementGroupID = -1; Body = agent.Body; Body.Mover = this; Body.OnContact += HandleCollision; timescaledSpeed = ((Speed * LockstepManager.Timestep) >> FixedMath.SHIFT_AMOUNT); closingDistance = agent.Body.Radius; }
public static bool CheckBox_Poly(LSBody box, LSBody poly) { bool Right = poly._position.x > box._position.x; bool Top = poly._position.y > box._position.y; bool xPassed = false; bool yPassed = false; int vertCount = poly.RealPoints.Length; for (int i = 0; i < vertCount; i++) { if (!xPassed) { if (Right) { if (poly.RealPoints [i].x <= box.XMax) { xPassed = true; } } else { if (poly.RealPoints [i].x >= box.XMin) { xPassed = true; } } } if (!yPassed) { if (Top) { if (poly.RealPoints [i].y <= box.YMax) { yPassed = true; } } else { if (poly.RealPoints [i].y >= box.YMin) { yPassed = true; } } } if (xPassed && yPassed) { return(true); } } return(false); }
public static void Assimilate(LSBody body) { if (CachedIDs.Count > 0) { id = CachedIDs.Pop (); } else { id = PeakCount; PeakCount++; } SimObjectExists [id] = true; SimObjects [id] = body; body.ID = id; for (i = 0; i < id; i++) { other = SimObjects [i]; if (!Physics2D.GetIgnoreLayerCollision (other.cachedGameObject.layer, body.cachedGameObject.layer)) { colPairIndex = i * MaxSimObjects + id; pair = CollisionPairs[colPairIndex]; if (pair == null) { pair = new CollisionPair (); CollisionPairs [colPairIndex] = pair; } FastCollisionPairs.Add (pair); pair.Initialize (other, body); CollisionPairCount++; } } for (j = id + 1; j < PeakCount; j++) { other = SimObjects [j]; if (!Physics2D.GetIgnoreLayerCollision (other.cachedGameObject.layer, body.cachedGameObject.layer)) { colPairIndex = id * MaxSimObjects + j; pair = CollisionPairs[colPairIndex]; if (pair == null) { pair = new CollisionPair (); CollisionPairs [colPairIndex] = pair; } FastCollisionPairs.Add (pair); pair.Initialize (body, other); CollisionPairCount++; } } AssimilatedCount++; }
void OnDrawGizmos() { if (!Application.isPlaying) { return; } Gizmos.color = Color.white; Vector3[] PolyLine; LSBody body = this; Vector3 TargetPosition = ((MonoBehaviour)body).transform.position; //TargetPosition.y += .55f; switch (body.Shape) { case ColliderType.Circle: LSEditorUtility.GizmoCircle(TargetPosition, FixedMath.ToFloat(body.Radius)); break; case ColliderType.AABox: PolyLine = new Vector3[] { TargetPosition, TargetPosition, TargetPosition, TargetPosition }; float halfWidth = FixedMath.ToFloat(body.HalfWidth); float halfHeight = FixedMath.ToFloat(body.HalfHeight); PolyLine [0].x += halfWidth; PolyLine [0].z += halfHeight; PolyLine [1].x += halfWidth; PolyLine [1].z -= halfHeight; PolyLine [2].x -= halfWidth; PolyLine [2].z -= halfHeight; PolyLine [3].x -= halfWidth; PolyLine [3].z += halfHeight; LSEditorUtility.GizmoPolyLine(PolyLine); break; case ColliderType.Polygon: int VertLength = body.Vertices.Length; PolyLine = new Vector3[VertLength]; for (int i = 0; i < VertLength; i++) { PolyLine[i] = body.RealPoints[i].ToVector3(TargetPosition.y); } LSEditorUtility.GizmoPolyLine(PolyLine); break; } }
public void Initialize(Vector2d StartPosition, Vector2d StartRotation) { Parent = null; PositionChanged = true; RotationChanged = true; VelocityChanged = true; PositionChangedBuffer = false; RotationChangedBuffer = false; Priority = _priority; Velocity = Vector2d.zero; VelocityFastMagnitude = 0; Position = StartPosition; Rotation = StartRotation; _parent = null; LocalPosition = Vector2d.zero; LocalRotation = Vector2d.up; XMin = 0; XMax = 0; YMin = 0; YMax = 0; PastGridXMin = long.MaxValue; PastGridXMax = long.MaxValue; PastGridYMin = long.MaxValue; PastGridYMax = long.MaxValue; if (Shape != ColliderType.None) { BuildPoints(); BuildBounds(); } ID = PhysicsManager.Assimilate(this); Partition.PartitionObject(this); visualPosition = Position.ToVector3(0f); lastVisualPos = visualPosition; _positionalTransform.position = visualPosition; visualRot = Quaternion.LookRotation(Rotation.ToVector3(0f)); lastVisualRot = visualRot; _positionalTransform.rotation = visualRot; }
private static CollisionPair CreatePair(LSBody body1, LSBody body2) { CollisionPair pair; if (CachedCollisionPairs.Count > 0) { pair = CachedCollisionPairs.Pop(); } else { pair = new CollisionPair(); } pair.Initialize(body1, body2); return(pair); }
void Reset() { LSBody body = this.GetComponent <LSBody> (); if (body.Shape == ColliderType.Polygon) { this._points = new Vector2d[body.Vertices.Length]; for (int i = 0; i < _points.Length; i++) { Vector2d point = body.Vertices[i]; point.RotateInverse(0, FixedMath.One); _points[i] = point; } } }
public static bool CheckCircle_Box(LSBody box, LSBody circle) { Collided = false; xMore = circle.Position.x > box.Position.x; yMore = circle.Position.y > box.Position.y; if (!Collided) { Collided = false; if (xMore) { if (circle.Position.x <= box.XMax) { Collided = true; } } else { if (circle.Position.x >= box.XMin) { Collided = true; } } if (yMore) { if (circle.Position.y <= box.YMax) { Collided = true; } } else { if (circle.Position.y >= box.YMin) { Collided = true; } } if (!Collided) { if (xMore) { xDist = (circle.Position.x) - (box.XMax); } else { xDist = (circle.Position.x) - (box.XMin); } if (yMore) { yDist = (circle.Position.y) - (box.YMax); } else { yDist = (circle.Position.y) - (box.YMin); } if ((xDist * xDist + yDist * yDist) <= circle.Radius * circle.Radius) { Collided = true; } } } return Collided; }
protected override void OnSetup() { cachedBody = Agent.Body; cachedBody.OnContact += HandleCollision; cachedTurn = Agent.Turner; collisionStopTreshold = FixedMath.Mul(timescaledSpeed, CollisionStopTreshold); collisionStopTreshold *= collisionStopTreshold; timescaledAcceleration = Acceleration * 32 / LockstepManager.FrameRate; if (timescaledAcceleration > FixedMath.One) { timescaledAcceleration = FixedMath.One; } closingDistance = cachedBody.Radius; stuckTolerance = ((Agent.Body.Radius * Speed) >> FixedMath.SHIFT_AMOUNT) / LockstepManager.FrameRate; stuckTolerance *= stuckTolerance; }
public void DistributeCircle_Box(LSBody box, LSBody circle) { xMore = circle._position.x > box._position.x; yMore = circle._position.y > box._position.y; if (xMore) { PenetrationX = (circle.XMin - box.XMax); } else { PenetrationX = (circle.XMax - box.XMin); } if (yMore) { PenetrationY = (circle.YMin - box.YMax); } else { PenetrationY = (circle.YMax - box.YMin); } xAbs = PenetrationX < 0 ? -PenetrationX : PenetrationX; yAbs = PenetrationY < 0 ? -PenetrationY : PenetrationY; if (xAbs <= circle.Radius && yAbs <= circle.Radius) { } else { if (xAbs > yAbs) { PenetrationX = 0;//FixedMath.Mul (PenetrationX, FixedMath.One * 1 / 4); } else { PenetrationY = 0;//FixedMath.Mul (PenetrationX, FixedMath.One * 1 / 4); } } //Resolving circle._position.x -= PenetrationX; //(PenetrationX * Multiplier) >> FixedMath.SHIFT_AMOUNT; circle._position.y -= PenetrationY; //(PenetrationY * Multiplier) >> FixedMath.SHIFT_AMOUNT; circle.PositionChanged = true; circle.BuildBounds(); }
internal static int Assimilate(LSBody body) { if (CachedIDs.Count > 0) { id = CachedIDs.Pop(); } else { id = PeakCount; PeakCount++; } SimObjectExists [id] = true; SimObjects [id] = body; AssimilatedCount++; return(id); }
public static void Visualize () { LerpTime = Time.fixedDeltaTime; if (ResetAccumulation) { AccumulatedTime = 0; } AccumulatedTime += Time.deltaTime; ExpectedAccumulation = AccumulatedTime / LerpTime; for (int i = 0; i < DynamicSimObjects.PeakCount; i++) { LSBody b1 = DynamicSimObjects.innerArray[i]; if (b1.IsNotNull()) { b1.SetVisuals(); } } ResetAccumulation = false; }
public static void PartitionObject(LSBody Body) { GridXMin = ((Body.XMin - OffsetX) >> ShiftSize); GridXMax = ((Body.XMax - OffsetX) >> ShiftSize); GridYMin = ((Body.YMin - OffsetY) >> ShiftSize); GridYMax = ((Body.YMax - OffsetY) >> ShiftSize); Body.PastGridXMin = GridXMin; Body.PastGridXMax = GridXMax; Body.PastGridYMin = GridYMin; Body.PastGridYMax = GridYMax; for (long i = GridXMin; i <= GridXMax; i++) { for (long j = GridYMin; j <= GridYMax; j++) { PartitionNode node = Nodes [i * Count + j]; node.Add (Body.ID); } } }
private void HandleCollision(LSBody other) { if (!CanMove) { return; } if ((tempAgent = other.Agent) == null) { return; } Move otherMover = tempAgent.GetAbility <Move>(); if (ReferenceEquals(otherMover, null) == false) { if (IsMoving && (GetFullCanAutoStop())) { if (otherMover.MyMovementGroupID == MyMovementGroupID || otherMover.targetPos == this.targetPos) { if (otherMover.IsMoving == false && otherMover.Arrived && otherMover.StoppedTime > MinimumOtherStopTime) { if (otherMover.CanCollisionStop == false) { PauseAutoStop(); } else { Arrive(); } } else if (hasPath && otherMover.hasPath && otherMover.pathIndex > 0 && otherMover.lastTargetPos.SqrDistance(targetPos.x, targetPos.y) < FixedMath.One ) { if (this.distance < this.closingDistance) { this.pathIndex++; } } } else { } } } }
public static bool CheckCircle_Poly(LSBody circle, LSBody poly) { int EdgeCount = poly.EdgeNorms.Length; ClosestDist = long.MaxValue; for (int i = 0; i < EdgeCount; i++) { Vector2d axis = poly.EdgeNorms [i]; long CircleProjection = circle._position.Dot(axis.x, axis.y); long CircleMin = CircleProjection - circle.Radius; long CircleMax = CircleProjection + circle.Radius; long PolyMin; long PolyMax; ProjectPolygon(axis.x, axis.y, poly, out PolyMin, out PolyMax); //TODO: Cache PolyMin and PolyMax? if (CheckOverlap(CircleMin, CircleMax, PolyMin, PolyMax)) { long dist1 = PolyMax - CircleMin; long dist2 = CircleMax - PolyMin; long localCloseDist = 0; if (dist1 <= dist2) { localCloseDist = dist1; } else { localCloseDist = -dist2; } if (localCloseDist.Abs() < ClosestDist.Abs()) { ClosestDist = localCloseDist; ClosestAxis = axis; ClosestAxisProjection = CircleProjection; } } else { return(false); } } return(true); }
public static void PartitionObject(LSBody Body) { GridXMin = Body.XMin <= Body.FutureXMin ? ((Body.XMin - OffsetX) >> ShiftSize) : ((Body.FutureXMin - OffsetX) >> ShiftSize); GridXMax = Body.XMax >= Body.FutureXMax ? ((Body.XMax - OffsetX) >> ShiftSize) : ((Body.FutureXMax - OffsetX) >> ShiftSize); GridYMin = Body.YMin <= Body.FutureXMin ? ((Body.YMin - OffsetY) >> ShiftSize) : ((Body.FutureYMin - OffsetY) >> ShiftSize); GridYMax = Body.YMax >= Body.FutureYMax ? ((Body.YMax - OffsetY) >> ShiftSize) : ((Body.FutureYMax - OffsetY) >> ShiftSize); #if UNITY_EDITOR if (GridXMin < 0 || GridXMax >= Count || GridYMin < 0 || GridYMax >= Count) { Debug.LogError("Body with ID " + Body.ID.ToString() + " is out of partition bounds."); return; } #endif if (Body.PastGridXMin != GridXMin || Body.PastGridXMax != GridXMax || Body.PastGridYMin != GridYMin || Body.PastGridYMax != GridYMax) { for (o = Body.PastGridXMin; o <= Body.PastGridXMax; o++) { for (p = Body.PastGridYMin; p <= Body.PastGridYMax; p++) { node = Nodes [o * Count + p]; node.Remove(Body.ID); } } for (i = GridXMin; i <= GridXMax; i++) { for (j = GridYMin; j <= GridYMax; j++) { node = Nodes [i * Count + j]; node.Add(Body.ID); } } Body.PastGridXMin = GridXMin; Body.PastGridXMax = GridXMax; Body.PastGridYMin = GridYMin; Body.PastGridYMax = GridYMax; } }
public static void PartitionObject(LSBody Body) { GetGridBounds(Body); Body.PastGridXMin = GridXMin; Body.PastGridXMax = GridXMax; Body.PastGridYMin = GridYMin; Body.PastGridYMax = GridYMax; for (int i = GridXMin; i <= GridXMax; i++) { for (int j = GridYMin; j <= GridYMax; j++) { PartitionNode node = GetNode(i, j); node.Add(Body.ID); } } }
internal static void Dessimilate(LSBody body) { int tid = body.ID; if (!SimObjects[tid].IsNotNull()) { Debug.LogWarning("Object with ID" + body.ID.ToString() + "cannot be dessimilated because it it not assimilated"); return; } SimObjects[tid] = null; CachedIDs.Add(tid); if (body.DynamicID >= 0) { DynamicSimObjects.RemoveAt(body.DynamicID); body.DynamicID = -1; } }
public static void PartitionObject(LSBody Body) { GridXMin = ((Body.XMin - OffsetX) >> ShiftSize); GridXMax = ((Body.XMax - OffsetX) >> ShiftSize); GridYMin = ((Body.YMin - OffsetY) >> ShiftSize); GridYMax = ((Body.YMax - OffsetY) >> ShiftSize); Body.PastGridXMin = GridXMin; Body.PastGridXMax = GridXMax; Body.PastGridYMin = GridYMin; Body.PastGridYMax = GridYMax; for (long i = GridXMin; i <= GridXMax; i++) { for (long j = GridYMin; j <= GridYMax; j++) { PartitionNode node = Nodes [i * Count + j]; node.Add(Body.ID); } } }
private void HandleCollision(LSBody other) { if (!CanMove) { return; } if ((tempAgent = other.Agent) == null) { return; } if (tempAgent == collidingAgent) { collidedWithTrackedAgent = true; } else if (collidingAgent == null) { collidingAgent = tempAgent; collidedWithTrackedAgent = true; } Move otherMover = tempAgent.Mover; if (ReferenceEquals(otherMover, null) == false) { if (IsMoving && CanCollisionStop) { if (otherMover.MyMovementGroupID == MyMovementGroupID) { if (otherMover.IsMoving == false && otherMover.Arrived && otherMover.stopTime > MinimumOtherStopTime) { Arrive(); } else if (hasPath && otherMover.hasPath && otherMover.pathIndex > 0 && otherMover.lastTargetPos.SqrDistance(targetPos.x, targetPos.y) < FixedMath.One) { if (movementDirection.Dot(targetDirection.x, targetDirection.y) < 0) { pathIndex++; } } } } } }
protected override void OnInitialize() { if (!EventsAttached) { _cachedBody = GetComponent <LSBody> (); if (_doContactEnter) { CachedBody.OnContactEnter += HandleOnContactEnter; } if (_doContact) { CachedBody.OnContact += HandleOnContact; } if (_doContactExit) { CachedBody.OnContactExit += HandleOnContactExit; } EventsAttached = true; } }
public static void Simulate() { for (i = 0; i < PeakCount; i++) { if (SimObjectExists [i]) { b1 = SimObjects [i]; b1.EarlySimulate(); } } Partition.CheckAndDistributeCollisions(); for (i = 0; i < PeakCount; i++) { if (SimObjectExists [i]) { b1 = SimObjects [i]; b1.Simulate(); } } }
private void HandleCollision(LSBody other) { if (!CanMove) { return; } if ((tempAgent = other.Agent) == null) { return; } Move otherMover = tempAgent.GetAbility <Move> (); if (ReferenceEquals(otherMover, null) == false) { if (IsMoving && (GetFullCanCollisionStop())) { if (otherMover.MyMovementGroupID == MyMovementGroupID) { if (otherMover.IsMoving == false && otherMover.Arrived && otherMover.StoppedTime > MinimumOtherStopTime) { if (otherMover.CanCollisionStop == false) { TempCanCollisionStop = false; } else { Arrive(); } } else if (hasPath && otherMover.hasPath && otherMover.pathIndex > 0 && otherMover.lastTargetPos.SqrDistance(targetPos.x, targetPos.y) < FixedMath.One) { if (movementDirection.Dot(targetDirection.x, targetDirection.y) < 0) { pathIndex++; } } } } } }
internal static int Assimilate(LSBody body, bool isDynamic) { if (CachedIDs.Count > 0) { id = CachedIDs.Pop(); } else { id = PeakCount; PeakCount++; if (PeakCount == SimObjects.Length) { //very very expensive Array.Resize(ref SimObjects, SimObjects.Length * 2); } } SimObjects[id] = body; //Important: If isDynamic is false, PhysicsManager won't check to update the item every frame. When the object is changed, it must be updated manually. if (isDynamic) { body.DynamicID = DynamicSimObjects.Add(body); } AssimilatedCount++; return id; }
private static void GetGridBounds(LSBody Body) { GridXMin = GetGridX(Body.XMin); GridXMax = GetGridX(Body.XMax); GridYMin = GetGridY(Body.YMin); GridYMax = GetGridY(Body.YMax); int iterationCount = 0; while (CheckSize(GridXMin, GridXMax, GridYMin, GridYMax)) { iterationCount++; if (iterationCount >= 5) { break; } GridXMin = GetGridX(Body.XMin); GridXMax = GetGridX(Body.XMax); GridYMin = GetGridY(Body.YMin); GridYMax = GetGridY(Body.YMax); } }
public static void ProjectPolygon(long AxisX, long AxisY, LSBody Poly, out long Min, out long Max) { Min = Poly.RealPoints [0].Dot(AxisX, AxisY); Max = Min; int PointCount = Poly.RealPoints.Length; long Projection; for (int i = 1; i < PointCount; i++) { Projection = Poly.RealPoints [i].Dot(AxisX, AxisY); if (Projection < Min) { Min = Projection; } else if (Projection > Max) { Max = Projection; } } }
void DistributeCircle_CirclePriority(LSBody higherPriority, LSBody lowerPriority) { if (true || higherPriority.Immovable || lowerPriority.ImmovableCollisionDirection.EqualsZero()) { DistributeCircle(lowerPriority); lowerPriority.ImmovableCollisionDirection = new Vector2d(DistX, DistY); } else { //TODO: Fix this behavior. It's supposed to prevent pass-through between i.e. buildings. //Only move if there isn't an immovable object in that direction if (lowerPriority.ImmovableCollisionDirection.x.Sign() != DistX.Sign()) { lowerPriority._position.x += DistX; } if (lowerPriority.ImmovableCollisionDirection.y.Sign() != DistY.Sign()) { lowerPriority._position.y += DistY; } } }
public static void PartitionObject(LSBody Body, bool gridBoundsCalculated = false) { if (gridBoundsCalculated == false) { GetGridBounds(Body); } Body.PastGridXMin = GridXMin; Body.PastGridXMax = GridXMax; Body.PastGridYMin = GridYMin; Body.PastGridYMax = GridYMax; for (int i = GridXMin; i <= GridXMax; i++) { for (int j = GridYMin; j <= GridYMax; j++) { PartitionNode node = GetNode(i, j); node.Add(Body.ID); } } }
public static void Dessimilate(LSBody body) { if (!SimObjectExists [body.ID]) { Debug.LogWarning("Object with ID" + body.ID.ToString() + "cannot be dessimilated because it it not assimilated"); return; } SimObjectExists [body.ID] = false; CachedIDs.Add(body.ID); for (i = 0; i < FastCollisionPairs.Count; i++) { pair = FastCollisionPairs.innerArray [i]; if (pair.Body1 == body || pair.Body2 == body) { pair.Deactivate(); } } AssimilatedCount--; }
public static void UpdateObject(LSBody Body, bool repartition = true) { GetGridBounds(Body); if (Body.PastGridXMin != GridXMin || Body.PastGridXMax != GridXMax || Body.PastGridYMin != GridYMin || Body.PastGridYMax != GridYMax) { for (int o = Body.PastGridXMin; o <= Body.PastGridXMax; o++) { for (int p = Body.PastGridYMin; p <= Body.PastGridYMax; p++) { PartitionNode node = GetNode(o, p); node.Remove(Body.ID); } } if (repartition) { PartitionObject(Body, true); } } }
/// <summary> /// Call this to deactivate this body and remove from simulation. /// </summary> public void Deactivate() { //Don't double deactivate if (this.Active == false) { return; } Partition.UpdateObject(this, false); foreach (var collisionPair in CollisionPairs.Values) { collisionPair.Body2.CollisionPairHolders.Remove(ID); DeactivatePair(collisionPair); } CollisionPairs.Clear(); foreach (var id in CollisionPairHolders) { LSBody other = PhysicsManager.SimObjects[id]; if (other.IsNotNull()) { CollisionPair collisionPair; if (other.CollisionPairs.TryGetValue(ID, out collisionPair)) { other.CollisionPairs.Remove(this.ID); DeactivatePair(collisionPair); } else { Debug.Log("nope " + ID); } } } CollisionPairHolders.Clear(); PhysicsManager.Dessimilate(this); Active = false; }
public static void UpdateObject(LSBody Body) { GetGridBounds(Body); if (Body.PastGridXMin != GridXMin || Body.PastGridXMax != GridXMax || Body.PastGridYMin != GridYMin || Body.PastGridYMax != GridYMax) { for (int o = Body.PastGridXMin; o <= Body.PastGridXMax; o++) { for (int p = Body.PastGridYMin; p <= Body.PastGridYMax; p++) { PartitionNode node = GetNode(o, p); node.Remove(Body.ID); } } for (int i = GridXMin; i <= GridXMax; i++) { for (int j = GridYMin; j <= GridYMax; j++) { PartitionNode node = GetNode(i, j); node.Add(Body.ID); } } Body.PastGridXMin = GridXMin; Body.PastGridXMax = GridXMax; Body.PastGridYMin = GridYMin; Body.PastGridYMax = GridYMax; } }
public static IEnumerable <LSBody> RaycastAll(Vector2d start, Vector2d end) { LSBody.PrepareAxisCheck(start, end); foreach (FractionalLineAlgorithm.Coordinate coor in GetRelevantNodeCoordinates(start, end)) { int indexX = coor.X; int indexY = coor.Y; if (!Partition.CheckValid(coor.X, coor.Y)) { break; } PartitionNode node = Partition.GetNode(indexX, indexY); for (int i = node.ContainedObjects.Count - 1; i >= 0; i--) { LSBody body = PhysicsManager.SimObjects [node.ContainedObjects [i]]; if (body.Overlaps()) { yield return(body); } } } yield break; }
public static bool CheckCircle_Poly(LSBody circle, LSBody poly) { int EdgeCount = poly.EdgeNorms.Length; for (int i = 0; i < EdgeCount; i++) { Vector2d axis = poly.EdgeNorms [i]; long CircleProjection = circle.Position.Dot(axis.x, axis.y); long CircleMin = CircleProjection - circle.Radius; long CircleMax = CircleProjection + circle.Radius; long PolyMin; long PolyMax; ProjectPolygon(axis.x, axis.y, poly, out PolyMin, out PolyMax); if (!CheckOverlap(CircleMin, CircleMax, PolyMin, PolyMax)) { return(false); } } return(true); }
private static void CreatePair(LSBody body1, LSBody body2, int pairIndex) { pair = CollisionPairs [pairIndex]; if (pair == null) { pair = new CollisionPair (); CollisionPairs [pairIndex] = pair; } FastCollisionPairs.Add (pair); pair.Initialize (body1, body2); }
public static void Visualize() { float smoothDeltaTime = Mathf.Max (Time.unscaledDeltaTime, 1f / 256); LerpDampScaler = Mathf.Lerp (LerpDampScaler, (4f / 64) / smoothDeltaTime, Time.deltaTime); LerpDamping = Time.unscaledDeltaTime * LerpDampScaler; LerpDamping *= Time.timeScale; long curTicks = LockstepManager.Ticks; LerpTime = (float)((curTicks - LastSimulateTicks) / (double)FixedDeltaTicks); LerpTime *= Time.timeScale; if (LerpTime <= 1f) { for (i = 0; i < PeakCount; i++) { if (SimObjectExists[i]) { b1 = SimObjects[i]; b1.Visualize (); } } } else { for (i = 0; i < PeakCount; i++) { if (SimObjectExists[i]) { SimObjects[i].LerpOverReset(); } } } }
public static void Simulate() { simulationCount--; if (simulationCount <= 0) { simulationCount = SimulationSpread; } else { return; } for (i = 0; i < PeakCount; i++) { if (SimObjectExists [i]) { b1 = SimObjects [i]; b1.EarlySimulate (); } } Partition.CheckAndDistributeCollisions (); for (i = 0; i < PeakCount; i++) { if (SimObjectExists [i]) { b1 = SimObjects [i]; b1.Simulate (); } } }
public static bool RequireCollisionPair(LSBody body1, LSBody body2) { if ( Physics2D.GetIgnoreLayerCollision (body1.Layer, body2.Layer) == false && (!body1.Immovable || !body2.Immovable) && (!body1.IsTrigger || !body2.IsTrigger) && (body1.Shape != ColliderType.None && body2.Shape != ColliderType.None) ) { return true; } return false; }
public override void Initialize(LSAgent agent) { MyMovementGroupID = -1; Body = agent.Body; Body.Mover = this; Body.OnContact += HandleCollision; Turner = agent.GetAbility<Turn> (); timescaledSpeed = ((Speed * LockstepManager.Timestep) >> FixedMath.SHIFT_AMOUNT); closingDistance = agent.Body.Radius; RepathCount = LSUtility.GetRandom (RepathRate); ViableDestination = false; }
private void HandleCollision(LSBody other) { if (!CanMove) { return; } if ((tempAgent = other.Agent) == null) { return; } if (tempAgent == collidingAgent) collidedWithTrackedAgent = true; else if (collidingAgent == null) { collidingAgent = tempAgent; collidedWithTrackedAgent = true; } Move otherMover = tempAgent.Mover; if (ReferenceEquals(otherMover, null) == false) { if (IsMoving && CanCollisionStop) { if (otherMover.MyMovementGroupID == MyMovementGroupID) { if (otherMover.IsMoving == false && otherMover.Arrived && otherMover.stopTime > MinimumOtherStopTime) { Arrive(); } else if (hasPath && otherMover.hasPath && otherMover.pathIndex > 0 && otherMover.lastTargetPos.SqrDistance(targetPos.x, targetPos.y) < FixedMath.One) { if (movementDirection.Dot(targetDirection.x, targetDirection.y) < 0) { pathIndex++; } } } } } }
public void Initialize(LSBody b1, LSBody b2) { PartitionVersion = 0; Body1 = b1; Body2 = b2; IsColliding = false; DistX = 0; DistY = 0; PenetrationX = 0; PenetrationY = 0; CacheSqrDistance = b1.Radius + b2.Radius; CacheSqrDistance *= CacheSqrDistance; LeCollisionType = CollisionType.None; if (Body1.Shape == ColliderType.None || Body2.Shape == ColliderType.None) { } else if (Body1.Shape == ColliderType.Circle) { if (Body2.Shape == ColliderType.Circle) { LeCollisionType = CollisionType.Circle_Circle; } else if (Body2.Shape == ColliderType.AABox) { LeCollisionType = CollisionType.Circle_AABox; } else if (Body2.Shape == ColliderType.Polygon) { LeCollisionType = CollisionType.Circle_Polygon; } } else if (Body1.Shape == ColliderType.AABox) { if (Body2.Shape == ColliderType.Circle) { LeCollisionType = CollisionType.Circle_AABox; } else if (Body2.Shape == ColliderType.AABox) { LeCollisionType = CollisionType.AABox_AABox; } else if (Body2.Shape == ColliderType.Polygon) { LeCollisionType = CollisionType.AABox_Polygon; } } else if (Body1.Shape == ColliderType.Polygon) { if (Body2.Shape == ColliderType.Circle) { LeCollisionType = CollisionType.Circle_Polygon; } else if (Body2.Shape == ColliderType.AABox) { LeCollisionType = CollisionType.AABox_Polygon; } else if (Body2.Shape == ColliderType.Polygon) { LeCollisionType = CollisionType.Polygon_Polygon; } } DoPhysics = ((Body1.IsTrigger || Body2.IsTrigger) == false); if (DoPhysics) { } Active = true; }
public static void ProjectPolygon(long AxisX, long AxisY, LSBody Poly, out long Min, out long Max) { Min = Poly.RealPoints [0].Dot (AxisX, AxisY); Max = Min; int PointCount = Poly.RealPoints.Length; long Projection; for (int i = 1; i < PointCount; i++) { Projection = Poly.RealPoints [i].Dot (AxisX, AxisY); if (Projection < Min) { Min = Projection; } else if (Projection > Max) Max = Projection; } }
public void DistributeCircle_Box(LSBody box, LSBody circle) { xMore = circle.Position.x > box.Position.x; yMore = circle.Position.y > box.Position.y; if (xMore) { PenetrationX = (circle.XMin - box.XMax); } else { PenetrationX = (circle.XMax - box.XMin); } if (yMore) { PenetrationY = (circle.YMin - box.YMax); } else { PenetrationY = (circle.YMax - box.YMin); } xAbs = PenetrationX < 0 ? -PenetrationX : PenetrationX; yAbs = PenetrationY < 0 ? -PenetrationY : PenetrationY; if (xAbs > yAbs) { PenetrationX = 0;//FixedMath.Mul (PenetrationX, FixedMath.One * 1 / 4); } else { PenetrationY = 0;//FixedMath.Mul (PenetrationX, FixedMath.One * 1 / 4); } //Resolving circle.Position.x -= PenetrationX;//(PenetrationX * Multiplier) >> FixedMath.SHIFT_AMOUNT; circle.Position.y -= PenetrationY;//(PenetrationY * Multiplier) >> FixedMath.SHIFT_AMOUNT; circle.Velocity.x -= PenetrationX; circle.Velocity.y -= PenetrationY; circle.VelocityChanged = true; circle.PositionChanged = true; circle.BuildBounds (); }
public void HandleImmovableCircleBoxCollision(LSBody imov, LSBody mov) { }
public void Initialize(LSBody b1, LSBody b2) { PartitionVersion = 0; Body1 = b1; Body2 = b2; IsColliding = false; DistX = 0; DistY = 0; PenetrationX = 0; PenetrationY = 0; CacheSqrDistance = b1.Radius + b2.Radius; CacheSqrDistance *= CacheSqrDistance; LeCollisionType = CollisionType.None; if (Body1.Shape == ColliderType.None || Body2.Shape == ColliderType.None) { } else if (Body1.Shape == ColliderType.Circle) { if (Body2.Shape == ColliderType.Circle) { LeCollisionType = CollisionType.Circle_Circle; } else if (Body2.Shape == ColliderType.AABox) { LeCollisionType = CollisionType.Circle_AABox; } else if (Body2.Shape == ColliderType.Polygon) { LeCollisionType = CollisionType.Circle_Polygon; } } else if (Body1.Shape == ColliderType.AABox) { if (Body2.Shape == ColliderType.Circle) { LeCollisionType = CollisionType.Circle_AABox; } else if (Body2.Shape == ColliderType.AABox) { LeCollisionType = CollisionType.AABox_AABox; } else if (Body2.Shape == ColliderType.Polygon) { LeCollisionType = CollisionType.AABox_Polygon; } } else if (Body1.Shape == ColliderType.Polygon) { if (Body2.Shape == ColliderType.Circle) { LeCollisionType = CollisionType.Circle_Polygon; } else if (Body2.Shape == ColliderType.AABox) { LeCollisionType = CollisionType.AABox_Polygon; } else if (Body2.Shape == ColliderType.Polygon) { LeCollisionType = CollisionType.Polygon_Polygon; } } if (DoPhysics) { if (Body1.Immovable) { physicsFavor = PhysicsFavor.Favor1; } else if (Body2.Immovable) { physicsFavor = PhysicsFavor.Favor2; } else if (Body1.Priority > Body2.Priority) { physicsFavor = PhysicsFavor.Favor1; } else if (Body2.Priority > Body1.Priority) { physicsFavor = PhysicsFavor.Favor2; } else { physicsFavor = PhysicsFavor.Same; } } Active = true; }
public static void UpdateObject(LSBody Body) { GridXMin = (Body.XMin - OffsetX) >> ShiftSize; GridXMax = ((Body.XMax - OffsetX) >> ShiftSize); GridYMin = ((Body.YMin - OffsetY) >> ShiftSize); GridYMax =((Body.YMax - OffsetY) >> ShiftSize); #if UNITY_EDITOR if (GridXMin < 0 || GridXMax >= Count || GridYMin < 0 || GridYMax >= Count) { Debug.LogError ("Body with ID " + Body.ID.ToString () + " is out of partition bounds."); return; } #endif if (Body.PastGridXMin != GridXMin || Body.PastGridXMax != GridXMax || Body.PastGridYMin != GridYMin || Body.PastGridYMax != GridYMax) { for (long o = Body.PastGridXMin; o <= Body.PastGridXMax; o++) { for (long p = Body.PastGridYMin; p <= Body.PastGridYMax; p++) { PartitionNode node = Nodes [o * Count + p]; node.Remove (Body.ID); } } for (long i = GridXMin; i <= GridXMax; i++) { for (long j = GridYMin; j <= GridYMax; j++) { PartitionNode node = Nodes [i * Count + j]; node.Add (Body.ID); } } Body.PastGridXMin = GridXMin; Body.PastGridXMax = GridXMax; Body.PastGridYMin = GridYMin; Body.PastGridYMax = GridYMax; } }
protected override void OnSetup() { cachedBody = Agent.Body; cachedBody.OnContact += HandleCollision; cachedTurn = Agent.Turner; collisionStopTreshold = FixedMath.Mul (timescaledSpeed,CollisionStopTreshold); collisionStopTreshold *= collisionStopTreshold; timescaledAcceleration = Acceleration * 32 / LockstepManager.FrameRate; if (timescaledAcceleration > FixedMath.One) timescaledAcceleration = FixedMath.One; closingDistance = cachedBody.Radius; if (closingDistance < FixedMath.One / 4) closingDistance = closingDistance; stuckTolerance = ((Agent.Body.Radius * Speed) >> FixedMath.SHIFT_AMOUNT) / LockstepManager.FrameRate; stuckTolerance *= stuckTolerance; }
public static void Simulate() { for (i = 0; i < PeakCount; i++) { if (SimObjectExists [i]) { b1 = SimObjects [i]; b1.EarlySimulate (); } } Partition.CheckAndDistributeCollisions (); for (i = 0; i < PeakCount; i++) { if (SimObjectExists [i]) { b1 = SimObjects [i]; b1.Simulate (); } } }
public static bool RequireCollisionPair(LSBody body1, LSBody body2) { if ( !Physics2D.GetIgnoreLayerCollision (body1.cachedGameObject.layer, body2.cachedGameObject.layer) && (!body1.Immovable || !body2.Immovable) && (!body1.IsTrigger || !body2.IsTrigger)) { return true; } return false; }
public static bool CheckPoly_Poly(LSBody poly1, LSBody poly2) { int Poly1EdgeCount = poly1.EdgeNorms.Length; int EdgeCount = Poly1EdgeCount + poly2.EdgeNorms.Length; for (int i = 0; i < EdgeCount; i++) { Vector2d edge; if (i < Poly1EdgeCount) { edge = poly1.EdgeNorms [i]; } else { edge = poly1.EdgeNorms [i - Poly1EdgeCount]; } long Poly1Min; long Poly1Max; ProjectPolygon (edge.x, edge.y, poly1, out Poly1Min, out Poly1Max); long Poly2Min; long Poly2Max; ProjectPolygon (edge.x, edge.y, poly2, out Poly2Min, out Poly2Max); if (!CheckOverlap (Poly1Min, Poly1Max, Poly2Min, Poly2Max)) return false; } return true; }
protected override void OnSetup() { cachedBody = Agent.Body; cachedTurn = Agent.Turner; cachedMove = Agent.Mover; if (Sight < Range) _sight = Range; baseDeltaCount = InfluenceManager.GenerateDeltaCount(Sight); rangeDeltaCount = InfluenceManager.GenerateDeltaCount(Range); fastRange = (Range * Range); attackFrameCount = AttackRate; basePriority = cachedBody.Priority; CanMove = cachedMove .IsNotNull(); if (CanMove) { cachedMove.OnArrive += HandleOnArrive; cachedMove.onGroupProcessed += _HandleMoveGroupProcessed; } CanTurn = cachedTurn .IsNotNull(); }
public static void Dessimilate(LSBody body) { if (!SimObjectExists [body.ID]) { Debug.LogWarning ("Object with ID" + body.ID.ToString () + "cannot be dessimilated because it it not assimilated"); return; } SimObjectExists [body.ID] = false; CachedIDs.Add (body.ID); for (i = 0; i < FastCollisionPairs.Count; i++) { pair = FastCollisionPairs.innerArray [i]; if (pair.Body1 == body || pair.Body2 == body) { pair.Deactivate (); } } AssimilatedCount--; body.Deactivate (); }
private void HandleCollision(LSBody other) { if (System.Object.ReferenceEquals (other.Mover, null) == false) { TouchingObjects.Add (other.Mover); if (IsMoving) { if (other.Mover.MyMovementGroupID == MyMovementGroupID) { if (!other.Mover.IsMoving && other.Mover.StopTime > MinimumOtherStopTime) { if (IsFormationMoving) { if (MovementDirection.Dot (TargetDirection.x, TargetDirection.y) < 0) { StopMove (); } } else { StopMove (); } } else if (HasPath && other.Mover.HasPath && other.Mover.PathIndex > 0 && other.Mover.LastTargetPos.SqrDistance (TargetPos.x, TargetPos.y) < FixedMath.One) { if (MovementDirection.Dot (TargetDirection.x, TargetDirection.y) < 0) PathIndex++; } } } } }
private bool CheckCollision(LSBody target) { return target.Position.FastDistance (Position.x, Position.y) <= target.FastRadius; }
public static bool CheckCircle_Poly(LSBody circle, LSBody poly) { int EdgeCount = poly.EdgeNorms.Length; for (int i = 0; i < EdgeCount; i++) { Vector2d axis = poly.EdgeNorms [i]; long CircleProjection = circle.Position.Dot (axis.x, axis.y); long CircleMin = CircleProjection - circle.Radius; long CircleMax = CircleProjection + circle.Radius; long PolyMin; long PolyMax; ProjectPolygon (axis.x, axis.y, poly, out PolyMin, out PolyMax); if (!CheckOverlap (CircleMin, CircleMax, PolyMin, PolyMax)) { return false; } } return true; }
private void HandleCollision(LSBody other) { if (other.Mover != null) { TouchingObjects.Add (other.Mover); if (IsMoving) { if (!other.Mover.IsMoving && other.Mover.MyMovementGroupID == MyMovementGroupID && other.Mover.StopTime > MinimumOtherStopTime) { StopMove (); } } } }