Esempio n. 1
0
        public IEnumerator Apply(MapMagic.CoordRect rect, Terrain terrain, object dataBox, Func <float, bool> stop = null)
        {
            TupleSet <float[, , ], SplatPrototypeWrapper[]> splatsTuple = (TupleSet <float[, , ], SplatPrototypeWrapper[]>)dataBox;

            float[,,] splats3D = splatsTuple.item1;
            SplatPrototypeWrapper[] prototypes = splatsTuple.item2;

            if (splats3D.GetLength(2) == 0)
            {
                Purge(rect, terrain); yield break;
            }

            //TerrainData data = terrain.terrainData;

            //setting resolution
            //int size = splats3D.GetLength(0);
            //if (data.alphamapResolution != size) data.alphamapResolution = size;

            //checking prototypes texture
            for (int i = 0; i < prototypes.Length; i++)
            {
                if (prototypes[i].Texture == null)
                {
                    prototypes[i].Texture = defaultTex;
                }
            }
            yield return(null);

            //welding
            if (MapMagic.MapMagic.instance != null && MapMagic.MapMagic.instance.splatsWeldMargins != 0)
            {
                MapMagic.Coord coord = MapMagic.Coord.PickCell(rect.offset, MapMagic.MapMagic.instance.resolution);
                //Chunk chunk = MapMagic.MapMagic.instance.chunks[coord.x, coord.z];

                Chunk neigPrevX = MapMagic.MapMagic.instance.chunks[coord.x - 1, coord.z];
                if (neigPrevX != null && neigPrevX.worker.ready)
                {
                    WeldTerrains.WeldSplatToPrevX(ref splats3D, neigPrevX.terrain, MapMagic.MapMagic.instance.splatsWeldMargins);
                }

                Chunk neigNextX = MapMagic.MapMagic.instance.chunks[coord.x + 1, coord.z];
                if (neigNextX != null && neigNextX.worker.ready)
                {
                    WeldTerrains.WeldSplatToNextX(ref splats3D, neigNextX.terrain, MapMagic.MapMagic.instance.splatsWeldMargins);
                }

                Chunk neigPrevZ = MapMagic.MapMagic.instance.chunks[coord.x, coord.z - 1];
                if (neigPrevZ != null && neigPrevZ.worker.ready)
                {
                    WeldTerrains.WeldSplatToPrevZ(ref splats3D, neigPrevZ.terrain, MapMagic.MapMagic.instance.splatsWeldMargins);
                }

                Chunk neigNextZ = MapMagic.MapMagic.instance.chunks[coord.x, coord.z + 1];
                if (neigNextZ != null && neigNextZ.worker.ready)
                {
                    WeldTerrains.WeldSplatToNextZ(ref splats3D, neigNextZ.terrain, MapMagic.MapMagic.instance.splatsWeldMargins);
                }
            }
            yield return(null);

            terrain.terrainData.splatPrototypes = new[] { new SplatPrototype()
                                                          {
                                                              texture = defaultTex
                                                          } };                                                       // To stop MapMagic purging what we're doing here alter on...

            var wrapper        = terrain.gameObject.GetOrAddComponent <TerrainWrapper>();
            var MMTerrainLayer = wrapper.GetLayer <MMTerrainLayer>(LayerName, false, true);

            MMTerrainLayer.SplatData.Clear();

            var splatWidth  = splats3D.GetLength(0);
            var splatHeight = splats3D.GetLength(1);

            if (terrain.terrainData.alphamapResolution != splatWidth)
            {
                Debug.Log("Set alphamapResolution to " + splatWidth);
                terrain.terrainData.alphamapResolution = splatWidth;
            }

            var data = new float[splatWidth, splatHeight];

            for (int i = 0; i < prototypes.Length; i++)
            {
                var splatPrototypeWrapper = prototypes[i];
                for (var u = 0; u < splatWidth; ++u)
                {
                    for (var v = 0; v < splatHeight; ++v)
                    {
                        data[v, u] = splats3D[u, v, i];
                    }
                }
                MMTerrainLayer.SetSplatmap(splatPrototypeWrapper, 0, 0, data, splatWidth);
            }

            global::MapMagic.MapMagic.OnApplyCompleted -= MapMagicIntegrationUtilities.MapMagicOnOnApplyCompleted;
            global::MapMagic.MapMagic.OnApplyCompleted += MapMagicIntegrationUtilities.MapMagicOnOnApplyCompleted;

            wrapper.SetDirtyAbove(MMTerrainLayer);
            yield return(null);
        }
Esempio n. 2
0
        public IEnumerator Apply(MapMagic.CoordRect rect, Terrain terrain, object dataBox, Func <float, bool> stop = null)
        {
            //init heights
            #if UN_MapMagic
                        #if WDEBUG
            Profiler.BeginSample("UNature");
                        #endif

            uNatureHeightTuple heightTuple;
            float[,] heights2D;

            if (FoliageCore_MainManager.instance != null)
            {
                heightTuple = (uNatureHeightTuple)dataBox; // get data
                heights2D   = heightTuple.normalizedHeights;
                UNMapMagic_Manager.ApplyHeightOutput(heightTuple, terrain);
            }
            else
            {
                //Debug.LogError("uNature_MapMagic extension is enabled but no foliage manager exists on the scene.");
                //yield break;
                heights2D = (float[, ])dataBox;
            }

                        #if WDEBUG
            Profiler.EndSample();
                        #endif
                        #else
            float[,] heights2D = (float[, ])dataBox;
                        #endif

            heights2D = heights2D.Flip();

            //quick lod apply

            /*if (chunk.lod)
             * {
             *      //if (chunk.lodTerrain == null) { chunk.lodTerrain = (MapMagic.instance.transform.AddChild("Terrain " + chunk.coord.x + "," + chunk.coord.z + " LOD")).gameObject.AddComponent<Terrain>(); chunk.lodTerrain.terrainData = new TerrainData(); }
             *      if (chunk.lodTerrain.terrainData==null) chunk.lodTerrain.terrainData = new TerrainData();
             *
             *      chunk.lodTerrain.Resize(heights2D.GetLength(0), new Vector3(MapMagic.instance.terrainSize, MapMagic.instance.terrainHeight, MapMagic.instance.terrainSize));
             *      chunk.lodTerrain.terrainData.SetHeightsDelayLOD(0,0,heights2D);
             *
             *      yield break;
             * }*/

            //determining data
            if (terrain == null || terrain.terrainData == null)
            {
                yield break;                                                         //chunk removed during apply
            }
            TerrainData data = terrain.terrainData;

            //resizing terrain (standard terrain resize is extremely slow. Even when creating a new terrain)
            Vector3 terrainSize       = terrain.terrainData.size;       //new Vector3(MapMagic.instance.terrainSize, MapMagic.instance.terrainHeight, MapMagic.instance.terrainSize);
            int     terrainResolution = heights2D.GetLength(0);         //heights2D[0].GetLength(0);
            if ((data.size - terrainSize).sqrMagnitude > 0.01f || data.heightmapResolution != terrainResolution)
            {
                if (terrainResolution <= 64)                 //brute force
                {
                    data.heightmapResolution = terrainResolution;
                    data.size = new Vector3(terrainSize.x, terrainSize.y, terrainSize.z);
                }

                else                 //setting res 64, re-scaling to 1/64, and then changing res
                {
                    data.heightmapResolution = 65;
                    terrain.Flush();                     //otherwise unity crushes without an error
                    int resFactor = (terrainResolution - 1) / 64;
                    data.size = new Vector3(terrainSize.x / resFactor, terrainSize.y, terrainSize.z / resFactor);
                    data.heightmapResolution = terrainResolution;
                }
            }
            yield return(null);

            var heightSize = heights2D.GetLength(0);
            for (int x = 0; x < heightSize - 1; x++)
            {
                for (int z = 0; z < heightSize - 1; z++)
                {
                    heights2D[z, x] = Mathf.Clamp01(heights2D[z, x]);
                }
            }

            var wrapper        = terrain.gameObject.GetOrAddComponent <TerrainWrapper>();
            var MMTerrainLayer = wrapper.GetLayer <MMTerrainLayer>(LayerName, false, true);
            MMTerrainLayer.SetHeights(0, 0, heights2D, MapMagic.MapMagic.instance.resolution + 1);
            _pendingWrappers.Remove(rect);

            //welding
            if (MapMagic.MapMagic.instance != null && MapMagic.MapMagic.instance.heightWeldMargins != 0)
            {
                MapMagic.Coord coord = MapMagic.Coord.PickCell(rect.offset, MapMagic.MapMagic.instance.resolution);
                Chunk          chunk = MapMagic.MapMagic.instance.chunks[coord.x, coord.z];

                Chunk neigPrevX = MapMagic.MapMagic.instance.chunks[coord.x - 1, coord.z];
                if (neigPrevX != null && !_pendingWrappers.Contains(neigPrevX.rect) && neigPrevX.terrain && neigPrevX.terrain.terrainData.heightmapResolution == terrainResolution)
                {
                    var neighbourWrapper = neigPrevX.terrain.GetComponent <TerrainWrapper>();
                    if (neigPrevX.worker.ready && neighbourWrapper)
                    {
                        WeldTerrains.WeldToPrevZ(ref heights2D, neighbourWrapper, MapMagic.MapMagic.instance.heightWeldMargins);
                    }
                    //WeldTerrains.WeldToPrevX(ref heights2D, neighbourWrapper, MapMagic.MapMagic.instance.heightWeldMargins);
                    Chunk.SetNeigsX(neigPrevX, chunk);
                }

                Chunk neigNextX = MapMagic.MapMagic.instance.chunks[coord.x + 1, coord.z];
                if (neigNextX != null && !_pendingWrappers.Contains(neigNextX.rect) && neigNextX.terrain.terrainData.heightmapResolution == terrainResolution)
                {
                    var neighbourWrapper = neigNextX.terrain.GetComponent <TerrainWrapper>();
                    if (neigNextX.worker.ready && neighbourWrapper)
                    {
                        WeldTerrains.WeldToNextZ(ref heights2D, neighbourWrapper, MapMagic.MapMagic.instance.heightWeldMargins);
                    }
                    //WeldTerrains.WeldToNextX(ref heights2D, neighbourWrapper, MapMagic.MapMagic.instance.heightWeldMargins);
                    Chunk.SetNeigsX(chunk, neigNextX);
                }

                Chunk neigPrevZ = MapMagic.MapMagic.instance.chunks[coord.x, coord.z - 1];
                if (neigPrevZ != null && !_pendingWrappers.Contains(neigPrevZ.rect) && neigPrevZ.terrain.terrainData.heightmapResolution == terrainResolution)
                {
                    var neighbourWrapper = neigPrevZ.terrain.GetComponent <TerrainWrapper>();
                    if (neigPrevZ.worker.ready && neighbourWrapper)
                    {
                        //WeldTerrains.WeldToNextX(ref heights2D, neighbourWrapper, MapMagic.MapMagic.instance.heightWeldMargins);
                        WeldTerrains.WeldToPrevX(ref heights2D, neighbourWrapper, MapMagic.MapMagic.instance.heightWeldMargins);
                    }
                    Chunk.SetNeigsZ(neigPrevZ, chunk);
                }

                Chunk neigNextZ = MapMagic.MapMagic.instance.chunks[coord.x, coord.z + 1];
                if (neigNextZ != null && !_pendingWrappers.Contains(neigNextZ.rect) && neigNextZ.terrain.terrainData.heightmapResolution == terrainResolution)
                {
                    var neighbourWrapper = neigNextZ.terrain.GetComponent <TerrainWrapper>();
                    if (neigNextZ.worker.ready && neighbourWrapper)
                    {
                        //WeldTerrains.WeldToPrevX(ref heights2D, neighbourWrapper, MapMagic.MapMagic.instance.heightWeldMargins);
                        WeldTerrains.WeldToNextX(ref heights2D, neighbourWrapper, MapMagic.MapMagic.instance.heightWeldMargins);
                    }
                    Chunk.SetNeigsZ(chunk, neigNextZ);
                }
            }
            yield return(null);

            MMTerrainLayer.SetHeights(0, 0, heights2D, MapMagic.MapMagic.instance.resolution + 1);
            global::MapMagic.MapMagic.OnApplyCompleted -= MapMagicIntegrationUtilities.MapMagicOnOnApplyCompleted;
            global::MapMagic.MapMagic.OnApplyCompleted += MapMagicIntegrationUtilities.MapMagicOnOnApplyCompleted;

            wrapper.SetDirtyAbove(MMTerrainLayer);

            yield return(null);
        }