public WorleySurfaceNoise GetEdgeData(float x, float y)
    {
        if (perterbAmp > 0)
        {
            SingleGradientPerturb(seed, perterbAmp, frequency, ref x, ref y);
        }

        x *= frequency;
        y *= frequency;

        int xr = FastRound(x);
        int yr = FastRound(y);

        float distance0 = 999999;
        float distance1 = 999999;

        //	Store distance1 index
        int xc1 = 0, yc1 = 0;

        //	Store distance0 index in case it is assigned to distance1 later
        int xc0 = 0, yc0 = 0;

        //	All adjacent cell indices and distances
        NineInts otherX = new NineInts();
        NineInts otherY = new NineInts();

        NineFloats otherDist = new NineFloats();

        for (int i = 0; i < 9; i++)
        {
            otherDist [i] = 999999;
        }

        int indexCount = 0;

        float3 currentCellPosition = float3.zero;
        int2   currentCellIndex    = int2.zero;

        for (int xi = xr - 1; xi <= xr + 1; xi++)
        {
            for (int yi = yr - 1; yi <= yr + 1; yi++)
            {
                float2 vec = cell_2D [Hash2D(seed, xi, yi) & 255];

                float vecX = xi - x + vec.x * cellularJitter;
                float vecY = yi - y + vec.y * cellularJitter;

                float cellX = xi + vec.x * cellularJitter;
                float cellY = yi + vec.y * cellularJitter;

                //	Natural distance function
                //float newDistance = (math.abs(vecX) + math.abs(vecY)) + (vecX * vecX + vecY * vecY);

                //	Euclidean distance function
                float newDistance = newDistance = vecX * vecX + vecY * vecY;

                if (newDistance <= distance1)     //	Math.Min(distance[i], newDistance)
                {
                    if (newDistance >= distance0) //	Math.Max((newDistance)), distance[i - 1])
                    {
                        distance1 = newDistance;
                        xc1       = xi;
                        yc1       = yi;
                    }
                    else
                    {
                        distance1 = distance0;
                        xc1       = xc0;
                        yc1       = yc0;
                    }
                }

                if (newDistance <= distance0)   //	Math.Min(distance0, newDistance)
                {
                    distance0 = newDistance;
                    xc0       = xi;
                    yc0       = yi;

                    currentCellPosition = new float3(cellX, 0, cellY) / frequency;
                    currentCellIndex    = new int2(xi, yi);
                }

                //	Store all adjacent cells
                otherX [indexCount]    = xi;
                otherY [indexCount]    = yi;
                otherDist [indexCount] = newDistance;
                indexCount++;
            }
        }

        //	Current cell
        float currentCellValue = To01(ValCoord2D(seed, xc0, yc0));
        int   currentBiome     = TerrainTypeIndex(currentCellValue);

        //	Final closest adjacent cell values
        float adjacentEdgeDistance = 999999;
        float adjacentCellValue    = 0;

        //	Iterate over all adjacent cells
        for (int i = 0; i < 9; i++)
        {
            //	Find closest cell within smoothing radius
            float dist2Edge = otherDist [i] - distance0;
            if (dist2Edge < adjacentEdgeDistance)
            {
                float otherCellValue = To01(ValCoord2D(seed, otherX [i], otherY [i]));
                int   otherBiome     = TerrainTypeIndex(otherCellValue);

                ///	Assign as final value if not current biome
                if (otherBiome != currentBiome)
                {
                    adjacentEdgeDistance = dist2Edge;
                    adjacentCellValue    = otherCellValue;
                }
            }
        }
        if (adjacentEdgeDistance == 999999)
        {
            adjacentEdgeDistance = 0;
        }

        WorleySurfaceNoise cell = new WorleySurfaceNoise
        {
            currentSurfaceCellValue  = currentCellValue,
            distance2Edge            = adjacentEdgeDistance,
            adjacentSurfaceCellValue = adjacentCellValue,
            currentCellPosition      = currentCellPosition,
            currentCellIndexInMap    = currentCellIndex
        };

        //	Data for use in terrain generation
        return(cell);
    }
Exemple #2
0
    public PointData GetPointData(float x, float y)
    {
        if (perterbAmp > 0)
        {
            SingleGradientPerturb(seed, perterbAmp, frequency, ref x, ref y);
        }

        x *= frequency;
        y *= frequency;

        int xr = FastRound(x);
        int yr = FastRound(y);

        float distance0 = 999999;
        float distance1 = 999999;

        //	Store distance1 index
        int xc1 = 0, yc1 = 0;

        //	Store distance0 index in case it is assigned to distance1 later
        int xc0 = 0, yc0 = 0;

        //	All adjacent cell indices and distances
        NineInts otherX = new NineInts();
        NineInts otherY = new NineInts();

        NineFloats otherCellX = new NineFloats();
        NineFloats otherCellY = new NineFloats();

        NineFloats otherDistance = new NineFloats();

        for (int i = 0; i < 9; i++)
        {
            otherDistance[i] = 999999;
        }

        int indexCount = 0;

        float3 currentCellPosition = float3.zero;
        int2   currentCellIndex    = int2.zero;

        float distance = 999999;

        for (int xi = xr - 1; xi <= xr + 1; xi++)
        {
            for (int yi = yr - 1; yi <= yr + 1; yi++)
            {
                float2 vec = cell_2D[Hash2D(seed, xi, yi) & 255];

                float vecX = xi - x + vec.x * cellularJitter;
                float vecY = yi - y + vec.y * cellularJitter;

                float cellX = xi + vec.x * cellularJitter;
                float cellY = yi + vec.y * cellularJitter;

                float newDistance;

                switch (distanceFunction)
                {
                case DistanceFunction.Natural:
                    newDistance = (math.abs(vecX) + math.abs(vecY)) + (vecX * vecX + vecY * vecY);
                    break;

                case DistanceFunction.Manhatten:
                    newDistance = math.abs(vecX) + math.abs(vecY);
                    break;

                case DistanceFunction.Euclidean:
                    newDistance = newDistance = vecX * vecX + vecY * vecY;
                    break;

                default:
                    newDistance = 0;
                    throw new System.Exception("Unrecognised cellular distance function");
                }

                if (newDistance < distance)
                {
                    distance = newDistance;
                }

                if (newDistance <= distance1)
                {
                    if (newDistance >= distance0)
                    {
                        distance1 = newDistance;
                        xc1       = xi;
                        yc1       = yi;
                    }
                    else
                    {
                        distance1 = distance0;
                        xc1       = xc0;
                        yc1       = yc0;
                    }
                }

                if (newDistance <= distance0)
                {
                    distance0 = newDistance;
                    xc0       = xi;
                    yc0       = yi;

                    currentCellPosition = math.round(new float3(cellX, 0, cellY) / frequency);
                    currentCellIndex    = new int2(xi, yi);
                }

                //	Store all adjacent cells
                otherCellX[indexCount]    = cellX;
                otherCellY[indexCount]    = cellY;
                otherX[indexCount]        = xi;
                otherY[indexCount]        = yi;
                otherDistance[indexCount] = newDistance;
                indexCount++;
            }
        }

        //	Current cell
        float currentCellValue = To01(ValCoord2D(seed, xc0, yc0));
        float currentBiome     = EdgeBorder(currentCellIndex);

        //	Final closest adjacent cell values
        float  distance2Edge        = 999999;
        float  adjacentCellValue    = 0;
        int2   adjacentCellIndex    = int2.zero;
        float3 adjacentCellPosition = float3.zero;

        //	Iterate over all adjacent cells
        for (int i = 0; i < 9; i++)
        {
            //	Find closest cell within smoothing radius

            float dist2Edge = ApplyDistanceType(distance0, otherDistance[i]);
            if (dist2Edge < distance2Edge)
            {
                int2  otherCellIndex = new int2(otherX[i], otherY[i]);
                float otherBiome     = EdgeBorder(otherCellIndex);

                ///	Assign as final value if not current biome
                if (otherBiome != currentBiome)
                {
                    distance2Edge        = dist2Edge;
                    adjacentCellValue    = To01(ValCoord2D(seed, otherX[i], otherY[i]));
                    adjacentCellIndex    = otherCellIndex;
                    adjacentCellPosition = math.round(new float3(otherCellX[i], 0, otherCellY[i]) / frequency);
                }
            }
        }
        if (distance2Edge == 999999)
        {
            distance2Edge = 0;
        }

        PointData cell = new PointData();

        cell.distance2Edge = distance2Edge;
        cell.distance      = distance;

        cell.currentCellValue  = currentCellValue;
        cell.adjacentCellValue = adjacentCellValue;

        cell.currentCellPosition  = currentCellPosition;
        cell.adjacentCellPosition = adjacentCellPosition;

        cell.currentCellIndex  = currentCellIndex;
        cell.adjacentCellIndex = adjacentCellIndex;

        return(cell);
    }