예제 #1
0
    /// <summary>
    /// Returns the linearly interpolated height for a given position in the grid. Safe to use in systems.
    /// </summary>
    /// <returns></returns>
    public static float GetGroundLevel(float3 position, NativeArray <float> heightMap, GridData grid)
    {
        // Use linear interpolation to avoid staircase-like movement
        int2 position2D = grid.GetGridPosition(position);

        if (!grid.IsInBounds(position2D))
        {
            return(0);
        }

        float xU = position.x - position2D.x;
        float zU = (position.z - position2D.y);

        xU = xU / grid.CellSize;
        zU = zU / grid.CellSize;

        int2 bottomRight = new int2(position2D.x + 1, position2D.y);
        int2 topLeft     = new int2(position2D.x, position2D.y + 1);
        int2 topRight    = new int2(position2D.x + 1, position2D.y + 1);

        int2 origin = position2D;

        if (xU + zU > 1f && grid.IsInBounds(topRight))
        {
            // On second triangle in this cell. Invert and switch xU and zU
            origin = topRight;
            xU     = 1f - zU;
            zU     = 1f - xU;
        }

        float xHeight;
        float zHeight;

        if (grid.IsInBounds(bottomRight))
        {
            xHeight = math.lerp(heightMap[grid.GetCellIndex(origin)],
                                heightMap[grid.GetCellIndex(bottomRight)], xU);
        }
        else
        {
            xHeight = heightMap[grid.GetCellIndex(position)];
        }

        if (grid.IsInBounds(topLeft))
        {
            zHeight = math.lerp(heightMap[grid.GetCellIndex(origin)],
                                heightMap[grid.GetCellIndex(topLeft)], zU);
        }
        else
        {
            zHeight = heightMap[grid.GetCellIndex(position)];
        }


        return((xHeight + zHeight) / 2f);
    }