private void SetTerrainValue(float x, float y, bool add) { float vsize2 = m_voxelSize * 2.0f; Vector2 from = new Vector2(x - radius - vsize2, y - radius - vsize2); Vector2 to = new Vector2(x + radius + vsize2, y + radius + vsize2); Vector2 center = new Vector2(x, y); int maxWidth = Mathf.CeilToInt((to.x - from.x) / m_voxelSize); int maxHeight = Mathf.CeilToInt((to.y - from.y) / m_voxelSize); int firstX = Mathf.RoundToInt(from.x / m_voxelSize); int firstY = Mathf.RoundToInt(from.y / m_voxelSize); for (int j = 0; j < maxHeight; j++) { int currY = firstY + j; if (currY < m_min.y) { continue; } if (currY >= m_max.y) { break; } for (int i = 0; i < maxWidth; i++) { int currX = firstX + i; if (currX < m_min.x) { continue; } if (currX >= m_max.x) { break; } float px = currX * m_voxelSize; float py = currY * m_voxelSize; Vector2 p = new Vector2(px, py); float d = (p - center).magnitude; if (add) { if (d <= radius) { VoxelData existing = read(currX, currY); VoxelData val = default(VoxelData); val.SetSolidState(true); if (d < radius - m_voxelSize) { val.SetExtentHorizontal(15, 15); val.SetExtentVertical(15, 15); } else { Vector2 up = default(Vector2), down = default(Vector2); Vector2 left = default(Vector2), right = default(Vector2); IntersectCircle(p, p + Vector2.up, center, radius, out up, out down); IntersectCircle(p, p + Vector2.left, center, radius, out left, out right); byte eleft = (byte)(Mathf.Clamp01((p.x - left.x) / m_voxelSize) * VoxelData.EXTENT_MAX_RESOLUTION); byte eright = (byte)(Mathf.Clamp01((right.x - p.x) / m_voxelSize) * VoxelData.EXTENT_MAX_RESOLUTION); byte etop = (byte)(Mathf.Clamp01((up.y - p.y) / m_voxelSize) * VoxelData.EXTENT_MAX_RESOLUTION); byte ebot = (byte)(Mathf.Clamp01((p.y - down.y) / m_voxelSize) * VoxelData.EXTENT_MAX_RESOLUTION); eleft = Math.Max(eleft, existing.GetExtentLeft()); eright = Math.Max(eright, existing.GetExtentRight()); etop = Math.Max(etop, existing.GetExtentTop()); ebot = Math.Max(ebot, existing.GetExtentBottom()); val.SetExtentHorizontal(eleft, eright); val.SetExtentVertical(ebot, etop); } write(currX, currY, val); } } else { if (d <= radius) { VoxelData val = default(VoxelData); val.SetSolidState(false); val.SetExtentHorizontal(0, 0); val.SetExtentVertical(0, 0); write(currX, currY, val); } else if (d <= radius + m_voxelSize) { VoxelData existing = read(currX, currY); int i1 = 0, i2 = 0; Vector2 up = default(Vector2), down = default(Vector2); Vector2 left = default(Vector2), right = default(Vector2); i1 = IntersectCircle(p, p + Vector2.up, center, radius, out up, out down); i2 = IntersectCircle(p, p + Vector2.left, center, radius, out left, out right); byte eleft = existing.GetExtentLeft(); byte eright = existing.GetExtentRight(); byte etop = existing.GetExtentTop(); byte ebot = existing.GetExtentBottom(); if (i1 > 0) { Vector2 topbot; if (i1 == 1) { topbot = up; } else { topbot = NearestPoint(p, up, down); } if (p.y < topbot.y) { etop = Math.Min(etop, (byte)(Mathf.Clamp01(Mathf.Abs(topbot.y - p.y) / m_voxelSize) * VoxelData.EXTENT_MAX_RESOLUTION)); } else if (p.y > topbot.y) { ebot = Math.Min(ebot, (byte)(Mathf.Clamp01(Mathf.Abs(topbot.y - p.y) / m_voxelSize) * VoxelData.EXTENT_MAX_RESOLUTION)); } } if (i2 > 0) { Vector2 leftright; if (i2 == 1) { leftright = left; } else { leftright = NearestPoint(p, left, right); } if (p.x < leftright.x) { eright = Math.Min(eright, (byte)(Mathf.Clamp01(Mathf.Abs(leftright.x - p.x) / m_voxelSize) * VoxelData.EXTENT_MAX_RESOLUTION)); } else if (p.x > leftright.x) { eleft = Math.Min(eleft, (byte)(Mathf.Clamp01(Mathf.Abs(leftright.x - p.x) / m_voxelSize) * VoxelData.EXTENT_MAX_RESOLUTION)); } } existing.SetExtentHorizontal(eleft, eright); existing.SetExtentVertical(ebot, etop); write(currX, currY, existing); } } } } }
private void SetTerrainValue(float x, float y, bool add) { Vector2 from = new Vector2(x - width / 2.0f, y - height / 2.0f); Vector2 to = new Vector2(x + width / 2.0f, y + height / 2.0f); int maxWidth = Mathf.CeilToInt(width / m_voxelSize) + 3; int maxHeight = Mathf.CeilToInt(height / m_voxelSize) + 3; int firstX = Mathf.RoundToInt(from.x / m_voxelSize) - 1; int firstY = Mathf.RoundToInt(from.y / m_voxelSize) - 1; for (int j = 0; j < maxHeight; j++) { int currY = firstY + j; if (currY < m_min.y) { continue; } if (currY >= m_max.y) { break; } for (int i = 0; i < maxWidth; i++) { int currX = firstX + i; if (currX < m_min.x) { continue; } if (currX >= m_max.x) { break; } float px = currX * m_voxelSize; float py = currY * m_voxelSize; float dx = Mathf.Abs(px - x) - width / 2.0f; float dy = Mathf.Abs(py - y) - height / 2.0f; if (add) { if (dx < 0.0f && dy < 0.0f) { VoxelData existing = read(currX, currY); VoxelData val = default(VoxelData); val.SetSolidState(true); float right = x + width / 2.0f; float left = x - width / 2.0f; float top = y + height / 2.0f; float bot = y - height / 2.0f; byte eleft = (byte)(Mathf.Clamp01((px - left) / m_voxelSize) * VoxelData.EXTENT_MAX_RESOLUTION); byte eright = (byte)(Mathf.Clamp01((right - px) / m_voxelSize) * VoxelData.EXTENT_MAX_RESOLUTION); byte etop = (byte)(Mathf.Clamp01((top - py) / m_voxelSize) * VoxelData.EXTENT_MAX_RESOLUTION); byte ebot = (byte)(Mathf.Clamp01((py - bot) / m_voxelSize) * VoxelData.EXTENT_MAX_RESOLUTION); eleft = Math.Max(eleft, existing.GetExtentLeft()); eright = Math.Max(eright, existing.GetExtentRight()); etop = Math.Max(etop, existing.GetExtentTop()); ebot = Math.Max(ebot, existing.GetExtentBottom()); val.SetExtentHorizontal(eleft, eright); val.SetExtentVertical(ebot, etop); write(currX, currY, val); } } else { if (dx < 0.0f && dy < 0.0f) { VoxelData val = default(VoxelData); val.SetSolidState(false); val.SetExtentHorizontal(0, 0); val.SetExtentVertical(0, 0); write(currX, currY, val); } else { VoxelData existing = read(currX, currY); if (dy < dx) { if (dx < m_voxelSize) { // Point is right of brush if (px - x > 0.0f) { byte eleft = (byte)(Mathf.Clamp01(dx / m_voxelSize) * VoxelData.EXTENT_MAX_RESOLUTION); eleft = Math.Min(eleft, existing.GetExtentLeft()); existing.SetExtentLeft(eleft); } // Left of brush else if (px - x < 0.0f) { byte eright = (byte)(Mathf.Clamp01(dx / m_voxelSize) * VoxelData.EXTENT_MAX_RESOLUTION); eright = Math.Min(eright, existing.GetExtentRight()); existing.SetExtentRight(eright); } } } else { if (dy < m_voxelSize) { // Point is above brush if (py - y > 0.0f) { byte ebot = (byte)(Mathf.Clamp01(dy / m_voxelSize) * VoxelData.EXTENT_MAX_RESOLUTION); ebot = Math.Min(ebot, existing.GetExtentBottom()); existing.SetExtentBottom(ebot); } // Below brush else if (py - y < 0.0f) { byte etop = (byte)(Mathf.Clamp01(dy / m_voxelSize) * VoxelData.EXTENT_MAX_RESOLUTION); etop = Math.Min(etop, existing.GetExtentTop()); existing.SetExtentTop(etop); } } } write(currX, currY, existing); } } } } }