Beispiel #1
0
        private void UpdateTerrainBicubic(int hid, Vector3 position, Func <int, int, int, int, float[, ]> getValues, Action <int, int, float[, ]> setValues)
        {
            var data = TerrainData;

            if (hid >= 0)
            {
                m_state.Grid[hid] = position.y / data.heightmapScale.y;
            }
            else
            {
                Debug.LogError("Handle is not found!");
            }

            int zCount = Mathf.FloorToInt(m_zCount);
            int xCount = Mathf.FloorToInt(m_xCount);

            int2 iidx = new int2(hid % xCount, hid / xCount);

            for (int y = 0; y < 7; y++)
            {
                int _y = math.clamp(iidx.y - 3 + y, 0, zCount - 1);

                for (int x = 0; x < 7; x++)
                {
                    //int _x = math.clamp(iidx.x - 3 + x, 0, zCount - 1);
                    int _x = math.clamp(iidx.x - 3 + x, 0, xCount - 1);
                    m_lerpGrid[y, x] = m_state.Grid[xCount * _y + _x];
                }
            }

            float2 heightmapScale = ((float3)data.heightmapScale).xz;
            float2 pos            = ((float3)position).xz;
            int2   block_size     = (int2)(new float2(m_state.XSpacing, m_state.ZSpacing) / heightmapScale);

            int2 hPos = (int2)(pos / heightmapScale);

            hPos -= block_size * 2;

            int2    max_block = new int2(block_size.x * 4, block_size.y * 4);
            int     res       = data.heightmapResolution;
            RectInt r         = new RectInt(hPos.x, hPos.y, max_block.x, max_block.y);

            r.xMin = math.clamp(r.xMin, 0, res);
            r.xMax = math.clamp(r.xMax, 0, res);
            r.yMin = math.clamp(r.yMin, 0, res);
            r.yMax = math.clamp(r.yMax, 0, res);

            float[,] hmap = getValues(r.x, r.y, r.width, r.height);

            for (int gy = 0; gy < 4; gy++)
            {
                int base_y = gy * block_size.y;

                for (int gx = 0; gx < 4; gx++)
                {
                    int base_x = gx * block_size.x;

                    m_interpolator.UpdateCoefficients(new float4x4(
                                                          m_lerpGrid[gy, gx], m_lerpGrid[gy, gx + 1], m_lerpGrid[gy, gx + 2], m_lerpGrid[gy, gx + 3],
                                                          m_lerpGrid[gy + 1, gx], m_lerpGrid[gy + 1, gx + 1], m_lerpGrid[gy + 1, gx + 2], m_lerpGrid[gy + 1, gx + 3],
                                                          m_lerpGrid[gy + 2, gx], m_lerpGrid[gy + 2, gx + 1], m_lerpGrid[gy + 2, gx + 2], m_lerpGrid[gy + 2, gx + 3],
                                                          m_lerpGrid[gy + 3, gx], m_lerpGrid[gy + 3, gx + 1], m_lerpGrid[gy + 3, gx + 2], m_lerpGrid[gy + 3, gx + 3]
                                                          ));

                    for (int y = 0; y < block_size.y; y++)
                    {
                        int _y = hPos.y + base_y + y;
                        if (_y >= r.yMin && _y < r.yMax)
                        {
                            float ty = (float)y / block_size.y;

                            for (int x = 0; x < block_size.x; x++)
                            {
                                int _x = hPos.x + base_x + x;
                                if (_x >= r.xMin && _x < r.xMax)
                                {
                                    float tx     = (float)x / block_size.x;
                                    float height = m_interpolator.GetValue(tx, ty);
                                    float u      = (float)(r.x + (_x - r.xMin)) / data.heightmapResolution;
                                    float v      = (float)(r.y + (_y - r.yMin)) / data.heightmapResolution;
                                    if (u >= 0 && u <= 1 && v >= 0 && v <= 1)
                                    {
                                        Color color = m_state.CutoutTexture.GetPixelBilinear(u, v);
                                        if (Mathf.Approximately(color.a, 1))
                                        {
                                            hmap[_y - r.yMin, _x - r.xMin] = 0;
                                        }
                                        else
                                        {
                                            hmap[_y - r.yMin, _x - r.xMin] = height;
                                        }
                                    }
                                    else
                                    {
                                        hmap[_y - r.yMin, _x - r.xMin] = height;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            setValues(r.x, r.y, hmap);

            float[,] terrainHeightMap = data.GetHeights(r.x, r.y, r.width, r.height);
            for (int y = 0; y < r.height; ++y)
            {
                for (int x = 0; x < r.width; ++x)
                {
                    float height = terrainHeightMap[y, x] - m_additiveHeights[r.y + y, r.x + x];
                    m_state.HeightMap[(r.y + y) * data.heightmapResolution + r.x + x] = height;
                    m_interpolatedHeights[r.y + y, r.x + x] = height;
                }
            }
        }
        private void UpdateTerrainBicubic(int hid, Vector3 position)
        {
            var data = m_activeTerrain.terrainData;

            if (hid >= 0)
            {
                m_state.Grid[hid] = position.y / data.heightmapScale.y;
            }
            else
            {
                Debug.LogError("Gizmo is not found!");
            }

            int2 iidx = new int2(hid % m_count, hid / m_count);

            for (int y = 0; y < 7; y++)
            {
                int _y = math.clamp(iidx.y - 3 + y, 0, m_count - 1);

                for (int x = 0; x < 7; x++)
                {
                    int _x = math.clamp(iidx.x - 3 + x, 0, m_count - 1);
                    m_lerpGrid[y, x] = m_state.Grid[m_count * _y + _x];
                }
            }

            float2 heightmapScale = ((float3)data.heightmapScale).xz;
            float2 pos            = ((float3)position).xz;
            int2   block_size     = (int2)(new float2(m_state.Spacing) / heightmapScale);

            int2 hPos = (int2)(pos / heightmapScale);

            hPos -= block_size * 2;

            int2    max_block = new int2(block_size.x * 4, block_size.y * 4);
            int     res       = data.heightmapResolution;// - 1;
            RectInt r         = new RectInt(hPos.x, hPos.y, max_block.x, max_block.y);

            r.xMin = math.clamp(r.xMin, 0, res);
            r.xMax = math.clamp(r.xMax, 0, res);
            r.yMin = math.clamp(r.yMin, 0, res);
            r.yMax = math.clamp(r.yMax, 0, res);

            float[,] hmap = data.GetHeights(r.x, r.y, r.width, r.height);

            for (int gy = 0; gy < 4; gy++)
            {
                int base_y = gy * block_size.y;

                for (int gx = 0; gx < 4; gx++)
                {
                    int base_x = gx * block_size.x;

                    m_interpolator.UpdateCoefficients(new float4x4(
                                                          m_lerpGrid[gy, gx], m_lerpGrid[gy, gx + 1], m_lerpGrid[gy, gx + 2], m_lerpGrid[gy, gx + 3],
                                                          m_lerpGrid[gy + 1, gx], m_lerpGrid[gy + 1, gx + 1], m_lerpGrid[gy + 1, gx + 2], m_lerpGrid[gy + 1, gx + 3],
                                                          m_lerpGrid[gy + 2, gx], m_lerpGrid[gy + 2, gx + 1], m_lerpGrid[gy + 2, gx + 2], m_lerpGrid[gy + 2, gx + 3],
                                                          m_lerpGrid[gy + 3, gx], m_lerpGrid[gy + 3, gx + 1], m_lerpGrid[gy + 3, gx + 2], m_lerpGrid[gy + 3, gx + 3]
                                                          ));

                    for (int y = 0; y < block_size.y; y++)
                    {
                        int _y = hPos.y + base_y + y;
                        if (_y >= r.yMin && _y < r.yMax)
                        {
                            float ty = (float)y / block_size.y;

                            for (int x = 0; x < block_size.x; x++)
                            {
                                int _x = hPos.x + base_x + x;
                                if (_x >= r.xMin && _x < r.xMax)
                                {
                                    float tx = (float)x / block_size.x;

                                    try
                                    {
                                        float height = m_interpolator.GetValue(tx, ty);
                                        float u      = (float)(r.x + (_x - r.xMin)) / data.heightmapWidth;
                                        float v      = (float)(r.y + (_y - r.yMin)) / data.heightmapHeight;
                                        if (u >= 0 && u <= 1 && v >= 0 && v <= 1)
                                        {
                                            Color color = m_state.CutoutTexture.GetPixelBilinear(u, v);
                                            if (Mathf.Approximately(color.a, 1))
                                            {
                                                hmap[_y - r.yMin, _x - r.xMin] = 0;
                                            }
                                            else
                                            {
                                                hmap[_y - r.yMin, _x - r.xMin] = height;
                                            }
                                        }
                                        else
                                        {
                                            hmap[_y - r.yMin, _x - r.xMin] = height;
                                        }

                                        m_state.HeightMap[(r.y + (_y - r.yMin)) * m_activeTerrain.terrainData.heightmapWidth + r.x + (_x - r.xMin)] = height;
                                    }
                                    catch
                                    {
                                        Debug.LogError("!!!!!!!!!!!!!!!!!!!");
                                    }
                                }
                            }
                        }
                    }
                }
            }

            data.SetHeights(r.x, r.y, hmap);
        }