Example #1
0
        public static FinalizeAction finalizeAction = Finalize;         //class identified for FinalizeData
        public static void Finalize(TileData data, StopToken stop)
        {
            //blending all biomes in data.height matrix
            if (data.heights == null ||
                data.heights.rect.size != data.area.full.rect.size ||
                data.heights.worldPos != data.area.full.worldPos ||
                data.heights.worldSize != data.area.full.worldSize)
            {
                data.heights = new MatrixWorld(data.area.full.rect, data.area.full.worldPos, data.area.full.worldSize, data.globals.height);
            }
            data.heights.worldSize.y = data.globals.height;
            data.heights.Fill(0);

            foreach ((HeightOutput200 output, MatrixWorld product, MatrixWorld biomeMask)
                     in data.finalize.ProductSets <HeightOutput200, MatrixWorld, MatrixWorld>(finalizeAction, data.subDatas))
            {
                if (stop != null && stop.stop)
                {
                    return;
                }

                for (int a = 0; a < data.heights.arr.Length; a++)
                {
                    float val      = product.arr[a];
                    float biomeVal = biomeMask != null ? biomeMask.arr[a] : 1;

                    data.heights.arr[a] += val * biomeVal;
                }
            }

            //creating upscaled/blurred height matrix
            Interpolation interpolation = data.globals.heightInterpolation;
            Matrix        matrix        = GetInterpolated(data.heights, interpolation);

            //determining resolutions
            int upscale = matrix.rect.size.x / data.heights.rect.size.x;
            int margins = data.area.Margins * upscale;
            int res     = matrix.rect.size.x - margins * 2;

            int splitSize = data.globals.heightSplit;
            int numSplits = res / splitSize;

            if (res % splitSize != 0)
            {
                numSplits++;
            }

            //getting apply data
            ApplyType  applyType = data.isDraft ? data.globals.heightDraftApply : data.globals.heightMainApply;
            IApplyData applyData;

            if (applyType == ApplyType.SetHeights)
            {
                float[,] heights2Dfull = new float[res, res];
                matrix.ExportHeights(heights2Dfull, matrix.rect.offset + margins);
                applyData = new ApplySetData()
                {
                    heights2D = heights2Dfull, height = data.globals.height
                };
            }

            else if (applyType == ApplyType.SetHeightsDelayLOD)
            {
                float[][,] height2DSplits = new float[numSplits][, ];

                int offset = 0;
                for (int i = 0; i < numSplits; i++)
                {
                    int spaceLeft     = res - offset;
                    int currSplitSize = Mathf.Min(splitSize, res - offset);

                    float[,] heights2D = new float[currSplitSize, res];

                    Coord heights2Dcoord = new Coord(
                        matrix.rect.offset.x + margins,
                        matrix.rect.offset.z + margins + offset);

                    matrix.ExportHeights(heights2D, heights2Dcoord);

                    height2DSplits[i] = heights2D;

                    offset += currSplitSize;
                }

                applyData = new ApplySplitData()
                {
                    heights2DSplits = height2DSplits, height = data.globals.height
                };
            }

                        #if UNITY_2019_1_OR_NEWER
            else             //if TextureToHeightmap
            {
                byte[] bytes = new byte[res * res * 4];
                matrix.ExportRawFloat(bytes, matrix.rect.offset + margins, new Coord(res, res), mult: 0.5f);
                //not coord(margins) since matrix rect has -margins offset
                //somehow requires halved values

                applyData = new ApplyTexData()
                {
                    res = res, margins = margins, splitSize = splitSize, height = data.globals.height, texBytes = bytes
                };
            }
Example #2
0
        public static FinalizeAction finalizeAction = Finalize;         //class identified for FinalizeData
        public static void Finalize(TileData data, StopToken stop)
        {
            //blending all biomes in data.height matrix
            if (data.heights == null ||
                data.heights.rect.size != data.area.full.rect.size ||
                data.heights.worldPos != (Vector3)data.area.full.worldPos ||
                data.heights.worldSize != (Vector3)data.area.full.worldSize)
            {
                data.heights = new MatrixWorld(data.area.full.rect, data.area.full.worldPos, data.area.full.worldSize, data.globals.height);
            }
            data.heights.worldSize.y = data.globals.height;
            data.heights.Fill(0);

            foreach ((HeightOutput200 output, MatrixWorld product, MatrixWorld biomeMask)
                     in data.Outputs <HeightOutput200, MatrixWorld, MatrixWorld> (typeof(HeightOutput200), inSubs:true))
            {
                if (data.heights == null)                 //height output not generated or received null result
                {
                    return;
                }

                for (int a = 0; a < data.heights.arr.Length; a++)
                {
                    if (stop != null && stop.stop)
                    {
                        return;
                    }

                    float val      = product.arr[a];
                    float biomeVal = biomeMask != null ? biomeMask.arr[a] : 1;

                    data.heights.arr[a] += val * biomeVal;
                }
            }

            //determining resolutions
            if (stop != null && stop.stop)
            {
                return;
            }
            Interpolation interpolation = data.globals.heightInterpolation;
            int           upscale       = GetUpscale(interpolation);
            int           margins       = data.area.Margins;
            int           matrixRes     = (data.heights.rect.size.x - margins * 2 - 1) * upscale + margins * 2 * upscale + 1;

            //creating upscaled/blurred height matrix
            if (stop != null && stop.stop)
            {
                return;
            }
            Matrix matrix;

            switch (interpolation)
            {
            default: matrix = data.heights; break;

            case Interpolation.Smooth:
                matrix = new Matrix(data.heights);
                MatrixOps.GaussianBlur(matrix, 0.5f);
                break;

            //case Interpolation.Scale2X:
            //	matrix = new Matrix( new CoordRect(data.heights.rect.offset, new Coord(matrixRes)) );
            //	MatrixOps.UpscaleFast(data.heights, matrix);
            //	MatrixOps.GaussianBlur(matrix, 0.5f); //upscaleFast interpolates linear, so each new vert is exactly between the old ones
            //	break;
            //nah, summary effect is better with classic resize
            case Interpolation.Scale4X:
            case Interpolation.Scale2X:
                matrix = new Matrix(new CoordRect(data.heights.rect.offset, new Coord(matrixRes)));
                MatrixOps.Resize(data.heights, matrix);
                break;
            }

            //clamping heights to 0-1 (otherwise culing issues can occur)
            matrix.Clamp01();

            //2Darray resolution and
            int arrRes = matrix.rect.size.x - margins * upscale * 2;

            //splits number (used for SetHeightsDelayLOD and Texture)
            int splitSize = data.globals.heightSplit;
            int numSplits = arrRes / splitSize;

            if (arrRes % splitSize != 0)
            {
                numSplits++;
            }

            //getting apply data
            ApplyType  applyType = data.isDraft ? data.globals.heightDraftApply : data.globals.heightMainApply;
            IApplyData applyData;

            if (applyType == ApplyType.SetHeights)
            {
                float[,] heights2Dfull = new float[arrRes, arrRes];
                matrix.ExportHeights(heights2Dfull, matrix.rect.offset + margins * upscale);
                applyData = new ApplySetData()
                {
                    heights2D = heights2Dfull, height = data.globals.height
                };
            }

            else if (applyType == ApplyType.SetHeightsDelayLOD)
            {
                float[][,] height2DSplits = new float[numSplits][, ];

                int offset = 0;
                for (int i = 0; i < numSplits; i++)
                {
                    int spaceLeft     = arrRes - offset;
                    int currSplitSize = Mathf.Min(splitSize, arrRes - offset);

                    float[,] heights2D = new float[currSplitSize, arrRes];

                    Coord heights2Dcoord = new Coord(
                        matrix.rect.offset.x + margins * upscale,
                        matrix.rect.offset.z + margins * upscale + offset);

                    matrix.ExportHeights(heights2D, heights2Dcoord);

                    height2DSplits[i] = heights2D;

                    offset += currSplitSize;
                }

                applyData = new ApplySplitData()
                {
                    heights2DSplits = height2DSplits, height = data.globals.height
                };
            }

                        #if UNITY_2019_1_OR_NEWER
            else             //if TextureToHeightmap
            {
                byte[] bytes         = new byte[arrRes * arrRes * 4];
                float  ushortEpsilon = 1f / 65535;                //since setheights is using not full ushort range, but range-1
                matrix.ExportRawFloat(bytes, matrix.rect.offset + margins * upscale, new Coord(arrRes, arrRes), mult: 0.5f - ushortEpsilon);
                //not coord(margins) since matrix rect has -margins offset
                //somehow requires halved values

                applyData = new ApplyTexData()
                {
                    res = arrRes, margins = margins, splitSize = splitSize, height = data.globals.height, texBytes = bytes
                };
            }