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++;
        }
Exemple #8
0
        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;
        }
Exemple #10
0
        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);
        }
Exemple #11
0
        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;
        }
Exemple #13
0
 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;
 }
Exemple #14
0
        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);
         }
     }
 }
Exemple #18
0
        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;
			}
		}
Exemple #23
0
 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++;
                            }
                        }
                    }
                }
            }
        }
Exemple #25
0
 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();
         }
     }
 }
Exemple #27
0
        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;
		}
Exemple #29
0
        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;
         }
     }
 }
Exemple #32
0
        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--;
        }
Exemple #34
0
 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);
         }
     }
 }
Exemple #35
0
        /// <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;
 }
Exemple #38
0
        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;
        }
Exemple #60
0
 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 ();
             }
         }
     }
 }