예제 #1
0
        /// <summary>
        /// Get current basic scene information
        /// </summary>
        /// <returns></returns>
        public static GaiaSceneInfo GetSceneInfo()
        {
            GaiaSceneInfo sceneInfo = new GaiaSceneInfo();


            //Get or create a session in order to get a sea level
            GaiaSessionManager sessionMgr = GaiaSessionManager.GetSessionManager();

            //Get the sea level
            sceneInfo.m_seaLevel = sessionMgr.GetSeaLevel();


            //Not used anywhere - obsolete?
            //Terrain terrain = Gaia.TerrainHelper.GetActiveTerrain();

            ////Get the terrain bounds
            //Gaia.TerrainHelper.GetTerrainBounds(terrain, ref sceneInfo.m_sceneBounds);


            ////Grab the central point on the terrain - handy for placing player etc
            //sceneInfo.m_centrePointOnTerrain = new Vector3(sceneInfo.m_sceneBounds.center.x, terrain.SampleHeight(sceneInfo.m_sceneBounds.center), sceneInfo.m_sceneBounds.center.z);


            return(sceneInfo);
        }
예제 #2
0
        /// <summary>
        /// Get current basic scene information
        /// </summary>
        /// <returns></returns>
        public static GaiaSceneInfo GetSceneInfo()
        {
            GaiaSceneInfo sceneInfo = new GaiaSceneInfo();
            Terrain       terrain   = Gaia.TerrainHelper.GetActiveTerrain();

            if (terrain == null)
            {
                Debug.LogWarning("You must have a valid terrain for sceneinfo to work correctly.");
            }
            else
            {
                //Get or create a session in order to get a sea level
                GaiaSessionManager sessionMgr = GaiaSessionManager.GetSessionManager();

                //Get the terrain bounds
                Gaia.TerrainHelper.GetTerrainBounds(terrain, ref sceneInfo.m_sceneBounds);

                //Get the sea level
                sceneInfo.m_seaLevel = sessionMgr.GetSeaLevel();

                //Grab the central point on the terrain - handy for placing player etc
                sceneInfo.m_centrePointOnTerrain = new Vector3(sceneInfo.m_sceneBounds.center.x, terrain.SampleHeight(sceneInfo.m_sceneBounds.center), sceneInfo.m_sceneBounds.center.z);
            }

            return(sceneInfo);
        }
예제 #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();
        }
예제 #4
0
        private void DrawSummary(bool helpEnabled)
        {
            m_manager.m_session = (GaiaSession)m_editorUtils.ObjectField("SessionData", m_manager.m_session, typeof(GaiaSession), helpEnabled);
            m_editorUtils.InlineHelp("SessionData", helpEnabled);
            if (m_manager.m_session == null)
            {
                if (m_editorUtils.Button("CreateSessionButton"))
                {
                    m_manager.CreateSession();
                }
            }
            if (m_manager.m_session == null)
            {
                return;
            }
            EditorGUI.BeginChangeCheck();
            m_manager.m_session.m_name = m_editorUtils.DelayedTextField("Name", m_manager.m_session.m_name, helpEnabled);
            if (EditorGUI.EndChangeCheck())
            {
                //Get the old path
                string oldSessionDataPath = GaiaDirectories.GetSessionSubFolderPath(m_manager.m_session);
                //Rename the session asset
                AssetDatabase.RenameAsset(AssetDatabase.GetAssetPath(m_manager.m_session), m_manager.m_session.m_name + ".asset");
                //rename the session data path as well
                string newSessionDataPath = GaiaDirectories.GetSessionSubFolderPath(m_manager.m_session, false);
                AssetDatabase.MoveAsset(oldSessionDataPath, newSessionDataPath);
                //if we have terrain scenes stored in the Terrain Loader, we need to update the paths in there as well
                foreach (TerrainScene terrainScene in TerrainLoaderManager.TerrainScenes)
                {
                    terrainScene.m_scenePath         = terrainScene.m_scenePath.Replace(oldSessionDataPath, newSessionDataPath);
                    terrainScene.m_impostorScenePath = terrainScene.m_impostorScenePath.Replace(oldSessionDataPath, newSessionDataPath);
                    terrainScene.m_backupScenePath   = terrainScene.m_backupScenePath.Replace(oldSessionDataPath, newSessionDataPath);
                    terrainScene.m_colliderScenePath = terrainScene.m_colliderScenePath.Replace(oldSessionDataPath, newSessionDataPath);
                }
                TerrainLoaderManager.Instance.SaveStorageData();

                AssetDatabase.DeleteAsset(oldSessionDataPath);
                AssetDatabase.SaveAssets();
            }

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField(m_editorUtils.GetContent("Description"), GUILayout.MaxWidth(EditorGUIUtility.labelWidth));
            m_manager.m_session.m_description = EditorGUILayout.TextArea(m_manager.m_session.m_description, GUILayout.MinHeight(100));
            EditorGUILayout.EndHorizontal();
            m_editorUtils.InlineHelp("Description", helpEnabled);
            m_manager.m_session.m_previewImage = (Texture2D)m_editorUtils.ObjectField("PreviewImage", m_manager.m_session.m_previewImage, typeof(Texture2D), helpEnabled);
            GUILayout.BeginHorizontal();
            Rect rect = EditorGUILayout.GetControlRect();

            GUILayout.Space(rect.width - 20);
            if (GUILayout.Button("Generate Image"))
            {
                string textureFileName = GaiaDirectories.GetSessionSubFolderPath(m_manager.m_session) + Path.DirectorySeparatorChar + m_manager.m_session + "_Preview";
                var    originalLODBias = QualitySettings.lodBias;
                QualitySettings.lodBias = 100;
                OrthographicBake.BakeTerrain(Terrain.activeTerrain, 2048, 2048, Camera.main.cullingMask, textureFileName);
                OrthographicBake.RemoveOrthoCam();
                QualitySettings.lodBias = originalLODBias;
                textureFileName        += ".png";
                AssetDatabase.ImportAsset(textureFileName);
                var importer = AssetImporter.GetAtPath(textureFileName) as TextureImporter;
                if (importer != null)
                {
                    importer.sRGBTexture         = false;
                    importer.alphaIsTransparency = false;
                    importer.alphaSource         = TextureImporterAlphaSource.None;
                    importer.mipmapEnabled       = false;
                }
                AssetDatabase.ImportAsset(textureFileName);
                m_manager.m_session.m_previewImage = (Texture2D)AssetDatabase.LoadAssetAtPath(textureFileName, typeof(Texture2D));
            }
            GUILayout.EndHorizontal();
            m_editorUtils.InlineHelp("PreviewImage", helpEnabled);
            m_editorUtils.LabelField("Created", new GUIContent(m_manager.m_session.m_dateCreated), helpEnabled);
            m_manager.m_session.m_isLocked = m_editorUtils.Toggle("Locked", m_manager.m_session.m_isLocked, helpEnabled);
            float maxSeaLevel = 2000f;

            if (Terrain.activeTerrain != null)
            {
                maxSeaLevel = Terrain.activeTerrain.terrainData.size.y + Terrain.activeTerrain.transform.position.y;
            }
            else
            {
                maxSeaLevel = m_manager.GetSeaLevel(false) + 500f;
            }

            float oldSeaLevel = m_manager.GetSeaLevel(false);
            float newSeaLEvel = oldSeaLevel;

            newSeaLEvel = m_editorUtils.Slider("SeaLevel", newSeaLEvel, 0, maxSeaLevel, helpEnabled);
            if (newSeaLEvel != oldSeaLevel)
            {
                //Do we have a water instance? If yes, update it & it will update the sea level in the session as well
                if (PWS_WaterSystem.Instance != null)
                {
                    PWS_WaterSystem.Instance.SeaLevel = newSeaLEvel;
                }
                else
                {
                    //no water instance yet, just update the sea level in the session
                    m_manager.SetSeaLevel(newSeaLEvel, false);
                    SceneView.RepaintAll();
                }
            }

            m_manager.m_session.m_spawnDensity = m_editorUtils.FloatField("SpawnDensity", Mathf.Max(0.01f, m_manager.m_session.m_spawnDensity), helpEnabled);
            GUILayout.BeginHorizontal();
            if (m_editorUtils.Button("DeleteAllOperations"))
            {
                if (EditorUtility.DisplayDialog(m_editorUtils.GetTextValue("PopupDeleteAllTitle"), m_editorUtils.GetTextValue("PopupDeleteAllMessage"), m_editorUtils.GetTextValue("Continue"), m_editorUtils.GetTextValue("Cancel")))
                {
                    foreach (GaiaOperation op in m_manager.m_session.m_operations)
                    {
                        try
                        {
                            if (!String.IsNullOrEmpty(op.scriptableObjectAssetGUID))
                            {
                                AssetDatabase.DeleteAsset(AssetDatabase.GUIDToAssetPath(op.scriptableObjectAssetGUID));
                            }
                        }
                        catch (Exception ex)
                        {
                            Debug.LogError("Error while deleting one of the operation data files: " + ex.Message + " Stack Trace:" + ex.StackTrace);
                        }
                    }

                    m_manager.m_session.m_operations.Clear();
                }
            }

            if (m_editorUtils.Button("PlaySession"))
            {
                GaiaLighting.SetDefaultAmbientLight(GaiaUtils.GetGaiaSettings().m_gaiaLightingProfile);
                GaiaSessionManager.PlaySession();
            }
            GUILayout.EndHorizontal();
        }
예제 #5
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);
        }