static double evaluate(const double* dataset, size_t stride, float turbidity, float albedo, float sunTheta) { // splines are functions of elevation^1/3 double elevationK = pow(max(0.f, 1 - sunTheta / (glm::pi<float>() / 2)), 1 / 3.0); // table has values for turbidity 1..10 int turbidity0 = glm::clamp(static_cast<int>(turbidity), 1, 10); int turbidity1 = min(turbidity0 + 1, 10); float turbidityK = glm::clamp(turbidity - turbidity0, 0.f, 1.f); const double* datasetA0 = dataset; const double* datasetA1 = dataset + stride * 6 * 10; double a0t0 = evaluateSpline(datasetA0 + stride * 6 * (turbidity0 - 1), stride, elevationK); double a1t0 = evaluateSpline(datasetA1 + stride * 6 * (turbidity0 - 1), stride, elevationK); double a0t1 = evaluateSpline(datasetA0 + stride * 6 * (turbidity1 - 1), stride, elevationK); double a1t1 = evaluateSpline(datasetA1 + stride * 6 * (turbidity1 - 1), stride, elevationK); return a0t0 * (1 - albedo) * (1 - turbidityK) + a1t0 * albedo * (1 - turbidityK) + a0t1 * (1 - albedo) * turbidityK + a1t1 * albedo * turbidityK; }
void Spline::generateArcLengthTable() { USING_ATLAS_MATH_NS; if (!mTable.empty()) { mTable.clear(); } float scale = 1.0f / mResolution; mTable.push_back(0.0f); for (int i = 1; i < mResolution + 1; ++i) { Point p0 = evaluateSpline((i - 1) * scale); Point p1 = evaluateSpline(i * scale); Point dist = p0 - p1; mTable.push_back(mTable[i - 1] + glm::length(dist)); } }
atlas::math::Point Spline::interpolateOnSpline() { int n = int(mTable.size()); float totalDistance = mTable[n - 1]; float step = totalDistance / mTotalFrames; float currDistance = step * mCurrentFrame; int index = tableLookUp(currDistance); float t = (1.0f / mResolution) * (index % mResolution); return evaluateSpline(t); }