/// <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); }
/// <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); }
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(); }
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(); }
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); }