コード例 #1
0
        /// <summary>
        /// Creates a heightmap of resolution <see cref="HeightmapResolution"/> asynchronously.
        /// If a <see cref="Heightmap"/> of the same resolution or higher has already been
        /// created, this method does nothing.
        /// A heightmap is 2D array of floats that represents the Y values (or heights)
        /// of to-be created vertices in 3D space.
        /// </summary>
        /// <param name="onComplete">Called when the heightmap has been created</param>
        public void CreateHeightmapAsync(Action onComplete)
        {
            ThreadPool.QueueUserWorkItem(d => {             //Worker thread
                CreateHeightmap();

                MTDispatch.Instance().Enqueue(onComplete);
            });
        }
コード例 #2
0
 void Awake()
 {
     if (_instance == null)
     {
         _instance = this;
         DontDestroyOnLoad(this.gameObject);
     }
 }
コード例 #3
0
        /// <summary>
        /// Fully constructs this Tile. This includes creating a Mesh, painting
        /// the terrain, and adding details (grass, objects, etc.)
        ///
        /// By default, calculating heights is done off of the main thread but
        /// can be disabled.
        /// </summary>
        /// <param name="onComplete">Called after all calculations have completed.
        /// <see cref="onComplete"/>Can be null if the result is not needed.</param>
        /// <param name="remapMin">Optionally linear transform the heightmap from [min, max] to [0, 1]</param>
        /// <param name="remapMax">Optionally linear transform the heightmap from [min, max] to [0, 1]</param>
        public void Generate(Action onComplete, float remapMin = 0f, float remapMax = 1f)
        {
            //Ensure MTD is instantiated
            MTDispatch.Instance();

            if (TerraConfig.IsInEditMode)
            {
                GenerateEditor(remapMin, remapMax);
                onComplete();
            }
            else
            {
                StartCoroutine(GenerateCoroutine(onComplete, remapMin, remapMax));
            }
        }
コード例 #4
0
        /// <summary>
        /// Creates a heightmap of resolution <see cref="HeightmapResolution"/> asynchronously.
        /// If a <see cref="Heightmap"/> of the same resolution or higher has already been
        /// created, this method does nothing.
        /// A heightmap is 2D array of floats that represents the Y values (or heights)
        /// of to-be created vertices in 3D space.
        /// </summary>
        /// <param name="remapMin">Optionally linear transform the heightmap from [min, max] to [0, 1]</param>
        /// <param name="remapMax">Optionally linear transform the heightmap from [min, max] to [0, 1]</param>
        /// <param name="onComplete">Called when the heightmap has been created</param>
        public void CalculateHeightmapAsync(float remapMin = 0f, float remapMax = 1f, Action onComplete = null)
        {
            _lastGeneratedLodLevel = _tile.GetLodLevel();
            Lod = _lastGeneratedLodLevel;
            bool shouldProfile = TerraConfig.Instance.EditorState.ShowDebugMessages;

            Stopwatch wsw = null;

            if (shouldProfile)
            {
                wsw = new Stopwatch();
                wsw.Start();
            }
            TerraConfig.Instance.Worker.Enqueue(() => {
                Stopwatch sw = null;
                if (shouldProfile)
                {
                    sw = new Stopwatch();
                    Profiler.BeginThreadProfiling("Heightmap Workers", "Tile " + _tile.GridPosition);
                    sw.Start();
                }
                CalculateHeightmap(null, remapMin, remapMax);

                if (shouldProfile)
                {
                    sw.Stop();
                    TerraConfig.Log("Tile " + _tile.GridPosition + " heightmap time: " + sw.ElapsedMilliseconds);
                    Profiler.EndThreadProfiling();
                }
            }, () => {
                if (shouldProfile)
                {
                    wsw.Stop();
                    MTDispatch.Instance().Enqueue(() => { TerraConfig.Log("CalculateHM worker time elapsed " + wsw.ElapsedMilliseconds); onComplete(); });
                }
            });
        }
コード例 #5
0
        /// <summary>
        /// Adds a tile at the passed position asynchronously
        /// </summary>
        /// <param name="pos">Position to add tile at</param>
        public IEnumerator AddTileAsync(Vector2 pos)
        {
            TerrainTile tile = new GameObject("Tile: " + pos).AddComponent <TerrainTile>();

            queuedTiles++;

            if (Settings.UseMultithreading)
            {
                ThreadData data = new ThreadData();
                data.tile = tile;
                data.gen  = Settings.Graph.GetEndGenerator();

                ThreadPool.QueueUserWorkItem(new WaitCallback((d) => {
                    //GetValue is not thread safe and must be locked
                    lock (pollLock) {
                        if (d is ThreadData)
                        {
                            ThreadData tData        = (ThreadData)d;
                            TerrainTile.MeshData md = tData.tile.CreateRawMesh(pos, tData.gen);

                            MTDispatch.Instance().Enqueue(() => {                             //Main Thread
                                tData.tile.RenderRawMeshData(md);

                                if (Settings.UseCustomMaterial)
                                {
                                    tile.ApplyCustomMaterial();
                                }
                                else
                                {
                                    tile.Details.ApplySplatmap();
                                }

                                tile.UpdatePosition(pos);
                                Cache.AddActiveTile(tile);
                                queuedTiles--;
                            });
                        }
                    }
                }), data);
            }
            else
            {
                yield return(new WaitForSecondsRealtime(ADD_TILE_DELAY));

                tile.CreateMesh(pos, false);
                yield return(null);

                if (Settings.UseCustomMaterial)
                {
                    tile.ApplyCustomMaterial();
                }
                else
                {
                    tile.Details.ApplySplatmap();
                }
                tile.gameObject.GetComponent <MeshRenderer>().enabled = true;

                Cache.AddActiveTile(tile);

                queuedTiles--;
            }
        }
コード例 #6
0
 void OnDestroy()
 {
     _instance = null;
 }