diff --git a/TODO b/TODO index 32a4b3e..4fd8f54 100644 --- a/TODO +++ b/TODO @@ -42,7 +42,6 @@ Technlogy Preview 3 : => Add user markers on OSD. => Add areas marking. - Add a noise automatic filler. -- Fix the distorted sun appearance. - Lock some previews together (eg: terrain height and colored preview). - Find a new licence. diff --git a/gui_qt/formatmosphere.cpp b/gui_qt/formatmosphere.cpp index 4d7b630..58add2f 100644 --- a/gui_qt/formatmosphere.cpp +++ b/gui_qt/formatmosphere.cpp @@ -82,7 +82,7 @@ FormAtmosphere::FormAtmosphere(QWidget *parent): addInputInt(tr("Day time (hour)"), &_definition->hour, 0, 23, 1, 10); addInputInt(tr("Day time (minute)"), &_definition->minute, 0, 59, 1, 10); //addInputColor(tr("Sun color"), &_definition->sun_color); - addInputDouble(tr("Sun radius"), &_definition->sun_radius, 0.0, 0.1, 0.001, 0.01); + addInputDouble(tr("Sun radius"), &_definition->sun_radius, 0.0, 5.0, 0.05, 0.5); addInputDouble(tr("Influence of skydome on lighting"), &_definition->dome_lighting, 0.0, 2.0, 0.01, 0.1); addInputDouble(tr("Humidity"), &_definition->humidity, 0.0, 1.0, 0.01, 0.1)->setVisibilityCondition((int*)&_definition->model, 0); diff --git a/gui_qt/widgetcurveeditor.cpp b/gui_qt/widgetcurveeditor.cpp index f4a55a3..c11ecff 100644 --- a/gui_qt/widgetcurveeditor.cpp +++ b/gui_qt/widgetcurveeditor.cpp @@ -219,7 +219,7 @@ int WidgetCurveEditor::getPointAt(int x, int y) { curveGetPoint(_curve, i, &point); curveToScreen(point.position, point.value, &dx, &dy); - ndistance = toolsGetDistance2D((double)x, (double)y, (double)dx, (double)dy); + ndistance = euclidGetDistance2D((double)x, (double)y, (double)dx, (double)dy); if (nearest < 0 || ndistance < distance) { distance = ndistance; diff --git a/lib_paysages/atmosphere/bruneton.c b/lib_paysages/atmosphere/bruneton.c index bc757cf..e20fb88 100644 --- a/lib_paysages/atmosphere/bruneton.c +++ b/lib_paysages/atmosphere/bruneton.c @@ -1,4 +1,4 @@ -#include "public.h" +#include "private.h" /* * Atmospheric scattering, based on E. Bruneton and F.Neyret work. @@ -18,7 +18,6 @@ /*********************** Constants ***********************/ -#define WORLD_SCALING 0.05 #define GROUND_OFFSET 0.5 static const double Rg = 6360.0; static const double Rt = 6420.0; @@ -1168,7 +1167,7 @@ Color brunetonApplyAerialPerspective(Renderer* renderer, Vector3 location, Color { Vector3 eye = renderer->camera_location; Vector3 direction = v3Scale(v3Sub(location, eye), WORLD_SCALING); - Vector3 sun_position = v3Scale(renderer->atmosphere->getSunDirection(renderer), 149597870.0); + Vector3 sun_position = v3Scale(renderer->atmosphere->getSunDirection(renderer), SUN_DISTANCE); Vector3 x = {0.0, Rg + (max(eye.y, 0.0) + GROUND_OFFSET) * WORLD_SCALING, 0.0}; Vector3 v = v3Normalize(direction); @@ -1200,7 +1199,7 @@ void brunetonGetLightingStatus(Renderer* renderer, LightStatus* status, Vector3 double r0 = Rg + (max(lightingGetStatusLocation(status).y, 0.0) + GROUND_OFFSET) * WORLD_SCALING; Vector3 up = {0.0, 1.0, 0.0}; - Vector3 sun_position = v3Scale(renderer->atmosphere->getSunDirection(renderer), 149597870.0); + Vector3 sun_position = v3Scale(renderer->atmosphere->getSunDirection(renderer), SUN_DISTANCE); Vector3 x = {0.0, r0, 0.0}; Vector3 s = v3Normalize(v3Sub(sun_position, x)); diff --git a/lib_paysages/atmosphere/main.c b/lib_paysages/atmosphere/main.c index 506686b..5611d0e 100644 --- a/lib_paysages/atmosphere/main.c +++ b/lib_paysages/atmosphere/main.c @@ -120,7 +120,6 @@ static Color _fakeGetSkyColor(Renderer* renderer, Vector3 direction) static Color _getSkyColor(Renderer* renderer, Vector3 direction) { AtmosphereDefinition* definition; - double dist; Vector3 sun_direction, sun_position; Color sky_color, sun_color; @@ -128,9 +127,7 @@ static Color _getSkyColor(Renderer* renderer, Vector3 direction) sun_direction = renderer->atmosphere->getSunDirection(renderer); direction = v3Normalize(direction); - dist = v3Norm(v3Sub(direction, sun_direction)); - - sun_position = v3Scale(sun_direction, 149597870.0); + sun_position = v3Scale(sun_direction, SUN_DISTANCE_SCALED); /* Get base scattering*/ switch (definition->model) @@ -146,19 +143,25 @@ static Color _getSkyColor(Renderer* renderer, Vector3 direction) } /* Get sun shape */ - if (dist < definition->sun_radius) + double sun_radius = definition->sun_radius * SUN_RADIUS_SCALED; + Vector3 hit1, hit2; + int hits = euclidRayIntersectSphere(renderer->camera_location, direction, sun_position, sun_radius, &hit1, &hit2); + if (hits > 1) { + double dist = v3Norm(v3Sub(hit2, hit1)) / sun_radius; /* distance between intersection points (relative to radius) */ + sun_color = definition->sun_color; sun_color.r *= 100.0; sun_color.g *= 100.0; sun_color.b *= 100.0; - if (dist <= definition->sun_radius * 0.9) + + if (dist > 0.05) { return sun_color; } else { - sun_color.a = (dist - definition->sun_radius * 0.9) / (definition->sun_radius * 0.1); + sun_color.a = 1.0 - dist / 0.05; colorMask(&sky_color, &sun_color); return sky_color; } diff --git a/lib_paysages/atmosphere/presets.c b/lib_paysages/atmosphere/presets.c index 5bb309a..941343d 100644 --- a/lib_paysages/atmosphere/presets.c +++ b/lib_paysages/atmosphere/presets.c @@ -10,7 +10,7 @@ void atmosphereAutoPreset(AtmosphereDefinition* definition, AtmospherePreset pre definition->sun_color.g = 0.95; definition->sun_color.b = 0.9; definition->sun_color.a = 1.0; - definition->sun_radius = 0.02; + definition->sun_radius = 1.0; definition->humidity = 0.1; switch (preset) diff --git a/lib_paysages/atmosphere/private.h b/lib_paysages/atmosphere/private.h index d39027b..aa0c03c 100644 --- a/lib_paysages/atmosphere/private.h +++ b/lib_paysages/atmosphere/private.h @@ -5,6 +5,13 @@ #define SPHERE_SIZE 10000.0 +/* Factor to convert software units to kilometers */ +#define WORLD_SCALING 0.05 +#define SUN_DISTANCE 149597870.0 +#define SUN_DISTANCE_SCALED (SUN_DISTANCE / WORLD_SCALING) +#define SUN_RADIUS 6.955e5 +#define SUN_RADIUS_SCALED (SUN_RADIUS / WORLD_SCALING) + Color basicApplyAerialPerspective(Renderer* renderer, Vector3 location, Color base); void basicGetLightingStatus(Renderer* renderer, LightStatus* status, Vector3 normal, int opaque); diff --git a/lib_paysages/scenery.c b/lib_paysages/scenery.c index 430092a..b18e492 100644 --- a/lib_paysages/scenery.c +++ b/lib_paysages/scenery.c @@ -46,7 +46,7 @@ void sceneryQuit() void sceneryAutoPreset() { terrainAutoPreset(_terrain, TERRAIN_PRESET_STANDARD); - atmosphereAutoPreset(_atmosphere, ATMOSPHERE_MODEL_BRUNETON); + atmosphereAutoPreset(_atmosphere, ATMOSPHERE_PRESET_CLEAR_DAY); cloudsAutoPreset(_clouds, CLOUDS_PRESET_PARTLY_CLOUDY); } diff --git a/lib_paysages/tools.c b/lib_paysages/tools.c index e76141e..858ee50 100644 --- a/lib_paysages/tools.c +++ b/lib_paysages/tools.c @@ -54,17 +54,3 @@ void toolsFloat2DMapCopy(double* src, double* dest, int src_xstart, int src_ysta dest = dest_row + dest_ystep; } } - -Vector3 toolsGetNormalFromTriangle(Vector3 center, Vector3 bottom, Vector3 right) -{ - Vector3 dx = v3Sub(right, center); - Vector3 dz = v3Sub(bottom, center); - return v3Normalize(v3Cross(dz, dx)); -} - -double toolsGetDistance2D(double x1, double y1, double x2, double y2) -{ - double dx = x2 - x1; - double dy = y2 - y1; - return sqrt(dx * dx + dy * dy); -} diff --git a/lib_paysages/tools.h b/lib_paysages/tools.h index 031347a..62a2ee4 100644 --- a/lib_paysages/tools.h +++ b/lib_paysages/tools.h @@ -2,7 +2,6 @@ #define _PAYSAGES_TOOLS_H_ #include "shared/types.h" -#include "tools/euclid.h" #ifdef __cplusplus extern "C" { @@ -14,8 +13,6 @@ double toolsRandom(); double toolsCubicInterpolate(double stencil[4], double x); double toolsBicubicInterpolate(double stencil[16], double x, double y); void toolsFloat2DMapCopy(double* src, double* dest, int src_xstart, int src_ystart, int dest_xstart, int dest_ystart, int xsize, int ysize, int src_xstep, int src_ystep, int dest_xstep, int dest_ystep); -Vector3 toolsGetNormalFromTriangle(Vector3 center, Vector3 bottom, Vector3 right); -double toolsGetDistance2D(double x1, double y1, double x2, double y2); #ifdef __cplusplus } diff --git a/lib_paysages/tools/euclid.c b/lib_paysages/tools/euclid.c index ea51196..f64f1e4 100644 --- a/lib_paysages/tools/euclid.c +++ b/lib_paysages/tools/euclid.c @@ -405,3 +405,51 @@ Matrix4 m4Inverse(Matrix4 m) } } +Vector3 euclidGetNormalFromTriangle(Vector3 center, Vector3 bottom, Vector3 right) +{ + Vector3 dx = v3Sub(right, center); + Vector3 dz = v3Sub(bottom, center); + return v3Normalize(v3Cross(dz, dx)); +} + +double euclidGetDistance2D(double x1, double y1, double x2, double y2) +{ + double dx = x2 - x1; + double dy = y2 - y1; + return sqrt(dx * dx + dy * dy); +} + +int euclidRayIntersectSphere(Vector3 ray_point, Vector3 ray_direction, Vector3 sphere_center, double sphere_radius, Vector3* hit1, Vector3* hit2) +{ + Vector3 ray_direction_sphere; + double a, b, c, d; + + ray_direction_sphere = v3Sub(ray_point, sphere_center); + + a = ray_direction.x * ray_direction.x + ray_direction.y * ray_direction.y + ray_direction.z * ray_direction.z; + b = 2 * (ray_direction.x * ray_direction_sphere.x + ray_direction.y * ray_direction_sphere.y + ray_direction.z * ray_direction_sphere.z); + c = ray_direction_sphere.x * ray_direction_sphere.x + ray_direction_sphere.y * ray_direction_sphere.y + ray_direction_sphere.z * ray_direction_sphere.z - sphere_radius * sphere_radius; + d = b * b - 4 * a * c; + + if (d < 0.0) + { + return 0; + } + else if (d > 0.0) + { + if (hit1 && hit2) + { + *hit1 = v3Add(ray_point, v3Scale(ray_direction, (-b - sqrt(d)) / (2 * a))); + *hit2 = v3Add(ray_point, v3Scale(ray_direction, (-b + sqrt(d)) / (2 * a))); + } + return 2; + } + else + { + if (hit1) + { + *hit1 = v3Add(ray_point, v3Scale(ray_direction, -b / (2 * a))); + } + return 1; + } +} diff --git a/lib_paysages/tools/euclid.h b/lib_paysages/tools/euclid.h index 5104cac..a732d6e 100644 --- a/lib_paysages/tools/euclid.h +++ b/lib_paysages/tools/euclid.h @@ -74,6 +74,10 @@ Matrix4 m4NewPerspective(double fov_y, double aspect, double near, double far); double m4Determinant(Matrix4 m); Matrix4 m4Inverse(Matrix4 m); +Vector3 euclidGetNormalFromTriangle(Vector3 center, Vector3 bottom, Vector3 right); +double euclidGetDistance2D(double x1, double y1, double x2, double y2); +int euclidRayIntersectSphere(Vector3 ray_point, Vector3 ray_direction, Vector3 sphere_center, double sphere_radius, Vector3* hit1, Vector3* hit2); + #ifdef __cplusplus } #endif