Ejemplo n.º 1
0
        public void RemoveForeignTerrainDetails(List <SpawnerSettings> biomeSpawnerSettings, List <string> validTerrainNames = null)
        {
            ProgressBar.Show(ProgressBarPriority.BiomeRemoval, "Removing Foreign Terrain Details", "Removing...");
            List <ResourceProtoDetail> knownTerrainDetails = new List <ResourceProtoDetail>();
            Terrain currentTerrain = GetCurrentTerrain();

            foreach (SpawnerSettings spawnerSettings in biomeSpawnerSettings)
            {
                foreach (SpawnRule sr in spawnerSettings.m_spawnerRules)
                {
                    if (sr.m_resourceType == GaiaConstants.SpawnerResourceType.TerrainDetail)
                    {
                        knownTerrainDetails.Add(spawnerSettings.m_resources.m_detailPrototypes[sr.m_resourceIdx]);
                    }
                }
            }

            GaiaMultiTerrainOperation operation = new GaiaMultiTerrainOperation(currentTerrain, transform, m_settings.m_range * 2f, false, validTerrainNames);

            operation.GetHeightmap();
            operation.GetNormalmap();
            operation.CollectTerrainDetails();
            operation.CollectTerrainTrees();
            operation.CollectTerrainGameObjects();
            operation.CollectTerrainBakedMasks();

            ProgressBar.Show(ProgressBarPriority.BiomeRemoval, "Removing Foreign Terrain Details", "Removing Terrain Details...");
            operation.RemoveForeignTerrainDetails(ApplyBrush(operation, MultiTerrainOperationType.TerrainDetail), knownTerrainDetails, m_settings.m_removeForeignTerrainDetailsStrength);

            operation.CloseOperation();
            ProgressBar.Clear(ProgressBarPriority.BiomeRemoval);
        }
Ejemplo n.º 2
0
        public void RemoveForeignTrees(List <SpawnerSettings> biomeSpawnerSettings, List <string> validTerrainNames = null)
        {
            ProgressBar.Show(ProgressBarPriority.BiomeRemoval, "Removing Foreign Trees", "Removing...");
            //Collect the "allowed" tree prefabs in a list, any tree that is not in this list will be affected by the removal operation
            List <GameObject> domesticTreePrefabs = new List <GameObject>();
            //List<TreePrototype> treeProtosToRemove = new List<TreePrototype>();
            Terrain currentTerrain = GetCurrentTerrain();

            foreach (SpawnerSettings spawnerSettings in biomeSpawnerSettings)
            {
                foreach (SpawnRule sr in spawnerSettings.m_spawnerRules)
                {
                    if (sr.m_resourceType == GaiaConstants.SpawnerResourceType.TerrainTree)
                    {
                        domesticTreePrefabs.Add(spawnerSettings.m_resources.m_treePrototypes[sr.m_resourceIdx].m_desktopPrefab);
                    }
                }
            }

            GaiaMultiTerrainOperation operation = new GaiaMultiTerrainOperation(currentTerrain, transform, m_settings.m_range * 2f, false, validTerrainNames);

            operation.GetHeightmap();
            operation.GetNormalmap();
            operation.CollectTerrainDetails();
            operation.CollectTerrainTrees();
            operation.CollectTerrainGameObjects();
            operation.CollectTerrainBakedMasks();

            operation.RemoveForeignTrees(ApplyBrush(operation, MultiTerrainOperationType.Tree), domesticTreePrefabs, m_settings.m_removeForeignTreesStrength);
            ProgressBar.Clear(ProgressBarPriority.BiomeRemoval);
            operation.CloseOperation();
        }
Ejemplo n.º 3
0
        public static void BakeMaskStack(ImageMask[] maskStack, Terrain terrain, Transform transform, float range, int resolution, string path)
        {
            //Simulate an operation to allow the image masks to acces the current terrain data
            GaiaMultiTerrainOperation operation = new GaiaMultiTerrainOperation(terrain, transform, range);

            operation.GetHeightmap();
            operation.GetNormalmap();
            operation.CollectTerrainBakedMasks();

            float maxCurrentTerrainHeight = 0f;
            float minCurrentTerrainHeight = 0f;
            float seaLevel;

            GaiaSessionManager gsm = GaiaSessionManager.GetSessionManager();

            gsm.GetWorldMinMax(ref minCurrentTerrainHeight, ref maxCurrentTerrainHeight);
            seaLevel = gsm.GetSeaLevel();

            if (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;

                //Iterate through all image masks and set up the required data that masks might need to function properly
                foreach (ImageMask mask in maskStack)
                {
                    //mask.m_heightmapContext = heightmapContext;
                    //mask.m_normalmapContext = normalmapContext;
                    //mask.m_collisionContext = collisionContext;
                    mask.m_multiTerrainOperation = operation;
                    mask.m_seaLevel       = seaLevel;
                    mask.m_maxWorldHeight = maxCurrentTerrainHeight;
                    mask.m_minWorldHeight = minCurrentTerrainHeight;
                }
            }

            RenderTexture inputTexture = RenderTexture.GetTemporary(resolution, resolution, 0, RenderTextureFormat.ARGBFloat);
            RenderTexture currentRT    = RenderTexture.active;

            RenderTexture.active = inputTexture;
            GL.Clear(true, true, Color.white);
            RenderTexture.active = currentRT;
            RenderTexture localOutputTexture  = RenderTexture.GetTemporary(inputTexture.descriptor);
            RenderTexture globalOutputTexture = RenderTexture.GetTemporary(inputTexture.descriptor);

            localOutputTexture  = ImageProcessing.ApplyMaskStack(inputTexture, localOutputTexture, maskStack, ImageMaskInfluence.Local);
            globalOutputTexture = ImageProcessing.ApplyMaskStack(localOutputTexture, globalOutputTexture, maskStack, ImageMaskInfluence.Global);

            WriteRenderTexture(path, globalOutputTexture);

            RenderTexture.ReleaseTemporary(inputTexture);
            RenderTexture.ReleaseTemporary(localOutputTexture);
            RenderTexture.ReleaseTemporary(globalOutputTexture);
            inputTexture        = null;
            localOutputTexture  = null;
            globalOutputTexture = null;
            operation.CloseOperation();
        }
Ejemplo n.º 4
0
        public void RemoveForeignGameObjects(List <SpawnerSettings> biomeSpawnerSettings, List <string> validTerrainNames = null)
        {
            ProgressBar.Show(ProgressBarPriority.BiomeRemoval, "Removing Foreign GameObjects", "Removing...");
            List <ResourceProtoGameObjectInstance> knownProtoInstances      = new List <ResourceProtoGameObjectInstance>();
            List <ResourceProtoGameObjectInstance> GoProtoInstancesToRemove = new List <ResourceProtoGameObjectInstance>();
            Terrain currentTerrain = GetCurrentTerrain();

            foreach (SpawnerSettings spawnerSettings in biomeSpawnerSettings)
            {
                foreach (SpawnRule sr in spawnerSettings.m_spawnerRules)
                {
                    if (sr.m_resourceType == GaiaConstants.SpawnerResourceType.GameObject)
                    {
                        foreach (ResourceProtoGameObjectInstance instance in spawnerSettings.m_resources.m_gameObjectPrototypes[sr.m_resourceIdx].m_instances)
                        {
                            knownProtoInstances.Add(instance);
                        }
                    }
                }
            }

            GaiaMultiTerrainOperation operation = new GaiaMultiTerrainOperation(currentTerrain, transform, m_settings.m_range * 2f, false, validTerrainNames);

            operation.GetHeightmap();
            operation.GetNormalmap();
            operation.CollectTerrainDetails();
            operation.CollectTerrainTrees();
            operation.CollectTerrainGameObjects();
            operation.CollectTerrainBakedMasks();

            int protoIndex  = 0;
            var allSpawners = Resources.FindObjectsOfTypeAll <Spawner>();

            foreach (Spawner spawner in allSpawners)
            {
                //During the removal we have to put the spawn settings in remove mode
                SpawnMode originalMode = spawner.m_settings.m_spawnMode;
                spawner.m_settings.m_spawnMode = SpawnMode.Remove;

                ProgressBar.Show(ProgressBarPriority.BiomeRemoval, "Removing Foreign GameObjects", "Removing Game Objects...", protoIndex, allSpawners.Length);
                foreach (SpawnRule sr in spawner.m_settings.m_spawnerRules)
                {
                    if (sr.m_resourceType == GaiaConstants.SpawnerResourceType.GameObject)
                    {
                        ResourceProtoGameObject protoGO = spawner.m_settings.m_resources.m_gameObjectPrototypes[sr.m_resourceIdx];
                        foreach (ResourceProtoGameObjectInstance instance in protoGO.m_instances)
                        {
                            if (!knownProtoInstances.Contains(instance))
                            {
                                operation.SetTerrainGameObjects(ApplyBrush(operation, MultiTerrainOperationType.GameObject), protoGO, sr, spawner.m_settings, 0, ref sr.m_spawnedInstances, m_settings.m_removeForeignGameObjectStrength, false);
                                //no need to look at other instances if this one triggered the removal already
                                break;
                            }
                        }
                    }
                }

                spawner.m_settings.m_spawnMode = originalMode;
                protoIndex++;
            }
            operation.CloseOperation();

#if UNITY_EDITOR
            //need to dirty the scene when we remove game objects
            EditorSceneManager.MarkSceneDirty(gameObject.scene);
#endif
            ProgressBar.Clear(ProgressBarPriority.BiomeRemoval);
        }
Ejemplo n.º 5
0
        private RenderTexture ApplyBrush(GaiaMultiTerrainOperation operation, MultiTerrainOperationType opType = MultiTerrainOperationType.Heightmap)
        {
            Terrain currentTerrain = GetCurrentTerrain();

            RenderTextureDescriptor rtDescriptor = operation.RTheightmap.descriptor;

            switch (opType)
            {
            case MultiTerrainOperationType.Heightmap:
                rtDescriptor = operation.RTheightmap.descriptor;
                break;

            case MultiTerrainOperationType.Texture:
                rtDescriptor = operation.RTtextureSplatmap.descriptor;
                break;

            case MultiTerrainOperationType.TerrainDetail:
                rtDescriptor = operation.RTdetailmap.descriptor;
                break;

            case MultiTerrainOperationType.Tree:
                rtDescriptor = operation.RTterrainTree.descriptor;
                break;

            case MultiTerrainOperationType.GameObject:
                rtDescriptor = operation.RTgameObject.descriptor;
                break;

            default:
                rtDescriptor = operation.RTheightmap.descriptor;
                break;
            }

            //Random write needs to be enabled for certain mask types to function!
            rtDescriptor.enableRandomWrite = true;

            RenderTexture inputTexture = RenderTexture.GetTemporary(rtDescriptor);

            RenderTexture currentRT = RenderTexture.active;

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

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

            //Get the combined masks for the biome
            RenderTexture biomeOutputTexture = RenderTexture.GetTemporary(rtDescriptor);

            Graphics.Blit(ImageProcessing.ApplyMaskStack(inputTexture, biomeOutputTexture, m_settings.m_imageMasks, ImageMaskInfluence.Local), biomeOutputTexture);
            ReleaseRenderTexture(inputTexture);
            inputTexture = null;
            return(biomeOutputTexture);
        }
Ejemplo n.º 6
0
        public void DrawBiomePreview()
        {
            if (m_drawPreview)
            {
                //Set up a multi-terrain operation once, all rules can then draw from the data collected here
                Terrain currentTerrain = GetCurrentTerrain();
                if (currentTerrain == null)
                {
                    return;
                }

                GaiaMultiTerrainOperation operation = new GaiaMultiTerrainOperation(currentTerrain, transform, m_settings.m_range * 2f);
                operation.GetHeightmap();


                //only re-generate all textures etc. if settings have changed and the preview is dirty, otherwise we can just use the cached textures
                if (m_biomePreviewDirty == true)
                {
                    //Get additional op data (required for certain image masks)
                    operation.GetNormalmap();
                    operation.CollectTerrainBakedMasks();

                    //Clear texture cache first
                    if (m_cachedPreviewRT != null)
                    {
                        m_cachedPreviewRT.Release();
                        DestroyImmediate(m_cachedPreviewRT);
                    }

                    m_cachedPreviewRT = new RenderTexture(operation.RTheightmap);
                    RenderTexture currentRT = RenderTexture.active;
                    RenderTexture.active = m_cachedPreviewRT;
                    GL.Clear(true, true, Color.black);
                    RenderTexture.active = currentRT;

                    Graphics.Blit(ApplyBrush(operation), m_cachedPreviewRT);
                    RenderTexture.active = currentRT;
                    //Everything processed, preview not dirty anymore
                    m_biomePreviewDirty = false;
                }

                //Now draw the preview according to the cached textures
                Material material = GaiaMultiTerrainOperation.GetDefaultGaiaSpawnerPreviewMaterial();
                material.SetInt("_zTestMode", (int)UnityEngine.Rendering.CompareFunction.Always);

                //assign the first color texture in the material
                material.SetTexture("_colorTexture0", m_cachedPreviewRT);

                //remove all other potential color textures, there can be caching issues if other visualisers were used in the meantime

                for (int colorIndex = 1; colorIndex < GaiaConstants.maxPreviewedTextures; colorIndex++)
                {
                    material.SetTexture("_colorTexture" + colorIndex, null);
                }



                //set the color
                material.SetColor("_previewColor0", m_settings.m_visualisationColor);

                Color seaLevelColor = GaiaSettings.m_stamperSeaLevelTintColor;
                if (!m_showSeaLevelinPreview)
                {
                    seaLevelColor.a = 0f;
                }
                material.SetColor("_seaLevelTintColor", seaLevelColor);
                material.SetFloat("_seaLevel", SessionManager.m_session.m_seaLevel);
                operation.Visualize(MultiTerrainOperationType.Heightmap, operation.RTheightmap, material, 1);

                //Clean up
                operation.CloseOperation();
                //Clean up temp textures
                GaiaUtils.ReleaseAllTempRenderTextures();
            }
        }
Ejemplo 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);
        }