WS30: Fix random lights density

Earlier calculations assumed degrees instead of radians for the
granularity of random lights, resulting to the wrong density. This
is now fixed. The scanline for random lights is also more efficient
now, taking the lower limit of light-coverage into account.
This commit is contained in:
Fahim Imaduddin Dalvi
2021-10-30 13:07:35 +03:00
parent a1d748a0de
commit 419e9bc128
+18 -14
View File
@@ -259,13 +259,18 @@ bool RandomLightsHandler::initialize(
void RandomLightsHandler::setLocation(const SGGeod loc, double r_E_lat, void RandomLightsHandler::setLocation(const SGGeod loc, double r_E_lat,
double r_E_lon) { double r_E_lon) {
// Approximately 1m x 1m // Approximately 31m x 31m (sqrt(1000) x sqrt(1000)), covering 1000m^2
// latitudeDelta [degrees] = 360 [degrees] / (2 * PI * polarRadius) // defined as the minimum light coverage in the documentation
delta_lat = 180.0 / (M_PI * r_E_lat); // 1m latitudeDelta [degrees] = 360 [degrees] / (2 * PI * polarRadius)
// 1m latitudeDelta [radians] = PI / 180 * latitudeDelta [degrees]
// 31m latitudeDelta [radians] = sqrt(1000) / latitudeDelta [radians]
delta_lat = sqrt(1000.0) / r_E_lat;
// longitudeDelta [degrees] = 360 [degrees] / (2 * PI * equitorialRadius * // 1m longitudeDelta [degrees] = 360 [degrees] / (2 * PI * equitorialRadius
// cos(latitude [radians])) // * cos(latitude [radians]))
delta_lon = 180.0 / (M_PI * r_E_lon * cos(loc.getLatitudeRad())); // 1m longitudeDelta [radians] = PI / 180 * longitudeDelta [degrees]
// 31m longitudeDelta [randians] = sqrt(1000) / longitudeDelta [radians]
delta_lon = sqrt(1000.0) / (r_E_lon * cos(loc.getLatitudeRad()));
} }
bool RandomLightsHandler::handleNewMaterial(SGMaterial *mat) { bool RandomLightsHandler::handleNewMaterial(SGMaterial *mat) {
@@ -294,14 +299,13 @@ bool RandomLightsHandler::handleIteration(
if (mat->get_light_coverage() <= 0) if (mat->get_light_coverage() <= 0)
return false; return false;
// Since we are scanning 1mx1m chunks, 1/lightCoverage gives the probability // Since we are scanning 31mx31m chunks, 1000/lightCoverage gives the
// of a particular 1x1 chunk having a light // probability of a particular 31x31 chunk having a light
// e.g. if lightCoverage = 10m^2 (i.e. every light point must cover around // e.g. if lightCoverage = 10000m^2 (i.e. every light point must
// 10m^2), // cover around 10000m^2), this roughly equates to
// this roughly equates to sqrt(10) * sqrt(10) chunks, and hence we need // sqrt(10000) * sqrt(10000) 1mx1m chunks, i.e. 100m x 100m, which
// to have a light in only one in 10 chunks (sqrt(10) * sqrt(10)), giving // translates to ~10 31mx31m chunks, giving us a probability of 1/10.
// us a probability of 1/10. if (pc_map_rand(lon_int, lat_int, 4) > (1000.0 / lightCoverage))
if (pc_map_rand(lon_int, lat_int, 4) > (1.0 / lightCoverage))
return false; return false;
p = osg::Vec2d(lon + delta_lon * pc_map_rand(lon_int, lat_int, 0), p = osg::Vec2d(lon + delta_lon * pc_map_rand(lon_int, lat_int, 0),