Ejemplo n.º 1
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));
                        }
                    }
                }
            }
        }
Ejemplo n.º 2
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.
        }