public void GetSpiralCoords_Should_ShareTheResult()
        {
            var initialRadius        = 1;
            var firstRadiusIncrease  = 2;
            var secondRadiusIncrease = 3;
            var sharedExpectedResult = new ReadOnlyCollection <Vector2>(
                new List <Vector2>()
            {
                new Vector2(0, 0),
                new Vector2(1, 0),
                new Vector2(1, 1),
                new Vector2(0, 1),
                new Vector2(-1, 1),
                new Vector2(-1, 0),
                new Vector2(-1, -1),
                new Vector2(0, -1),
                new Vector2(1, -1),
            }
                );

            var cachedSpiral = new Spiral(initialRadius);
            var initialRadiusActualResult        = cachedSpiral.GetCoords(initialRadius);
            var firstRadiusIncreaseActualResult  = cachedSpiral.GetCoords(firstRadiusIncrease);
            var secondRadiusIncreaseActualResult = cachedSpiral.GetCoords(secondRadiusIncrease);

            CollectionAssert.AreEqual(sharedExpectedResult, initialRadiusActualResult);
            CollectionAssert.AreEqual(sharedExpectedResult, firstRadiusIncreaseActualResult);
            CollectionAssert.AreEqual(sharedExpectedResult, secondRadiusIncreaseActualResult);
        }
Ejemplo n.º 2
0
        public void SpiralGetCoords_Once_Radius17_Precached()
        {
            var radius = 17;
            var coords = _cachedSpiral17.GetCoords(radius);

            for (int i = 0; i < coords.Count; i++)
            {
                var coord = coords[i];
            }
        }
Ejemplo n.º 3
0
        public void SpiralGetCoords_Once_Radius17_Precached()
        {
            var posX = 3621;
            var posY = 2342;
            var BUILDINGGRID_CELL_SIZE  = 64;
            var BUILDINGGRID_RESOLUTION = 270;

            var centerI = (int)((posX / BUILDINGGRID_CELL_SIZE) +
                                (BUILDINGGRID_RESOLUTION / 2f));
            var centerJ = (int)((posY / BUILDINGGRID_CELL_SIZE) +
                                (BUILDINGGRID_RESOLUTION / 2f));

            int radius = 17;

            ushort     ignoreParked   = 1;
            Vector3    refPos         = Vector3.back;
            float      width          = 5f;
            float      length         = 5f;
            bool       randomize      = true;
            ushort     foundSegmentId = 0;
            Vector3    myParkPos      = Vector3.back;
            Quaternion myParkRot      = Quaternion.identity;
            float      myParkOffset   = 10f;

            bool LoopHandler(int x, int y)
            {
                if (randomize)
                {
                    width = ignoreParked
                            + refPos.x
                            + length
                            + length
                            + foundSegmentId
                            + myParkPos.x
                            + myParkPos.x
                            + myParkRot.x
                            + myParkOffset;
                }

                return(true);
            }

            var loopCoords = _spiral17.GetCoords(17);

            for (int i = 0; i < radius * radius; i++)
            {
                var positionWithOffset = loopCoords[i] + new Vector2(centerI, centerJ);
                if (LoopHandler((int)positionWithOffset.x, (int)positionWithOffset.y))
                {
                    break;
                }
            }
        }
        public void Constructor_Radius1_Should_Generate1SpiralCoords()
        {
            var initialRadius             = 1;
            var expectedSpiralCoordsCount = initialRadius * initialRadius;

            var cachedSpiral = new Spiral(initialRadius);

            Assert.AreEqual(expectedSpiralCoordsCount, cachedSpiral.GetCoords(initialRadius).Count);
        }
        public void GetSpiralCoords_Should_IncreaseIfRadiusLargerInitialRadius()
        {
            var initialRadius             = 1;
            var newRadius                 = 5;
            var expectedSpiralCoordsCount = newRadius * newRadius;

            var cachedSpiral = new Spiral(initialRadius);

            Assert.AreEqual(expectedSpiralCoordsCount, cachedSpiral.GetCoords(newRadius).Count);
        }
Ejemplo n.º 6
0
        public void SpiralGetCoords_Once_Radius17()
        {
            var radius = 17;
            var spiral = new Spiral(radius);
            var coords = spiral.GetCoords(radius);

            for (int i = 0; i < coords.Count; i++)
            {
                var coord = coords[i];
            }
        }
Ejemplo n.º 7
0
        public void SpiralGetCoords_10Times_Radius17()
        {
            var radius = 17;
            var spiral = new Spiral(radius);

            for (int i = 0; i < 10; i++)
            {
                var coords = spiral.GetCoords(radius);
                for (int j = 0; j < coords.Count; j++)
                {
                    var coord = coords[j];
                }
            }
        }
Ejemplo n.º 8
0
        public bool FindPathPositionWithSpiralLoop(Vector3 position,
                                                   Vector3?secondaryPosition,
                                                   ItemClass.Service service,
                                                   NetInfo.LaneType laneType,
                                                   VehicleInfo.VehicleType vehicleType,
                                                   NetInfo.LaneType otherLaneType,
                                                   VehicleInfo.VehicleType otherVehicleType,
                                                   VehicleInfo.VehicleType stopType,
                                                   bool allowUnderground,
                                                   bool requireConnect,
                                                   float maxDistance,
                                                   out PathUnit.Position pathPosA,
                                                   out PathUnit.Position pathPosB,
                                                   out float distanceSqrA,
                                                   out float distanceSqrB)
        {
            int iMin = Mathf.Max(
                (int)(((position.z - NetManager.NODEGRID_CELL_SIZE) / NetManager.NODEGRID_CELL_SIZE) +
                      (NetManager.NODEGRID_RESOLUTION / 2f)),
                0);
            int iMax = Mathf.Min(
                (int)(((position.z + NetManager.NODEGRID_CELL_SIZE) / NetManager.NODEGRID_CELL_SIZE) +
                      (NetManager.NODEGRID_RESOLUTION / 2f)),
                NetManager.NODEGRID_RESOLUTION - 1);

            int jMin = Mathf.Max(
                (int)(((position.x - NetManager.NODEGRID_CELL_SIZE) / NetManager.NODEGRID_CELL_SIZE) +
                      (NetManager.NODEGRID_RESOLUTION / 2f)),
                0);
            int jMax = Mathf.Min(
                (int)(((position.x + NetManager.NODEGRID_CELL_SIZE) / NetManager.NODEGRID_CELL_SIZE) +
                      (NetManager.NODEGRID_RESOLUTION / 2f)),
                NetManager.NODEGRID_RESOLUTION - 1);

            int width  = iMax - iMin + 1;
            int height = jMax - jMin + 1;

            int centerI = (int)(position.z / NetManager.NODEGRID_CELL_SIZE +
                                NetManager.NODEGRID_RESOLUTION / 2f);
            int centerJ = (int)(position.x / NetManager.NODEGRID_CELL_SIZE +
                                NetManager.NODEGRID_RESOLUTION / 2f);

            int radius = Math.Max(1, (int)(maxDistance / (BuildingManager.BUILDINGGRID_CELL_SIZE / 2f)) + 1);

            NetManager netManager = Singleton <NetManager> .instance;

            /*pathPosA.m_segment = 0;
             * pathPosA.m_lane = 0;
             * pathPosA.m_offset = 0;*/
            distanceSqrA = 1E+10f;

            /*pathPosB.m_segment = 0;
             * pathPosB.m_lane = 0;
             * pathPosB.m_offset = 0;*/
            distanceSqrB = 1E+10f;
            float minDist = float.MaxValue;

            PathUnit.Position myPathPosA     = default;
            float             myDistanceSqrA = float.MaxValue;

            PathUnit.Position myPathPosB     = default;
            float             myDistanceSqrB = float.MaxValue;

            int  lastSpiralDist = 0;
            bool found          = false;

            bool FindHelper(int i, int j)
            {
                if (i < 0 || i >= NetManager.NODEGRID_RESOLUTION ||
                    j < 0 || j >= NetManager.NODEGRID_RESOLUTION)
                {
                    return(true);
                }

                int spiralDist = Math.Max(Math.Abs(i - centerI), Math.Abs(j - centerJ)); // maximum norm

                if (found && spiralDist > lastSpiralDist)
                {
                    // last iteration
                    return(false);
                }

                ushort segmentId  = netManager.m_segmentGrid[i * NetManager.NODEGRID_RESOLUTION + j];
                int    iterations = 0;

                while (segmentId != 0)
                {
                    NetInfo segmentInfo = netManager.m_segments.m_buffer[segmentId].Info;

                    if (segmentInfo != null && segmentInfo.m_class.m_service == service &&
                        (netManager.m_segments.m_buffer[segmentId].m_flags &
                         (NetSegment.Flags.Collapsed | NetSegment.Flags.Flooded)) ==
                        NetSegment.Flags.None &&
                        (allowUnderground || !segmentInfo.m_netAI.IsUnderground()))
                    {
                        bool otherPassed = true;
                        if (otherLaneType != NetInfo.LaneType.None ||
                            otherVehicleType != VehicleInfo.VehicleType.None)
                        {
                            // check if any lane is present that matches the given conditions
                            otherPassed = false;
                            Constants.ServiceFactory.NetService.IterateSegmentLanes(
                                segmentId,
                                (uint laneId,
                                 ref NetLane lane,
                                 NetInfo.Lane laneInfo,
                                 ushort segtId,
                                 ref NetSegment segment,
                                 byte laneIndex) => {
                                if ((otherLaneType == NetInfo.LaneType.None ||
                                     (laneInfo.m_laneType & otherLaneType) !=
                                     NetInfo.LaneType.None) &&
                                    (otherVehicleType ==
                                     VehicleInfo.VehicleType.None ||
                                     (laneInfo.m_vehicleType & otherVehicleType) !=
                                     VehicleInfo.VehicleType.None))
                                {
                                    otherPassed = true;
                                    return(false);
                                }

                                return(true);
                            });
                        }

                        if (otherPassed)
                        {
                            if (netManager.m_segments.m_buffer[segmentId].GetClosestLanePosition(
                                    position,
                                    laneType,
                                    vehicleType,
                                    stopType,
                                    requireConnect,
                                    out Vector3 posA,
                                    out int laneIndexA,
                                    out float laneOffsetA,
                                    out Vector3 posB,
                                    out int laneIndexB,
                                    out float laneOffsetB))
                            {
                                float dist = Vector3.SqrMagnitude(position - posA);
                                if (secondaryPosition != null)
                                {
                                    dist += Vector3.SqrMagnitude((Vector3)secondaryPosition - posA);
                                }

                                if (dist < minDist)
                                {
                                    found = true;

                                    minDist = dist;
                                    myPathPosA.m_segment = segmentId;
                                    myPathPosA.m_lane    = (byte)laneIndexA;
                                    myPathPosA.m_offset  = (byte)Mathf.Clamp(
                                        Mathf.RoundToInt(laneOffsetA * 255f),
                                        0,
                                        255);
                                    myDistanceSqrA = dist;

                                    dist = Vector3.SqrMagnitude(position - posB);
                                    if (secondaryPosition != null)
                                    {
                                        dist += Vector3.SqrMagnitude(
                                            (Vector3)secondaryPosition - posB);
                                    }

                                    if (laneIndexB < 0)
                                    {
                                        myPathPosB.m_segment = 0;
                                        myPathPosB.m_lane    = 0;
                                        myPathPosB.m_offset  = 0;
                                        myDistanceSqrB       = float.MaxValue;
                                    }
                                    else
                                    {
                                        myPathPosB.m_segment = segmentId;
                                        myPathPosB.m_lane    = (byte)laneIndexB;
                                        myPathPosB.m_offset  = (byte)Mathf.Clamp(
                                            Mathf.RoundToInt(laneOffsetB * 255f),
                                            0,
                                            255);
                                        myDistanceSqrB = dist;
                                    }
                                }
                            } // if GetClosestLanePosition
                        }     // if othersPassed
                    }         // if

                    segmentId = netManager.m_segments.m_buffer[segmentId].m_nextGridSegment;
                    if (++iterations >= NetManager.MAX_SEGMENT_COUNT)
                    {
                        CODebugBase <LogChannel> .Error(
                            LogChannel.Core,
                            "Invalid list detected!\n" + Environment.StackTrace);

                        break;
                    }
                }

                lastSpiralDist = spiralDist;
                return(true);
            }

            var coords = _spiral.GetCoords(radius);

            for (int i = 0; i < radius * radius; i++)
            {
                if (!FindHelper((int)(centerI + coords[i].x), (int)(centerJ + coords[i].y)))
                {
                    break;
                }
            }

            pathPosA     = myPathPosA;
            distanceSqrA = myDistanceSqrA;
            pathPosB     = myPathPosB;
            distanceSqrB = myDistanceSqrB;

            return(pathPosA.m_segment != 0);
        }
        public void GetSpiralCoords_RadiusOutOfRange_Should_ThrowException()
        {
            var spiral = new Spiral(1);

            spiral.GetCoords(-1);
        }