コード例 #1
0
 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;
             }
         }
     }
 }
コード例 #2
0
 public static void Initialize()
 {
     for (i = 0; i < Count * Count; i++)
     {
         Nodes[i] = new PartitionNode();
     }
 }
コード例 #3
0
 public static void Initialize()
 {
     for (i = 0; i < Count * Count; i++)
     {
         Nodes[i] = new PartitionNode ();
     }
 }
コード例 #4
0
        public static void UpdateObject(LSBody Body, bool repartition = true)
        {
            GetGridBounds(Body);

            if (
                repartition == false ||
                (Body.PastGridXMin != GridXMin ||
                 Body.PastGridXMax != GridXMax ||
                 Body.PastGridYMin != GridYMin ||
                 Body.PastGridYMax != GridYMax))
            {
                //Remove from all partitions no longer located on
                for (int o = Body.PastGridXMin; o <= Body.PastGridXMax; o++)
                {
                    for (int p = Body.PastGridYMin; p <= Body.PastGridYMax; p++)
                    {
                        PartitionNode node = GetNode(o, p);
                        if (Body.Immovable)
                        {
                            node.RemoveImmovable(Body.ID);
                        }
                        else
                        {
                            node.Remove(Body.ID);
                        }
                    }
                }
                if (repartition)
                {
                    PartitionObject(Body, true);
                }
            }
        }
コード例 #5
0
 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;
             }
         }
     }
 }
コード例 #6
0
        /// <summary>
        /// Finds all dynamic bodies touching a defined circle.
        /// </summary>
        /// <param name="radius">Radius.</param>
        /// <param name="output">Output.</param>
        public static void CircleCast(Vector2d position, long radius, FastList <LSBody> output)
        {
            long xMin = position.x - radius,
                 xmax = position.x + radius;
            long yMin = position.y - radius,
                 yMax = position.y + radius;

            //Find the partition tiles we have to search in first
            int gridXMin, gridXMax, gridYMin, gridYMax;

            Partition.GetGridBounds(xMin, xmax, yMin, yMax,
                                    out gridXMin, out gridXMax, out gridYMin, out gridYMax);


            for (int i = gridXMin; i <= gridXMax; i++)
            {
                for (int j = gridYMin; j <= gridYMax; j++)
                {
                    PartitionNode node = Partition.GetNode(i, j);
                    for (int k = 0; k < node.ContainedDynamicObjects.Count; k++)
                    {
                        var  body        = PhysicsManager.SimObjects [node.ContainedDynamicObjects [k]];
                        long minFastDist = body.Radius + radius;
                        //unnormalized distance value for comparison
                        minFastDist *= minFastDist;

                        if (body.Position.FastDistance(position) <= minFastDist)
                        {
                            //Body touches circle!
                            output.Add(body);
                        }
                    }
                }
            }
        }
コード例 #7
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);
                    Body.PartitionChanged = true;
                    if (Body.Immovable)
                    {
                        node.AddImmovable(Body.ID);
                    }
                    else
                    {
                        node.Add(Body.ID);
                    }
                }
            }
        }
コード例 #8
0
 public static IEnumerable <LSBody> RaycastAll(Vector2d start, Vector2d end)
 {
     _Version++;
     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.ContainedDynamicObjects.Count - 1; i >= 0; i--)
         {
             LSBody body = PhysicsManager.SimObjects[node.ContainedDynamicObjects[i]];
             if (body.IsNotNull() && body.RaycastVersion != _Version)
             {
                 if (Conditional.IsNull() || Conditional())
                 {
                     body.RaycastVersion = _Version;
                     if (body.Overlaps(bufferIntersectionPoints))
                     {
                         yield return(body);
                     }
                 }
             }
         }
     }
     Conditional = null;
     yield break;
 }
コード例 #9
0
        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;
                        }

                    }
                }
            }
        }
コード例 #10
0
        public static int AddNode(PartitionNode node)
        {
            int activationID = ActivatedNodes.Add(node);

            AllocatedNodes.Add(node);
            return(activationID);
        }
コード例 #11
0
 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;
                 }
             }
         }
     }
 }
コード例 #12
0
 public static void Setup()
 {
     _Version = 1;
     for (int i = 0; i < Count * Count; i++)
     {
         Nodes [i] = new PartitionNode();
     }
 }
コード例 #13
0
        public static PartitionNode GetNode(int indexX, int indexY)
        {
            PartitionNode node = Nodes [indexX, indexY];

            if (node.IsNull())
            {
                node = new PartitionNode();
                Nodes [indexX, indexY] = node;
            }
            return(node);
        }
コード例 #14
0
 public static void CheckAndDistributeCollisions()
 {
     _Version++;
     for (int i = ActivatedNodes.PeakCount - 1; i >= 0; i--)
     {
         if (ActivatedNodes.arrayAllocation [i])
         {
             PartitionNode node = ActivatedNodes [i];
             node.Distribute();
         }
     }
 }
コード例 #15
0
        public static void GetTouchingPartitions(LSBody Body, FastList <PartitionNode> output)
        {
            GetGridBounds(Body);

            for (int i = GridXMin; i <= GridXMax; i++)
            {
                for (int j = GridYMin; j <= GridYMax; j++)
                {
                    PartitionNode node = GetNode(i, j);
                    output.Add(node);
                }
            }
        }
コード例 #16
0
 public static void CheckAndDistributeCollisions()
 {
     count = 0;
     _Version++;
     for (int i = ActivatedNodes.PeakCount - 1; i >= 0; i--)
     {
         if (ActivatedNodes.arrayAllocation [i])
         {
             PartitionNode node = ActivatedNodes [i];
             node.Distribute();
         }
     }
     //Debug.Log (count + " pairs checked");
 }
コード例 #17
0
        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;
            }
        }
コード例 #18
0
        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);
                }
            }
        }
コード例 #19
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);
         }
     }
 }
コード例 #20
0
ファイル: Partition.cs プロジェクト: Fitcal/LockstepFramework
 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);
         }
     }
 }
コード例 #21
0
        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;
            }
        }
コード例 #22
0
 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;
 }
コード例 #23
0
        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;
            }
        }
コード例 #24
0
        private bool InternalRaycast(Vector2d From, Vector2d To, int ExceptionID)
        {
            _Version++;

            MadeContact = false;
            Hits.FastClear();


            const int StepSize = 1 << Partition.ShiftSize;

            x0 = From.x;
            y0 = From.y;
            x1 = To.x;
            y1 = To.y;
            if (y1 > y0)
            {
                compare1 = y1 - y0;
            }
            else
            {
                compare1 = y0 - y1;
            }
            if (x1 > x0)
            {
                compare2 = x1 - x0;
            }
            else
            {
                compare2 = x0 - x1;
            }
            steep = compare1 > compare2;
            if (steep)
            {
                t  = x0;                // swap x0 and y0
                x0 = y0;
                y0 = t;
                t  = x1;                // swap x1 and y1
                x1 = y1;
                y1 = t;
            }
            if (x0 > x1)
            {
                t  = x0;                // swap x0 and x1
                x0 = x1;
                x1 = t;
                t  = y0;                // swap y0 and y1
                y0 = y1;
                y1 = t;
            }
            dx = x1 - x0;

            dy = (y1 - y0);
            if (dy < 0)
            {
                dy = -dy;
            }

            error = dx / 2;
            ystep = (y0 < y1) ? StepSize : -StepSize;
            y     = y0;

            AxisX = From.x - To.x;
            AxisY = From.y - To.y;
            Mag   = FixedMath.Sqrt((AxisX * AxisX + AxisY * AxisY) >> FixedMath.SHIFT_AMOUNT);
            if (Mag == 0)
            {
                return(false);
            }
            AxisX   = FixedMath.Div(AxisX, Mag);
            AxisY   = FixedMath.Div(AxisY, Mag);
            AxisMin = Vector2d.Dot(AxisX, AxisY, From.x, From.y);
            AxisMax = Vector2d.Dot(AxisX, AxisY, To.x, To.y);
            if (AxisMin > AxisMax)
            {
                SwapValue = AxisMin;
                AxisMin   = AxisMax;
                AxisMax   = SwapValue;
            }
            PerpProj = Vector2d.Dot(-AxisY, AxisX, From.x, From.y);

            XMin = From.x;
            XMax = To.x;
            if (XMin > XMax)
            {
                SwapValue = XMin;
                XMin      = XMax;
                XMax      = SwapValue;
            }
            YMin = From.y;
            YMax = To.y;
            if (YMin > YMax)
            {
                SwapValue = YMin;
                YMin      = YMax;
                YMax      = SwapValue;
            }
            x = x0;
            while (true)
            {
                if (steep)
                {
                    retX = (y - Partition.OffsetX) / StepSize;
                    retY = (x - Partition.OffsetY) / StepSize;
                }
                else
                {
                    retX = (x - Partition.OffsetX) / StepSize;
                    retY = (y - Partition.OffsetY) / StepSize;
                }

                PartitionNode node = Partition.Nodes [retX * Partition.Count + retY];
                if (node.Count > 0)
                {
                    for (i = 0; i < node.Count; i++)
                    {
                        DidHit = false;

                        LSBody body = PhysicsManager.SimObjects [node [i]];
                        if (body.RaycastVersion != _Version && body.ID != ExceptionID)
                        {
                            body.RaycastVersion = _Version;
                            switch (body.Shape)
                            {
                            case ColliderType.Circle:
                                Projection = Vector2d.Dot(AxisX, AxisY, body.Position.x, body.Position.y);
                                TestMin    = Projection - body.Radius;
                                TestMax    = Projection + body.Radius;
                                if (TestMin < AxisMax)
                                {
                                    if (TestMax > AxisMin)
                                    {
                                        Projection = Vector2d.Dot(-AxisY, AxisX, body.Position.x, body.Position.y);
                                        TestMin    = Projection - body.Radius;
                                        TestMax    = Projection + body.Radius;
                                        if (PerpProj < TestMax && PerpProj > TestMin)
                                        {
                                            DidHit = true;
                                        }
                                    }
                                }
                                break;

                            case ColliderType.AABox:
                                if (AxisMin < body.XMax)
                                {
                                    if (AxisMax > body.XMin)
                                    {
                                        if (PerpProj < body.YMax)
                                        {
                                            if (PerpProj > body.YMin)
                                            {
                                                DidHit = true;
                                            }
                                        }
                                    }
                                }
                                break;
                            }
                            if (DidHit)
                            {
                                Hits.Add(body);
                                MadeContact = true;
                                break;
                            }
                        }
                    }
                }

                error = error - dy;
                if (error < 0)
                {
                    y     += ystep;
                    error += dx;
                }

                if (x >= x1)
                {
                    break;
                }
                x += StepSize;
            }
            return(MadeContact);
        }
コード例 #25
0
 public static void Setup()
 {
     _Version = 1;
     for (int i = 0; i < Count * Count; i++) {
         Nodes [i] = new PartitionNode ();
     }
 }