Ejemplo n.º 1
0
        public static void GenerateHeightMap(TerrainExtension ter, string path)
        {
            Texture2D heightMap = ter.GetHeightMap();

            if (heightMap.format != TextureFormat.RGBA32)
            {
                Debug.LogError("Format must be RGBA32 it is now " + heightMap.format);
                return;
            }
            Terrain t            = ter.GetComponent <Terrain>();
            float   pixelWidthT  = 1 / (float)heightMap.width;
            float   pixelWidthT2 = pixelWidthT * 0.5f;

            int splatMapWidth = t.terrainData.alphamapWidth;

            float[,,] splatmapData = t.terrainData.GetAlphamaps(0, 0, splatMapWidth, splatMapWidth);

            float sh = TerrainManager.FindInstance().SnowHeight;

            for (int j = 0; j < heightMap.height; j++)
            {
                for (int i = 0; i < heightMap.width; i++)
                {
                    float tu = i / ((float)heightMap.width) + pixelWidthT2;
                    float tv = j / ((float)heightMap.height) + pixelWidthT2;

                    int   sxi       = Mathf.Clamp(Mathf.RoundToInt((float)splatMapWidth * tv), 0, splatMapWidth - 1);
                    int   syi       = Mathf.Clamp(Mathf.RoundToInt((float)splatMapWidth * tu), 0, splatMapWidth - 1);
                    float snowDepth = sh * (splatmapData[sxi, syi, 0] + splatmapData[sxi, syi, 2]);

                    Vector3 normal = t.terrainData.GetInterpolatedNormal(tu, tv);
                    normal = ter.transform.InverseTransformDirection(normal);

                    Vector3 pos = t.GetPosition();
                    pos.x += tu * t.terrainData.size.x; //+pixelWidth*0.5f;
                    pos.z += tv * t.terrainData.size.z; //+pixelWidth*0.5f;

                    float intHeight = t.terrainData.GetInterpolatedHeight(tu, tv) + snowDepth;
                    //pos.y += intHeight;
                    //pos.y += snowDepth;

                    float   h    = Mathf.Clamp01((intHeight) / t.terrainData.size.y);
                    float[] encs = EncodeFloatRGBA(h);
                    Color   c    = new Color(encs[0], encs[1], encs[2], encs[3]);
                    heightMap.SetPixel(i, j, c);
                }
            }
            heightMap.Apply();

            byte[] bytes = heightMap.EncodeToPNG();

            //string path = AssetDatabase.GetAssetOrScenePath(heightMap);
            Debug.Log("Writing to path" + path);
            if (!string.IsNullOrEmpty(path))
            {
                File.WriteAllBytes(path, bytes);
            }
        }
Ejemplo n.º 2
0
        internal static void GenerateRockNoise(TerrainExtension ter)
        {
            Terrain t = ter.GetComponent <Terrain>();

            if (t == null)
            {
                return;
            }

            int heightMapWidth = t.terrainData.heightmapWidth;

            float[,] masterData = t.terrainData.GetHeights(0, 0, heightMapWidth, heightMapWidth);
            int asize = t.terrainData.alphamapWidth;

            float[,,] alphaData = t.terrainData.GetAlphamaps(0, 0, asize, asize);

            float tx = 0;
            float tz = 0;

            float   addHeightScale = 1 / t.terrainData.size.y;
            Vector3 pos            = Vector3.zero;

            for (int x = 0; x < heightMapWidth; x++)
            {
                tx = (float)x / (float)(heightMapWidth - 1);
                for (int y = 0; y < heightMapWidth; y++)
                {
                    tz = (float)y / (float)(heightMapWidth - 1);

                    int atx = Mathf.FloorToInt(tx * (asize - 1));
                    int aty = Mathf.FloorToInt(tz * (asize - 1));

                    pos    = t.transform.position;
                    pos.z += t.terrainData.size.x * (((float)x) / ((float)heightMapWidth - 1.0f));
                    pos.x += t.terrainData.size.z * (((float)y) / ((float)heightMapWidth - 1.0f));
                    float heightAdd = 0;
                    for (int i = 0; i < ter.GetDeformSettings().channelSettings.Count; i++)
                    {
                        var settings = ter.GetDeformSettings().channelSettings[i];
                        if (settings.enabled)
                        {
                            float typeStrength = alphaData[atx, aty, settings.Channel];
                            float noise        = settings.NoiseMap.GetPixelBilinear(pos.x * settings.UVScale.x, pos.z * settings.UVScale.y).r;
                            if (settings.UseFilter && settings.TerrainFilterMap != null)
                            {
                                float filter = settings.TerrainFilterMap.GetPixelBilinear(tz, tx).r;
                                typeStrength = filter;
                            }
                            heightAdd += typeStrength * settings.Strength * addHeightScale * noise;
                        }
                    }
                    masterData[x, y] = Mathf.Clamp01(masterData[x, y] + heightAdd);
                }
            }

            t.terrainData.SetHeights(0, 0, masterData);
        }
Ejemplo n.º 3
0
        public static void SetSplatFromMap(TerrainExtension ter)
        {
            Terrain t             = ter.GetComponent <Terrain>();
            int     splatMapWidth = t.terrainData.alphamapWidth;

            float[,,] splatmapData = new float[splatMapWidth, splatMapWidth, t.terrainData.alphamapLayers];

            float tx = 0;
            float ty = 0;

            for (int y = 0; y < splatMapWidth; y++)
            {
                ty = (float)(y) / (float)splatMapWidth;
                for (int x = 0; x < splatMapWidth; x++)
                {
                    tx = (float)(x) / (float)splatMapWidth;

                    float etx = tx;
                    if (ter.FlipSplatMapX)
                    {
                        etx = 1 - tx;
                    }
                    float ety = ty;
                    if (ter.FlipSplatMapY)
                    {
                        ety = 1 - ty;
                    }
                    Color   c     = ter.GetSplatMap().GetPixelBilinear(ety, etx);
                    float[] ts    = new float[4];
                    float   total = 1; //c.g+c.b+c.a;
                                       //Normalize splats
                    ts[1]  = c.g;
                    total -= ts[1];
                    ts[2]  = Mathf.Clamp01(c.b * total);
                    total -= ts[2];
                    ts[3]  = Mathf.Clamp01(c.r * total);
                    total -= ts[3];

                    ts[0] = Mathf.Clamp01(total);
                    for (int j = 0; j < t.terrainData.alphamapLayers; j++)
                    {
                        splatmapData[x, y, j] = ts[j];
                    }
                }
            }
            t.terrainData.SetAlphamaps(0, 0, splatmapData);
        }
Ejemplo n.º 4
0
        public static void SaveSplatMapFromTerrain(TerrainExtension ter, string path)
        {
            Terrain t = ter.GetComponent <Terrain>();

            int splatMapWidth = t.terrainData.alphamapWidth;

            float[,,] splatmapData = t.terrainData.GetAlphamaps(0, 0, splatMapWidth, splatMapWidth);
            var targetSplatmap = ter.GetSplatMap();

            Color [] colors = new Color[splatMapWidth * splatMapWidth];
            if (splatmapData != null && t.terrainData.splatPrototypes.Length > 1)
            {
                for (int j = 0; j < targetSplatmap.height; j++)
                {
                    for (int i = 0; i < targetSplatmap.width; i++)
                    {
                        float tu = i / ((float)targetSplatmap.width);
                        float tv = j / ((float)targetSplatmap.height);

                        Color splatC = Color.red;

                        int sxi = Mathf.Clamp(Mathf.RoundToInt((float)splatMapWidth * tv), 0, splatMapWidth - 1);
                        int syi = Mathf.Clamp(Mathf.RoundToInt((float)splatMapWidth * tu), 0, splatMapWidth - 1);
                        splatC.r = splatmapData[sxi, syi, 3];
                        splatC.g = splatmapData[sxi, syi, 1];
                        splatC.b = splatmapData[sxi, syi, 2];
                        splatC.a = 1;

                        colors[j * targetSplatmap.height + i] = splatC;
                        //targetSplatmap.SetPixel(i, j, splatC);
                    }
                }
            }

            targetSplatmap.SetPixels(colors);

            byte[] bytes = targetSplatmap.EncodeToPNG();

            //string path = AssetDatabase.GetAssetOrScenePath(ter.GetSplatMap());
            Debug.Log("Writing to path" + path);
            if (!string.IsNullOrEmpty(path))
            {
                File.WriteAllBytes(path, bytes);
            }
        }
Ejemplo n.º 5
0
        public static void GenerateSplatMap(TerrainExtension ter)
        {
            Terrain t = ter.GetComponent <Terrain>();

            int splatMapWidth = t.terrainData.alphamapWidth;

            float[,,] splatmapData = new float[splatMapWidth, splatMapWidth, t.terrainData.alphamapLayers];
            float pixelWidthT  = 1 / (float)splatMapWidth;
            float pixelWidthT2 = pixelWidthT * 0.5f;

            float tx = 0;
            float ty = 0;

            for (int y = 0; y < splatMapWidth; y++)
            {
                ty = (float)(y) / (float)splatMapWidth;
                for (int x = 0; x < splatMapWidth; x++)
                {
                    tx = (float)(x) / (float)splatMapWidth;

                    float   tu     = y / ((float)splatMapWidth) + pixelWidthT2;
                    float   tv     = x / ((float)splatMapWidth) + pixelWidthT2;
                    Vector3 normal = t.terrainData.GetInterpolatedNormal(tu, tv);
                    normal = ter.transform.InverseTransformDirection(normal);

                    Vector3 pos = t.GetPosition();
                    pos.x += tu * t.terrainData.size.x;
                    pos.z += tv * t.terrainData.size.z;
                    pos.y += t.terrainData.GetInterpolatedHeight(tu, tv);

                    float[] ts           = new float[4];
                    float   total        = 1;
                    float   rockStrength = splatmapData[x, y, 3];

                    Color mask = Color.white;
                    mask.a = 1;
                    if (ter.SplatGenerationMask != null)
                    {
                        mask = ter.SplatGenerationMask.GetPixelBilinear(tu, tv);
                    }

                    float cov = 1 - Mathf.Clamp01((normal.y - ter.SnowCoverNormalThreshold.x) / (ter.SnowCoverNormalThreshold.y - ter.SnowCoverNormalThreshold.x));

                    float dirtFade      = 1 - (pos.y - ter.DirtHeightStart) / (ter.DirtHeightEnd - ter.DirtHeightStart);
                    float grassStrength = Mathf.Clamp01(dirtFade + normal.y * normal.y * normal.y * ter.DirtNormalMultiplier);

                    if (ter.BigTerrainMode)
                    {
                        ts[1] = cov * grassStrength;
                        ts[3] = cov * (1 - grassStrength);
                        total = 1 - (ts[1] + ts[3]);
                        ts[2] = total * grassStrength;
                        ts[0] = total * (1 - grassStrength);
                    }
                    else
                    {
                        ts[1]  = splatmapData[x, y, 1];
                        total -= ts[1];
                        ts[2]  = splatmapData[x, y, 2];
                        total -= ts[2];
                        ts[3]  = 0;

                        if ((rockStrength > 0 && ter.OnlyAddSnowToRocks) || !ter.OnlyAddSnowToRocks)
                        {
                            ts[3] = Mathf.Clamp01(cov * total);
                        }
                        total -= ts[3];
                        ts[0]  = Mathf.Clamp01(total);
                    }

                    splatmapData[x, y, 0] = Mathf.Lerp(splatmapData[x, y, 0], ts[0], mask.r);
                    splatmapData[x, y, 1] = Mathf.Lerp(splatmapData[x, y, 1], ts[1], mask.g);
                    splatmapData[x, y, 2] = Mathf.Lerp(splatmapData[x, y, 2], ts[2], mask.b);
                    splatmapData[x, y, 3] = Mathf.Lerp(splatmapData[x, y, 3], ts[3], mask.a);
                }
            }
            t.terrainData.SetAlphamaps(0, 0, splatmapData);
        }
Ejemplo n.º 6
0
        public static void GenerateNormalMap(TerrainExtension ter, string path)
        {
            Texture2D normalMap = ter.GetNormalMap();

            if (normalMap.format != TextureFormat.RGBA32)
            {
                Debug.LogError("Format must be RGBA32 it is now " + normalMap.format);
                return;
            }
            Terrain t            = ter.GetComponent <Terrain>();
            float   pixelWidthT  = 1 / (float)normalMap.width;
            float   pixelWidthT2 = pixelWidthT * 0.5f;

            for (int j = 0; j < normalMap.height; j++)
            {
                for (int i = 0; i < normalMap.width; i++)
                {
                    float   tu     = i / ((float)normalMap.width) + pixelWidthT2;
                    float   tv     = j / ((float)normalMap.height) + pixelWidthT2;
                    Vector3 normal = t.terrainData.GetInterpolatedNormal(tu, tv);
                    normal = ter.transform.InverseTransformDirection(normal);

                    Vector3 pos = t.GetPosition();
                    pos.x += tu * t.terrainData.size.x;    //+pixelWidth*0.5f;
                    pos.z += tv * t.terrainData.size.z;    //+pixelWidth*0.5f;
                    pos.y += t.terrainData.GetInterpolatedHeight(tu, tv);

                    if (ter.BakeMeshesIntoNormals)
                    {
                        RaycastHit hit;
                        if (Physics.Raycast(pos + Vector3.up * 100, Vector3.down, out hit, 1000, Masks.GroundMask))
                        {
                            MeshCollider meshCollider  = hit.collider as MeshCollider;
                            float        diff          = hit.point.y - pos.y;
                            float        blendStrength = Mathf.Clamp01((diff - 0.2f) / 0.8f);

                            if (meshCollider != null && meshCollider.sharedMesh != null)
                            {
                                //var modifier = Find.RecursiveParent<MeshModifier>(meshCollider.gameObject.transform);

                                Mesh mesh = meshCollider.sharedMesh;

                                Vector3[] normals   = mesh.normals;
                                int[]     triangles = mesh.triangles;

                                Vector3 n0 = normals[triangles[hit.triangleIndex * 3 + 0]];
                                Vector3 n1 = normals[triangles[hit.triangleIndex * 3 + 1]];
                                Vector3 n2 = normals[triangles[hit.triangleIndex * 3 + 2]];

                                Vector3 baryCenter = hit.barycentricCoordinate;

                                var newNormal = n0 * baryCenter.x + n1 * baryCenter.y + n2 * baryCenter.z;
                                //if (modifier == null || !modifier.Settings.OutputWorldNormalTangent)
                                //    newNormal = hit.collider.transform.TransformDirection(newNormal);
                                normal = Vector3.Lerp(normal, ter.transform.InverseTransformDirection(newNormal), blendStrength).normalized;
                            }
                        }
                    }

                    Color shadowC = normalMap.GetPixel(i, j);
                    Color c       = PackNormal(normal.normalized, 1);
                    normalMap.SetPixel(i, j, c);
                }
            }
            normalMap.Apply();

            byte[] bytes = normalMap.EncodeToPNG();

            Debug.Log("Writing to path" + path);
            if (!string.IsNullOrEmpty(path))
            {
                File.WriteAllBytes(path, bytes);
            }
        }
Ejemplo n.º 7
0
        public override void OnInspectorGUI()
        {
            base.OnInspectorGUI();

            TerrainExtension ter = (TerrainExtension)target as TerrainExtension;

            EditorGUILayout.Separator();
            EditorGUILayout.BeginHorizontal();
            GUILayout.Label("Editor for terrain extension");
            EditorGUILayout.EndHorizontal();

            /*if (ter.Lightmap != null)
             * {
             *  if (GUILayout.Button("Generate NormalMap"))
             *  {
             *      if (ter.BakeAllTimeIndicesUpTo > 0)
             *      {
             *          for (int i = 0; i < ter.BakeAllTimeIndicesUpTo; i++)
             *          {
             *              ter.BakeTimeIndex = i;
             *              TerrainMapGenerator.GenerateNormalMap(ter, AssetDatabase.GetAssetOrScenePath(ter.GetNormalMap()));
             *          }
             *      }
             *      else
             *      {
             *          TerrainMapGenerator.GenerateNormalMap(ter, AssetDatabase.GetAssetOrScenePath(ter.GetNormalMap()));
             *      }
             *  }
             *
             *  if (GUILayout.Button("Generate HeightMap"))
             *  {
             *      TerrainMapGenerator.GenerateHeightMap(ter, AssetDatabase.GetAssetOrScenePath(ter.GetHeightMap()));
             *  }
             *
             * }
             * else
             * {
             *  GUILayout.Label("Must create a png map (with correct settings)\n and associate it as Normal map on both the material\n and on the terrain extension");
             * }*/


            if (ter.GetSplatMap() != null)
            {
                if (GUILayout.Button("Set splat from map"))
                {
                    SetSplatFromMap(ter);
                }

                if (GUILayout.Button("Save splatmap"))
                {
                    TerrainMapGenerator.SaveSplatMapFromTerrain(ter, AssetDatabase.GetAssetOrScenePath(ter.GetSplatMap()));
                }
            }

            if (GUILayout.Button("Generate splatmap from terrain"))
            {
                TerrainMapGenerator.GenerateSplatMap(ter);
            }

            if (GUILayout.Button("Smooth terrain"))
            {
                SmoothTerrain(ter);
            }

            /*if (GUILayout.Button("AddRockNoise"))
             * {
             *  TerrainMapGenerator.GenerateRockNoise(ter);
             * }*/
        }
Ejemplo n.º 8
0
        public static void SmoothTerrain(TerrainExtension ext)
        {
            Terrain t = ext.GetComponent <Terrain>();

            if (t == null)
            {
                return;
            }

            int heightMapWidth = t.terrainData.heightmapWidth;

            float[,] masterData = t.terrainData.GetHeights(0, 0, heightMapWidth, heightMapWidth);
            int asize = t.terrainData.alphamapWidth;

            float[,,] alphaData = t.terrainData.GetAlphamaps(0, 0, asize, asize);

            float tx = 0;
            float tz = 0;

            Vector3 pos = Vector3.zero;

            for (int x = 0; x < heightMapWidth; x++)
            {
                tx = (float)x / (float)(heightMapWidth - 1);
                for (int y = 0; y < heightMapWidth; y++)
                {
                    tz = (float)y / (float)(heightMapWidth - 1);
                    float blend = 0;
                    if (t.terrainData.alphamapLayers >= ext.AutoSettings.SmoothBlendPerSplat.Length)
                    {
                        int atx = Mathf.FloorToInt(tx * (asize - 1));
                        int aty = Mathf.FloorToInt(tz * (asize - 1));

                        for (int ic = 0; ic < ext.AutoSettings.SmoothBlendPerSplat.Length; ic++)
                        {
                            blend += alphaData[atx, aty, ic] * ext.AutoSettings.SmoothBlendPerSplat[ic];
                        }
                    }
                    else
                    {
                        blend = ext.AutoSettings.SmoothBlend;
                        //Debug.Log("Mismatch in layers");
                    }

                    List <float> accumulated = new List <float>();

                    List <int> xshifts = new List <int>();
                    List <int> yshifts = new List <int>();
                    if (x > 0)
                    {
                        xshifts.Add(-1);
                    }
                    xshifts.Add(0);
                    if (x < heightMapWidth - 1)
                    {
                        xshifts.Add(1);
                    }

                    if (y > 0)
                    {
                        yshifts.Add(-1);
                    }
                    yshifts.Add(0);
                    if (y < heightMapWidth - 1)
                    {
                        yshifts.Add(1);
                    }

                    float accumHeight = 0;
                    float numSamples  = 0;
                    for (int ii = 0; ii < xshifts.Count; ii++)
                    {
                        for (int jj = 0; jj < yshifts.Count; jj++)
                        {
                            float h = masterData[x + xshifts[ii], y + yshifts[jj]];
                            accumulated.Add(h);
                            accumHeight += h;
                            numSamples  += 1;
                        }
                    }

                    masterData[x, y] = Mathf.Lerp(masterData[x, y], accumHeight / numSamples, blend);
                }
            }

            t.terrainData.SetHeights(0, 0, masterData);
        }