// 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); } }
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)); } } } } }
public override void AddPoint(Vector2Int p, float z) { base.AddPoint(p, z); m_AuxGrid.Write(0, p, z); }
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)); } } } } }
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)); } } } }
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. }