Esempio n. 1
0
//        public static void ShowWorldBiomeMasksSpawner()
//        {

//            Terrain worldMapTerrain = TerrainHelper.GetWorldMapTerrain();

//            if (worldMapTerrain == null)
//            {
//                Debug.LogError("No world map created yet! Please create a world map first before opening the Biome Masks setup!");
//                return;
//            }

//            GaiaSessionManager gsm = GaiaSessionManager.GetSessionManager(false);

//            //Get the Gaia Settings
//            GaiaSettings settings = GaiaUtils.GetGaiaSettings();

//            //Create or find the stamper
//            GameObject spawnerObj = GameObject.Find(GaiaConstants.worldBiomeMasks);
//            if (spawnerObj == null)
//            {
//                spawnerObj = new GameObject(GaiaConstants.worldBiomeMasks);
//                GameObject worldMapObj = GaiaUtils.GetOrCreateWorldDesigner();
//                spawnerObj.transform.parent = worldMapObj.transform;
//                Spawner spawner = spawnerObj.AddComponent<WorldBiomeMasks>();
//                //Existing settings for world mask biomes in session? -> Take those!
//                if (gsm.m_session.m_worldBiomeMaskSettings != null)
//                {
//                    spawner.LoadSettings(gsm.m_session.m_worldBiomeMaskSettings);
//                }
//                else
//                {
//                    //No session settings? Use default setup from Gaia settings then
//                    if (settings != null)
//                    {
//                        if (settings.m_defaultBiomeMaskSettings != null)
//                        {
//                            spawner.LoadSettings(settings.m_defaultBiomeMaskSettings);
//                        }
//                    }
//                }
//                spawner.m_settings.m_isWorldmapSpawner = true;
//                spawner.m_settings.m_worldmapSpawnerType = WorldmapSpawnerType.WorldBiomeMasks;
//                spawner.m_worldMapTerrain = worldMapTerrain;
//                spawner.FitToTerrain();
//                spawner.UpdateMinMaxHeight();
//                gsm.m_session.m_worldBiomeMaskSettings = spawner.m_settings;
//            }
//            else
//            {
//                Spawner spawner = spawnerObj.GetComponent<Spawner>();
//                spawner.m_settings.m_isWorldmapSpawner = true;
//                spawner.m_worldMapTerrain = worldMapTerrain;
//                spawner.FitToTerrain();
//                spawner.UpdateMinMaxHeight();
//                gsm.m_session.m_worldBiomeMaskSettings = spawner.m_settings;
//            }

//            gsm.SwitchToWorldMap();
//#if UNITY_EDITOR
//            Selection.activeGameObject = spawnerObj;
//#endif
//        }


        public static GameObject GetOrCreateWorldMapStamper()
        {
            //Create or find the stamper
            GameObject stamperObj = GameObject.Find(GaiaConstants.worldMapStamper);

            if (stamperObj == null)
            {
                stamperObj = new GameObject(GaiaConstants.worldMapStamper);
                GameObject worldMapObj = GaiaUtils.GetOrCreateWorldDesigner();
                stamperObj.transform.parent = worldMapObj.transform;
                Stamper stamper = stamperObj.AddComponent <Stamper>();
                stamper.m_settings = ScriptableObject.CreateInstance <StamperSettings>();
                stamper.m_settings.m_isWorldmapStamper = true;
                stamper.m_recordUndo = false;
                stamper.UpdateMinMaxHeight();
                //stamper.m_seaLevel = m_settings.m_currentDefaults.m_seaLevel;
                stamper.FitToTerrain();
            }
            else
            {
                Stamper stamper = stamperObj.GetComponent <Stamper>();
                stamper.m_settings.m_isWorldmapStamper = true;
                stamper.m_recordUndo = false;
                stamper.UpdateMinMaxHeight();
                //stamper.m_seaLevel = m_settings.m_currentDefaults.m_seaLevel;
                stamper.FitToTerrain();
            }
            Terrain worldMapTerrain = TerrainHelper.GetWorldMapTerrain();

            if (worldMapTerrain != null)
            {
                stamperObj.transform.position = worldMapTerrain.transform.position + worldMapTerrain.terrainData.size / 2f;
            }
            return(stamperObj);
        }
Esempio n. 2
0
        public void OnWorldMapCreate()
        {
            m_worldMapTerrain = TerrainHelper.GetWorldMapTerrain();
            GaiaSettings gaiaSettings    = GaiaUtils.GetGaiaSettings();
            GaiaDefaults currentDefaults = gaiaSettings.m_currentDefaults;

            TerrainLoaderManager.Instance.TerrainSceneStorage.m_hasWorldMap = true;

            float worldheightmapRes = m_worldMapTerrain.terrainData.heightmapResolution / m_worldMapTerrain.terrainData.size.x;

            BoundsDouble bounds = new BoundsDouble();

            TerrainHelper.GetTerrainBounds(ref bounds);
            if (bounds.size.x > 0)
            {
                TerrainLoaderManager.Instance.TerrainSceneStorage.m_worldMaprelativeSize            = (float)m_currentWorldCreationSettings.m_tileSize / (float)bounds.size.x;
                TerrainLoaderManager.Instance.TerrainSceneStorage.m_worldMapRelativeHeightmapPixels = (((float)bounds.size.x / m_localTileSize) * m_localHeightmapRes / m_localHeightmapRes);
            }
            else
            {
                //no bounds size means no real terrains (yet) - set these parameters according to the current settings/defaults then
                TerrainLoaderManager.Instance.TerrainSceneStorage.m_worldMaprelativeSize            = (float)m_currentWorldCreationSettings.m_tileSize / (gaiaSettings.m_tilesX * currentDefaults.m_terrainSize);
                TerrainLoaderManager.Instance.TerrainSceneStorage.m_worldMapRelativeHeightmapPixels = ((gaiaSettings.m_tilesX * currentDefaults.m_terrainSize) / currentDefaults.m_terrainSize) * currentDefaults.m_heightmapResolution / currentDefaults.m_heightmapResolution;
            }
            SyncLocalMapToWorldMap();
            ShowWorldMapStampSpawner();
            GaiaSessionManager.OnWorldCreated -= OnWorldMapCreate;
        }
Esempio n. 3
0
        private void CopyWorldMapToLocalMap(BoundsDouble bounds, Terrain t)
        {
            //make sure we have a world map terrain first
            if (m_worldMapTerrain == null)
            {
                m_worldMapTerrain = TerrainHelper.GetWorldMapTerrain();
            }

            if (m_worldMapTerrain == null)
            {
                Debug.LogError("Can't export world map to local terrains - world map terrain is missing!");
                return;
            }

            RenderTexture chunkContent = RenderTexture.GetTemporary(t.terrainData.heightmapTexture.descriptor);
            //FilterMode oldFilterMode = m_worldMapTerrain.terrainData.heightmapTexture.filterMode;
            //m_worldMapTerrain.terrainData.heightmapTexture.filterMode = FilterMode.Trilinear;
            //t.terrainData.heightmapTexture.filterMode = FilterMode.Trilinear;
            //chunkContent.filterMode = FilterMode.Trilinear;
            int   maxTilesX    = Mathf.RoundToInt((float)bounds.size.x / t.terrainData.size.x);
            int   maxTilesZ    = Mathf.RoundToInt((float)bounds.size.z / t.terrainData.size.z);
            int   currentTileX = Mathf.RoundToInt((t.transform.position.x - (float)bounds.min.x) / t.terrainData.size.x);
            int   currentTileZ = Mathf.RoundToInt((t.transform.position.z - (float)bounds.min.z) / t.terrainData.size.z);
            float res          = (t.terrainData.heightmapResolution) / ((float)bounds.size.x / t.terrainData.bounds.size.x * (t.terrainData.heightmapResolution - 1));


            Bounds worldSpaceBounds = t.terrainData.bounds;

            worldSpaceBounds.center = new Vector3(worldSpaceBounds.center.x + t.transform.position.x, worldSpaceBounds.center.y + t.transform.position.y, worldSpaceBounds.center.z + t.transform.position.z);
            float   xPos = ((float)currentTileX * t.terrainData.heightmapResolution) / (maxTilesX * t.terrainData.heightmapResolution);
            float   zPos = ((float)currentTileZ * t.terrainData.heightmapResolution) / (maxTilesZ * t.terrainData.heightmapResolution);
            Vector2 pos  = new Vector2(xPos, zPos);



            Graphics.Blit(m_worldMapTerrain.terrainData.heightmapTexture, chunkContent, new Vector2(res, res), pos);
            //m_worldMapTerrain.terrainData.heightmapTexture.filterMode = oldFilterMode;
            RenderTexture previousRT = RenderTexture.active;

            RenderTexture.active = chunkContent;
            t.terrainData.CopyActiveRenderTextureToHeightmap(new RectInt(0, 0, t.terrainData.heightmapResolution, t.terrainData.heightmapResolution), new Vector2Int(0, 0), t.drawInstanced ? TerrainHeightmapSyncControl.None : TerrainHeightmapSyncControl.HeightOnly);
            RenderTexture.active = previousRT;
            t.terrainData.SyncHeightmap();
            t.editorRenderFlags = TerrainRenderFlags.All;

            RenderTexture.ReleaseTemporary(chunkContent);
            chunkContent = null;
        }
Esempio n. 4
0
        public void LoadStorageData()
        {
#if UNITY_EDITOR
            //Try to get the terrain scene storage file from the last used GUID first
            if (!String.IsNullOrEmpty(m_lastUsedGUID))
            {
                m_terrainSceneStorage = (TerrainSceneStorage)AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(m_lastUsedGUID), typeof(TerrainSceneStorage));
            }

            //No guid / storage object? Then we need to create one in the current session directory
            if (m_terrainSceneStorage == null)
            {
                GaiaSessionManager gsm = GaiaSessionManager.GetSessionManager();
                if (gsm != null && gsm.m_session != null)
                {
                    string path = GaiaDirectories.GetScenePath(gsm.m_session) + "/TerrainScenes.asset";
                    if (File.Exists(path))
                    {
                        m_terrainSceneStorage = (TerrainSceneStorage)AssetDatabase.LoadAssetAtPath(path, typeof(TerrainSceneStorage));
                    }
                    else
                    {
                        m_terrainSceneStorage = ScriptableObject.CreateInstance <TerrainSceneStorage>();
                        if (TerrainHelper.GetWorldMapTerrain() != null)
                        {
                            m_terrainSceneStorage.m_hasWorldMap = true;
                        }
                        AssetDatabase.CreateAsset(m_terrainSceneStorage, path);
                        AssetDatabase.ImportAsset(path);
                    }
                }
                else
                {
                    m_terrainSceneStorage = ScriptableObject.CreateInstance <TerrainSceneStorage>();
                }
            }

            //Check if there are scene files existing already and if they are in the storage data - if not, we should pick them up accordingly
            string directory = GaiaDirectories.GetTerrainScenePathForStorageFile(m_terrainSceneStorage);
            var    dirInfo   = new DirectoryInfo(directory);

            bool madeChanges = false;

            if (dirInfo != null)
            {
                FileInfo[] allFiles = dirInfo.GetFiles();
                foreach (FileInfo fileInfo in allFiles)
                {
                    if (fileInfo.Extension == ".unity")
                    {
                        string path = GaiaDirectories.GetPathStartingAtAssetsFolder(fileInfo.FullName);

                        if (!m_terrainSceneStorage.m_terrainScenes.Exists(x => x.GetTerrainName() == x.GetTerrainName(path)))
                        {
                            string firstSegment = fileInfo.Name.Split('-')[0];
                            int    xCoord = -99;
                            int    zCoord = -99;
                            bool   successX, successZ;
                            try
                            {
                                successX = Int32.TryParse(firstSegment.Substring(firstSegment.IndexOf('_') + 1, firstSegment.LastIndexOf('_') - (firstSegment.IndexOf('_') + 1)), out xCoord);
                                successZ = Int32.TryParse(firstSegment.Substring(firstSegment.LastIndexOf('_') + 1, firstSegment.Length - 1 - firstSegment.LastIndexOf('_')), out zCoord);
                            }
                            catch (Exception ex)
                            {
                                if (ex.Message == "123")
                                {
                                }
                                successX = false;
                                successZ = false;
                            }


                            if (successX && successZ)
                            {
                                //double centerX = (xCoord - (m_terrainSceneStorage.m_terrainTilesX / 2f)) * m_terrainSceneStorage.m_terrainTilesSize + (m_terrainSceneStorage.m_terrainTilesSize /2f);
                                //double centerZ = (zCoord - (m_terrainSceneStorage.m_terrainTilesZ / 2f)) * m_terrainSceneStorage.m_terrainTilesSize + (m_terrainSceneStorage.m_terrainTilesSize / 2f);
                                Vector2       offset   = new Vector2(-m_terrainSceneStorage.m_terrainTilesSize * m_terrainSceneStorage.m_terrainTilesX * 0.5f, -m_terrainSceneStorage.m_terrainTilesSize * m_terrainSceneStorage.m_terrainTilesZ * 0.5f);
                                Vector3Double position = new Vector3(m_terrainSceneStorage.m_terrainTilesSize * xCoord + offset.x, 0, m_terrainSceneStorage.m_terrainTilesSize * zCoord + offset.y);
                                Vector3Double center   = new Vector3Double(position + new Vector3Double(m_terrainSceneStorage.m_terrainTilesSize / 2f, 0f, m_terrainSceneStorage.m_terrainTilesSize / 2f));
                                BoundsDouble  bounds   = new BoundsDouble(center, new Vector3Double(m_terrainSceneStorage.m_terrainTilesSize, m_terrainSceneStorage.m_terrainTilesSize * 4, m_terrainSceneStorage.m_terrainTilesSize));
                                //Use forward slashes in the path - The Unity scene management classes expect it that way
                                path = path.Replace("\\", "/");
                                TerrainScene terrainScene = new TerrainScene()
                                {
                                    m_scenePath           = path,
                                    m_pos                 = position,
                                    m_bounds              = bounds,
                                    m_useFloatingPointFix = m_terrainSceneStorage.m_useFloatingPointFix
                                };

                                if (File.Exists(path.Replace("Terrain", GaiaConstants.ImpostorTerrainName)))
                                {
                                    terrainScene.m_impostorScenePath = path.Replace("Terrain", GaiaConstants.ImpostorTerrainName);
                                }

                                if (File.Exists(path.Replace("Terrain", "Collider")))
                                {
                                    terrainScene.m_colliderScenePath = path.Replace("Terrain", "Collider");
                                }

                                if (File.Exists(path.Replace("Terrain", "Backup")))
                                {
                                    terrainScene.m_backupScenePath = path.Replace("Terrain", "Backup");
                                }

                                m_terrainSceneStorage.m_terrainScenes.Add(terrainScene);
                                madeChanges = true;
                            }
                        }
                    }
                }
                if (madeChanges)
                {
                    EditorUtility.SetDirty(m_terrainSceneStorage);
                    AssetDatabase.SaveAssets();
                }
            }

            m_lastUsedGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m_terrainSceneStorage));


            RefreshTerrainsWithCurrentData();

            RefreshSceneViewLoadingRange();

            ////Go over the currently open scene and close the ones that do not seem to have a reference on them
            //for (int i = EditorSceneManager.loadedSceneCount-1; i >= 0; i--)
            //{
            //    Scene scene = EditorSceneManager.GetSceneAt(i);
            //    if (EditorSceneManager.GetActiveScene().Equals(scene))
            //    {
            //        continue;
            //    }
            //      TerrainScene terrainScene = m_terrainSceneStorage.m_terrainScenes.Find(x => x.m_scenePath == scene.path || x.m_impostorScenePath == scene.path || x.m_colliderScenePath == scene.path);
            //      if (terrainScene != null)
            //      {
            //            terrainScene.UpdateWithCurrentData();
            //      }
            //      else
            //      {
            //            EditorSceneManager.UnloadSceneAsync(scene);
            //      }
            //}
#endif
        }
Esempio n. 5
0
        public static void ShowWorldMapStampSpawner()
        {
            Terrain worldMapTerrain = TerrainHelper.GetWorldMapTerrain();

            if (worldMapTerrain == null)
            {
                Debug.LogError("No world map created yet! Please create a world map first before opening the random terrain generator");
                return;
            }

            GaiaSessionManager gsm = GaiaSessionManager.GetSessionManager(false);

            //Get the Gaia Settings
            GaiaSettings settings = GaiaUtils.GetGaiaSettings();

            //Create or find the stamper
            GameObject spawnerObj = GaiaUtils.GetOrCreateWorldDesigner();
            Spawner    spawner    = spawnerObj.GetComponent <WorldDesigner>();

            if (spawner == null)
            {
                spawner = spawnerObj.AddComponent <WorldDesigner>();
                if (settings != null)
                {
                    if (settings.m_defaultStampSpawnSettings != null)
                    {
                        spawner.LoadSettings(settings.m_defaultStampSpawnSettings);
                    }
                }
                spawner.m_settings.m_isWorldmapSpawner = true;
                spawner.m_worldMapTerrain = worldMapTerrain;

                //set up the export settings with the current Gaia Settings / defaults
                spawner.m_worldCreationSettings.m_targeSizePreset = settings.m_targeSizePreset;
                spawner.m_worldCreationSettings.m_xTiles          = settings.m_tilesX;
                spawner.m_worldCreationSettings.m_zTiles          = settings.m_tilesZ;
                spawner.m_worldTileSize = GaiaUtils.IntToEnvironmentSize(settings.m_currentDefaults.m_terrainSize);
                spawner.m_worldCreationSettings.m_tileSize              = settings.m_currentDefaults.m_terrainSize;
                spawner.m_worldCreationSettings.m_tileHeight            = settings.m_currentDefaults.m_terrainHeight;
                spawner.m_worldCreationSettings.m_createInScene         = settings.m_createTerrainScenes;
                spawner.m_worldCreationSettings.m_autoUnloadScenes      = settings.m_unloadTerrainScenes;
                spawner.m_worldCreationSettings.m_applyFloatingPointFix = settings.m_floatingPointFix;
                spawner.m_worldCreationSettings.m_qualityPreset         = settings.m_currentEnvironment;
                if (spawner.m_worldCreationSettings.m_gaiaDefaults == null)
                {
                    spawner.m_worldCreationSettings.m_gaiaDefaults = settings.m_currentDefaults;
                }

                spawner.StoreWorldSize();
                //spawner.StoreHeightmapResolution();

                //Check if we do have an existing terrain already, if yes, we would want to re-use it for the world map -> terrain export
                if (GaiaUtils.HasTerrains())
                {
                    spawner.m_useExistingTerrainForWorldMapExport = true;
                }
                else
                {
                    //No terrains yet - set up the terrain tiles in the session according to the current world creation settings
                    //so that the stamp previews will come out right.
                    TerrainLoaderManager.Instance.TerrainSceneStorage.m_terrainTilesX = settings.m_tilesX;
                    TerrainLoaderManager.Instance.TerrainSceneStorage.m_terrainTilesZ = settings.m_tilesZ;
                }

                spawner.FitToTerrain();
                spawner.UpdateMinMaxHeight();
            }
            else
            {
                spawner.m_settings.m_isWorldmapSpawner = true;
                spawner.m_worldMapTerrain = worldMapTerrain;
                spawner.FitToTerrain();
                spawner.UpdateMinMaxHeight();
            }
            gsm.m_session.m_worldBiomeMaskSettings = spawner.m_settings;
            TerrainLoaderManager.Instance.SwitchToWorldMap();
#if UNITY_EDITOR
            Selection.activeGameObject = spawnerObj;
#endif
        }
Esempio n. 6
0
        public void CreateWorldMapTerrain()
        {
            //Remove old world map terrain, if any
            Terrain oldWMTerrain = TerrainHelper.GetWorldMapTerrain();

            if (oldWMTerrain != null)
            {
#if UNITY_EDITOR
                if (EditorUtility.DisplayDialog("Delete old world map?", "You are about to create a new world map in this scene. This will delete the existing world map and the stamp tokens on it. This will only affect the small world map terrain, the actual full scene terrain tiles will not be removed. Continue?", "Continue", "Cancel"))
                {
                    DestroyImmediate(oldWMTerrain.gameObject);
                }
                else
                {
                    return;
                }
#else
                Destroy(oldWMTerrain.gameObject);
#endif
            }

            GaiaSettings       gaiaSettings    = GaiaUtils.GetGaiaSettings();
            GaiaDefaults       currentDefaults = gaiaSettings.m_currentDefaults;
            GaiaSessionManager gsm             = GaiaSessionManager.GetSessionManager();

            //Collect some info from the existing world, if any.

            //We need the average height from the terrains to create the height of the worldmap accordingly in scale
            double averageHeight = currentDefaults.m_terrainHeight;
            //We need the heightmap resolution and terrain size stored in the session
            //To properly scale between world map and local map even when one of the two is not loaded at the moment

            int count = 0;

            foreach (Terrain t in Terrain.activeTerrains)
            {
                averageHeight += t.terrainData.size.y;
                if (!TerrainHelper.IsWorldMapTerrain(t))
                {
                    m_localHeightmapRes = t.terrainData.heightmapResolution;
                    m_localTileSize     = t.terrainData.size.x;
                }

                count++;
            }
            //}
            //only calculate an average if there is at least one placeholder or terrain
            if (count > 0)
            {
                averageHeight /= count;
            }


            BoundsDouble bounds = new BoundsDouble();
            TerrainHelper.GetTerrainBounds(ref bounds);
            //Collect the new world settings for world creation
            WorldCreationSettings worldCreationSettings = ScriptableObject.CreateInstance <WorldCreationSettings>();
            worldCreationSettings.m_xTiles                = 1;
            worldCreationSettings.m_zTiles                = 1;
            worldCreationSettings.m_tileSize              = (count > 0) ? Mathd.RoundToInt(bounds.size.x) : gaiaSettings.m_tilesX * currentDefaults.m_terrainSize;
            worldCreationSettings.m_tileHeight            = currentDefaults.m_terrainHeight;
            worldCreationSettings.m_createInScene         = false;
            worldCreationSettings.m_autoUnloadScenes      = false;
            worldCreationSettings.m_applyFloatingPointFix = false;
            worldCreationSettings.m_applyFloatingPointFix = false;
            worldCreationSettings.m_centerOffset          = Vector3.zero; //(count > 0) ? new Vector2Double(bounds.center.x + bounds.extents.x + worldCreationSettings.m_tileSize, bounds.center.z) : Vector2Double.zero;
            worldCreationSettings.m_isWorldMap            = true;
            //clone defaults so we can inject our custom heightmap resolution for the worldmap
            GaiaDefaults clonedDefaults = Instantiate(currentDefaults);
            clonedDefaults.m_heightmapResolution = (int)m_heightmapResolution;

            worldCreationSettings.m_gaiaDefaults = clonedDefaults;

            m_currentWorldCreationSettings     = worldCreationSettings;
            GaiaSessionManager.OnWorldCreated -= OnWorldMapCreate;
            GaiaSessionManager.OnWorldCreated += OnWorldMapCreate;
            GaiaSessionManager.CreateWorld(worldCreationSettings);
        }
Esempio n. 7
0
        public RenderTexture BakeTerrainWorldBiomeMask(Terrain terrain, string worldBiomeMaskGUID)
        {
            if (m_gaiaSessionManager == null)
            {
                m_gaiaSessionManager = GaiaSessionManager.GetSessionManager(false);
            }
            if (m_worldMapTerrain == null)
            {
                m_worldMapTerrain = TerrainHelper.GetWorldMapTerrain();
            }
            if (m_worldMapTerrain == null)
            {
                Debug.LogWarning("Found no world map terrain for baking a world biome mask.");
                return(null);
            }
            if (String.IsNullOrEmpty(worldBiomeMaskGUID))
            {
                return(null);
            }

            if (m_gaiaSessionManager.m_session == null)
            {
                Debug.LogWarning("Found no session for baking a world biome mask.");
                return(null);
            }

            if (m_gaiaSessionManager.m_session.m_worldBiomeMaskSettings == null)
            {
                Debug.LogWarning("Found no world designer settings in the session for baking a world biome mask.");
                return(null);
            }

            //we need to apply the mask stack for this biome mask on the world map to get the result, then copy the appropiate rectangle for the queried terrain into the cache & return it.
            bool worldMapActiveState = m_worldMapTerrain.gameObject.activeInHierarchy;

            m_worldMapTerrain.gameObject.SetActive(true);
            GameObject emptyGO = new GameObject();

            emptyGO.transform.position = new Vector3(m_worldMapTerrain.transform.position.x + m_worldMapTerrain.terrainData.size.x / 2f, m_worldMapTerrain.transform.position.y, m_worldMapTerrain.transform.position.z + +m_worldMapTerrain.terrainData.size.z / 2f);
            GaiaMultiTerrainOperation operation = new GaiaMultiTerrainOperation(m_worldMapTerrain, emptyGO.transform, m_worldMapTerrain.terrainData.size.x);

            operation.m_isWorldMapOperation = true;
            operation.GetHeightmap();
            operation.GetNormalmap();
            operation.CollectTerrainBakedMasks();
            RenderTextureDescriptor rtDescriptor = operation.RTbakedMask.descriptor;

            RenderTexture inputTexture = RenderTexture.GetTemporary(rtDescriptor);

            RenderTexture currentRT = RenderTexture.active;

            RenderTexture.active = inputTexture;
            GL.Clear(true, true, Color.white);
            RenderTexture.active = currentRT;
            RenderTexture ruleOutputTexture = RenderTexture.GetTemporary(rtDescriptor);

            ImageMask[] maskStack = m_gaiaSessionManager.m_session.m_worldBiomeMaskSettings.m_spawnerRules.Find(x => x.GUID == worldBiomeMaskGUID).m_imageMasks;

            //Calculate Target position &/ resolution
            BoundsDouble bounds = new BoundsDouble();

            TerrainHelper.GetTerrainBounds(ref bounds);
            bounds.center -= TerrainLoaderManager.Instance.GetOrigin();
            RenderTexture chunkContent = new RenderTexture(terrain.terrainData.heightmapTexture.descriptor);
            int           maxTilesX    = Mathf.RoundToInt((float)bounds.size.x / terrain.terrainData.size.x);
            int           maxTilesZ    = Mathf.RoundToInt((float)bounds.size.z / terrain.terrainData.size.z);
            int           currentTileX = Mathf.RoundToInt((terrain.transform.position.x - (float)bounds.min.x) / terrain.terrainData.size.x);
            int           currentTileZ = Mathf.RoundToInt((terrain.transform.position.z - (float)bounds.min.z) / terrain.terrainData.size.z);
            float         res          = (terrain.terrainData.heightmapResolution) / ((float)bounds.size.x / terrain.terrainData.bounds.size.x * (terrain.terrainData.heightmapResolution - 1));


            Bounds worldSpaceBounds = terrain.terrainData.bounds;

            worldSpaceBounds.center = new Vector3(worldSpaceBounds.center.x + terrain.transform.position.x, worldSpaceBounds.center.y + terrain.transform.position.y, worldSpaceBounds.center.z + terrain.transform.position.z);
            float   xPos = ((float)currentTileX * terrain.terrainData.heightmapResolution) / (maxTilesX * terrain.terrainData.heightmapResolution);
            float   zPos = ((float)currentTileZ * terrain.terrainData.heightmapResolution) / (maxTilesZ * terrain.terrainData.heightmapResolution);
            Vector2 pos  = new Vector2(xPos, zPos);

            //If we have a mask stack, we need to process it
            if (maskStack != null && maskStack.Length > 0)
            {
                //We start from a white texture, so we need the first mask action in the stack to always be "Multiply", otherwise there will be no result.
                maskStack[0].m_blendMode = ImageMaskBlendMode.Multiply;

                float maxWorldHeight = 0f;
                float minWorldHeight = 0f;
                m_gaiaSessionManager.GetWorldMinMax(ref minWorldHeight, ref maxWorldHeight, true);

                //Iterate through all image masks and set up the current paint context in case the shader uses heightmap data
                foreach (ImageMask mask in maskStack)
                {
                    mask.m_multiTerrainOperation = operation;
                    mask.m_seaLevel       = m_gaiaSessionManager.GetSeaLevel(true);
                    mask.m_maxWorldHeight = maxWorldHeight;
                    mask.m_minWorldHeight = minWorldHeight;
                }

                Graphics.Blit(ImageProcessing.ApplyMaskStack(inputTexture, ruleOutputTexture, maskStack, ImageMaskInfluence.Local), ruleOutputTexture);
            }
            else
            {
                //no mask stack -> just blit the white input texture over as the output
                Graphics.Blit(inputTexture, ruleOutputTexture);
            }
            operation.CloseOperation();
            DestroyImmediate(emptyGO);
            RenderTexture.ReleaseTemporary(inputTexture);
            m_worldMapTerrain.gameObject.SetActive(worldMapActiveState);

            //copy the rule output into the right size for the requested terrain chunk
            Graphics.Blit(ruleOutputTexture, chunkContent, new Vector2(res, res), pos);

            string filename = GetWorldBiomeMaskFilename(terrain, worldBiomeMaskGUID);

            SaveBakedMaskInCache(chunkContent, terrain, filename);

            RenderTexture.ReleaseTemporary(ruleOutputTexture);

            return(chunkContent);
        }