예제 #1
0
        // Write additional observations besides distance (3D) or first
        // observation (2D), using either the originally added points or
        // the points calculated in Process().

        public virtual void Write(ChannelGrid grid, int channel, float value)
        {
            foreach (Vector2Int p in m_UniqueGridPoints)
            {
                grid.Write(channel, p, value);
            }
        }
예제 #2
0
        public override void Process(ChannelGrid grid, int channel)
        {
            float s = Mathf.Sqrt(Width * Height / (float)m_UniqueGridPoints.Count);

            if (s > 1)
            {
                s *= c_SizeMult;

                foreach (Vector2Int p in m_UniqueGridPoints)
                {
                    int   gx     = p.x;
                    int   gy     = p.y;
                    float v      = grid.Read(channel, gx, gy);
                    float invZ   = 1 - m_AuxGrid.Read(0, gx, gy);
                    var   kernel = m_Kernels[Mathf.Min(Mathf.RoundToInt(s * invZ), c_MaxRadius - 1)];

                    for (int i = 0, n = kernel.Count; i < n; i++)
                    {
                        int x = gx + kernel[i].x;
                        int y = gy + kernel[i].y;

                        if (m_AuxGrid.TryRead(1, x, y, out float k))
                        {
                            m_AuxGrid.Write(1, x, y, Mathf.Max(kernel[i].value, k));
                            m_AuxGrid.Write(2, x, y, Mathf.Max(m_AuxGrid.Read(2, x, y), v));
                            Expand(x, y);
                        }
                    }
                }

                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)
                        {
                            grid.Write(channel, x, y, m_AuxGrid.Read(2, x, y));
                            m_UniqueGridPoints.Add(new Vector2Int(x, y));
                        }
                    }
                }
            }
        }
예제 #3
0
 public override void AddPoint(Vector2Int p, float z)
 {
     base.AddPoint(p, z);
     m_AuxGrid.Write(0, p, z);
 }
예제 #4
0
        public override void Process(ChannelGrid grid, int channel)
        {
            if (Width > Height)
            {
                int   cx    = (m_xMin + m_xMax) / 2;
                float value = 0;

                for (int x = m_xMin + 1; x <= cx; x++)
                {
                    for (int y = m_yMin; y <= m_yMax; y++)
                    {
                        float v = grid.Read(channel, x, y);

                        if (v == 0)
                        {
                            int xp = x - 1;
                            v = grid.Read(channel, xp, y);

                            if (y > m_yMin)
                            {
                                v = Mathf.Max(v, grid.Read(channel, xp, y - 1));
                            }
                            if (y < m_yMax)
                            {
                                v = Mathf.Max(v, grid.Read(channel, xp, y + 1));
                            }

                            if (v > 0)
                            {
                                grid.Write(channel, x, y, v);
                                m_UniqueGridPoints.Add(new Vector2Int(x, y));
                                value = v;
                            }
                        }
                        else
                        {
                            grid.Write(channel, x, y, Mathf.Max(value, v));
                        }
                    }
                }

                value = 0;

                for (int x = m_xMax - 1; x > cx; x--)
                {
                    for (int y = m_yMin; y <= m_yMax; y++)
                    {
                        float v = grid.Read(channel, x, y);

                        if (v == 0)
                        {
                            int xp = x + 1;
                            v = grid.Read(channel, xp, y);

                            if (y > m_yMin)
                            {
                                v = Mathf.Max(v, grid.Read(channel, xp, y - 1));
                            }
                            if (y < m_yMax)
                            {
                                v = Mathf.Max(v, grid.Read(channel, xp, y + 1));
                            }

                            if (v > 0)
                            {
                                grid.Write(channel, x, y, v);
                                m_UniqueGridPoints.Add(new Vector2Int(x, y));
                                value = v;
                            }
                        }
                        else
                        {
                            grid.Write(channel, x, y, Mathf.Max(value, v));
                        }
                    }
                }
            }
            else
            {
                int   cy    = (m_yMin + m_yMax) / 2;
                float value = 0;

                for (int y = m_yMin + 1; y <= cy; y++)
                {
                    for (int x = m_xMin; x <= m_xMax; x++)
                    {
                        float v = grid.Read(channel, x, y);

                        if (v == 0)
                        {
                            int yp = y - 1;
                            v = grid.Read(channel, x, yp);

                            if (x > m_xMin)
                            {
                                v = Mathf.Max(v, grid.Read(channel, x - 1, yp));
                            }
                            if (x < m_xMax)
                            {
                                v = Mathf.Max(v, grid.Read(channel, x + 1, yp));
                            }

                            if (v > 0)
                            {
                                grid.Write(channel, x, y, v);
                                m_UniqueGridPoints.Add(new Vector2Int(x, y));
                                value = v;
                            }
                        }
                        else
                        {
                            grid.Write(channel, x, y, Mathf.Max(value, v));
                        }
                    }
                }

                value = 0;

                for (int y = m_yMax - 1; y > cy; y--)
                {
                    for (int x = m_xMin; x <= m_xMax; x++)
                    {
                        float v = grid.Read(channel, x, y);

                        if (v == 0)
                        {
                            int yp = y + 1;
                            v = grid.Read(channel, x, yp);

                            if (x > m_xMin)
                            {
                                v = Mathf.Max(v, grid.Read(channel, x - 1, yp));
                            }
                            if (x < m_xMax)
                            {
                                v = Mathf.Max(v, grid.Read(channel, x + 1, yp));
                            }

                            if (v > 0)
                            {
                                grid.Write(channel, x, y, v);
                                m_UniqueGridPoints.Add(new Vector2Int(x, y));
                                value = v;
                            }
                        }
                        else
                        {
                            grid.Write(channel, x, y, Mathf.Max(value, v));
                        }
                    }
                }
            }
        }
예제 #5
0
        public override void Process(ChannelGrid grid, int channel)
        {
            int cx = (m_xMin + m_xMax) / 2;
            int cy = (m_yMin + m_yMax) / 2;

            float value = 0;

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

                for (int y = m_yMin; y <= cy; y++)
                {
                    float v = grid.Read(channel, x, y);

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

                        v = Mathf.Max(
                            grid.Read(channel, xp, y),
                            grid.Read(channel, x, yp),
                            grid.Read(channel, xp, yp));

                        if (v > 0)
                        {
                            grid.Write(channel, x, y, v);
                            m_UniqueGridPoints.Add(new Vector2Int(x, y));
                            value = v;
                        }
                    }
                    else
                    {
                        grid.Write(channel, x, y, Mathf.Max(value, v));
                    }
                }
            }

            value = 0;

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

                for (int y = m_yMin; y <= cy; y++)
                {
                    float v = grid.Read(channel, x, y);

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

                        v = Mathf.Max(
                            grid.Read(channel, xp, y),
                            grid.Read(channel, x, yp),
                            grid.Read(channel, xp, yp));

                        if (v > 0)
                        {
                            grid.Write(channel, x, y, v);
                            m_UniqueGridPoints.Add(new Vector2Int(x, y));
                            value = v;
                        }
                    }
                    else
                    {
                        grid.Write(channel, x, y, Mathf.Max(value, v));
                    }
                }
            }

            value = 0;

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

                for (int y = m_yMax; y > cy; y--)
                {
                    float v = grid.Read(channel, x, y);

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

                        v = Mathf.Max(
                            grid.Read(channel, xp, y),
                            grid.Read(channel, x, yp),
                            grid.Read(channel, xp, yp));

                        if (v > 0)
                        {
                            grid.Write(channel, x, y, v);
                            m_UniqueGridPoints.Add(new Vector2Int(x, y));
                            value = v;
                        }
                    }
                    else
                    {
                        grid.Write(channel, x, y, Mathf.Max(value, v));
                    }
                }
            }

            value = 0;

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

                for (int y = m_yMax; y > cy; y--)
                {
                    float v = grid.Read(channel, x, y);

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

                        v = Mathf.Max(
                            grid.Read(channel, xp, y),
                            grid.Read(channel, x, yp),
                            grid.Read(channel, xp, yp));

                        if (v > 0)
                        {
                            grid.Write(channel, x, y, v);
                            m_UniqueGridPoints.Add(new Vector2Int(x, y));
                            value = v;
                        }
                    }
                    else
                    {
                        grid.Write(channel, x, y, Mathf.Max(value, v));
                    }
                }
            }
        }
예제 #6
0
        public override void Process(ChannelGrid grid, int channel)
        {
            // Side length of squares around points required for filling w * h,
            // *if* points were distributed evenly. We're adding some value
            // to this below for preventing gaps.
            int   w = Width;
            int   h = Height;
            float s = Mathf.Sqrt(w * h / (float)m_UniqueGridPoints.Count);

            if (s > 1)
            {
                int size = Mathf.RoundToInt(s) + 2; // TBD add. value

                // Bottom/left offset (padding).
                int xPad = m_xMin - (size - w % size) / 2;
                int yPad = m_yMin - (size - h % size) / 2;

                int nx = 0, ny = 0;
                foreach (Vector2Int p in m_UniqueGridPoints)
                {
                    int sx = (p.x - xPad) / size;
                    int sy = (p.y - yPad) / size;
                    nx = Mathf.Max(nx, sx);
                    ny = Mathf.Max(ny, sy);
                    // For 3D, we sample the max (closest) value.
                    // For 2D, point values are identical anyway.
                    m_Samples[sx, sy] = Mathf.Max(m_Samples[sx, sy], grid.Read(channel, p));
                }

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

                for (int sx = 0; sx <= nx; sx++)
                {
                    for (int sy = 0; sy <= ny; sy++)
                    {
                        float value = m_Samples[sx, sy];

                        if (value > 0)
                        {
                            int gx = xPad + sx * size;
                            int gy = yPad + sy * size;

                            for (int x = 0; x < size; x++)
                            {
                                for (int y = 0; y < size; y++)
                                {
                                    Vector2Int p = new Vector2Int(gx + x, gy + y);
                                    if (grid.TryRead(channel, p, out float prev))
                                    {
                                        // 3D: storing max value for distance channel (closest).
                                        // TODO
                                        // 2D: neighbouring down-sampled areas might overlap and
                                        // their max value isn't necessarily what we want to observe?
                                        grid.Write(channel, p, Mathf.Max(prev, value));
                                        m_UniqueGridPoints.Add(p);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            // else: keep original points.
        }