Exemplo n.º 1
0
        private static void Update()
        {
            if (currentTask != null)
            {
                lock (_queueLock)
                {
                    int count       = 0;
                    int maxDuration = 200;
                    System.Diagnostics.Stopwatch stopwatch = System.Diagnostics.Stopwatch.StartNew();

                    while (TaskQueue.Count > 0 && (stopwatch.ElapsedMilliseconds < maxDuration))
                    {
                        TaskQueue.Dequeue()();
                        count++;
                    }

//					int duration = (int)(stopwatch.ElapsedMilliseconds);
//					Debug.Log("handled " + count + " tasks in " + duration);
                    if (TaskQueue.Count == 0)
                    {
                        currentTask = null;
                    }
                }
            }
            else
            {
                // Should we start new th
                if (pendingTasks.Count > 0)
                {
                    currentTask = pendingTasks.Dequeue();

                    TerrainCombiner terrainCombiner = currentTask.terrainCombiner;

                    Debug.Log("TerrainCombiner starting update tasks");

                    // Cache updated instantly so we get data for all parts in one frame
                    UpdateCaches(terrainCombiner);


                    lock (_queueLock)
                    {
                        // Start combine
                        TaskQueue.Enqueue(delegate() { TCHeightmapHelper.StartCombine(terrainCombiner, terrainCombiner.groundLevelFraction); });
                        TaskQueue.Enqueue(delegate() { TCMaterialHelper.StartCombine(terrainCombiner); });

                        // Sample texture
                        TaskQueue.Enqueue(delegate() { TCHeightmapHelper.SampleTexture(currentTask.terrainCombiner, currentTask.heightmapResolution); });
                        for (int nLayer = 0; nLayer < currentTask.terrainData.alphamapLayers; nLayer++)
                        {
                            int i = nLayer;
                            TaskQueue.Enqueue(delegate() { TCMaterialHelper.SampleTexture(currentTask.terrainCombiner, i); });
                        }

                        // Apply data
                        TaskQueue.Enqueue(delegate() { TCHeightmapHelper.ApplyData(currentTask.terrainCombiner); });
                        TaskQueue.Enqueue(delegate() { TCMaterialHelper.ApplyData(currentTask.terrainCombiner); });
                    }
                }
            }
        }
Exemplo n.º 2
0
        public static void ApplyData(TerrainCombiner terrainCombiner)
        {
            Terrain     targetTerrain     = terrainCombiner.GetComponent <Terrain>();
            TerrainData targetTerrainData = targetTerrain.terrainData;

            targetTerrainData.SetAlphamaps(0, 0, terrainCombiner.MaterialCache.ResultData);
        }
Exemplo n.º 3
0
        void OnEnable()
        {
            terrainCombiner = (TerrainCombiner)target;

            terrainCombiner.CacheDirty = true;
            bTriggerUpdate             = true;
        }
Exemplo n.º 4
0
        public static void ApplyData(TerrainCombiner terrainCombiner)
        {
            Terrain     targetTerrain     = terrainCombiner.GetComponent <Terrain>();
            TerrainData targetTerrainData = targetTerrain.terrainData;

            targetTerrainData.SetHeights(0, 0, terrainCombiner.HeightmapCache.ResultData);
        }
Exemplo n.º 5
0
        public static void UpdateCombinerCache(TerrainCombiner combiner)
        {
            TerrainData terrainData = combiner.GetComponent <Terrain>().terrainData;

            // Update target materials from sources
            List <SplatPrototype> targetSplatList = new List <SplatPrototype>();

            for (int i = 0; i < combiner.Instances.Length; i++)
            {
                TerrainCombinerInstance sourceData = combiner.Instances[i];

                if (sourceData.source == null)
                {
                    continue;
                }

                Terrain sourceTerrain = sourceData.source.GetComponent <Terrain>();
                foreach (SplatPrototype splat in sourceTerrain.terrainData.splatPrototypes)
                {
                    if (splat.texture == null)
                    {
                        continue;
                    }

                    // If splay use alpha material it should not be added to target
                    if (sourceData.source.alphaMaterial != null && splat.texture.ToString() == sourceData.source.alphaMaterial.ToString())
                    {
                        continue;
                    }

                    int index = FindMaterialIndex(targetSplatList, splat.texture);
                    if (index == -1)
                    {
                        targetSplatList.Add(splat);
                    }
                }
            }
            terrainData.splatPrototypes = targetSplatList.ToArray();


            // TODO: release ??
            combiner.MaterialCache.RenderTextures.Clear();

            int size             = terrainData.alphamapResolution;
            int targetLayerCount = terrainData.alphamapLayers;

            for (int i = 0; i < targetLayerCount; i++)
            {
                RenderTexture renderTexture = TCGraphicsHelper.CreateRenderTarget(size);
                combiner.MaterialCache.RenderTextures.Add(renderTexture);
            }

            combiner.MaterialCache.Texture    = TCGraphicsHelper.CreateTexture(size);
            combiner.MaterialCache.ResultData = new float[size, size, terrainData.alphamapLayers];
        }
Exemplo n.º 6
0
        public static void SampleTexture(TerrainCombiner terrainCombiner, int size)
        {
            RenderTexture prevRenderTarget = RenderTexture.active;

            Graphics.SetRenderTarget(terrainCombiner.HeightmapCache.RenderTarget);

            TCGraphicsHelper.ReadRenderTarget(size, ref terrainCombiner.HeightmapCache.Texture);
            TCGraphicsHelper.ReadDataFromTexture(terrainCombiner.HeightmapCache.Texture, ref terrainCombiner.HeightmapCache.ResultData);

            Graphics.SetRenderTarget(prevRenderTarget);
        }
Exemplo n.º 7
0
        public static void UpdateCombinerCache(TerrainCombiner combiner)
        {
            TerrainData terrainData = combiner.GetComponent <Terrain>().terrainData;

            // TODO: release ??

            int targetSize = terrainData.heightmapResolution;

            combiner.HeightmapCache.Texture      = TCGraphicsHelper.CreateTexture(targetSize);
            combiner.HeightmapCache.ResultData   = new float[targetSize, targetSize];
            combiner.HeightmapCache.RenderTarget = TCGraphicsHelper.CreateRenderTarget(targetSize);
        }
Exemplo n.º 8
0
        public static void StartCombine(TerrainCombiner terrainCombiner, float groundLevelFraction)
        {
            Terrain targetTerrain = terrainCombiner.GetComponent <Terrain>();
//			TerrainData targetTerrainData = targetTerrain.terrainData;

            RenderTexture prevRenderTarget = RenderTexture.active;

            Graphics.SetRenderTarget(terrainCombiner.HeightmapCache.RenderTarget);
            GL.Clear(false, true, new Color(groundLevelFraction, 0, 0, 1));

            {
                for (int i = 0; i < terrainCombiner.Instances.Length; i++)
                {
                    TerrainCombinerInstance terrainInstance = terrainCombiner.Instances[i];

                    if (terrainInstance.source == null)
                    {
                        continue;
                    }

                    Terrain sourceTerrain = terrainInstance.source.GetComponent <Terrain>();
                    if (sourceTerrain == null)
                    {
                        continue;
                    }

//					TerrainData sourceTerrainData = sourceTerrain.terrainData;

//					Texture2D sourceTexture = heightmapDataCache.sourceTextures[i];
                    Texture2D sourceTexture = terrainInstance.source.CachedHeightmapTexture;


                    Vector2 position = terrainInstance.position;

                    //			Material material = new Material(Shader.Find("Unlit/Texture"));
                    Material material = new Material(Shader.Find("PockerHammer/TCHeightmapShader"));
                    material.SetFloat("_HeighOffset", -terrainInstance.source.GroundLevelFraction);

                    float heightScale = terrainInstance.WorldSize.y / terrainCombiner.WorldSize.y;
                    material.SetFloat("_HeightScale", heightScale);

                    Vector2 scale = TerrainCombiner.CalcChildTerrainPlaneScale(targetTerrain.terrainData.size, sourceTerrain.terrainData.size, terrainInstance.size);

                    TCGraphicsHelper.DrawTexture(sourceTexture, material, position, terrainInstance.rotation, scale);
                }
            }

            Graphics.SetRenderTarget(prevRenderTarget);
        }
Exemplo n.º 9
0
        public static void SampleTexture(TerrainCombiner terrainCombiner, int nLayer)
        {
            Terrain     targetTerrain     = terrainCombiner.GetComponent <Terrain>();
            TerrainData targetTerrainData = targetTerrain.terrainData;

            RenderTexture prevRenderTarget = RenderTexture.active;

            Graphics.SetRenderTarget(terrainCombiner.MaterialCache.RenderTextures[nLayer]);

            // Sample render target
            int targetSize = targetTerrainData.alphamapResolution;

            TCGraphicsHelper.ReadRenderTarget(targetSize, ref terrainCombiner.MaterialCache.Texture);
            TCGraphicsHelper.ReadDataFromTexture(terrainCombiner.MaterialCache.Texture, ref terrainCombiner.MaterialCache.ResultData, nLayer);

            Graphics.SetRenderTarget(prevRenderTarget);
        }
Exemplo n.º 10
0
        public static void RequestUpdate(TerrainCombiner combiner)
        {
            foreach (TaskData task in pendingTasks)
            {
                if (task.terrainCombiner == combiner)
                {
                    // TODO: Update request
                    return;
                }
            }

            TaskData newTask = new TaskData();

            newTask.terrainCombiner     = combiner;
            newTask.terrain             = combiner.GetComponent <Terrain>();
            newTask.terrainData         = newTask.terrain.terrainData;
            newTask.heightmapResolution = newTask.terrainData.heightmapResolution;
            newTask.frameCount          = 0;
            pendingTasks.Enqueue(newTask);
        }
Exemplo n.º 11
0
        private static void UpdateCaches(TerrainCombiner terrainCombiner)
        {
            // Update source caches
            for (int i = 0; i < terrainCombiner.Instances.Length; i++)
            {
                TerrainCombinerSource source = terrainCombiner.Instances[i].source;
                if (source != null && source.CacheDirty)
                {
                    TCHeightmapHelper.UpdateSourceCache(source);
                    TCMaterialHelper.UpdateSourceCache(source);

                    source.CacheDirty = false;
                }
            }

            // Update target caches
            if (terrainCombiner.CacheDirty)
            {
                TCHeightmapHelper.UpdateCombinerCache(terrainCombiner);
                TCMaterialHelper.UpdateCombinerCache(terrainCombiner);

                terrainCombiner.CacheDirty = false;
            }
        }
Exemplo n.º 12
0
        public static void StartCombine(TerrainCombiner terrainCombiner)
        {
            Terrain     targetTerrain     = terrainCombiner.GetComponent <Terrain>();
            TerrainData targetTerrainData = targetTerrain.terrainData;

            RenderTexture prevRenderTarget = RenderTexture.active;

            Texture2D blackTexture = CreateTexture(Color.black);             // TODO: cache?


            // Iterate through alphamaps
            for (int nLayer = 0; nLayer < targetTerrainData.alphamapLayers; nLayer++)
            {
                Graphics.SetRenderTarget(terrainCombiner.MaterialCache.RenderTextures[nLayer]);
                GL.Clear(false, true, Color.black);

                SplatPrototype targetSplat = targetTerrainData.splatPrototypes[nLayer];

                // Apply all sources
                for (int i = 0; i < terrainCombiner.Instances.Length; i++)
                {
                    TerrainCombinerInstance sourceData = terrainCombiner.Instances[i];

                    if (sourceData.source == null)
                    {
                        continue;
                    }

                    Terrain     sourceTerrain     = sourceData.source.GetComponent <Terrain>();
                    TerrainData sourceTerrainData = sourceTerrain.terrainData;

                    //					// TODO: map splat prototypes to find correct id
                    //					int nTexture = nLayer/4;
                    //					int nColor = nLayer % 4;
                    //
                    //					Texture2D[] textures = sourceTerrainData.alphamapTextures;
                    //
                    //					if(textures != null && textures.Length > nTexture) {
                    //
                    //						Vector2 position = sourceData.position;
                    //						Texture2D sourceTexture = textures[nTexture];
                    //
                    //						Material material = new Material(Shader.Find("PockerHammer/TCMaterialShader"));
                    //						Matrix4x4 m = Matrix4x4.zero;
                    //
                    //						switch(nColor) {
                    //						case 0:
                    //							m.m00 = 1.0f;
                    //							break;
                    //						case 1:
                    //							m.m11 = 1.0f;
                    //							break;
                    //						case 2:
                    //							m.m22 = 1.0f;
                    //							break;
                    //						case 3:
                    //							m.m33 = 1.0f;
                    //							break;
                    //						}
                    //
                    //						material.SetMatrix ("_ColorMapping", m);
                    //
                    //						TCGraphicsHelper.DrawTexture(sourceTexture, material, position, sourceData.rotation, sourceData.scale);
                    //
                    //					}

                    //				if(nSourceLayer < sourceData.source.CachedMaterialTextures.Count) {


                    int       nSourceLayer  = FindMaterialIndex(sourceTerrainData, targetSplat.texture);
                    Texture2D sourceTexture = nSourceLayer != -1 ?sourceData.source.CachedMaterialTextures[nSourceLayer] : blackTexture;

                    Texture2D alphaTexture = blackTexture;
                    if (sourceData.source.alphaMaterial != null)
                    {
                        int nSourceAlphaLayer = FindMaterialIndex(sourceTerrainData, sourceData.source.alphaMaterial);
                        alphaTexture = sourceData.source.CachedMaterialTextures[nSourceAlphaLayer];
                    }

                    Material material = new Material(Shader.Find("PockerHammer/TCMaterialShader"));
                    material.SetTexture("_Texture2", alphaTexture);

                    Vector2 scale = TerrainCombiner.CalcChildTerrainPlaneScale(targetTerrain.terrainData.size, sourceTerrain.terrainData.size, sourceData.size);

                    TCGraphicsHelper.DrawTexture(sourceTexture, material, sourceData.position, sourceData.rotation, scale);
                }
            }
            Graphics.SetRenderTarget(prevRenderTarget);
        }