Exemple #1
0
            /// <summary>
            /// Resize the grid while maintain old Colors data
            /// </summary>
            /// <param name="oldDimensions"></param>
            /// <param name="newDimensions"></param>
            internal void ResizeGrid(Index2D oldDimensions, Index2D newDimensions)
            {
                if (colors == null || colors.Length == 0)
                {
                    colors = new Color[newDimensions.X * newDimensions.Z];
                    Utilities.Fill(colors, Color.clear);
                }
                else
                {
                    Color[] tmp = new Color[newDimensions.X * newDimensions.Z];
                    Utilities.Fill(tmp, Color.clear);
                    int   xLimit = Mathf.Min(oldDimensions.X, newDimensions.X);
                    int   zLimit = Mathf.Min(oldDimensions.Z, newDimensions.Z);
                    Color value;

                    for (int z = 0; z < zLimit; ++z)
                    {
                        for (int x = 0; x < xLimit; ++x)
                        {
                            value = colors[Utilities.To1DIndex(x, z, oldDimensions.X)];
                            tmp[Utilities.To1DIndex(x, z, newDimensions.X)] = value;
                        }
                    }

                    colors = tmp;
                }
            }
Exemple #2
0
 public void EnsureDimensionsUpToDate(Index2D dimensions)
 {
     if (surfaceDimensions != dimensions)
     {
         UpdateDimension(dimensions);
     }
 }
            /// <summary>
            /// Resize the grid while maintain old elevations data
            /// </summary>
            /// <param name="oldDimensions"></param>
            /// <param name="newDimensions"></param>
            internal void ResizeGrid(Index2D oldDimensions, Index2D newDimensions)
            {
                if (elevations == null || elevations.Length == 0)
                {
                    elevations = new float[newDimensions.X * newDimensions.Z];
                    Utilities.Fill(elevations, 0);
                }
                else
                {
                    float[] tmp = new float[newDimensions.X * newDimensions.Z];
                    Utilities.Fill(tmp, 0);
                    int   xLimit = Mathf.Min(oldDimensions.X, newDimensions.X);
                    int   zLimit = Mathf.Min(oldDimensions.Z, newDimensions.Z);
                    float value;

                    for (int z = 0; z < zLimit; ++z)
                    {
                        for (int x = 0; x < xLimit; ++x)
                        {
                            value = elevations[Utilities.To1DIndex(x, z, oldDimensions.X)];
                            tmp[Utilities.To1DIndex(x, z, newDimensions.X)] = value;
                        }
                    }

                    elevations = tmp;
                }
            }
Exemple #4
0
 /// <summary>
 /// Update grid dimension
 /// </summary>
 /// <param name="newSurfaceDimensions"></param>
 internal void UpdateDimension(Index2D newSurfaceDimensions)
 {
     if (surfaceDimensions != newSurfaceDimensions ||
         colors == null ||
         colors.Length != newSurfaceDimensions.X * newSurfaceDimensions.Z)
     {
         ResizeGrid(surfaceDimensions, newSurfaceDimensions);
         surfaceDimensions = newSurfaceDimensions;
     }
 }
        /// <summary>
        /// Perform a paint action at a specific location
        /// </summary>
        /// <param name="hit"></param>
        /// <param name="currentEvent"></param>
        private void Paint(RaycastHit hit, Event currentEvent)
        {
            if (!GuiEventUtilities.IsLeftMouse)
            {
                return;
            }
            Vector3[]    vertices              = Terrain.MeshData.vertices;
            float        sqrRadius             = Settings.brushSettings.brushRadius * Settings.brushSettings.brushRadius;
            float        sqrMagnitude          = 0;
            List <int>   modifiedVertexIndices = new List <int>();
            List <Color> deltas = new List <Color>();
            List <float> f      = new List <float>(); //how much a vertex be affected by the brush

            //determine the vertices are being modified and how much they are affected (f)
            for (int i = 0; i < vertices.Length; ++i)
            {
                Index2D i2d = Utilities.To2DIndex(i, Terrain.VerticesGridLength.X);
                //only modify surface vertex
                if (!Terrain.IsSurfaceVertex(i2d))
                {
                    continue;
                }
                Vector3 worldPos = Terrain.transform.TransformPoint(vertices[i]);
                sqrMagnitude = Vector3.SqrMagnitude(hit.point - worldPos);
                if (sqrMagnitude >= sqrRadius)
                {
                    continue;
                }

                f.Add(1 - sqrMagnitude / sqrRadius);
                modifiedVertexIndices.Add(i);
            }

            float sign = GuiEventUtilities.IsCtrl ? -1 : 1;

            for (int i = 0; i < modifiedVertexIndices.Count; ++i)
            {
                int index = modifiedVertexIndices[i];
                if (sign > 0)
                {
                    AddColor(index, settings.brushSettings.color, f[i] * settings.brushSettings.strength);
                }
                else
                {
                    EraseColor(index, f[i] * settings.brushSettings.strength);
                }
            }

            //send data to the terrain to modify itself
            if (Painting != null)
            {
                Painting(modifiedVertexIndices, deltas);
            }
        }
 public static Index2D[] GetIndicesArray2D(int row, int column)
 {
     Index2D[] indices = new Index2D[row * column];
     for (int i = 0; i < row; ++i)
     {
         for (int j = 0; j < column; ++j)
         {
             indices[i * column + j] = new Index2D(j, i);
         }
     }
     return(indices);
 }
 public static Index2D[] GetShuffleIndicesArray2D(int row, int column)
 {
     Index2D[] indices = GetIndicesArray2D(row, column);
     for (int i = 0; i < indices.Length - 1; ++i)
     {
         int     j   = UnityEngine.Random.Range(0, indices.Length);
         Index2D tmp = indices[i];
         indices[i] = indices[j];
         indices[j] = tmp;
     }
     return(indices);
 }
Exemple #8
0
        /// <summary>
        /// Add elevation value for a vertex
        /// </summary>
        /// <param name="vertexIndex"></param>
        /// <param name="value"></param>
        public void AddElevation(int vertexIndex, float value)
        {
            Settings.EnsureDimensionsUpToDate(new Index2D(Terrain.SurfaceTileCountX + 1, Terrain.SurfaceTileCountZ + 1));
            Index2D i2d = Utilities.To2DIndex(vertexIndex, Terrain.VerticesGridLength.X);

            if (!Terrain.IsSurfaceVertex(i2d))
            {
                return;
            }
            Index2D surfaceIndex = Terrain.GetSurfaceVertexIndex(i2d);

            Settings.AddElevation(surfaceIndex, value);
        }
Exemple #9
0
            /// <summary>
            /// Add Color value for a vertex
            /// </summary>
            /// <param name="surfaceIndex"></param>
            /// <param name="value"></param>
            public void EraseColor(Index2D surfaceIndex, float f)
            {
                if (colors == null ||
                    colors.Length != surfaceDimensions.X * surfaceDimensions.Z)
                {
                    colors = new Color[surfaceDimensions.X * surfaceDimensions.Z];
                }

                int index = Utilities.To1DIndex(surfaceIndex.X, surfaceIndex.Z, surfaceDimensions.X);

                if (index < colors.Length)
                {
                    colors[index] = Color.Lerp(colors[index], Color.clear, f);
                }
            }
            /// <summary>
            /// Add elevation value for a vertex
            /// </summary>
            /// <param name="surfaceIndex"></param>
            /// <param name="value"></param>
            public void AddElevation(Index2D surfaceIndex, float value)
            {
                if (elevations == null ||
                    elevations.Length != surfaceDimensions.X * surfaceDimensions.Z)
                {
                    elevations = new float[surfaceDimensions.X * surfaceDimensions.Z];
                }

                int index = Utilities.To1DIndex(surfaceIndex.X, surfaceIndex.Z, surfaceDimensions.X);

                if (index < elevations.Length)
                {
                    elevations[index] += value;
                }
            }
Exemple #11
0
            /// <summary>
            /// Add Color value for a vertex
            /// </summary>
            /// <param name="surfaceIndex"></param>
            /// <param name="value"></param>
            public void AddColor(Index2D surfaceIndex, Color value, float f)
            {
                if (colors == null ||
                    colors.Length != surfaceDimensions.X * surfaceDimensions.Z)
                {
                    colors = new Color[surfaceDimensions.X * surfaceDimensions.Z];
                }

                int index = Utilities.To1DIndex(surfaceIndex.X, surfaceIndex.Z, surfaceDimensions.X);

                if (index < colors.Length)
                {
                    //colors[index] = ColorLibrary.Blend(colors[index], 1 - Mathf.Clamp01(f), value, Mathf.Clamp01(f));
                    colors[index] = Color.Lerp(colors[index], value, f);
                }
            }
Exemple #12
0
            /// <summary>
            /// Get Color value for a vertex
            /// </summary>
            /// <param name="i"></param>
            /// <returns></returns>
            public Color GetColor(Index2D i)
            {
                if (colors == null)
                {
                    return(Color.clear);
                }
                int index = Utilities.To1DIndex(i.X, i.Z, surfaceDimensions.X);

                if (index >= colors.Length)
                {
                    return(Color.clear);
                }
                else
                {
                    return(colors[index]);
                }
            }
            /// <summary>
            /// Get elevation value for a vertex
            /// </summary>
            /// <param name="i"></param>
            /// <returns></returns>
            public float GetElevation(Index2D i)
            {
                if (elevations == null)
                {
                    return(0);
                }
                int index = Utilities.To1DIndex(i.X, i.Z, surfaceDimensions.X);

                if (index >= elevations.Length)
                {
                    return(0);
                }
                else
                {
                    return(elevations[index]);
                }
            }
Exemple #14
0
            public Texture2D ExportTextureData()
            {
                Texture2D tex = new Texture2D(textureSize, textureSize);

                Color[]  textureData = new Color[textureSize * textureSize];
                MeshData data        = terrain.MeshData;
                int      trisCount   = data.triangles.Length / 3;

                for (int i = 0; i < trisCount; ++i)
                {
                    int i0 = data.triangles[i * 3 + 0];
                    int i1 = data.triangles[i * 3 + 1];
                    int i2 = data.triangles[i * 3 + 2];

                    Index2D i2d0 = Utilities.To2DIndex(i0, terrain.VerticesGridLength.X);
                    Index2D i2d1 = Utilities.To2DIndex(i1, terrain.VerticesGridLength.X);
                    Index2D i2d2 = Utilities.To2DIndex(i2, terrain.VerticesGridLength.X);

                    if (!terrain.IsSurfaceVertex(i2d0) || !terrain.IsSurfaceVertex(i2d1) || !terrain.IsSurfaceVertex(i2d2))
                    {
                        continue;
                    }

                    Vector2 uv0 = terrain.GetVertexUVOnHeightMap(i2d0);
                    Vector2 uv1 = terrain.GetVertexUVOnHeightMap(i2d1);
                    Vector2 uv2 = terrain.GetVertexUVOnHeightMap(i2d2);

                    float minHeight = terrain.BaseHeight;
                    float maxHeight = terrain.BaseHeight + terrain.SurfaceMaxHeight;
                    Color c0        = Color.white * Mathf.InverseLerp(minHeight, maxHeight, data.vertices[i0].y);
                    Color c1        = Color.white * Mathf.InverseLerp(minHeight, maxHeight, data.vertices[i1].y);
                    Color c2        = Color.white * Mathf.InverseLerp(minHeight, maxHeight, data.vertices[i2].y);

                    TextureExporter.DrawTriangleOnTexture(
                        tex,
                        new Vector2[] { uv0, uv1, uv2 },
                        new Color[] { c0, c1, c2 },
                        textureData);
                }
                tex.SetPixels(textureData);
                tex.Apply();
                return(tex);
            }
Exemple #15
0
 /// <summary>
 /// Get elevation value for a vertex
 /// </summary>
 /// <param name="i"></param>
 /// <returns></returns>
 public float GetElevation(Index2D i)
 {
     return(Settings.GetElevation(i));
 }
 /// <summary>
 /// Get color value for a vertex
 /// </summary>
 /// <param name="i"></param>
 /// <returns></returns>
 public Color GetColor(Index2D i)
 {
     return(Settings.GetColor(i));
 }
Exemple #17
0
        /// <summary>
        /// Perform a paint action at a specific location
        /// </summary>
        /// <param name="hit"></param>
        /// <param name="currentEvent"></param>
        private void Paint(RaycastHit hit, Event currentEvent)
        {
            if (!GuiEventUtilities.IsLeftMouse)
            {
                return;
            }

            Vector3[]    vertices              = Terrain.MeshData.vertices;
            float        sqrRadius             = Settings.brushRadius * Settings.brushRadius;
            float        sqrMagnitude          = 0;
            List <int>   modifiedVertexIndices = new List <int>();
            List <float> deltas = new List <float>();
            List <float> f      = new List <float>(); //how much a vertex be affected by the brush

            //determine the vertices are being modified and how much they are affected (f)
            for (int i = 0; i < vertices.Length; ++i)
            {
                Index2D i2d = Utilities.To2DIndex(i, Terrain.VerticesGridLength.X);
                //only modify surface vertex
                if (!Terrain.IsSurfaceVertex(i2d))
                {
                    continue;
                }
                //project brush and vertex position to XZ-plane if using Cylindrical mode
                Vector3 hitPoint     = Settings.brushMode == BrushMode.Spherical ? hit.point : new Vector3(hit.point.x, 0, hit.point.z);
                Vector3 worldPos     = Terrain.transform.TransformPoint(vertices[i]);
                Vector3 projWorldPos = Settings.brushMode == BrushMode.Spherical ? worldPos : new Vector3(worldPos.x, 0, worldPos.z);
                sqrMagnitude = Vector3.SqrMagnitude(hitPoint - projWorldPos);
                if (sqrMagnitude >= sqrRadius)
                {
                    continue;
                }

                f.Add(1 - sqrMagnitude / sqrRadius);
                modifiedVertexIndices.Add(i);
            }

            if (GuiEventUtilities.IsShift)
            {
                //apply a Laplacian smooth function to the vertices
                List <Vector3> verts = new List <Vector3>();
                for (int i = 0; i < modifiedVertexIndices.Count; ++i)
                {
                    Vector3 v = vertices[modifiedVertexIndices[i]];
                    verts.Add(v);
                }

                for (int i = 0; i < modifiedVertexIndices.Count; ++i)
                {
                    Vector3        v         = vertices[modifiedVertexIndices[i]];
                    List <Vector3> adjacents = FindAdjacents(v, verts);
                    float          expectedY = CalculateExpectedY(adjacents);
                    float          newY      = Mathf.MoveTowards(v.y, expectedY, Settings.strength * f[i]);
                    deltas.Add(newY - v.y);
                }
            }
            else
            {
                //raise or lower vertices
                float sign = GuiEventUtilities.IsCtrl ? -1 : 1;
                for (int i = 0; i < modifiedVertexIndices.Count; ++i)
                {
                    deltas.Add(sign * f[i] * Settings.strength);
                }
            }

            //send data to the terrain to modify itself
            if (Painting != null)
            {
                Painting(modifiedVertexIndices, deltas);
            }
        }