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:
@@ -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),
|
||||||
|
|||||||
Reference in New Issue
Block a user