public override void Place(TrackSegment segment, int[,] spots)
        {
            base.Place(segment, spots);

            PlacerSpot spot = new PlacerSpot();              //be gentle with the stack, allocate only once

            //iterate on each row
            for (int i = 0; i < TrackSegment.LENGTH; i++)
            {
                //get curent deviation
                int shift = stretch.Get();

                //mark and add assets along path's width
                for (int j = 0; j < thickness; j++)
                {
                    spot.x = column + shift + j;
                    spot.y = i;

                    Mark(spot);
                    AddAsset(spot);
                }

                //increment stretch and start a new one if needed
                if (!stretch.Advance())
                {
                    //save column for the next stretch
                    column += shift;
                    StartStretch();
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Scans segment's occupancy matrix and fills the areas list according to placer values.
        /// </summary>
        private void MapAreas()
        {
            PlacerSpot spot = new PlacerSpot();              //be gentle with the stack, allocate only once

            for (int i = 0; i <= TrackSegment.WIDTH - size; i++)
            {
                for (int j = 0; j <= TrackSegment.LENGTH - size; j++)
                {
                    spot.x = i;
                    spot.y = j;

                    float fill = PlacerArea.GetSpotRatio(PlacerSpot.Type.Empty, spots, spot, size);

                    if (!allowIntertwined && !Mathf.Approximately(fill, 1f))
                    {
                        continue;
                    }

                    if (fill >= targetFillRatio)
                    {
                        areas.Add(new PlacerArea(spots, spot, size));
                    }
                }
            }
        }
        /// <summary>
        /// Scans the surface of a segment's occupancy matrix for a specific spot type and computes it's ratio.
        /// </summary>
        /// <param name="type">Value to search for.</param>
        /// <param name="spots">Ref to occupancy matrix.</param>
        /// <param name="pivot">Start of area.</param>
        /// <param name="size">Extents of area.</param>
        /// <returns>A value between [0f, 1f].</returns>
        public static float GetSpotRatio(PlacerSpot.Type type, int[,] spots, PlacerSpot pivot, int size)
        {
            int count = 0;

            for (int i = 0; i < size; i++)
            {
                for (int j = 0; j < size; j++)
                {
                    if (spots[pivot.x + i, pivot.y + j] == (int)type)
                    {
                        count++;
                    }
                }
            }

            return((float)count / (size * size));
        }
Exemple #4
0
        /// <summary>
        /// Instatiates a clone of the asset and positions it in segment's space, applying the offsets.
        /// </summary>
        /// <param name="spot">Matrix coordinates.</param>
        protected void AddAsset(PlacerSpot spot)
        {
            //determine offsets
            Vector3 posOffset = new Vector3(
                Random.Range(-positionsRange.x, positionsRange.x),
                Random.Range(-positionsRange.y, positionsRange.y),
                Random.Range(-positionsRange.z, positionsRange.z)
                );

            Vector3 rotOffset = new Vector3(
                Random.Range(-rotationsRange.x, rotationsRange.x),
                Random.Range(-rotationsRange.y, rotationsRange.y),
                Random.Range(-rotationsRange.z, rotationsRange.z)
                );

            //create and place clone
            Instantiate(asset, segment.GetSpotPos(spot.x, spot.y) + posOffset, Quaternion.Euler(rotOffset), segment.transform);
        }
        /// <summary>
        /// Returns all the spots of a certain type from a specified area.
        /// </summary>
        /// <param name="type">Value to search for.</param>
        /// <param name="spots">Ref to occupancy matrix.</param>
        /// <param name="pivot">Start of area.</param>
        /// <param name="size">Extents of area.</param>
        /// <param name="output">List to add the spots to.</param>
        public static void GetSpots(PlacerSpot.Type type, int[,] spots, PlacerSpot pivot, int size, List <PlacerSpot> output)
        {
            PlacerSpot spot = new PlacerSpot();              //be gentle with the stack, allocate only once

            for (int i = 0; i < size; i++)
            {
                for (int j = 0; j < size; j++)
                {
                    spot.x = pivot.x + i;
                    spot.y = pivot.y + j;

                    if (spots[spot.x, spot.y] == (int)type)
                    {
                        output.Add(spot);
                    }
                }
            }
        }
Exemple #6
0
        public override void Place(TrackSegment segment, int[,] spots)
        {
            base.Place(segment, spots);

            MapAreas();             //build list

            if (areas.Count == 0)   //nothing to do, exit
            {
                return;
            }

            //determine actual possible pathes count - not all may fit
            int count = (areas.Count < targetCount)? areas.Count : targetCount;

            //place patches towards the target count
            for (int i = 0; i < count && areas.Count > 0; i++)
            {
                //choose area
                PlacerArea area = areas[Random.Range(0, areas.Count)];
                //builds free spots list
                area.GetSpots(PlacerSpot.Type.Empty, free);

                //choose from free spots and place assets
                for (int j = 0; j < assetsPerPatch; j++)
                {
                    int        index = Random.Range(0, free.Count);
                    PlacerSpot spot  = free[index];

                    Mark(spot);
                    AddAsset(spot);

                    free.RemoveAt(index);
                }

                //prepare for next patch
                free.Clear();
                areas.RemoveAll(item => area.Overlaps(item) && (!allowIntertwined || allowIntertwined && item.GetSpotRatio(PlacerSpot.Type.Empty) < targetFillRatio));
            }

            //cleanup
            areas.Clear();
        }
Exemple #7
0
 /// <summary>
 /// Set mark value in occupation matrix.
 /// </summary>
 /// <param name="spot">Matrix coordinates.</param>
 protected void Mark(PlacerSpot spot)
 {
     spots[spot.x, spot.y] = (int)mark;
 }
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="spots">Ref to occupancy matrix.</param>
 /// <param name="pivot">Start of area.</param>
 /// <param name="size">Extents of area.</param>
 public PlacerArea(int[,] spots, PlacerSpot pivot, int size)
 {
     this.spots = spots;
     this.pivot = pivot;
     this.size  = size;
 }