Commit f5bcbc27 authored by Insectslayer's avatar Insectslayer
Browse files

Implement methods to sample lookup tables

Instead of recreating the whole texture each call.
parent 633be376
Loading
Loading
Loading
Loading
+85 −7
Original line number Diff line number Diff line
@@ -12,7 +12,19 @@ public class ArcLength
    private readonly int xSize;
    private readonly double lMax;
    private readonly int lSize;
    /// <summary>
    /// Lookup table for arc length values.
    /// First index: a parameter.
    /// Second index: x coordinate.
    /// Value: arc length from 0 to x for given a.
    /// </summary>
    private List<List<double>> lut;
    /// <summary>
    /// Lookup table for inverse arc length values.
    /// First index: a parameter.
    /// Second index: arc length.
    /// Value: x coordinate for given a and arc length.
    /// </summary>
    private List<List<double>> inverseLut;

    /// <summary>
@@ -152,23 +164,89 @@ public class ArcLength
    /// <returns></returns>
    private double BisectionSearch(double aParam, double l, double epsilon)
    {
        double lower_bound = 0.0;
        double upper_bound = l > 1 ? l : 2;
        double lowerBound = 0.0;
        double upperBound = l > 1 ? l : 2;

        while (upper_bound - lower_bound > epsilon)
        while (upperBound - lowerBound > epsilon)
        {
            double mid = (lower_bound + upper_bound) / 2;
            double mid = (lowerBound + upperBound) / 2;
            if (ArcFunc(aParam, mid) < l)
            {
                lower_bound = mid;
                lowerBound = mid;
            }
            else
            {
                upper_bound = mid;
                upperBound = mid;
            }
        }

        return (lowerBound + upperBound) / 2;
    }

    /// <summary>
    /// Samples the arc length LUT using bilinear interpolation.
    /// </summary>
    public double SampleArcLengthLut(double aParam, double x)
    {
        aParam = Math.Clamp(aParam, 0.0, aMax); // makes sure aParam is within the range covered by the LUT
        x = Math.Clamp(x, 0.0, xMax);
        
        var aIndex1 = (int)(aParam / aMax * (aSize - 1));
        var xIndex1 = (int)(x / xMax * (xSize - 1));
        var aIndex2 = Math.Min(aIndex1 + 1, aSize - 1);
        var xIndex2 = Math.Min(xIndex1 + 1, xSize - 1);
        
        var a1 = aIndex1 * aMax / (aSize - 1);
        var a2 = aIndex2 * aMax / (aSize - 1);
        var x1 = xIndex1 * xMax / (xSize - 1);
        var x2 = xIndex2 * xMax / (xSize - 1);
        
        var q11 = lut[aIndex1][xIndex1];
        var q12 = lut[aIndex1][xIndex2];
        var q21 = lut[aIndex2][xIndex1];
        var q22 = lut[aIndex2][xIndex2];
        
        return BiLerp(x, aParam, x1, x2, a1, a2, q11, q12, q21, q22);
    }
    
    /// <summary>
    /// Samples the inverse arc length LUT using bilinear interpolation.
    /// </summary>
    public double SampleInverseArcLengthLut(double aParam, double l)
    {
        aParam = Math.Clamp(aParam, 0.0, aMax); // makes sure aParam is within the range covered by the LUT
        l = Math.Clamp(l, 0.0, lMax);
        
        var aIndex1 = (int)(aParam / aMax * (aSize - 1));
        var lIndex1 = (int)(l / lMax * (lSize - 1));
        var aIndex2 = Math.Min(aIndex1 + 1, aSize - 1);
        var lIndex2 = Math.Min(lIndex1 + 1, lSize - 1);
        
        var a1 = aIndex1 * aMax / (aSize - 1);
        var a2 = aIndex2 * aMax / (aSize - 1);
        var l1 = lIndex1 * lMax / (lSize - 1);
        var l2 = lIndex2 * lMax / (lSize - 1);
        
        var q11 = inverseLut[aIndex1][lIndex1];
        var q12 = inverseLut[aIndex1][lIndex2];
        var q21 = inverseLut[aIndex2][lIndex1];
        var q22 = inverseLut[aIndex2][lIndex2];
        
        return BiLerp(l, aParam, l1, l2, a1, a2, q11, q12, q21, q22);
    }
    
        return (lower_bound + upper_bound) / 2;
    /// <summary>
    /// Bilinear interpolation function.
    /// Follows notation from <see href="https://en.wikipedia.org/wiki/Bilinear_interpolation"/>.
    /// </summary>
    private static double BiLerp(double x, double y, double x1, double x2, double y1, double y2, double q11, double q12, double q21, double q22)
    {
        return 1 / ((x2 - x1) * (y2 - y1)) * (
            q11 * (x2 - x) * (y2 - y) +
            q21 * (x - x1) * (y2 - y) +
            q12 * (x2 - x) * (y - y1) +
            q22 * (x - x1) * (y - y1)
        );
    }

    public void ExportArcLengthFile(string filename)
+0 −17
Original line number Diff line number Diff line
@@ -169,23 +169,6 @@ public class CurvedWorldManager : MonoBehaviour
    }





    public float SampleInverseArcLengthLUT(float a, float l)
    {
        if (ArcLength == null) return 0f;

        // normalisiere a und l auf [0,1] entsprechend LUT
        float u = Mathf.Clamp01(l / (float)lMax);
        float v = Mathf.Clamp01(a / (float)curveMax);

        // Texture2D LUT abfragen
        Color col = ArcLength.GetInverseArcLengthTexture().GetPixelBilinear(u, v);
        return col.r; // LUT-Wert
    }


    public void RecomputeLuts()
    {