コード例 #1
0
        public static FinalizeAction finalizeAction = Finalize; //class identified for FinalizeData
        public static void Finalize(TileData data, StopToken stop)
        {
            if (stop != null && stop.stop)
            {
                return;
            }

            int upscale   = 1;
            int margins   = data.area.Margins;
            int matrixRes = (data.heights.rect.size.x - margins * 2 - 1) * upscale + margins * 2 * upscale + 1;


            if (stop != null && stop.stop)
            {
                return;
            }
            Matrix matrix = data.heights;

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

            //2Darray resolution (this should still match our 69x69 size input as well)
            int arrRes = matrix.rect.size.x - margins * upscale * 2;

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

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

            IApplyData applyData;

            // we do some comparisons on this
            float[,] heights2Dfull = new float[arrRes, arrRes];
            // we do some our data operation on this
            bool[,] bool2Dfull = new bool[arrRes - 1, arrRes - 1];


            // We need to honour multiple outputs  // sigh.  the horror story negative logic.
            // Why did unity make FALSE = hole is TRUE.  //And, yes, I know why, but still.

            bool firstPass = true;

            foreach ((HoleOutMark1 output, MatrixWorld product, MatrixWorld biomeMask)
                     in data.Outputs <HoleOutMark1, MatrixWorld, MatrixWorld>(typeof(HoleOutMark1), inSubs: true))
            {
                Matrix othermatrix = product;

                // This is our holes then
                // product.


                Coord  heightsOffset = othermatrix.rect.offset + margins * upscale;
                Matrix matrixbool    = othermatrix;

                matrix.ExportHeights(heights2Dfull, matrix.rect.offset + margins * upscale);

                Coord     heightsSize = new Coord(heights2Dfull.GetLength(1), heights2Dfull.GetLength(0)); //x and z swapped
                CoordRect heightsRect = new CoordRect(heightsOffset, heightsSize);

                CoordRect intersection = CoordRect.Intersected(matrixbool.rect, heightsRect);
                Coord     min = intersection.Min; Coord max = intersection.Max;

                for (int x = min.x; x < max.x - 1; x++)
                {
                    for (int z = min.z; z < max.z - 1; z++)
                    {
                        int matrixPos   = (z - matrixbool.rect.offset.z) * matrixbool.rect.size.x + x - matrixbool.rect.offset.x;
                        int heightsPosX = x - heightsRect.offset.x;
                        int heightsPosZ = z - heightsRect.offset.z;

                        float val = matrixbool.arr[matrixPos];

                        bool result = true;  // TERRAIN

                        // The samples are represented as bool values: true for surface and false for hole

                        bool test1 = bool2Dfull[heightsPosZ, heightsPosX];
                        bool test2 = val < float.Epsilon;

                        // It is already true
                        if (test1 || firstPass)
                        // just slap in the value
                        {
                            result = test2;
                        }
                        else // Last time it was false or we didn't set it.   and FALSE means ADD A HOLE
                        {
                            result = test1 && test2;
                        }

                        bool2Dfull[heightsPosZ, heightsPosX] = result;
                    }
                }
                firstPass = false;
            }

            applyData = new ApplySetData()
            {
                heights2D = heights2Dfull, height = data.globals.height, bools2D = bool2Dfull
            };

            //pushing to apply
            if (stop != null && stop.stop)
            {
                return;
            }
            Graph.OnOutputFinalized?.Invoke(typeof(HoleOutMark1), data, applyData, stop);
            data.MarkApply(applyData);

#if MM_DEBUG
            Log.Add("HOLEOut Finalized");
#endif
        }
コード例 #2
0
ファイル: HeightOut.cs プロジェクト: galqawala/Senganget
        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
                };
            }
コード例 #3
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
                };
            }