public static void EstablishPartitions()
 {
     for (i = 0 ; i < Count * Count; i++)
     {
          node = Nodes[i];
         ListLength = node.Count;
         if (ListLength == 0) continue;
         for (j = 0; j < ListLength; j++)
         {
             id1 = node.innerArray[j];
             for (k = j + 1; k < ListLength; k++)
             {
                 id2 = node.innerArray[k];
                 if (id1 < id2)
                 {
                     pair = PhysicsManager.CollisionPairs[id1 * PhysicsManager.MaxSimObjects + id2];
                 }
                 else {
                     pair = PhysicsManager.CollisionPairs[id2 * PhysicsManager.MaxSimObjects + id1];
                 }
                 if (pair == null) continue;
                 pair.SamePartition = true;
             }
         }
     }
 }
        public void Distribute()
        {
            int nodePeakCount = PeakCount;
            for (int j = 0; j < nodePeakCount; j++) {
                if (ContainedObjects.arrayAllocation[j])
                {
                    id1 = this[j];
                    for (int k = j + 1; k < nodePeakCount; k++) {
                        if (ContainedObjects.arrayAllocation[k]) {
                            id2 = this [k];
                            if (id1 < id2) {
                                pair = PhysicsManager.CollisionPairs [id1 * PhysicsManager.MaxSimObjects + id2];
                            } else {
                                pair = PhysicsManager.CollisionPairs [id2 * PhysicsManager.MaxSimObjects + id1];
                            }

                            if (System.Object.ReferenceEquals (null, pair) == false && (pair.PartitionVersion != Partition._Version)) {
                                pair.CheckAndDistributeCollision ();
                                pair.PartitionVersion = Partition._Version;
                            }
                        }
                    }
                }
            }
        }
        public static void CheckAndDistributeCollisions()
        {
            _Version++;
            for (i = 0; i < Count * Count; i++) {
                node = Nodes [i];
                ListLength = node.Count;
                if (ListLength == 0)
                    continue;
                for (j = 0; j < ListLength; j++) {
                    id1 = node.innerArray [j];
                    for (k = j + 1; k < ListLength; k++) {
                        id2 = node.innerArray [k];
                        if (id1 < id2) {
                            pair = PhysicsManager.CollisionPairs [id1 * PhysicsManager.MaxSimObjects + id2];
                        } else {
                            pair = PhysicsManager.CollisionPairs [id2 * PhysicsManager.MaxSimObjects + id1];
                        }
                        if (System.Object.ReferenceEquals (null, pair) == false && (pair.PartitionVersion != _Version)) {
                            pair.CheckAndDistributeCollision ();
                            pair.PartitionVersion = _Version;
                        }

                    }
                }
            }
        }
        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++;
        }
Example #5
0
        public bool IsPositionCovered(Vector2d position)
        {
            //Checks if this body covers a position

            //Different techniques for different shapes
            switch (this.Shape)
            {
            case ColliderType.Circle:
                long maxDistance = this.Radius + FixedMath.Half;
                maxDistance *= maxDistance;
                if ((this._position - position).FastMagnitude() > maxDistance)
                {
                    return(false);
                }
                goto case ColliderType.AABox;

            case ColliderType.AABox:
                return(position.x + FixedMath.Half >= this.XMin && position.x - FixedMath.Half <= this.XMax &&
                       position.y + FixedMath.Half >= this.YMin && position.y - FixedMath.Half <= this.YMax);

                break;

            case ColliderType.Polygon:
                for (int i = this.EdgeNorms.Length - 1; i >= 0; i--)
                {
                    Vector2d norm = this.EdgeNorms [i];
                    long     posProj = norm.Dot(position);
                    long     polyMin, polyMax;
                    CollisionPair.ProjectPolygon(norm.x, norm.y, this, out polyMin, out polyMax);
                    if (posProj >= polyMin && posProj <= polyMax)
                    {
                    }
                    else
                    {
                        return(false);
                    }
                }
                return(true);

                break;
            }


            return(false);
        }
        public void Distribute()
        {
            int nodePeakCount = PeakCount;

            for (int j = 0; j < nodePeakCount; j++)
            {
                id1 = ContainedObjects [j];
                for (int k = j + 1; k < nodePeakCount; k++)
                {
                    id2 = ContainedObjects [k];


                    pair = PhysicsManager.GetCollisionPair(id1, id2);
                    if (System.Object.ReferenceEquals(null, pair) == false && (pair.PartitionVersion != Partition._Version))
                    {
                        pair.CheckAndDistributeCollision();
                        pair.PartitionVersion = Partition._Version;
                    }
                }
            }
        }
        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--;
        }
Example #8
0
 public InstanceCollisionPair(ushort version, CollisionPair pair)
 {
     Version = version;
     Pair    = pair;
 }
        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 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 ();
        }
Example #11
0
 static void DeactivatePair(CollisionPair collisionPair)
 {
     PhysicsManager.DeactivateCollisionPair(collisionPair);
 }
        public void CheckAndDistributeCollision()
        {
            if (!Active)
            {
                return;
            }
            if (_ranIndex < 0)
            {
                _ranIndex = PhysicsManager.RanCollisionPairs.Add(new PhysicsManager.InstanceCollisionPair(_Version, this));
            }
            IsCollidingChanged   = false;
            LastFrame            = LockstepManager.FrameCount;
            CurrentCollisionPair = this;
            if (CullCounter <= 0)
            {
                GenerateCircleValues();
                if (CheckHeight())
                {
                    bool result = CheckCollision();

                    if (result != IsColliding)
                    {
                        IsColliding        = result;
                        IsCollidingChanged = true;
                    }
                    if (CheckCollision())
                    {
                        DistributeCollision();
                    }
                }
                Body1.NotifyContact(Body2, IsColliding, IsCollidingChanged);
                Body2.NotifyContact(Body1, IsColliding, IsCollidingChanged);
                if (IsColliding == false)
                {
                    //A negative cull counter means a Body is preventing culling
                    if (CullCounter >= 0)
                    {
                        if (PreventDistanceCull)
                        {
                            CullCounter = (short)(
                                (LockstepManager.FrameCount - LastCollidedFrame) / PhysicsManager.CullTimeStep);
                            if (CullCounter > PhysicsManager.CullTimeMax)
                            {
                                CullCounter = PhysicsManager.CullTimeMax;
                            }
                        }
                        else
                        {
                            //Set number of frames until next collision check based on distance
                            var distCull = (
                                ((FastDistance - FastDistanceOffset) >> FixedMath.SHIFT_AMOUNT)
                                / PhysicsManager.CullDistanceStep + PhysicsManager.CullDistributor
                                );
                            if (distCull > PhysicsManager.CullDistanceMax)
                            {
                                distCull = PhysicsManager.CullDistanceMax;
                            }
                            if (distCull < 0)
                            {
                                distCull = 0;
                            }

                            var timeCull = (LockstepManager.FrameCount - LastCollidedFrame) / PhysicsManager.CullTimeStep;
                            if (timeCull > PhysicsManager.CullTimeMax)
                            {
                                timeCull = PhysicsManager.CullTimeMax;
                            }

                            CullCounter = (short)(timeCull + distCull);
                        }
                    }
                }
                else
                {
                    LastCollidedFrame = LockstepManager.FrameCount;
                }
            }
            else
            {
                if (Body1.PartitionChanged || Body2.PartitionChanged)
                {
                    //New partition so collision culling may not be calculated yet
                    CullCounter = 0;
                    CheckAndDistributeCollision();
                }
                else
                {
                    //Culled and counter 1 step closer until checking again
                    CullCounter--;
                }
            }
        }
        public bool Overlaps(FastList <Vector2d> outputIntersectionPoints)
        {
            outputIntersectionPoints.FastClear();
            //Checks if this object overlaps the line formed by p1 and p2
            switch (this.Shape)
            {
            case ColliderType.Circle:
            {
                bool overlaps = false;
                //Check if the circle completely fits between the line
                long projPos = this._position.Dot(cacheAxis.x, cacheAxis.y);
                //Circle withing bounds?
                if (projPos >= axisMin && projPos <= axisMax)
                {
                    long projPerp = this._position.Dot(cacheAxisNormal.x, cacheAxisNormal.y);
                    long perpDif  = (cacheProjPerp - projPerp);
                    long perpDist = perpDif.Abs();
                    if (perpDist <= _radius)
                    {
                        overlaps = true;
                    }
                    if (overlaps)
                    {
                        long sin = (perpDif);
                        long cos = FixedMath.Sqrt(_radius.Mul(_radius) - sin.Mul(sin));
                        if (cos == 0)
                        {
                            outputIntersectionPoints.Add((cacheAxis * projPos) + perpVector);
                        }
                        else
                        {
                            outputIntersectionPoints.Add(cacheAxis * (projPos - cos) + perpVector);
                            outputIntersectionPoints.Add(cacheAxis * (projPos + cos) + perpVector);
                        }
                    }
                }
                else
                {
                    //If not, check distances to points
                    long p1Dist = _position.FastDistance(cacheP1.x, cacheP2.y);
                    if (p1Dist <= this.FastRadius)
                    {
                        outputIntersectionPoints.Add(cacheP1);
                        overlaps = true;
                    }
                    long p2Dist = _position.FastDistance(cacheP2.x, cacheP2.y);
                    if (p2Dist <= this.FastRadius)
                    {
                        outputIntersectionPoints.Add(cacheP2);
                        overlaps = true;
                    }
                }
                return(overlaps);
            }
            break;

            case ColliderType.AABox:
            {
            }
            break;

            case ColliderType.Polygon:
            {
                bool intersected = false;


                for (int i = 0; i < this.Vertices.Length; i++)
                {
                    int      edgeIndex = i;
                    Vector2d pivot     = this.RealPoints [edgeIndex];
                    Vector2d edge      = this.Edges [edgeIndex];
                    long     proj1     = 0;
                    int      nextIndex = edgeIndex + 1 < this.RealPoints.Length ? edgeIndex + 1 : 0;
                    Vector2d nextPoint = RealPoints [nextIndex];
                    long     proj2     = (nextPoint - pivot).Dot(edge);

                    long min;
                    long max;
                    if (proj1 < proj2)
                    {
                        min = proj1;
                        max = proj2;
                    }
                    else
                    {
                        min = proj2;
                        max = proj1;
                    }

                    long lineProj1 = (cacheP1 - pivot).Dot(edge);
                    long lineProj2 = (cacheP2 - pivot).Dot(edge);

                    long lineMin;
                    long lineMax;
                    if (lineProj1 < lineProj2)
                    {
                        lineMin = lineProj1;
                        lineMax = lineProj2;
                    }
                    else
                    {
                        lineMin = lineProj2;
                        lineMax = lineProj1;
                    }
                    if (CollisionPair.CheckOverlap(min, max, lineMin, lineMax))
                    {
                        Vector2d edgeNorm      = this.EdgeNorms [edgeIndex];
                        long     normProj      = 0;
                        long     normLineProj1 = (cacheP1 - pivot).Dot(edgeNorm);
                        long     normLineProj2 = (cacheP2 - pivot).Dot(edgeNorm);

                        long normLineMin;
                        long normLineMax;

                        if (normLineProj1 < normLineProj2)
                        {
                            normLineMin = normLineProj1;
                            normLineMax = normLineProj2;
                        }
                        else
                        {
                            normLineMin = normLineProj2;
                            normLineMax = normLineProj1;
                        }

                        if (normProj >= normLineMin && normProj <= normLineMax)
                        {
                            long revProj1 = pivot.Dot(LSBody.cacheAxisNormal);
                            long revProj2 = nextPoint.Dot(cacheAxisNormal);

                            long revMin;
                            long revMax;
                            if (revProj1 < revProj2)
                            {
                                revMin = revProj1;
                                revMax = revProj2;
                            }
                            else
                            {
                                revMin = revProj2;
                                revMax = revProj1;
                            }

                            if (LSBody.cacheProjPerp >= revMin && LSBody.cacheProjPerp <= revMax)
                            {
                                intersected = true;
                                if (LSBody.calculateIntersections)
                                {
                                    long fraction         = normLineProj1.Abs().Div(normLineMax - normLineMin);
                                    long intersectionProj = FixedMath.Lerp(lineProj1, lineProj2, fraction);
                                    outputIntersectionPoints.Add(edge * intersectionProj + pivot);

                                    if (outputIntersectionPoints.Count == 2)
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
                return(intersected);
            }
            break;
            }
            return(false);
        }
        public void CheckAndDistributeCollision()
        {
            if (!Active)
                return;
            CurrentCollisionPair = this;

            if (CheckCollision ()) {
                if (IsColliding == false) {
                    if (Body1.OnContactEnter != null)
                        Body1.OnContactEnter (Body2);
                    if (Body2.OnContactEnter != null)
                        Body2.OnContactEnter (Body1);
                    IsColliding = true;
                } else {

                }
                DistributeCollision ();
            } else {
                if (IsColliding) {
                    if (Body1.OnContactExit != null) {
                        Body1.OnContactExit (Body2);
                    }
                    if (Body2.OnContactExit != null) {
                        Body2.OnContactExit (Body1);
                    }
                    IsColliding = false;
                } else {

                }
            }
        }
Example #15
0
 public static void RemovePairReferences(CollisionPair pair)
 {
     pair.Body1.CollisionPairs.Remove(pair.Body2.ID);
     pair.Body2.CollisionPairHolders.Remove(pair.Body1.ID);
 }
		public static void PoolPair(CollisionPair pair)
		{
			pair.Deactivate();
			if (LockstepManager.PoolingEnabled)
				CachedCollisionPairs.Add(pair);
		}
Example #17
0
        public static void Simulate()
        {
            CollisionIterationRemain = (CollisionPairCount) / CollisionIterationSpread + 1;
            if (CollisionIterationCount == CollisionIterationSpread)
            {
                CollisionIterationCount = 0;
                CollisionIterationMark  = 0;
            }
            else
            {
                CollisionIterationMark += CollisionIterationRemain;
            }


            CurCount = 0;
            for (i = 0; i < FastCollisionPairs.Count; i++)
            {
                pair = FastCollisionPairs[i];
                CurCount++;
                if (CollisionIterationRemain == 0 || CurCount < CollisionIterationMark)
                {
                    pair.DistributeCollision();
                }
                else
                {
                    pair.CheckAndDistributeCollision();
                    CollisionIterationRemain--;
                }
            }


            if (CollisionIterationCount == 0)
            {
                for (i = 0; i < PeakCount; i++)
                {
                    if (SimObjectExists [i])
                    {
                        LSBody b1 = SimObjects [i];
                        b1.EarlySimulate();
                        if (b1.PositionChanged)
                        {
                            Partition.Body = b1;
                            Partition.PartitionObject();
                        }

                        b1.Simulate();
                    }
                }

                Partition.EstablishPartitions();
            }
            else
            {
                for (i = 0; i < PeakCount; i++)
                {
                    if (SimObjectExists [i])
                    {
                        LSBody b1 = SimObjects [i];
                        b1.EarlySimulate();
                        b1.Simulate();
                    }
                }
            }



            CollisionIterationCount++;
        }
        public static void Simulate()
        {
            CollisionIterationRemain = (CollisionPairCount) / CollisionIterationSpread + 1;
            if (CollisionIterationCount == CollisionIterationSpread) {
                CollisionIterationCount = 0;
                CollisionIterationMark = 0;
            } else {
                CollisionIterationMark += CollisionIterationRemain;
            }

            CurCount = 0;
            for (i = 0; i < FastCollisionPairs.Count; i++)
            {
                pair = FastCollisionPairs[i];
                CurCount ++;
                if (CollisionIterationRemain == 0 || CurCount < CollisionIterationMark) {

                    pair.DistributeCollision ();
                } else {
                    pair.CheckAndDistributeCollision ();
                    CollisionIterationRemain--;
                }
            }

            if (CollisionIterationCount == 0) {

                for (i = 0; i < PeakCount; i++) {
                    if (SimObjectExists [i]) {
                        LSBody b1 = SimObjects [i];
                        b1.EarlySimulate ();
                        if (b1.PositionChanged) {
                            Partition.Body = b1;
                            Partition.PartitionObject ();
                        }

                        b1.Simulate ();
                    }
                }

                Partition.EstablishPartitions ();

            } else {
                for (i = 0; i < PeakCount; i++) {
                    if (SimObjectExists [i]) {
                        LSBody b1 = SimObjects [i];
                        b1.EarlySimulate ();
                        b1.Simulate ();
                    }
                }
            }

            CollisionIterationCount++;
        }
        public void CheckAndDistributeCollision()
        {
            if (!Active || Body1.HasParent || Body2.HasParent) {
                return;
            }
            CurrentCollisionPair = this;

            if (CheckCollision ()) {
                if (IsColliding == false) {
                    if (Body1.OnContactEnter .IsNotNull ()) {
                        Body1.OnContactEnter (Body2);
                    }
                    if (Body2.OnContactEnter .IsNotNull ()) {
                        Body2.OnContactEnter (Body1);
                    }
                    IsColliding = true;
                } else {

                }
                DistributeCollision ();
            } else {
                if (IsColliding) {
                    if (Body1.OnContactExit .IsNotNull ()) {
                        Body1.OnContactExit (Body2);
                    }
                    if (Body2.OnContactExit .IsNotNull ()) {
                        Body2.OnContactExit (Body1);
                    }
                    IsColliding = false;
                } else {

                }
            }
        }