Exemple #1
0
    public static void GenerateTerrainBlendData(MicroSplatTerrain bt)
    {
        Terrain t = bt.GetComponent <Terrain>();
        int     w = t.terrainData.heightmapResolution;
        int     h = t.terrainData.heightmapResolution;

        Texture2D data = new Texture2D(w, h, TextureFormat.RGBAHalf, true, true);

        for (int x = 0; x < w; ++x)
        {
            for (int y = 0; y < h; ++y)
            {
                float   height = t.terrainData.GetHeight(x, y);
                Vector3 normal = t.terrainData.GetInterpolatedNormal((float)x / w, (float)y / h);
                // When you save a texture to EXR format, either in the saving or import stage,
                // some type of gamma curve is applied regardless of the fact that the textures is
                // set to linear. So we pow it here to counteract it, whis is total BS, but works..
                normal.x = (normal.x >= 0) ? Mathf.Pow(normal.x, 2.0f) : Mathf.Pow(normal.x, 2) * -1;
                normal.z = (normal.z >= 0) ? Mathf.Pow(normal.z, 2.0f) : Mathf.Pow(normal.z, 2) * -1;
                data.SetPixel(x, y, new Color(normal.x, normal.y, normal.z, height));
            }
        }
        data.Apply();

        var path = MicroSplatUtilities.RelativePathFromAsset(t.terrainData);

        path += "/" + t.name + ".exr";
        var bytes = data.EncodeToEXR(Texture2D.EXRFlags.OutputAsFloat);

        System.IO.File.WriteAllBytes(path, bytes);
        GameObject.DestroyImmediate(data);
        AssetDatabase.Refresh();
        bt.terrainDesc = AssetDatabase.LoadAssetAtPath <Texture2D>(path);
        var ai = AssetImporter.GetAtPath(path);
        var ti = ai as TextureImporter;
        var ps = ti.GetDefaultPlatformTextureSettings();

        if (ti.isReadable == true ||
            ti.wrapMode != TextureWrapMode.Clamp ||
            ps.format != TextureImporterFormat.RGBAHalf ||
            ps.textureCompression != TextureImporterCompression.Uncompressed ||
            ps.overridden != true ||
            ti.filterMode != FilterMode.Bilinear ||
            ti.sRGBTexture != false)
        {
            ti.sRGBTexture        = false;
            ti.filterMode         = FilterMode.Bilinear;
            ti.mipmapEnabled      = true;
            ti.wrapMode           = TextureWrapMode.Clamp;
            ti.isReadable         = false;
            ps.format             = TextureImporterFormat.RGBAHalf;
            ps.textureCompression = TextureImporterCompression.Uncompressed;
            ps.overridden         = true;
            ti.SetPlatformTextureSettings(ps);
            ti.SaveAndReimport();
        }
        bt.sTerrainDirty = false;
        EditorUtility.SetDirty(bt);
        MicroSplatTerrain.SyncAll();
    }
Exemple #2
0
        static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
        {
            var cfgs = AssetDatabase.FindAssets("t:TextureArrayConfig");

            for (int i = 0; i < cfgs.Length; ++i)
            {
                var asset = AssetDatabase.GUIDToAssetPath(cfgs[i]);
                var cfg   = AssetDatabase.LoadAssetAtPath <TextureArrayConfig>(asset);
                if (cfg != null)
                {
                    int hash = GetNewHash(cfg);
                    if (hash != cfg.hash)
                    {
                        cfg.hash = hash;
                        EditorUtility.SetDirty(cfg);
                        try
                        {
                            sIsPostProcessing = true;
                            TextureArrayConfigEditor.CompileConfig(cfg);
                        }
                        finally
                        {
                            sIsPostProcessing = false;
                            AssetDatabase.Refresh();
                            AssetDatabase.SaveAssets();
                            MicroSplatTerrain.SyncAll();
                        }
                    }
                }
            }
        }
Exemple #3
0
    void Bake(MicroSplatTerrain mst)
    {
        // for each pass
        int pass = 1;

        while (pass <= (int)(BakingPasses.Emissive))
        {
            BakingPasses p = (BakingPasses)pass;
            pass *= 2;
            if (!IsEnabled(p))
            {
                continue;
            }
            Texture2D worldPos, worldNormal;
            GenerateWorldData(mst.terrain, out worldNormal, out worldPos, (int)res);

            var debugOutput = OutputFromPass(p);
            var tex         = Bake(mst, p, (int)res, worldPos, worldNormal);
            var bytes       = tex.EncodeToPNG();

            DestroyImmediate(worldPos, worldNormal);
            string texPath = MicroSplatUtilities.RelativePathFromAsset(mst.terrain) + "/" + mst.terrain.name + "_" + debugOutput.ToString();
            System.IO.File.WriteAllBytes(texPath + ".png", bytes);
        }

        AssetDatabase.Refresh();
    }
Exemple #4
0
    public void ComputeCavityFlowMap(MicroSplatTerrain bt)
    {
        Terrain   t    = bt.terrain;
        Texture2D data = new Texture2D(t.terrainData.heightmapResolution, t.terrainData.heightmapResolution, TextureFormat.RGBA32, true, true);

        CurvatureMapGenerator.CreateMap(t.terrainData.GetHeights(0, 0, data.width, data.height), data);

        var path = MicroSplatUtilities.RelativePathFromAsset(t.terrainData);

        path += "/" + t.name + "_cavity.png";
        var bytes = data.EncodeToPNG();

        System.IO.File.WriteAllBytes(path, bytes);
        GameObject.DestroyImmediate(data);
        AssetDatabase.Refresh();
        bt.cavityMap = AssetDatabase.LoadAssetAtPath <Texture2D>(path);
        var ai = AssetImporter.GetAtPath(path);
        var ti = ai as TextureImporter;

        if (ti.sRGBTexture != false)
        {
            ti.sRGBTexture = false;
            ti.SaveAndReimport();
        }
        bt.sTerrainDirty = false;
        EditorUtility.SetDirty(bt);
        EditorUtility.SetDirty(t);
        MicroSplatTerrain.SyncAll();
        AssetDatabase.SaveAssets();
    }
Exemple #5
0
    public void DoPerPixelNormalGUI()
    {
        MicroSplatTerrain bt = target as MicroSplatTerrain;
        Terrain           t  = bt.GetComponent <Terrain>();

        if (t == null || t.terrainData == null)
        {
            EditorGUILayout.HelpBox("No Terrain data found", MessageType.Error);
            return;
        }
        if (t.materialTemplate == null)
        {
            return;
        }

        if (bt.keywordSO == null)
        {
            return;
        }

        if (bt.terrain.drawInstanced && bt.perPixelNormal != null && !bt.keywordSO.IsKeywordEnabled("_TERRAINBLENDING"))
        {
            EditorGUILayout.HelpBox("Per Pixel Normal is assigned, but shader is using Instance rendering, which automatically provides per-pixel normal. You may turn off per pixel normal if it's on and clear the normal data to save memory.", MessageType.Warning);
            if (bt.perPixelNormal != null && GUILayout.Button("Clear"))
            {
                bt.perPixelNormal = null;
                EditorUtility.SetDirty(bt);
                EditorUtility.SetDirty(bt.terrain);
            }
        }

        MicroSplatUtilities.DrawTextureField(bt, CPerPixelNormal, ref bt.perPixelNormal, "_PERPIXNORMAL", "_TERRAINBLENDING", null, null, false);

        if (bt.perPixelNormal == null &&
            (bt.keywordSO.IsKeywordEnabled("_PERPIXNORMAL") || bt.keywordSO.IsKeywordEnabled("_TERRAINBLENDING")))
        {
            EditorGUILayout.HelpBox("Terrain Normal Data is not present, please generate", MessageType.Warning);
        }

        if (bt.keywordSO.IsKeywordEnabled("_PERPIXNORMAL") || bt.keywordSO.IsKeywordEnabled("_TERRAINBLENDING"))
        {
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.PrefixLabel("Normal Data");
            if (GUILayout.Button(bt.perPixelNormal == null ? "Generate" : "Update"))
            {
                GenerateTerrainNormalMap(bt);
                EditorUtility.SetDirty(bt);
                EditorUtility.SetDirty(bt.terrain);
            }

            if (bt.perPixelNormal != null && GUILayout.Button("Clear"))
            {
                bt.perPixelNormal = null;
                EditorUtility.SetDirty(bt);
                EditorUtility.SetDirty(bt.terrain);
            }
            EditorGUILayout.EndHorizontal();
        }
    }
    public void DoTerrainDescGUI()
    {
        MicroSplatTerrain bt = target as MicroSplatTerrain;
        Terrain           t  = bt.GetComponent <Terrain>();

        if (t == null || t.terrainData == null)
        {
            return;
        }
        if (t.materialTemplate == null)
        {
            return;
        }
        if (bt.keywordSO == null)
        {
            return;
        }

        if (!bt.keywordSO.IsKeywordEnabled("_TERRAINBLENDING") && !bt.keywordSO.IsKeywordEnabled("_DYNAMICFLOWS"))
        {
            return;
        }
        EditorGUILayout.Space();

        if (bt.blendMat == null && bt.templateMaterial != null && bt.keywordSO != null && bt.keywordSO.IsKeywordEnabled("_TERRAINBLENDING"))
        {
            var path = AssetDatabase.GetAssetPath(bt.templateMaterial);
            path        = path.Replace(".mat", "_TerrainObjectBlend.mat");
            bt.blendMat = AssetDatabase.LoadAssetAtPath <Material>(path);
            if (bt.blendMat == null)
            {
                string shaderPath = path.Replace(".mat", ".shader");
                Shader shader     = AssetDatabase.LoadAssetAtPath <Shader>(shaderPath);
                if (shader == null)
                {
                    shaderPath = path.Replace(".shader", ".surfshader");
                    shader     = AssetDatabase.LoadAssetAtPath <Shader>(shaderPath);
                }

                if (shader == null)
                {
                    shaderPath = AssetDatabase.GetAssetPath(bt.templateMaterial.shader);
                    shaderPath = shaderPath.Replace(".shader", "_TerrainObjectBlend.shader");
                    shaderPath = shaderPath.Replace(".surfshader", "_TerrainObjectBlend.surfshader");
                    shader     = AssetDatabase.LoadAssetAtPath <Shader>(shaderPath);
                }
                if (shader != null)
                {
                    Material mat = new Material(shader);
                    AssetDatabase.CreateAsset(mat, path);
                    AssetDatabase.SaveAssets();
                    MicroSplatTerrain.SyncAll();
                }
            }
        }
        EditorUtility.SetDirty(bt);
        EditorUtility.SetDirty(bt.terrain);
    }
Exemple #7
0
        void InitTerrains()
        {
            Object[] objs = Selection.GetFiltered(typeof(Terrain), SelectionMode.Editable | SelectionMode.OnlyUserModifiable | SelectionMode.Deep);
            List <MicroSplatTerrainJob> ts = new List <MicroSplatTerrainJob>();

            rawTerrains.Clear();
            for (int i = 0; i < objs.Length; ++i)
            {
                Terrain           t   = objs[i] as Terrain;
                MicroSplatTerrain mst = t.GetComponent <MicroSplatTerrain>();
                if (mst == null)
                {
                    continue;
                }
                rawTerrains.Add(t);
                if (t.materialType == Terrain.MaterialType.Custom && t.materialTemplate != null)
                {
                    if (!t.materialTemplate.HasProperty("_StreamControl"))
                    {
                        continue;
                    }
                    if (mst.streamTexture == null)
                    {
                        CreateTexture(t);
                    }

                    var tj = FindJob(t);
                    if (tj != null)
                    {
                        tj.collider   = t.GetComponent <Collider>();
                        tj.terrainTex = mst.streamTexture;
                        ts.Add(tj);
                    }
                    else
                    {
                        tj            = MicroSplatTerrainJob.CreateInstance <MicroSplatTerrainJob>();
                        tj.terrain    = t;
                        tj.collider   = t.GetComponent <Collider>();
                        tj.terrainTex = mst.streamTexture;
                        ts.Add(tj);
                    }
                }
            }
            if (terrains != null)
            {
                // clear out old terrains
                for (int i = 0; i < terrains.Length; ++i)
                {
                    if (!ts.Contains(terrains[i]))
                    {
                        DestroyImmediate(terrains[i]);
                    }
                }
            }

            terrains = ts.ToArray();
            jobEdits = new bool[ts.Count];
        }
Exemple #8
0
    public void DoPerPixelNormalGUI()
    {
        MicroSplatTerrain bt = target as MicroSplatTerrain;
        Terrain           t  = bt.GetComponent <Terrain>();

        if (t == null || t.terrainData == null)
        {
            EditorGUILayout.HelpBox("No Terrain data found", MessageType.Error);
            return;
        }
        if (t.materialType != Terrain.MaterialType.Custom || t.materialTemplate == null)
        {
            return;
        }

        if (bt.keywordSO == null)
        {
            return;
        }

        if (!bt.keywordSO.IsKeywordEnabled("_PERPIXNORMAL"))
        {
            bt.perPixelNormal = null;
            return;
        }

#if UNITY_2018_3_OR_NEWER
        if (bt.terrain.drawInstanced && bt.perPixelNormal)
        {
            EditorGUILayout.HelpBox("Per Pixel Normal is assigned, but shader is using Instance rendering, which automatically provides per-pixel normal. You may turn off per pixel normal and clear the normal data to save memory.", MessageType.Warning);
        }
#endif


        if (bt.perPixelNormal == null)
        {
            EditorGUILayout.HelpBox("Terrain Normal Data is not present, please generate", MessageType.Warning);
        }

        if (bt.perPixelNormal != null && bt.sTerrainDirty)
        {
            EditorGUILayout.HelpBox("Terrain Normal data is out of date, please update", MessageType.Warning);
        }
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.PrefixLabel("Normal Data");
        if (GUILayout.Button(bt.perPixelNormal == null ? "Generate" : "Update"))
        {
            GenerateTerrainNormalMap(bt);
        }

        if (bt.perPixelNormal != null && GUILayout.Button("Clear"))
        {
            bt.perPixelNormal = null;
        }
        EditorGUILayout.EndHorizontal();
    }
Exemple #9
0
    public static void SyncAll()
    {
        MicroSplatTerrain.SyncAll();
#if __MICROSPLAT_MESHTERRAIN__
        MicroSplatMeshTerrain.SyncAll();
#endif
#if __MICROSPLAT_MESH__
        MicroSplatMesh.SyncAll();
#endif
    }
Exemple #10
0
    void ExportSplatMaps()
    {
        var path = EditorUtility.SaveFolderPanel("Save textures to directory", "", "");

        if (string.IsNullOrEmpty(path))
        {
            return;
        }

        path = path.Replace("\\", "/");
        if (!path.EndsWith("/"))
        {
            path += "/";
        }


        MicroSplatTerrain mst = target as MicroSplatTerrain;
        var terrain           = mst.terrain;

        if (terrain == null)
        {
            return;
        }
        var tdata = terrain.terrainData;

        if (tdata == null)
        {
            return;
        }


        var data         = tdata.GetAlphamaps(0, 0, tdata.alphamapWidth, tdata.alphamapHeight);
        int textureCount = tdata.alphamapLayers / 4 + 1;

        for (int i = 0; i < textureCount; ++i)
        {
            Texture2D tex = new Texture2D(tdata.alphamapWidth, tdata.alphamapHeight, TextureFormat.ARGB32, false, true);
            for (int x = 0; x < tdata.alphamapWidth; ++x)
            {
                for (int y = 0; y < tdata.alphamapHeight; ++y)
                {
                    Color c;
                    c.r = data[x, y, i * 4];
                    c.g = tdata.alphamapLayers > i * 4 + 1 ? data[x, y, i * 4 + 1] : 0;
                    c.b = tdata.alphamapLayers > i * 4 + 2 ? data[x, y, i * 4 + 2] : 0;
                    c.a = tdata.alphamapLayers > i * 4 + 3 ? data[x, y, i * 4 + 3] : 0;
                    tex.SetPixel(x, y, c);
                }
            }
            tex.Apply();
            var bytes = tex.EncodeToPNG();
            System.IO.File.WriteAllBytes(path + "SplatControl" + i + ".png", bytes);
            DestroyImmediate(tex);
        }
    }
        bool VerifySnow()
        {
#if __MICROSPLAT_SNOW__
            for (int i = 0; i < rawTerrains.Count; ++i)
            {
                Terrain           t   = rawTerrains [i];
                MicroSplatTerrain mst = t.GetComponent <MicroSplatTerrain> ();

                if (mst != null)
                {
                    var tex = mst.snowMaskOverride;
                    if (tex != null)
                    {
                        AssetImporter   ai = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(tex));
                        TextureImporter ti = ai as TextureImporter;
                        if (ti == null || !ti.isReadable)
                        {
                            EditorGUILayout.HelpBox("Snow Mask texture is not read/write", MessageType.Error);
                            if (GUILayout.Button("Fix it!"))
                            {
                                ti.isReadable = true;
                                ti.SaveAndReimport();
                            }
                            return(false);
                        }

                        bool isLinear = ti.sRGBTexture == false;
                        bool isRGB32  = ti.textureCompression == TextureImporterCompression.Uncompressed && ti.GetDefaultPlatformTextureSettings().format == TextureImporterFormat.RGBA32;

                        if (isRGB32 == false || isLinear == false || ti.wrapMode == TextureWrapMode.Repeat)
                        {
                            EditorGUILayout.HelpBox("Snow Mask is not in the correct format (Uncompressed, linear, clamp, RGBA32)", MessageType.Error);
                            if (GUILayout.Button("Fix it!"))
                            {
                                ti.sRGBTexture        = false;
                                ti.textureCompression = TextureImporterCompression.Uncompressed;
                                var ftm = ti.GetDefaultPlatformTextureSettings();
                                ftm.format = TextureImporterFormat.RGBA32;
                                ti.SetPlatformTextureSettings(ftm);

                                ti.mipmapEnabled = true;
                                ti.wrapMode      = TextureWrapMode.Clamp;
                                ti.SaveAndReimport();
                            }
                            return(false);
                        }
                    }
                }
            }
#endif


            return(true);
        }
        void RevertTerrainSplats(MicroSplatTerrain t)
        {
            MicroSplatKeywords keywords = MicroSplatUtilities.FindOrCreateKeywords(t.templateMaterial);

            if (keywords.IsKeywordEnabled("_CUSTOMSPLATTEXTURES"))
            {
                if (t.customControl0 == null)
                {
                    Debug.LogError("Could not revert terrain because textures are missing!");
                    return;
                }

                UncompressTexture(t.customControl0);
                UncompressTexture(t.customControl1);
                UncompressTexture(t.customControl2);
                UncompressTexture(t.customControl3);
                UncompressTexture(t.customControl4);
                UncompressTexture(t.customControl5);
                UncompressTexture(t.customControl6);
                UncompressTexture(t.customControl7);

                int size   = t.customControl0.width;
                int layers = t.terrain.terrainData.alphamapLayers;
                t.terrain.terrainData.alphamapResolution = size;
                var maps = t.terrain.terrainData.GetAlphamaps(0, 0, size, size);

                ExtractSplats(ref maps, t.customControl0, 0, layers);
                ExtractSplats(ref maps, t.customControl1, 4, layers);
                ExtractSplats(ref maps, t.customControl2, 8, layers);
                ExtractSplats(ref maps, t.customControl3, 12, layers);
                ExtractSplats(ref maps, t.customControl4, 16, layers);
                ExtractSplats(ref maps, t.customControl5, 20, layers);
                ExtractSplats(ref maps, t.customControl6, 24, layers);
                ExtractSplats(ref maps, t.customControl7, 28, layers);

                t.terrain.terrainData.SetAlphamaps(0, 0, maps);
                EditorUtility.SetDirty(t.terrain.terrainData);


                keywords.DisableKeyword("_CUSTOMSPLATTEXTURES");
                MicroSplatShaderGUI.MicroSplatCompiler compiler = new MicroSplatShaderGUI.MicroSplatCompiler();
                compiler.Compile(t.templateMaterial);
                t.customControl0 = null;
                t.customControl1 = null;
                t.customControl2 = null;
                t.customControl3 = null;
                t.customControl4 = null;
                t.customControl5 = null;
                t.customControl6 = null;
                t.customControl7 = null;
                EditorUtility.SetDirty(t);
                MicroSplatTerrain.SyncAll();
            }
        }
Exemple #13
0
            public void ApplyTmp(Terrain terrain)
            {
                //checking microsplat component
                MicroSplatTerrain mso = terrain.GetComponent <MicroSplatTerrain>();

                if (mso == null)
                {
                    mso = terrain.gameObject.AddComponent <MicroSplatTerrain>();
                }
                mso.terrain          = terrain;        //otherwise nullref on newly created tiles
                mso.templateMaterial = terrain.materialTemplate;


                int numTextures = colors.Length;

                if (numTextures == 0)
                {
                    return;
                }
                int resolution = (int)Mathf.Sqrt(colors[0].Length);

                for (int t = 0; t < numTextures; t++)
                {
                    if (colors[t] == null)
                    {
                        continue;
                    }

                    Texture2D tex = GetTex(mso, t);
                    if (tex == null || tex.width != resolution || tex.height != resolution || tex.format != TextureFormat.RGBA32)
                    {
                        if (tex != null)
                        {
                                                        #if UNITY_EDITOR
                            if (!UnityEditor.AssetDatabase.Contains(tex))
                                                        #endif
                            GameObject.DestroyImmediate(tex);
                        }

                        tex          = new Texture2D(resolution, resolution, TextureFormat.RGBA32, false, true);
                        tex.wrapMode = TextureWrapMode.Mirror;                         //to avoid border seams
                        tex.name     = "CustomControl " + t;
                        SetTex(mso, t, tex);
                        //tex.hideFlags = HideFlags.DontSave;
                    }

                    tex.SetPixels(0, 0, tex.width, tex.height, colors[t]);
                    tex.Apply();
                }

                mso.Sync();
                //terrain.basemapDistance = 1000000;
            }
        //

#if __MICROSPLAT_DIGGER__
        public static Shader GetDiggerShader(MicroSplatTerrain mst)
        {
            if (mst.templateMaterial == null)
            {
                Debug.LogError("Digger: Template Material is not assigned to MicroSplatTerrain component");
                return(null);
            }
            var    path       = AssetDatabase.GetAssetPath(mst.templateMaterial.shader);
            string diggerPath = path.Replace(".shader", "_Digger.shader");

            return(AssetDatabase.LoadAssetAtPath <Shader> (diggerPath));
        }
Exemple #15
0
    public static void GenerateTerrainNormalMap(MicroSplatTerrain bt)
    {
        Terrain t = bt.GetComponent <Terrain>();
        int     w = t.terrainData.heightmapResolution;
        int     h = t.terrainData.heightmapResolution;

        Texture2D data = new Texture2D(w, h, TextureFormat.RGBA32, true, true);

        for (int x = 0; x < w; ++x)
        {
            for (int y = 0; y < h; ++y)
            {
                Vector3 normal = t.terrainData.GetInterpolatedNormal((float)x / w, (float)y / h);
                data.SetPixel(x, y, new Color(normal.x * 0.5f + 0.5f, normal.z * 0.5f + 0.5f, normal.y));
            }
        }
        data.Apply();

        var path = MicroSplatUtilities.RelativePathFromAsset(t.terrainData);

        path += "/" + t.name + "_normal.png";
        var bytes = data.EncodeToPNG();

        System.IO.File.WriteAllBytes(path, bytes);
        GameObject.DestroyImmediate(data);
        AssetDatabase.Refresh();
        bt.perPixelNormal = AssetDatabase.LoadAssetAtPath <Texture2D>(path);
        var ai = AssetImporter.GetAtPath(path);
        var ti = ai as TextureImporter;
        var ps = ti.GetDefaultPlatformTextureSettings();

        if (ti.isReadable == true ||
            ti.wrapMode != TextureWrapMode.Clamp ||
            ps.overridden != true ||
            ti.textureType != TextureImporterType.NormalMap)

        {
            ti.textureType   = TextureImporterType.NormalMap;
            ti.mipmapEnabled = true;
            ti.wrapMode      = TextureWrapMode.Clamp;
            ti.isReadable    = false;
            ps.overridden    = true;
            ti.SetPlatformTextureSettings(ps);
            ti.SaveAndReimport();
        }
        bt.sTerrainDirty = false;
        EditorUtility.SetDirty(bt);
        EditorUtility.SetDirty(bt.terrain);
        MicroSplatTerrain.SyncAll();
        AssetDatabase.SaveAssets();
    }
    public static void SyncAll()
    {
        MicroSplatTerrain.SyncAll();
#if __MICROSPLAT_MESHTERRAIN__
        MicroSplatMeshTerrain.SyncAll();
#endif
#if __MICROSPLAT_MESH__
        MicroSplatMesh.SyncAll();
        MicroSplatVertexMesh.SyncAll();
#endif
#if __MICROSPLAT_POLARIS__
        MicroSplatPolarisMesh.SyncAll();
#endif
    }
Exemple #17
0
        public static void DrawTextureField(MicroSplatTerrain t, GUIContent content, ref Texture2D tex, string keword)
        {
            if (t.templateMaterial.IsKeywordEnabled(keword))
            {
                EditorGUI.BeginChangeCheck();

                tex = EditorGUILayout.ObjectField(content, tex, typeof(Texture2D), false) as Texture2D;

                if (EditorGUI.EndChangeCheck())
                {
                    EditorUtility.SetDirty(t);
                }
            }
        }
        public void Revert(MicroSplatObject mso)
        {
            MicroSplatTerrain t = mso as MicroSplatTerrain;

            if (t != null)
            {
                if (t.templateMaterial == null)
                {
                    Debug.LogError("MicroSplatTerrain " + mso.gameObject.name + " does not have template material");
                }
                else
                {
                    RevertTerrainSplats(t);
                }
            }

#if __MICROSPLAT_MESH__
            MicroSplatMesh msm = mso as MicroSplatMesh;
            if (msm != null)
            {
                foreach (var subMesh in msm.subMeshEntries)
                {
                    foreach (var tex in subMesh.subMeshOverride.controlTextures)
                    {
                        UncompressTexture(tex);
                    }
                }
            }
#endif

#if __MICROSPLAT_PROCTEX__
            UncompressTexture(mso.procBiomeMask);
            UncompressTexture(mso.procBiomeMask2);
            UncompressTexture(mso.templateMaterial, "_ProcTexBiomeMask");
            UncompressTexture(mso.templateMaterial, "_ProcTexBiomeMask2");
#endif
#if __MICROSPLAT_SNOW__
            UncompressTexture(mso.snowMaskOverride);
            UncompressTexture(mso.templateMaterial, "_SnowMask");
#endif
#if __MICROSPLAT_STREAMS__
            UncompressTexture(mso.streamTexture);
            UncompressTexture(mso.templateMaterial, "_StreamControl");
#endif
#if __MICROSPLAT_GLOBALTEXTURE__
            UncompressTexture(mso.streamTexture);
            UncompressTexture(mso.templateMaterial, "_GlobalTintTex");
#endif
        }
Exemple #19
0
        //private Loading _loader;

        // Start is called before the first frame update
        private void Start()
        {
            DontDestroyOnLoad(this.gameObject);

            Terrain[] terrains = GameObject.FindObjectsOfType <Terrain>();

            foreach (Terrain terrain in terrains)
            {
                MicroSplatTerrain msTerrain = terrain.GetComponent <MicroSplatTerrain>();
                msTerrain.Sync();
            }

            terrainData = new TerrainMap(terrains, scene);

            pathFinderData = new PathfinderData(terrainData);
        }
    void WeightLimitingGUI(MicroSplatTerrain t)
    {
        if (MicroSplatUtilities.DrawRollup("Weight Limiting", false))
        {
            weightLimit          = EditorGUILayout.IntSlider("Weight Limit", weightLimit, 2, 4);
            multipassWeightLimit = EditorGUILayout.Toggle(CMultipassWeight, multipassWeightLimit);

            if (GUILayout.Button("Limit"))
            {
                WeightLimitTerrain(t, weightLimit, false);
                if (multipassWeightLimit)
                {
                    WeightLimitTerrain(t, weightLimit, true);
                }
            }
        }
    }
            public Material materialTemplate;             //source material assigned. Can't use terrain.materialTemplate since it will be changed with copy

            public override void Apply(Terrain terrain)
            {
                //checking microsplat component
                //this should be done before applying control since
                //microsplat removes template from terrain on disable (lod switch), so ensuring we have a material before base.Apply
                MicroSplatTerrain mso = null;

                if (assignComponent)
                {
                    mso = terrain.GetComponent <MicroSplatTerrain>();
                    if (mso == null)
                    {
                        mso = terrain.gameObject.AddComponent <MicroSplatTerrain>();
                    }
                    mso.terrain = terrain;                     //otherwise nullref on newly created tiles

                    MapMagic.Core.MapMagicObject mapMagic = terrain.transform.parent.parent.GetComponent <MapMagic.Core.MapMagicObject>();
                    mso.templateMaterial = mapMagic.terrainSettings.material;
                    if (terrain.materialTemplate == mso.templateMaterial || terrain.materialTemplate == null)                   //if material instance assigned (first run)
                    {
                        mso.matInstance          = new Material(mapMagic.terrainSettings.material);
                        terrain.materialTemplate = mso.matInstance;
                    }
                    else
                    {
                        mso.matInstance = terrain.materialTemplate;
                    }

                    mso.propData = propData;
                }
                else if (terrain.materialTemplate == null)                 //prevents an error (materialTemplate is null) on disabling "Set Component"
                {
                    MapMagic.Core.MapMagicObject mapMagic = terrain.transform.parent.parent.GetComponent <MapMagic.Core.MapMagicObject>();
                    terrain.materialTemplate = mapMagic.terrainSettings.material;
                }


                base.Apply(terrain);

                if (assignComponent)
                {
                    mso.Sync();
                }
            }
Exemple #22
0
    public void DoCavityMapGUI()
    {
        MicroSplatTerrain bt = target as MicroSplatTerrain;
        Terrain           t  = bt.GetComponent <Terrain>();

        if (t == null || t.terrainData == null)
        {
            EditorGUILayout.HelpBox("No Terrain data found", MessageType.Error);
            return;
        }
        if (t.materialTemplate == null)
        {
            return;
        }

        if (bt.keywordSO == null)
        {
            return;
        }

        if (bt.cavityMap == null)
        {
            EditorGUILayout.HelpBox("Cavity Map Data is not present, please generate or provide", MessageType.Warning);
        }
        bt.cavityMap = (Texture2D)EditorGUILayout.ObjectField("Cavity Map", bt.cavityMap, typeof(Texture2D), false);
        if (bt.cavityMap != null && bt.sTerrainDirty)
        {
            EditorGUILayout.HelpBox("Cavity data may be out of date as terrain has changed", MessageType.Warning);
        }
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.PrefixLabel("Cavity Data");
        if (GUILayout.Button(bt.cavityMap == null ? "Generate" : "Update"))
        {
            ComputeCavityFlowMap(bt);
        }

        if (bt.cavityMap != null && GUILayout.Button("Clear"))
        {
            bt.cavityMap = null;
        }
        EditorGUILayout.EndHorizontal();
    }
    private void Awake()
    {
        _terrain = Terrain.activeTerrain;

        if (_microSplatTerrain == null)
        {
            _microSplatTerrain = _terrain.GetComponent <MicroSplatTerrain>();
        }

        if (_microSplatTerrain == null)
        {
            throw new Exception("Camera not set up correctly, microsplat reference missing!");
        }

        if (_terrainMaterials == null || _terrainMaterials.Count == 0)
        {
            throw new Exception("Camera not set up correctly, terrain materials missing!");
        }

        _cam = GetComponent <Camera>();
    }
            public void SetTex(MicroSplatTerrain mso, int num, Texture2D tex)
            {
                switch (num)
                {
                case 0: mso.customControl0 = tex; break;

                case 1: mso.customControl1 = tex; break;

                case 2: mso.customControl2 = tex; break;

                case 3: mso.customControl3 = tex; break;

                case 4: mso.customControl4 = tex; break;

                case 5: mso.customControl5 = tex; break;

                case 6: mso.customControl6 = tex; break;

                case 7: mso.customControl7 = tex; break;
                }
            }
Exemple #25
0
    void SaveStream(StreamManager sm)
    {
        MicroSplatTerrain mt = sm.gameObject.GetComponent <MicroSplatTerrain>();
        var streamTex        = mt.streamTexture;
        var buffer           = sm.updateBuffer.GetCurrent();

        if (mt == null || streamTex == null || buffer == null || buffer.width != streamTex.width || buffer.height != streamTex.height)
        {
            return;
        }
        RenderTexture.active = buffer;
        Texture2D tex = new Texture2D(buffer.width, buffer.height, TextureFormat.ARGB32, false, true);

        tex.ReadPixels(new Rect(0, 0, buffer.width, buffer.height), 0, 0);
        tex.Apply();
        RenderTexture.active = null;
        var srcClrs = tex.GetPixels();
        var trgClrs = streamTex.GetPixels();

        for (int i = 0; i < srcClrs.Length; ++i)
        {
            Color t = trgClrs[i];
            Color d = srcClrs[i];
            t.b        = d.b;
            trgClrs[i] = t;
        }
        streamTex.SetPixels(trgClrs);
        streamTex.Apply();

        DestroyImmediate(tex);
        var path = AssetDatabase.GetAssetPath(streamTex);

        path = path.Replace("\\", "/");
        path = Application.dataPath.Substring(0, Application.dataPath.Length - 6) + "/" + path;
        var bytes = streamTex.EncodeToPNG();

        System.IO.File.WriteAllBytes(path, bytes);
        AssetDatabase.Refresh();
    }
        private static void CheckConfigForUpdates(TextureArrayConfig cfg)
        {
            int hash = GetNewHash(cfg);

            if (hash != cfg.hash)
            {
                cfg.hash = hash;
                EditorUtility.SetDirty(cfg);
                try
                {
                    sIsPostProcessing = true;
                    TextureArrayConfigEditor.CompileConfig(cfg);
                }
                finally
                {
                    sIsPostProcessing = false;
                    AssetDatabase.Refresh();
                    AssetDatabase.SaveAssets();
                    MicroSplatTerrain.SyncAll();
                }
            }
        }
    public void BakingGUI(MicroSplatTerrain t)
    {
        if (needsBake && Event.current.type == EventType.Repaint)
        {
            needsBake = false;
            Bake(t);
        }
        if (MicroSplatUtilities.DrawRollup("Render Baking", false))
        {
            res = (BakingResolutions)EditorGUILayout.EnumPopup(new GUIContent("Resolution"), res);

         #if UNITY_2017_3_OR_NEWER
            passes = (BakingPasses)EditorGUILayout.EnumFlagsField(new GUIContent("Features"), passes);
         #else
            passes = (BakingPasses)EditorGUILayout.EnumMaskPopup(new GUIContent("Features"), passes);
         #endif

            if (GUILayout.Button("Export Selected"))
            {
                needsBake = true;
            }
        }
    }
            public Texture2D GetTex(MicroSplatTerrain mso, int num)
            {
                switch (num)
                {
                case 0: return(mso.customControl0);

                case 1: return(mso.customControl1);

                case 2: return(mso.customControl2);

                case 3: return(mso.customControl3);

                case 4: return(mso.customControl4);

                case 5: return(mso.customControl5);

                case 6: return(mso.customControl6);

                case 7: return(mso.customControl7);

                default: return(null);
                }
            }
Exemple #29
0
    void ExportSplatMaps()
    {
        var path = EditorUtility.SaveFolderPanel("Save textures to directory", "", "");

        if (string.IsNullOrEmpty(path))
        {
            return;
        }

        path = path.Replace("\\", "/");
        if (!path.EndsWith("/"))
        {
            path += "/";
        }


        MicroSplatTerrain mst = target as MicroSplatTerrain;
        var terrain           = mst.terrain;

        if (terrain == null)
        {
            return;
        }
        var tdata = terrain.terrainData;

        if (tdata == null)
        {
            return;
        }

        for (int i = 0; i < tdata.alphamapTextures.Length; ++i)
        {
            var bytes = tdata.alphamapTextures[i].EncodeToTGA();
            System.IO.File.WriteAllBytes(path + "SplatControl" + i + ".tga", bytes);
        }
        AssetDatabase.Refresh();
    }
    /// <summary>
    /// Preprocess the terrain to clamp down on the number of splat maps which have weights on each control point. First pass
    /// limits the number of weights to the specified amount per control point. Since each rendered pixel is a blend of 4 possible
    /// control points, this still means a given pixel may need up to 4 weights even if the control point is clamped to 1 weight.
    /// In the second pass, we check all of the neighoring pixels to see if they have different weights- if they do, we clamp
    /// down to one less weight on this control point. The idea here is to create some extra headroom for the blend, but since
    /// you can still need 4 blend weights in some cases, there is no perfect solution to this issue when running with less than
    /// 4 blend weights. It does, however, greatly help when running under those constraints.
    ///
    /// </summary>
    /// <param name="bt">Bt.</param>
    /// <param name="maxWeights">Max weights.</param>
    /// <param name="secondPass">If set to <c>true</c> second pass.</param>
    public static void WeightLimitTerrain(MicroSplatTerrain bt, int maxWeights, bool secondPass = false)
    {
        Terrain t = bt.GetComponent <Terrain>();

        if (t == null)
        {
            return;
        }
        UnityEngine.TerrainData td = t.terrainData;
        if (td == null)
        {
            return;
        }

        int w = td.alphamapWidth;
        int h = td.alphamapHeight;
        int l = td.alphamapLayers;

        Undo.RegisterCompleteObjectUndo(t, "Weight Limit Terrain");

        var splats = td.GetAlphamaps(0, 0, w, h);

        float[]           data         = new float[16];
        List <WeightPair> sorted       = new List <WeightPair>();
        List <int>        validIndexes = new List <int>();

        for (int x = 0; x < w; ++x)
        {
            for (int y = 0; y < h; ++y)
            {
                // gather all weights
                for (int i = 0; i < l; ++i)
                {
                    data[i] = splats[x, y, i];
                }

                sorted.Clear();
                for (int i = 0; i < 16; ++i)
                {
                    var wp = new WeightPair();
                    wp.index  = i;
                    wp.weight = data[i];
                    sorted.Add(wp);
                }

                sorted.Sort((w0, w1) => w1.weight.CompareTo(w0.weight));

                // remove lower weights
                int allowedWeights = maxWeights;
                while (sorted.Count > allowedWeights)
                {
                    sorted.RemoveAt(sorted.Count - 1);
                }

                // generate valid index list
                validIndexes.Clear();
                for (int i = 0; i < sorted.Count; ++i)
                {
                    if (sorted[i].weight > 0)
                    {
                        validIndexes.Add(sorted[i].index);
                    }
                }
                // figure out if our neighbors have weights which we don't have- if so, clamp down harder to make room for blending..
                // if not, allow us to blend fully. We do this in a second pass so that small weights are reduced before we make
                // this decision..

                if (secondPass)
                {
                    for (int xm = -1; xm < 2; ++xm)
                    {
                        for (int ym = -1; ym < 2; ++ym)
                        {
                            int nx = x + xm;
                            int ny = y + ym;
                            if (nx >= 0 && ny >= 0 && nx < w && ny < y)
                            {
                                for (int layer = 0; layer < l; ++layer)
                                {
                                    float weight = splats[nx, ny, layer];
                                    if (weight > 0 && !validIndexes.Contains(layer))
                                    {
                                        allowedWeights = maxWeights - 1;
                                    }
                                }
                            }
                        }
                    }
                    while (sorted.Count > allowedWeights)
                    {
                        sorted.RemoveAt(sorted.Count - 1);
                    }
                    // generate valid index list
                    validIndexes.Clear();
                    for (int i = 0; i < sorted.Count; ++i)
                    {
                        if (sorted[i].weight > 0)
                        {
                            validIndexes.Add(sorted[i].index);
                        }
                    }
                }


                // clear non-valid indexes

                for (int j = 0; j < 16; ++j)
                {
                    if (!validIndexes.Contains(j))
                    {
                        data[j] = 0;
                    }
                }


                // now normalize weights so that they total one on each pixel

                float total = 0;
                for (int j = 0; j < 16; ++j)
                {
                    total += data[j];
                }
                float scale = 1.0f / total;
                for (int j = 0; j < 16; ++j)
                {
                    data[j] *= scale;
                }


                // now map back to splat data array
                for (int i = 0; i < l; ++i)
                {
                    splats[x, y, i] = data[i];
                }
            }
        }

        td.SetAlphamaps(0, 0, splats);
    }