public void TerrainToolboxUtilities_WhenSplitTerrain_HeightmapResolutionIsCorrect(int xSplit, int zSplit, int originalHeightmapRes)
        {
            TerrainToolboxWindow toolboxWindow   = EditorWindow.GetWindow(typeof(TerrainToolboxWindow)) as TerrainToolboxWindow;
            Texture2D            gradientTexture = CreateGradientTexture();
            int baseLevel     = 0;
            int remapLevel    = 1;
            int numberOfTiles = 1;

            ToolboxHelper.CopyTextureToTerrainHeight(m_TerrainComponent.terrainData, gradientTexture, Vector2Int.zero, originalHeightmapRes, numberOfTiles, baseLevel, remapLevel);

            Selection.activeGameObject = m_TerrainGO;
            m_TerrainGO.name           = "TestTerrain";
            m_TerrainComponent.name    = "TestComponent";

            RenderTexture oldRT = RenderTexture.active;

            RenderTexture.active = m_TerrainComponent.terrainData.heightmapTexture;

            // Run the test
            TestSplitTerrainHeightmapResolution(toolboxWindow, originalHeightmapRes, xSplit, zSplit);

            AssetDatabase.Refresh();
            RenderTexture.active = oldRT;
            toolboxWindow.Close();
        }
        public void TerrainToolboxUtilites_WhenApplySplatmaps_DoesNotDividebyZero()
        {
            // Preparation:
            // Collect data, create needed objects
            Texture2D    texture = new Texture2D(512, 512);
            TerrainLayer layer   = new TerrainLayer();

            layer.diffuseTexture = texture;
            TerrainLayer[] terrainLayers = { layer };

            //Add splatmap to terrain in order to import into the Utilities Window
            m_TerrainComponent.terrainData.terrainLayers = terrainLayers;
            Selection.activeGameObject = m_TerrainGO;

            // Execute the repro steps in code
            TerrainToolboxWindow toolboxWindow = EditorWindow.GetWindow(typeof(TerrainToolboxWindow)) as TerrainToolboxWindow;

            toolboxWindow.m_TerrainUtilitiesMode.ImportSplatmapsFromTerrain(true);
            Selection.activeGameObject = null;

            Assert.That(() =>
            {
                toolboxWindow.m_TerrainUtilitiesMode.ExportSplatmapsToTerrain(true);
            }, !Throws.TypeOf <System.DivideByZeroException>());
            toolboxWindow.Close();
        }
        public void TerrainToolboxUtilites_WhenSelectSplatmap_DoesNotIndexOutOfRange()
        {
            //Collect data, create needed objects
            Texture2D    texture = new Texture2D(512, 512);
            TerrainLayer layer   = new TerrainLayer();

            layer.diffuseTexture = texture;
            TerrainLayer[] terrainLayers = { layer };

            //Create gameobject with terrain component
            m_TerrainGO = new GameObject();
            Terrain terrain = m_TerrainGO.AddComponent <Terrain>();

            terrain.terrainData = new TerrainData();

            //Add splatmap to terrain in order to import into the Utilities Window
            terrain.terrainData.terrainLayers = terrainLayers;

            //Execute the repro steps in code
            TerrainToolboxWindow toolboxWindow = EditorWindow.GetWindow(typeof(TerrainToolboxWindow)) as TerrainToolboxWindow;

            Selection.activeGameObject = m_TerrainGO;
            toolboxWindow.m_TerrainUtilitiesMode.ImportSplatmapsFromTerrain();

            Assert.That(() =>
            {
                toolboxWindow.m_TerrainUtilitiesMode.ExportSplatmapsToTerrain(true);
            }, !Throws.TypeOf <System.IndexOutOfRangeException>());
            toolboxWindow.Close();
        }
        public void TerrainToolboxUtilites_WhenExportHeightmap_LevelCorrectionWorks(float min, float max, Heightmap.Format format, Heightmap.Depth depth = Heightmap.Depth.Bit16)
        {
            TerrainToolboxWindow toolboxWindow   = EditorWindow.GetWindow(typeof(TerrainToolboxWindow)) as TerrainToolboxWindow;
            Texture2D            gradientTexture = CreateGradientTexture();

            int heightmapResolution = 513;
            int numberOfTiles       = 1;
            int baseLevel           = 0;
            int remapLevel          = 1;

            ToolboxHelper.CopyTextureToTerrainHeight(m_TerrainComponent.terrainData, gradientTexture, Vector2Int.zero, heightmapResolution, numberOfTiles, baseLevel, remapLevel);

            Selection.activeGameObject = m_TerrainGO;
            m_TerrainGO.name           = "TestTerrain";
            m_TerrainComponent.name    = "TestComponent";

            RenderTexture oldRT = RenderTexture.active;

            RenderTexture.active = m_TerrainComponent.terrainData.heightmapTexture;

            //Run Tests and Cleanup files
            string fileName = m_TerrainGO.name + "_heightmap";
            string path     = Path.Combine(toolboxWindow.m_TerrainUtilitiesMode.m_Settings.HeightmapFolderPath, fileName);

            switch (format)
            {
            case Heightmap.Format.PNG:
                path += ".png";
                Assert.IsTrue(TestLevelCorrection(toolboxWindow, new Vector2(min, max), path, format));
                FileUtil.DeleteFileOrDirectory(path);
                FileUtil.DeleteFileOrDirectory(path + ".meta");
                break;

            case Heightmap.Format.TGA:
                path += ".tga";
                Assert.IsTrue(TestLevelCorrection(toolboxWindow, new Vector2(min, max), path, format));
                FileUtil.DeleteFileOrDirectory(path);
                FileUtil.DeleteFileOrDirectory(path + ".meta");
                break;

            case Heightmap.Format.RAW:
                path += ".raw";
                Assert.IsTrue(TestLevelCorrection(toolboxWindow, new Vector2(min, max), path, depth));
                FileUtil.DeleteFileOrDirectory(path);
                FileUtil.DeleteFileOrDirectory(path + ".meta");
                break;
            }

            AssetDatabase.Refresh();
            RenderTexture.active = oldRT;
            toolboxWindow.Close();
        }
        public void TerrainToolboxUtilites_WhenSplitTerrain_MissingTrees(int amountOfTreesX, int amountOfTreesZ, int tileXAxis, int tileZAxis)
        {
            //Setup tree prefab (Needs to be persistent)
            GameObject treePrefab = GameObject.CreatePrimitive(PrimitiveType.Cube);

            treePrefab.GetComponent <Renderer>().sharedMaterial.shader = Shader.Find("Nature/Tree Soft Occlusion Bark");
            string localPath = $"Assets/{treePrefab.name}.prefab";

            localPath = AssetDatabase.GenerateUniqueAssetPath(localPath);
            PrefabUtility.SaveAsPrefabAsset(treePrefab, localPath);
            treePrefab = AssetDatabase.LoadAssetAtPath(localPath, typeof(GameObject)) as GameObject;

            //Setup terrain object with trees
            TerrainData   terrainData = m_TerrainComponent.terrainData;
            TreePrototype prototype   = new TreePrototype();

            prototype.prefab = treePrefab;

            terrainData.treePrototypes = new TreePrototype[]
            {
                prototype
            };

            TreeInstance[] treeInstancesArray = new TreeInstance[amountOfTreesX * amountOfTreesZ];
            for (int z = 0; z < amountOfTreesZ; z++)
            {
                for (int x = 0; x < amountOfTreesX; x++)
                {
                    TreeInstance treeInstance = new TreeInstance();
                    treeInstance.prototypeIndex = 0;
                    treeInstance.position       = new Vector3(x / (float)amountOfTreesX, 0, z / (float)amountOfTreesZ);
                    treeInstancesArray[(z * amountOfTreesZ) + x] = treeInstance;
                }
            }
            terrainData.treeInstances = treeInstancesArray;


            // Set up parent object so we can locate the split tiles for cleanup after testing
            int groupingId = 12345;
            var parent     = new GameObject().AddComponent <TerrainGroup>();

            parent.GroupID = groupingId;
            m_TerrainComponent.transform.SetParent(parent.transform);

            //Execute the repro steps checking to make sure split terrains have trees
            Selection.activeGameObject = m_TerrainGO;
            TerrainToolboxWindow toolboxWindow = EditorWindow.GetWindow(typeof(TerrainToolboxWindow)) as TerrainToolboxWindow;

            toolboxWindow.m_TerrainUtilitiesMode.m_Settings.KeepOldTerrains = true;
            toolboxWindow.m_TerrainUtilitiesMode.m_Settings.TileXAxis       = tileXAxis;
            toolboxWindow.m_TerrainUtilitiesMode.m_Settings.TileZAxis       = tileZAxis;
            toolboxWindow.m_TerrainUtilitiesMode.SplitTerrains(true);

            Terrain[] objs          = GameObject.FindObjectsOfType <Terrain>();
            Terrain[] splitTerrains = objs.Where(
                obj => obj.terrainData?.treeInstanceCount > 0
                ).ToArray();
            Assert.IsNotEmpty(splitTerrains);

            //Cleanup
            toolboxWindow.Close();
            FileUtil.DeleteFileOrDirectory("Assets/Terrain");
            File.Delete("Assets/Terrain.meta");
            File.Delete(localPath);
            File.Delete(localPath + ".meta");
            UnityEditor.AssetDatabase.Refresh();
        }