void DynamicSkyLight::SetLightParams(float4 newLightDir, float startAngle, float orbitTime) { newLightDir.ANormalize(); sunStartAngle = PI + startAngle; //FIXME WHY +PI? sunOrbitTime = orbitTime; initialSunAngle = GetRadFromXY(newLightDir.x, newLightDir.z); //FIXME This function really really needs comments about what it does! if (newLightDir.w == FLT_MAX) { // old: newLightDir is position where sun reaches highest altitude const float sunLen = newLightDir.Length2D(); const float sunAzimuth = (sunLen <= 0.001f) ? PI / 2.0f : atan(newLightDir.y / sunLen); const float sunHeight = tan(sunAzimuth - 0.001f); float3 v1(cos(initialSunAngle), sunHeight, sin(initialSunAngle)); v1.ANormalize(); if (v1.y <= orbitMinSunHeight) { newLightDir = UpVector; sunOrbitHeight = v1.y; sunOrbitRad = sqrt(1.0f - sunOrbitHeight * sunOrbitHeight); } else { float3 v2(cos(initialSunAngle + PI), orbitMinSunHeight, sin(initialSunAngle + PI)); v2.ANormalize(); float3 v3 = v2 - v1; sunOrbitRad = v3.Length() / 2.0f; v3.ANormalize(); float3 v4 = (v3.cross(UpVector)).ANormalize(); float3 v5 = (v3.cross(v4)).ANormalize(); if (v5.y < 0.0f) v5 = -v5; newLightDir = v5; sunOrbitHeight = v5.dot(v1); } } else { // new: newLightDir is center position of orbit, and newLightDir.w is orbit height sunOrbitHeight = std::max(-1.0f, std::min(newLightDir.w, 1.0f)); sunOrbitRad = sqrt(1.0f - sunOrbitHeight * sunOrbitHeight); } sunRotation.LoadIdentity(); sunRotation.SetUpVector(newLightDir); const float4& peakDir = CalculateSunPos(0.0f); const float peakElev = std::max(0.01f, peakDir.y); shadowDensityFactor = 1.0f / peakElev; SetLightDir(CalculateSunPos(sunStartAngle).ANormalize()); }
void CGlobalRendering::UpdateSunParams(float4 newSunDir, float startAngle, float orbitTime, bool iscompat) { newSunDir.ANormalize(); sunStartAngle = startAngle; sunOrbitTime = orbitTime; initialSunAngle = fastmath::coords2angle(newSunDir.x, newSunDir.z); if(iscompat) { // backwards compatible: sunDir is position where sun reaches highest altitude float sunLen = newSunDir.Length2D(); float sunAzimuth = (sunLen <= 0.001f) ? PI / 2.0f : atan(newSunDir.y / sunLen); float sunHeight = tan(sunAzimuth - 0.001f); float orbitMinSunHeight = 0.1f; // the lowest sun altitude for an auto generated orbit float3 v1(cos(initialSunAngle), sunHeight, sin(initialSunAngle)); v1.ANormalize(); if(v1.y <= orbitMinSunHeight) { newSunDir = float3(0.0f, 1.0f, 0.0f); sunOrbitHeight = v1.y; sunOrbitRad = sqrt(1.0f - sunOrbitHeight * sunOrbitHeight); } else { float3 v2(cos(initialSunAngle + PI), orbitMinSunHeight, sin(initialSunAngle + PI)); v2.ANormalize(); float3 v3 = v2 - v1; sunOrbitRad = v3.Length() / 2.0f; v3.ANormalize(); float3 v4 = v3.cross(float3(0.0f, 1.0f, 0.0f)); v4.ANormalize(); float3 v5 = v3.cross(v4); v5.ANormalize(); if(v5.y < 0) v5 = -v5; newSunDir = v5; sunOrbitHeight = v5.dot(v1); } } else { // new: sunDir is center position of orbit, and sunDir.w is orbit height sunOrbitHeight = std::max(-1.0f, std::min(newSunDir.w, 1.0f)); sunOrbitRad = sqrt(1.0f - sunOrbitHeight * sunOrbitHeight); } sunRotation.LoadIdentity(); sunRotation.SetUpVector(newSunDir); float4 peakSunDir = CalculateSunDir(0.0f); shadowDensityFactor = 1.0f / std::max(0.01f, peakSunDir.y); UpdateSun(true); }