示例#1
0
        /// <inheritdoc/>
        public override void Initialize(GridBuffer buffer)
        {
            base.Initialize(buffer);

            // Helper GridBuffer, channels:
            // 0 - proximity lookup
            // 1 - kernel value (max, dilated area)
            // 2 - buffer value (max, dilated area)
            m_AuxGrid = new GridBuffer(3, buffer.Width, buffer.Height);
            m_Kernels = new List <Point> [c_MaxRadius];

            for (int radius = 1; radius <= c_MaxRadius; radius++)
            {
                int i = radius - 1;
                m_Kernels[i] = new List <Point>(radius * radius * 4); // TBD

                for (int x = -radius; x <= radius; x++)
                {
                    for (int y = -radius; y <= radius; y++)
                    {
                        float value = 1 - new Vector2(x, y).magnitude / radius;

                        if (value > 0)
                        {
                            m_Kernels[i].Add(new Point
                            {
                                x     = x,
                                y     = y,
                                value = value
                            });
                        }
                    }
                }
            }
        }
示例#2
0
 /// <summary>
 /// Writes additional value to stored grid positions,
 /// using either the originally added positions
 /// or the positions calculated in <see cref="Process"/>.
 /// </summary>
 /// <param name="buffer"><see cref="GridBuffer"/> used by the sensor</param>
 /// <param name="channel">Grid channel index</param>
 /// <param name="value">The value to write</param>
 public virtual void Write(GridBuffer buffer, int channel, float value)
 {
     foreach (Vector2Int pos in GridPositions)
     {
         buffer.Write(channel, pos, value);
     }
 }
        /// <inheritdoc/>
        public override void Initialize(GridBuffer buffer)
        {
            base.Initialize(buffer);

            m_Samples = new float[
                Mathf.CeilToInt(buffer.Width / 2f),
                Mathf.CeilToInt(buffer.Height / 2f)];
        }
示例#4
0
        /// <inheritdoc/>
        public override void Process(GridBuffer buffer, int channel)
        {
            // Side length of squares around points required for filling
            // Width x Height, IF positions were distributed evenly.
            float sparseness = Mathf.Sqrt(Width * Height / (float)GridPositions.Count);

            if (sparseness > 1)
            {
                sparseness *= c_Multiplier;

                foreach (Vector2Int pGrid in GridPositions)
                {
                    int xGrid = pGrid.x;
                    int yGrid = pGrid.y;

                    float proximity = m_AuxGrid.Read(0, xGrid, yGrid);
                    // Get matching kernel size for current proximity and point sparseness.
                    var kernel = m_Kernels[Mathf.Min(Mathf.RoundToInt(sparseness * proximity), c_MaxRadius - 1)];

                    float bufferValue = buffer.Read(channel, xGrid, yGrid);

                    foreach (var pKernel in kernel)
                    {
                        int xDilate = xGrid + pKernel.x;
                        int yDilate = yGrid + pKernel.y;

                        // TryRead -> Dilation area might go beyond grid size.
                        if (m_AuxGrid.TryRead(1, xDilate, yDilate, out float kernelValue))
                        {
                            // Occlusion, 3D specific:
                            // Write maximum kernel value if already set.
                            m_AuxGrid.Write(1, xDilate, yDilate, Mathf.Max(pKernel.value, kernelValue));
                            // Write maximum buffer value if already set.
                            m_AuxGrid.Write(2, xDilate, yDilate, Mathf.Max(m_AuxGrid.Read(2, xDilate, yDilate), bufferValue));
                            Expand(xDilate, yDilate);
                        }
                    }
                }

                // Expanded area.
                for (int x = m_xMin; x <= m_xMax; x++)
                {
                    for (int y = m_yMin; y <= m_yMax; y++)
                    {
                        if (m_AuxGrid.Read(1, x, y) > c_Threshold)
                        {
                            // Copy back dilated buffer values.
                            buffer.Write(channel, x, y, m_AuxGrid.Read(2, x, y));
                            // Store for later Write(buffer, channel, value) call.
                            GridPositions.Add(new Vector2Int(x, y));
                        }
                    }
                }
            }
            // else: keep original positions, they're dense enough.
        }
示例#5
0
        /// <summary>
        /// Enables drawer.
        /// </summary>
        /// <param name="channelData"><see cref="DebugChannelData"/> instance</param>
        /// <param name="buffer"><see cref="GridBuffer"/> instance</param>
        public void Enable(MonoBehaviour context, DebugChannelData channelData, GridBuffer buffer)
        {
            ChannelData   = channelData;
            Buffer        = buffer;
            GridSizeRatio = buffer.Height / (float)buffer.Width;

            Context = context;
            m_RepaintOnFirstUpdate = true;
            m_StopRepaintCoroutine ??= StopRepaintCoroutine();

            IsEnabled = true;
            IsStandby = false;
        }
示例#6
0
        /// <summary>
        /// Creates a <see cref="GridSensor"/> instance.
        /// </summary>
        /// <param name="buffer">The <see cref="GridBuffer"/> instance to wrap</param>
        /// <param name="compressionType">The <see cref="SensorCompressionType"/>
        /// to apply to the generated image</param>
        /// <param name="observationType">The <see cref="ObservationType"/>
        /// (default or goal signal) of the sensor</param>
        /// <param name="name">Name of the sensor</param>
        public GridSensor(
            string name,
            GridBuffer buffer,
            SensorCompressionType compressionType,
            ObservationType observationType)
        {
            m_Name = name;

            buffer.GetShape().Validate();
            m_GridBuffer = buffer;

            m_CompressionType = compressionType;
            HandleCompressionType();

            m_ObservationSpec = ObservationSpec.Visual(
                m_GridBuffer.Height, m_GridBuffer.Width, m_GridBuffer.NumChannels, observationType);
        }
示例#7
0
        /// <summary>
        /// <see cref="PointModifier"/> factory.
        /// </summary>
        /// <param name="settings"><see cref="IEncodingSettings"/></param>
        /// <param name="buffer"><see cref="GridBuffer"/> used by the sensor</param>
        /// <returns>Dictionary of <see cref="PointModifiers"/>s by tag</returns>
        public static IDictionary <string, PointModifier> CreateModifiers(
            IEncodingSettings settings, GridBuffer buffer)
        {
            var modifiers = new Dictionary <string, PointModifier>();

            foreach (string tag in settings.DetectableTags)
            {
                PointModifier modifier = settings.GetPointModifierType(tag) switch
                {
                    PointModifierType.Dilation => new PointModDilation(),
                    PointModifierType.Downsampling => new PointModDownsampling(),
                    PointModifierType.OrthogonalFill => new PointModOrthogonalFill(),
                    PointModifierType.DiagonalFill => new PointModDiagonalFill(),
                    _ => new PointModNone(),
                };
                modifier.Initialize(buffer);
                modifiers.Add(tag, modifier);
            }

            return(modifiers);
        }
示例#8
0
        /// <inheritdoc/>
        public override void Process(GridBuffer buffer, int channel)
        {
            int xCenter = (m_xMin + m_xMax) / 2;
            int yCenter = (m_yMin + m_yMax) / 2;

            float tmpValue = 0;

            for (int x = m_xMin; x <= xCenter; x++)
            {
                int xLeft = Mathf.Max(m_xMin, x - 1);

                for (int y = m_yMin; y <= yCenter; y++)
                {
                    float bufferValue = buffer.Read(channel, x, y);

                    if (bufferValue == 0)
                    {
                        int yTop = Mathf.Max(m_yMin, y - 1);

                        bufferValue = Mathf.Max(
                            buffer.Read(channel, xLeft, y),
                            buffer.Read(channel, x, yTop),
                            buffer.Read(channel, xLeft, yTop));

                        if (bufferValue > 0)
                        {
                            buffer.Write(channel, x, y, bufferValue);
                            tmpValue = bufferValue;
                            // Store for later Write(buffer, channel, value) call.
                            GridPositions.Add(new Vector2Int(x, y));
                        }
                    }
                    else
                    {
                        // Occlusion, 3D specific:
                        // Write maximum buffer value if already set.
                        buffer.Write(channel, x, y, Mathf.Max(tmpValue, bufferValue));
                    }
                }
            }

            tmpValue = 0;

            for (int x = m_xMax; x > xCenter; x--)
            {
                int xRight = Mathf.Min(m_xMax, x + 1);

                for (int y = m_yMin; y <= yCenter; y++)
                {
                    float bufferValue = buffer.Read(channel, x, y);

                    if (bufferValue == 0)
                    {
                        int yTop = Mathf.Max(m_yMin, y - 1);

                        bufferValue = Mathf.Max(
                            buffer.Read(channel, xRight, y),
                            buffer.Read(channel, x, yTop),
                            buffer.Read(channel, xRight, yTop));

                        if (bufferValue > 0)
                        {
                            buffer.Write(channel, x, y, bufferValue);
                            tmpValue = bufferValue;
                            // Store for later Write(buffer, channel, value) call.
                            GridPositions.Add(new Vector2Int(x, y));
                        }
                    }
                    else
                    {
                        // Occlusion, 3D specific:
                        // Write maximum buffer value if already set.
                        buffer.Write(channel, x, y, Mathf.Max(tmpValue, bufferValue));
                    }
                }
            }

            tmpValue = 0;

            for (int x = m_xMin; x <= xCenter; x++)
            {
                int xLeft = Mathf.Max(m_xMin, x - 1);

                for (int y = m_yMax; y > yCenter; y--)
                {
                    float bufferValue = buffer.Read(channel, x, y);

                    if (bufferValue == 0)
                    {
                        int yBottom = Mathf.Min(m_yMax, y + 1);

                        bufferValue = Mathf.Max(
                            buffer.Read(channel, xLeft, y),
                            buffer.Read(channel, x, yBottom),
                            buffer.Read(channel, xLeft, yBottom));

                        if (bufferValue > 0)
                        {
                            buffer.Write(channel, x, y, bufferValue);
                            tmpValue = bufferValue;
                            // Store for later Write(buffer, channel, value) call.
                            GridPositions.Add(new Vector2Int(x, y));
                        }
                    }
                    else
                    {
                        // Occlusion, 3D specific:
                        // Write maximum buffer value if already set.
                        buffer.Write(channel, x, y, Mathf.Max(tmpValue, bufferValue));
                    }
                }
            }

            tmpValue = 0;

            for (int x = m_xMax; x > xCenter; x--)
            {
                int xRight = Mathf.Min(m_xMax, x + 1);

                for (int y = m_yMax; y > yCenter; y--)
                {
                    float bufferValue = buffer.Read(channel, x, y);

                    if (bufferValue == 0)
                    {
                        int yBottom = Mathf.Min(m_yMax, y + 1);

                        bufferValue = Mathf.Max(
                            buffer.Read(channel, xRight, y),
                            buffer.Read(channel, x, yBottom),
                            buffer.Read(channel, xRight, yBottom));

                        if (bufferValue > 0)
                        {
                            buffer.Write(channel, x, y, bufferValue);
                            tmpValue = bufferValue;
                            // Store for later Write(buffer, channel, value) call.
                            GridPositions.Add(new Vector2Int(x, y));
                        }
                    }
                    else
                    {
                        // Occlusion, 3D specific:
                        // Write maximum buffer value if already set.
                        buffer.Write(channel, x, y, Mathf.Max(tmpValue, bufferValue));
                    }
                }
            }
        }
示例#9
0
 /// <summary>
 /// Initializes the <see cref="PointModifier"/>.
 /// </summary>
 /// <param name="buffer"><see cref="GridBuffer"/> used by the sensor</param>
 public virtual void Initialize(GridBuffer buffer)
 {
     // TODO Capacity? https://stackoverflow.com/a/23071206
     GridPositions = new HashSet <Vector2Int>();
 }
示例#10
0
 /// <summary>
 /// Processes a specific channel of the <see cref="GridBuffer"/>.
 /// </summary>
 /// <param name="buffer"><see cref="GridBuffer"/> used by the sensor</param>
 /// <param name="channel">Grid channel index</param>
 public virtual void Process(GridBuffer buffer, int channel)
 {
 }
示例#11
0
        /// <inheritdoc/>
        public override void Process(GridBuffer buffer, int channel)
        {
            // Side length of squares around points required for filling
            // Width x Height, IF positions were distributed evenly.
            float sparseness = Mathf.Sqrt(Width * Height / (float)GridPositions.Count);

            if (sparseness > 1)
            {
                // Make downsample area a bit larger than
                // sparseness value in order to prevent gaps.
                int size = Mathf.RoundToInt(sparseness) + 2; // TBD pad

                // Bottom/left offset.
                int xOffset = m_xMin - (size - Width % size) / 2;
                int yOffset = m_yMin - (size - Height % size) / 2;

                int nx = 0, ny = 0;
                foreach (Vector2Int point in GridPositions)
                {
                    // Downsampling: grid pos -> sample pos.
                    int xSample = (point.x - xOffset) / size;
                    int ySample = (point.y - yOffset) / size;

                    nx = Mathf.Max(nx, xSample);
                    ny = Mathf.Max(ny, ySample);

                    m_Samples[xSample, ySample] = Mathf.Max(
                        m_Samples[xSample, ySample], buffer.Read(channel, point));
                }

                // Replace grid points with squares (size x size).
                GridPositions.Clear();

                for (int xSample = 0; xSample <= nx; xSample++)
                {
                    for (int ySample = 0; ySample <= ny; ySample++)
                    {
                        float sampleValue = m_Samples[xSample, ySample];

                        if (sampleValue > 0)
                        {
                            // Upscaling: sample pos -> grid pos.
                            int xGrid = xOffset + xSample * size;
                            int yGrid = yOffset + ySample * size;

                            for (int x = 0; x < size; x++)
                            {
                                for (int y = 0; y < size; y++)
                                {
                                    Vector2Int gridPos = new Vector2Int(xGrid + x, yGrid + y);
                                    // TryRead -> Square might go beyond grid size.
                                    if (buffer.TryRead(channel, gridPos, out float bufferValue))
                                    {
                                        // Occlusion, 3D specific:
                                        // Write maximum buffer value if already set.
                                        buffer.Write(channel, gridPos, Mathf.Max(bufferValue, sampleValue));
                                        // Store for later Write(buffer, channel, value) call.
                                        GridPositions.Add(gridPos);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            // else: keep original positions, they're dense enough.
        }