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