Esempio n. 1
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. 2
0
        void OnDrawGizmosSelected()
        {
#if UNITY_EDITOR
            if (Selection.activeObject == gameObject)
            {
                if (m_showBoundingBox)
                {
                    Gizmos.color = Color.red;
                    Gizmos.DrawWireCube(transform.position, new Vector3(m_settings.m_range * 2f, m_settings.m_range * 2f, m_settings.m_range * 2f));
                }

                //Water
                if (m_showSeaLevelPlane && PWS_WaterSystem.Instance == null)
                {
                    BoundsDouble bounds = new BoundsDouble();
                    if (TerrainHelper.GetTerrainBounds(ref bounds) == true)
                    {
                        bounds.center = new Vector3Double(bounds.center.x, SessionManager.GetSeaLevel(), bounds.center.z);
                        bounds.size   = new Vector3Double(bounds.size.x, 0.05f, bounds.size.z);
                        Gizmos.color  = new Color(Color.blue.r, Color.blue.g, Color.blue.b, Color.blue.a / 4f);
                        Gizmos.DrawCube(bounds.center, bounds.size);
                    }
                }
            }
#endif
        }
Esempio n. 3
0
        private Vector3 GetLocalStamperPosition()
        {
            BoundsDouble b = new BoundsDouble();

            TerrainHelper.GetTerrainBounds(ref b);
            Transform worldmapTransform = transform.parent.parent;
            Terrain   worldMapTerrain   = worldmapTransform.GetComponent <Terrain>();
            float     relativeX         = (transform.position.x - worldmapTransform.position.x) / worldMapTerrain.terrainData.size.x;
            float     relativeZ         = (transform.position.z - worldmapTransform.position.z) / worldMapTerrain.terrainData.size.z;
            float     relativeY         = transform.position.y / TerrainLoaderManager.Instance.TerrainSceneStorage.m_worldMaprelativeSize;

            //TODO: Check if double precision required
            float newX = (float)b.min.x + (float)b.size.x * relativeX;
            float newZ = (float)b.min.z + (float)b.size.z * relativeZ;

            return(new Vector3(newX, relativeY, newZ));
        }
Esempio n. 4
0
        /// <summary>
        /// Position and fit the spawner to the terrain
        /// </summary>
        public void FitToAllTerrains()
        {
            Terrain currentTerrain = GetCurrentTerrain();

            if (currentTerrain == null)
            {
                Debug.LogError("Could not fit to terrain - no active terrain present");
                return;
            }

            BoundsDouble b = new Bounds();

            if (TerrainHelper.GetTerrainBounds(ref b))
            {
                transform.position = b.center;
                m_settings.m_range = (float)b.extents.x;
            }
        }
Esempio n. 5
0
        public void SyncLocalMapToWorldMap()
        {
            BoundsDouble bounds = new BoundsDouble();

            TerrainHelper.GetTerrainBounds(ref bounds);
            if (GaiaUtils.HasDynamicLoadedTerrains())
            {
                Action <Terrain> act = (t) => CopyLocalMapToWorldMap(bounds, t);
                GaiaUtils.CallFunctionOnDynamicLoadedTerrains(act, false);
            }
            else
            {
                foreach (Terrain t in Terrain.activeTerrains)
                {
                    if (t != m_worldMapTerrain)
                    {
                        CopyLocalMapToWorldMap(bounds, t);
                    }
                }
            }
        }
Esempio n. 6
0
        public void SyncLocationFromStamperSettings()
        {
            BoundsDouble b = new BoundsDouble();

            TerrainHelper.GetTerrainBounds(ref b);
            Transform worldmapTransform = transform.parent.parent;
            Terrain   worldMapTerrain   = worldmapTransform.GetComponent <Terrain>();
            //TODO: review if this needs to be in double precision

            Vector3Double origin = TerrainLoaderManager.Instance.GetOrigin();

            float relativeX = (float)(m_connectedStamperSettings.m_x - b.min.x + origin.x / TerrainLoaderManager.Instance.TerrainSceneStorage.m_worldMaprelativeSize) / (float)b.size.x;
            float relativeY = (float)m_connectedStamperSettings.m_y * TerrainLoaderManager.Instance.TerrainSceneStorage.m_worldMaprelativeSize;
            float relativeZ = (float)(m_connectedStamperSettings.m_z - b.min.z + origin.z / TerrainLoaderManager.Instance.TerrainSceneStorage.m_worldMaprelativeSize) / (float)b.size.z;

            //float relativeX = (float)(m_connectedStamperSettings.m_x - b.min.x) / (float)b.size.x;
            //float relativeY = (float) m_connectedStamperSettings.m_y * SessionManager.m_session.m_worldMaprelativeSize;
            //float relativeZ = (float)(m_connectedStamperSettings.m_z - b.min.z) / (float)b.size.z;

            float newX = worldmapTransform.position.x + worldMapTerrain.terrainData.size.x * relativeX;
            float newZ = worldmapTransform.position.z + worldMapTerrain.terrainData.size.z * relativeZ;

            transform.position = new Vector3(newX, relativeY, newZ);
        }
Esempio n. 7
0
        //void OnEnable()
        //{
        //    if (m_gaiaSettings == null)
        //    {
        //        m_gaiaSettings = GaiaUtils.GetGaiaSettings();
        //    }
        //}

        /// <summary>
        /// Position and fit the spawner to the terrain
        /// </summary>
        public void FitToTerrain(Terrain t = null)
        {
            if (t == null)
            {
                t = Gaia.TerrainHelper.GetTerrain(transform.position, false);
                if (t == null)
                {
                    t = Terrain.activeTerrain;
                }
                if (t == null)
                {
                    Debug.LogWarning("Could not fit to terrain - no terrain present");
                    return;
                }
            }

            Bounds b = new Bounds();

            if (TerrainHelper.GetTerrainBounds(t, ref b))
            {
                transform.position = new Vector3(b.center.x, t.transform.position.y, b.center.z);
                m_settings.m_range = b.extents.x;
            }
        }
Esempio n. 8
0
        /// <summary>
        /// Syncs the heightmap of the world map to the local terrain tiles, preserving correct height scale, heightmap resolution, etc.
        /// </summary>
        /// <param name="validLocalTerrainNames">A list of local terrain tile names that are valid to change for the sync operation. If the list is null, all tiles will be assumed valid.</param>
        public void SyncWorldMapToLocalMap(List <string> validLocalTerrainNames = null)
        {
            BoundsDouble bounds = new BoundsDouble();

            TerrainHelper.GetTerrainBounds(ref bounds);
            if (GaiaUtils.HasDynamicLoadedTerrains())
            {
                Action <Terrain> act = (t) => CopyWorldMapToLocalMap(bounds, t);
                GaiaUtils.CallFunctionOnDynamicLoadedTerrains(act, false, validLocalTerrainNames);
            }
            else
            {
                foreach (Terrain t in Terrain.activeTerrains)
                {
                    if (t != m_worldMapTerrain)
                    {
                        if (validLocalTerrainNames == null || validLocalTerrainNames.Contains(t.name))
                        {
                            CopyWorldMapToLocalMap(bounds, t);
                        }
                    }
                }
            }
        }
Esempio n. 9
0
        /// <summary>
        /// Draw gizmos
        /// </summary>
        void OnDrawGizmos()
        {
            if (m_resources == null)
            {
                return;
            }

            if (m_spawner == null)
            {
                return;
            }

            if (m_terrainHeightMap == null)
            {
                return;
            }

            //Lets visualise fitness
            float x, y = transform.position.y, z;
            float xStart   = transform.position.x - m_range;
            float xEnd     = transform.position.x + m_range;
            float zStart   = transform.position.z - m_range;
            float zEnd     = transform.position.z + m_range;
            float ballsize = Mathf.Clamp(m_resolution * 0.25f, 0.5f, 5f);

            m_spawner.m_settings.m_spawnRange = m_range;
            m_spawner.m_spawnerBounds         = new Bounds(transform.position, new Vector3(m_range * 2f, m_range * 20f, m_range * 2f));

            SpawnInfo spawnInfo = new SpawnInfo();
            Vector3   location  = new Vector3();
            float     fitness   = 0f;

            //Create caches
            if ((DateTime.Now - m_lastCacheUpdateDate).TotalSeconds > 5)
            {
                m_lastCacheUpdateDate = DateTime.Now;
                m_spawner.DeleteSpawnCaches();
                m_spawner.CreateSpawnCaches(m_selectedResourceType, m_selectedResourceIdx);

                //Also update the location so make moving it easier
                Terrain terrain = TerrainHelper.GetTerrain(transform.position);
                if (terrain != null)
                {
                    transform.position = new Vector3(transform.position.x, terrain.SampleHeight(transform.position) + 5f, transform.position.z);
                }
            }

            //Set up the texture layer array in spawn info
            spawnInfo.m_textureStrengths = new float[Terrain.activeTerrain.terrainData.alphamapLayers];

            //Now visualise fitness
            for (x = xStart; x < xEnd; x += m_resolution)
            {
                for (z = zStart; z < zEnd; z += m_resolution)
                {
                    location.Set(x, y, z);
                    if (m_spawner.CheckLocation(location, ref spawnInfo))
                    {
                        fitness = GetFitness(ref spawnInfo);
                        if (fitness < m_minimumFitness)
                        {
                            continue;
                        }
                        Gizmos.color = Color.Lerp(m_unfitColour, m_fitColour, fitness);
                        Gizmos.DrawSphere(spawnInfo.m_hitLocationWU, ballsize);
                    }
                }
            }

            //Now draw water
            //Water
            if (m_resources != null)
            {
                BoundsDouble bounds = new BoundsDouble();
                if (TerrainHelper.GetTerrainBounds(ref bounds) == true)
                {
                    bounds.center = new Vector3Double(bounds.center.x, GaiaSessionManager.GetSessionManager().GetSeaLevel(), bounds.center.z);
                    bounds.size   = new Vector3Double(bounds.size.x, 0.05f, bounds.size.z);
                    Gizmos.color  = new Color(Color.blue.r, Color.blue.g, Color.blue.b, Color.blue.a / 4f);
                    Gizmos.DrawCube(bounds.center, bounds.size);
                }
            }
        }
Esempio n. 10
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. 11
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);
        }