paysages : Fixed sun drawing algorithm.
git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@510 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
parent
ed268098a1
commit
620877bf64
12 changed files with 76 additions and 33 deletions
1
TODO
1
TODO
|
@ -42,7 +42,6 @@ Technlogy Preview 3 :
|
||||||
=> Add user markers on OSD.
|
=> Add user markers on OSD.
|
||||||
=> Add areas marking.
|
=> Add areas marking.
|
||||||
- Add a noise automatic filler.
|
- Add a noise automatic filler.
|
||||||
- Fix the distorted sun appearance.
|
|
||||||
- Lock some previews together (eg: terrain height and colored preview).
|
- Lock some previews together (eg: terrain height and colored preview).
|
||||||
- Find a new licence.
|
- Find a new licence.
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,7 @@ FormAtmosphere::FormAtmosphere(QWidget *parent):
|
||||||
addInputInt(tr("Day time (hour)"), &_definition->hour, 0, 23, 1, 10);
|
addInputInt(tr("Day time (hour)"), &_definition->hour, 0, 23, 1, 10);
|
||||||
addInputInt(tr("Day time (minute)"), &_definition->minute, 0, 59, 1, 10);
|
addInputInt(tr("Day time (minute)"), &_definition->minute, 0, 59, 1, 10);
|
||||||
//addInputColor(tr("Sun color"), &_definition->sun_color);
|
//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("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);
|
addInputDouble(tr("Humidity"), &_definition->humidity, 0.0, 1.0, 0.01, 0.1)->setVisibilityCondition((int*)&_definition->model, 0);
|
||||||
|
|
||||||
|
|
|
@ -219,7 +219,7 @@ int WidgetCurveEditor::getPointAt(int x, int y)
|
||||||
{
|
{
|
||||||
curveGetPoint(_curve, i, &point);
|
curveGetPoint(_curve, i, &point);
|
||||||
curveToScreen(point.position, point.value, &dx, &dy);
|
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)
|
if (nearest < 0 || ndistance < distance)
|
||||||
{
|
{
|
||||||
distance = ndistance;
|
distance = ndistance;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "public.h"
|
#include "private.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Atmospheric scattering, based on E. Bruneton and F.Neyret work.
|
* Atmospheric scattering, based on E. Bruneton and F.Neyret work.
|
||||||
|
@ -18,7 +18,6 @@
|
||||||
|
|
||||||
/*********************** Constants ***********************/
|
/*********************** Constants ***********************/
|
||||||
|
|
||||||
#define WORLD_SCALING 0.05
|
|
||||||
#define GROUND_OFFSET 0.5
|
#define GROUND_OFFSET 0.5
|
||||||
static const double Rg = 6360.0;
|
static const double Rg = 6360.0;
|
||||||
static const double Rt = 6420.0;
|
static const double Rt = 6420.0;
|
||||||
|
@ -1168,7 +1167,7 @@ Color brunetonApplyAerialPerspective(Renderer* renderer, Vector3 location, Color
|
||||||
{
|
{
|
||||||
Vector3 eye = renderer->camera_location;
|
Vector3 eye = renderer->camera_location;
|
||||||
Vector3 direction = v3Scale(v3Sub(location, eye), WORLD_SCALING);
|
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 x = {0.0, Rg + (max(eye.y, 0.0) + GROUND_OFFSET) * WORLD_SCALING, 0.0};
|
||||||
Vector3 v = v3Normalize(direction);
|
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;
|
double r0 = Rg + (max(lightingGetStatusLocation(status).y, 0.0) + GROUND_OFFSET) * WORLD_SCALING;
|
||||||
Vector3 up = {0.0, 1.0, 0.0};
|
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 x = {0.0, r0, 0.0};
|
||||||
Vector3 s = v3Normalize(v3Sub(sun_position, x));
|
Vector3 s = v3Normalize(v3Sub(sun_position, x));
|
||||||
|
|
||||||
|
|
|
@ -120,7 +120,6 @@ static Color _fakeGetSkyColor(Renderer* renderer, Vector3 direction)
|
||||||
static Color _getSkyColor(Renderer* renderer, Vector3 direction)
|
static Color _getSkyColor(Renderer* renderer, Vector3 direction)
|
||||||
{
|
{
|
||||||
AtmosphereDefinition* definition;
|
AtmosphereDefinition* definition;
|
||||||
double dist;
|
|
||||||
Vector3 sun_direction, sun_position;
|
Vector3 sun_direction, sun_position;
|
||||||
Color sky_color, sun_color;
|
Color sky_color, sun_color;
|
||||||
|
|
||||||
|
@ -128,9 +127,7 @@ static Color _getSkyColor(Renderer* renderer, Vector3 direction)
|
||||||
|
|
||||||
sun_direction = renderer->atmosphere->getSunDirection(renderer);
|
sun_direction = renderer->atmosphere->getSunDirection(renderer);
|
||||||
direction = v3Normalize(direction);
|
direction = v3Normalize(direction);
|
||||||
dist = v3Norm(v3Sub(direction, sun_direction));
|
sun_position = v3Scale(sun_direction, SUN_DISTANCE_SCALED);
|
||||||
|
|
||||||
sun_position = v3Scale(sun_direction, 149597870.0);
|
|
||||||
|
|
||||||
/* Get base scattering*/
|
/* Get base scattering*/
|
||||||
switch (definition->model)
|
switch (definition->model)
|
||||||
|
@ -146,19 +143,25 @@ static Color _getSkyColor(Renderer* renderer, Vector3 direction)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get sun shape */
|
/* 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 = definition->sun_color;
|
||||||
sun_color.r *= 100.0;
|
sun_color.r *= 100.0;
|
||||||
sun_color.g *= 100.0;
|
sun_color.g *= 100.0;
|
||||||
sun_color.b *= 100.0;
|
sun_color.b *= 100.0;
|
||||||
if (dist <= definition->sun_radius * 0.9)
|
|
||||||
|
if (dist > 0.05)
|
||||||
{
|
{
|
||||||
return sun_color;
|
return sun_color;
|
||||||
}
|
}
|
||||||
else
|
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);
|
colorMask(&sky_color, &sun_color);
|
||||||
return sky_color;
|
return sky_color;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ void atmosphereAutoPreset(AtmosphereDefinition* definition, AtmospherePreset pre
|
||||||
definition->sun_color.g = 0.95;
|
definition->sun_color.g = 0.95;
|
||||||
definition->sun_color.b = 0.9;
|
definition->sun_color.b = 0.9;
|
||||||
definition->sun_color.a = 1.0;
|
definition->sun_color.a = 1.0;
|
||||||
definition->sun_radius = 0.02;
|
definition->sun_radius = 1.0;
|
||||||
definition->humidity = 0.1;
|
definition->humidity = 0.1;
|
||||||
|
|
||||||
switch (preset)
|
switch (preset)
|
||||||
|
|
|
@ -5,6 +5,13 @@
|
||||||
|
|
||||||
#define SPHERE_SIZE 10000.0
|
#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);
|
Color basicApplyAerialPerspective(Renderer* renderer, Vector3 location, Color base);
|
||||||
void basicGetLightingStatus(Renderer* renderer, LightStatus* status, Vector3 normal, int opaque);
|
void basicGetLightingStatus(Renderer* renderer, LightStatus* status, Vector3 normal, int opaque);
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ void sceneryQuit()
|
||||||
void sceneryAutoPreset()
|
void sceneryAutoPreset()
|
||||||
{
|
{
|
||||||
terrainAutoPreset(_terrain, TERRAIN_PRESET_STANDARD);
|
terrainAutoPreset(_terrain, TERRAIN_PRESET_STANDARD);
|
||||||
atmosphereAutoPreset(_atmosphere, ATMOSPHERE_MODEL_BRUNETON);
|
atmosphereAutoPreset(_atmosphere, ATMOSPHERE_PRESET_CLEAR_DAY);
|
||||||
cloudsAutoPreset(_clouds, CLOUDS_PRESET_PARTLY_CLOUDY);
|
cloudsAutoPreset(_clouds, CLOUDS_PRESET_PARTLY_CLOUDY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,17 +54,3 @@ void toolsFloat2DMapCopy(double* src, double* dest, int src_xstart, int src_ysta
|
||||||
dest = dest_row + dest_ystep;
|
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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
#define _PAYSAGES_TOOLS_H_
|
#define _PAYSAGES_TOOLS_H_
|
||||||
|
|
||||||
#include "shared/types.h"
|
#include "shared/types.h"
|
||||||
#include "tools/euclid.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -14,8 +13,6 @@ double toolsRandom();
|
||||||
double toolsCubicInterpolate(double stencil[4], double x);
|
double toolsCubicInterpolate(double stencil[4], double x);
|
||||||
double toolsBicubicInterpolate(double stencil[16], double x, double y);
|
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);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -74,6 +74,10 @@ Matrix4 m4NewPerspective(double fov_y, double aspect, double near, double far);
|
||||||
double m4Determinant(Matrix4 m);
|
double m4Determinant(Matrix4 m);
|
||||||
Matrix4 m4Inverse(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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue