16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-23 02:49:19 +02:00

moon object, tweaks to the lighting model

This commit is contained in:
tmj-fstate
2017-03-28 13:09:01 +02:00
parent 2ec6cad7cb
commit 9dda5037d3
12 changed files with 220 additions and 128 deletions

View File

@@ -80,11 +80,12 @@ double Global::pCameraRotation;
double Global::pCameraRotationDeg; double Global::pCameraRotationDeg;
std::vector<vector3> Global::FreeCameraInit; std::vector<vector3> Global::FreeCameraInit;
std::vector<vector3> Global::FreeCameraInitAngle; std::vector<vector3> Global::FreeCameraInitAngle;
double Global::fFogStart = 1700;
double Global::fFogEnd = 2000;
float Global::Background[3] = {0.2f, 0.4f, 0.33f}; float Global::Background[3] = {0.2f, 0.4f, 0.33f};
GLfloat Global::AtmoColor[] = {0.423f, 0.702f, 1.0f}; GLfloat Global::AtmoColor[] = {0.423f, 0.702f, 1.0f};
GLfloat Global::FogColor[] = {0.6f, 0.7f, 0.8f}; GLfloat Global::FogColor[] = {0.6f, 0.7f, 0.8f};
double Global::fFogStart = 1700;
double Global::fFogEnd = 2000;
float Global::Overcast{ 0.1f }; // NOTE: all this weather stuff should be moved elsewhere
#ifdef EU07_USE_OLD_LIGHTING_MODEL #ifdef EU07_USE_OLD_LIGHTING_MODEL
GLfloat Global::ambientDayLight[] = {0.40f, 0.40f, 0.45f, 1.0f}; // robocze GLfloat Global::ambientDayLight[] = {0.40f, 0.40f, 0.45f, 1.0f}; // robocze
GLfloat Global::diffuseDayLight[] = {0.55f, 0.54f, 0.50f, 1.0f}; GLfloat Global::diffuseDayLight[] = {0.55f, 0.54f, 0.50f, 1.0f};

View File

@@ -218,6 +218,7 @@ class Global
static float Background[3]; static float Background[3];
static GLfloat AtmoColor[]; static GLfloat AtmoColor[];
static GLfloat FogColor[]; static GLfloat FogColor[];
static float Overcast;
// static bool bTimeChange; // static bool bTimeChange;
#ifdef EU07_USE_OLD_LIGHTING_MODEL #ifdef EU07_USE_OLD_LIGHTING_MODEL
static opengl_light AmbientLight; static opengl_light AmbientLight;

View File

@@ -2798,16 +2798,29 @@ bool TGround::Init(std::string File)
{ // Ra: ustawienie parametrów OpenGL przeniesione do FirstInit { // Ra: ustawienie parametrów OpenGL przeniesione do FirstInit
WriteLog("Scenery atmo definition"); WriteLog("Scenery atmo definition");
parser.getTokens(3); parser.getTokens(3);
parser >> Global::AtmoColor[0] >> Global::AtmoColor[1] >> Global::AtmoColor[2]; parser
>> Global::AtmoColor[0]
>> Global::AtmoColor[1]
>> Global::AtmoColor[2];
parser.getTokens(2); parser.getTokens(2);
parser >> Global::fFogStart >> Global::fFogEnd; parser
>> Global::fFogStart
>> Global::fFogEnd;
if (Global::fFogEnd > 0.0) if (Global::fFogEnd > 0.0)
{ // ostatnie 3 parametry są opcjonalne { // ostatnie 3 parametry są opcjonalne
parser.getTokens(3); parser.getTokens(3);
parser >> Global::FogColor[0] >> Global::FogColor[1] >> Global::FogColor[2]; parser
>> Global::FogColor[0]
>> Global::FogColor[1]
>> Global::FogColor[2];
} }
parser.getTokens(); parser.getTokens();
parser >> token; parser >> token;
if( token != "endatmo" ) {
// optional overcast parameter
// NOTE: parameter system needs some decent replacement, but not worth the effort if we're moving to built-in editor
Global::Overcast = clamp( std::stof( token ), 0.0f, 1.0f );
}
while (token.compare("endatmo") != 0) while (token.compare("endatmo") != 0)
{ // a kolejne parametry są pomijane { // a kolejne parametry są pomijane
parser.getTokens(); parser.getTokens();

View File

@@ -313,12 +313,16 @@ int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic)
} }
std::string discard; std::string discard;
parser.getTokens(13, false); parser.getTokens(13, false);
parser >> fNearAttenStart >> discard >> fNearAttenEnd >> discard >> bUseNearAtten >> parser
discard >> iFarAttenDecay >> discard >> fFarDecayRadius >> discard >> >> fNearAttenStart
fCosFalloffAngle // kąt liczony dla średnicy, a nie promienia >> discard >> fNearAttenEnd
>> discard >> bUseNearAtten
>> discard >> iFarAttenDecay
>> discard >> fFarDecayRadius
>> discard >> fCosFalloffAngle // kąt liczony dla średnicy, a nie promienia
>> discard >> fCosHotspotAngle; // kąt liczony dla średnicy, a nie promienia >> discard >> fCosHotspotAngle; // kąt liczony dla średnicy, a nie promienia
fCosFalloffAngle = cos(DegToRad(0.5 * fCosFalloffAngle)); fCosFalloffAngle = std::cos( DegToRad( 0.5f * fCosFalloffAngle ) );
fCosHotspotAngle = cos(DegToRad(0.5 * fCosHotspotAngle)); fCosHotspotAngle = std::cos( DegToRad( 0.5f * fCosHotspotAngle ) );
iNumVerts = 1; iNumVerts = 1;
/* /*
iFlags |= 0x4010; // rysowane w cyklu nieprzezroczystych, macierz musi zostać bez zmiany iFlags |= 0x4010; // rysowane w cyklu nieprzezroczystych, macierz musi zostać bez zmiany

View File

@@ -18,7 +18,7 @@ double ResourceManager::_lastReport = 0.0f;
void ResourceManager::Register(Resource *resource) void ResourceManager::Register(Resource *resource)
{ {
_resources.push_back(resource); _resources.emplace_back(resource);
}; };
void ResourceManager::Unregister(Resource *resource) void ResourceManager::Unregister(Resource *resource)

View File

@@ -401,7 +401,9 @@ void TSegment::RenderLoft(const vector6 *ShapePoints, int iNumShapePoints, doubl
jmm1 * ShapePoints[j].z + m1 * ShapePoints[j + iNumShapePoints].z, tv1); jmm1 * ShapePoints[j].z + m1 * ShapePoints[j + iNumShapePoints].z, tv1);
glVertex3f(pt.x, pt.y, pt.z); // pt nie mamy gdzie zapamiętać? glVertex3f(pt.x, pt.y, pt.z); // pt nie mamy gdzie zapamiętać?
} }
if (p) // jeśli jest wskaźnik do tablicy // BUG: things blow up badly in the following part in 64bit version on baltyk.scn
// TODO: sort this mess out when the time comes to reorganize spline generation
if( p ) // jeśli jest wskaźnik do tablicy
if (*p) if (*p)
if (!j) // to dla pierwszego punktu if (!j) // to dla pierwszego punktu
{ {

View File

@@ -2311,37 +2311,75 @@ void
world_environment::init() { world_environment::init() {
m_sun.init(); m_sun.init();
m_moon.init();
m_stars.init(); m_stars.init();
m_clouds.Init(); m_clouds.Init();
} }
void void
world_environment::update() { world_environment::update() {
// move celestial bodies...
// move sun...
m_sun.update(); m_sun.update();
auto const position = m_sun.getPosition(); m_moon.update();
// ...update the global data to match new sun state... // ...determine source of key light and adjust global state accordingly...
auto const sunlightlevel = m_sun.getIntensity();
auto const moonlightlevel = m_moon.getIntensity();
float keylightintensity;
float twilightfactor;
float3 keylightcolor;
if( moonlightlevel > sunlightlevel ) {
// rare situations when the moon is brighter than the sun, typically at night
Global::SunAngle = m_moon.getAngle();
Global::DayLight.set_position( m_moon.getPosition() );
Global::DayLight.direction = -1.0 * m_moon.getDirection();
keylightintensity = moonlightlevel;
// if the moon is up, it overrides the twilight
twilightfactor = 0.0f;
keylightcolor = float3( 255.0f / 255.0f, 242.0f / 255.0f, 202.0f / 255.0f );
}
else {
// regular situation with sun as the key light
Global::SunAngle = m_sun.getAngle(); Global::SunAngle = m_sun.getAngle();
Global::DayLight.set_position( position ); Global::DayLight.set_position( m_sun.getPosition() );
Global::DayLight.direction = -1.0 * m_sun.getDirection(); Global::DayLight.direction = -1.0 * m_sun.getDirection();
keylightintensity = sunlightlevel;
// diffuse (sun) intensity goes down after twilight, and reaches minimum 18 degrees below horizon
twilightfactor = clamp( -Global::SunAngle, 0.0f, 18.0f ) / 18.0f;
// TODO: crank orange up at dawn/dusk
keylightcolor = float3( 255.0f / 255.0f, 242.0f / 255.0f, 231.0f / 255.0f );
float const duskfactor = 1.0f - clamp( Global::SunAngle, 0.0f, 18.0f ) / 18.0f;
keylightcolor = interpolate(
float3( 255.0f / 255.0f, 242.0f / 255.0f, 231.0f / 255.0f ),
float3( 235.0f / 255.0f, 140.0f / 255.0f, 36.0f / 255.0f ),
duskfactor );
}
// ...update skydome to match the current sun position as well... // ...update skydome to match the current sun position as well...
m_skydome.Update( position ); m_skydome.SetOvercastFactor( Global::Overcast );
m_skydome.Update( m_sun.getPosition() );
// ...retrieve current sky colour and brightness... // ...retrieve current sky colour and brightness...
auto const skydomecolour = m_skydome.GetAverageColor(); auto const skydomecolour = m_skydome.GetAverageColor();
auto const skydomehsv = RGBtoHSV( skydomecolour ); auto const skydomehsv = RGBtoHSV( skydomecolour );
auto const intensity = std::min( 1.15f * (0.05f + m_sun.getIntensity() + skydomehsv.z), 1.25f ); // sun strength is reduced by overcast level
// ...update light colours and intensity. keylightintensity *= ( 1.0f - Global::Overcast * 0.65f );
// NOTE: intensity combines intensity of the sun and the light reflected by the sky dome
// intensity combines intensity of the sun and the light reflected by the sky dome
// it'd be more technically correct to have just the intensity of the sun here, // it'd be more technically correct to have just the intensity of the sun here,
// but whether it'd _look_ better is something to be tested // but whether it'd _look_ better is something to be tested
Global::DayLight.diffuse[ 0 ] = intensity * 255.0f / 255.0f; auto const intensity = std::min( 1.15f * ( 0.05f + keylightintensity + skydomehsv.z ), 1.25f );
Global::DayLight.diffuse[ 1 ] = intensity * 242.0f / 255.0f; // the impact of sun component is reduced proportionally to overcast level, as overcast increases role of ambient light
Global::DayLight.diffuse[ 2 ] = intensity * 231.0f / 255.0f; auto const diffuselevel = interpolate( keylightintensity, intensity * ( 1.0f - twilightfactor ), 1.0f - Global::Overcast * 0.75f );
// ...update light colours and intensity.
keylightcolor = keylightcolor * diffuselevel;
Global::DayLight.diffuse[ 0 ] = keylightcolor.x;
Global::DayLight.diffuse[ 1 ] = keylightcolor.y;
Global::DayLight.diffuse[ 2 ] = keylightcolor.z;
Global::DayLight.ambient[ 0 ] = skydomecolour.x; // tonal impact of skydome color is inversely proportional to how high the sun is above the horizon
Global::DayLight.ambient[ 1 ] = skydomecolour.y; // (this is pure conjecture, aimed more to 'look right' than be accurate)
Global::DayLight.ambient[ 2 ] = skydomecolour.z; float const ambienttone = clamp( 1.0f - ( Global::SunAngle / 90.0f ), 0.0f, 1.0f );
Global::DayLight.ambient[ 0 ] = interpolate( skydomehsv.z, skydomecolour.x, ambienttone );
Global::DayLight.ambient[ 1 ] = interpolate( skydomehsv.z, skydomecolour.y, ambienttone );
Global::DayLight.ambient[ 2 ] = interpolate( skydomehsv.z, skydomecolour.z, ambienttone );
Global::fLuminance = intensity; Global::fLuminance = intensity;
@@ -2379,11 +2417,22 @@ world_environment::render() {
m_skydome.Render(); m_skydome.Render();
m_stars.render(); m_stars.render();
m_clouds.Render( m_skydome.GetAverageColor() * 2.5f ); float const duskfactor = 1.0f - clamp( std::abs(m_sun.getAngle()), 0.0f, 12.0f ) / 12.0f;
float3 suncolor = interpolate(
m_skydome.GetAverageColor(),
float3( 235.0f / 255.0f, 140.0f / 255.0f, 36.0f / 255.0f ),
duskfactor ) * m_skydome.GetAverageColor().z;
m_clouds.Render(
interpolate( m_skydome.GetAverageColor(), suncolor, duskfactor * 0.65f )
// m_skydome.GetAverageColor()
* ( 1.0f - Global::Overcast * 0.5f ) // overcast darkens the clouds
* 2.5f ); // arbitrary adjustment factor
if( DebugModeFlag == true ) { if( DebugModeFlag == true ) {
// mark sun position for easier debugging // mark sun position for easier debugging
m_sun.render(); m_sun.render();
m_moon.render();
} }
Global::DayLight.apply_angle(); Global::DayLight.apply_angle();
Global::DayLight.apply_intensity(); Global::DayLight.apply_intensity();

View File

@@ -15,6 +15,7 @@ http://mozilla.org/MPL/2.0/.
#include "Ground.h" #include "Ground.h"
#include "sky.h" #include "sky.h"
#include "sun.h" #include "sun.h"
#include "moon.h"
#include "stars.h" #include "stars.h"
#include "skydome.h" #include "skydome.h"
#include "mczapkie/mover.h" #include "mczapkie/mover.h"
@@ -33,6 +34,7 @@ private:
CSkyDome m_skydome; CSkyDome m_skydome;
cStars m_stars; cStars m_stars;
cSun m_sun; cSun m_sun;
cMoon m_moon;
TSky m_clouds; TSky m_clouds;
}; };

View File

@@ -210,6 +210,9 @@
<ClCompile Include="openglmatrixstack.cpp"> <ClCompile Include="openglmatrixstack.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="moon.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Globals.h"> <ClInclude Include="Globals.h">
@@ -407,6 +410,9 @@
<ClInclude Include="openglmatrixstack.h"> <ClInclude Include="openglmatrixstack.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="moon.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="maszyna.rc"> <ResourceCompile Include="maszyna.rc">

View File

@@ -184,7 +184,7 @@ void CSkyDome::SetGammaCorrection( float const Gamma ) {
void CSkyDome::SetOvercastFactor( float const Overcast ) { void CSkyDome::SetOvercastFactor( float const Overcast ) {
m_overcast = clamp( Overcast, 0.0f, 1.0f ); m_overcast = clamp( Overcast, 0.0f, 1.0f ) * 0.75f; // going above 0.65 makes the model go pretty bad, appearance-wise
} }
void CSkyDome::GetPerez( float *Perez, float Distribution[ 5 ][ 2 ], const float Turbidity ) { void CSkyDome::GetPerez( float *Perez, float Distribution[ 5 ][ 2 ], const float Turbidity ) {
@@ -277,7 +277,7 @@ void CSkyDome::RebuildColors() {
// luminance(Y) for clear & overcast sky // luminance(Y) for clear & overcast sky
float const yclear = PerezFunctionO2( perezluminance, icostheta, gamma, cosgamma2, zenithluminance ); float const yclear = PerezFunctionO2( perezluminance, icostheta, gamma, cosgamma2, zenithluminance );
float const yover = ( 1.0f + 2.0f * vertex.y ) / 3.0f; float const yover = zenithluminance * ( 1.0f + 2.0f * vertex.y ) / 3.0f;
float const Y = interpolate( yclear, yover, m_overcast ); float const Y = interpolate( yclear, yover, m_overcast );
float const X = (x / y) * Y; float const X = (x / y) * Y;
@@ -295,6 +295,11 @@ void CSkyDome::RebuildColors() {
colorconverter.z = 1.0f - exp( -m_expfactor * colorconverter.z ); colorconverter.z = 1.0f - exp( -m_expfactor * colorconverter.z );
} }
// desaturate sky colour, based on overcast level
if( colorconverter.y > 0.0f ) {
colorconverter.y *= ( 1.0f - m_overcast );
}
// override the hue, based on sun height above the horizon. crude way to deal with model shortcomings // override the hue, based on sun height above the horizon. crude way to deal with model shortcomings
// correction begins when the sun is higher than 10 degrees above the horizon, and fully in effect at 10+15 degrees // correction begins when the sun is higher than 10 degrees above the horizon, and fully in effect at 10+15 degrees
float const degreesabovehorizon = 90.0f - m_thetasun * ( 180.0f / M_PI ); float const degreesabovehorizon = 90.0f - m_thetasun * ( 180.0f / M_PI );
@@ -318,8 +323,8 @@ void CSkyDome::RebuildColors() {
*/ */
// crude correction for the times where the model breaks (late night) // crude correction for the times where the model breaks (late night)
// TODO: use proper night sky calculation for these times instead // TODO: use proper night sky calculation for these times instead
if( ( color.x <= 0.0f ) if( ( color.x <= 0.05f )
&& ( color.y <= 0.0f ) ) { && ( color.y <= 0.05f ) ) {
// darken the sky as the sun goes deeper below the horizon // darken the sky as the sun goes deeper below the horizon
// 15:50:75 is picture-based night sky colour. it may not be accurate but looks 'right enough' // 15:50:75 is picture-based night sky colour. it may not be accurate but looks 'right enough'
color.z = 0.75f * std::max( color.z + m_sundirection.y, 0.075f ); color.z = 0.75f * std::max( color.z + m_sundirection.y, 0.075f );

99
sun.cpp
View File

@@ -48,8 +48,6 @@ cSun::render() {
GLfloat LightPosition[]= { 10.0f, 50.0f, -5.0f, 1.0f }; // ambient GLfloat LightPosition[]= { 10.0f, 50.0f, -5.0f, 1.0f }; // ambient
glLightfv(GL_LIGHT1, GL_POSITION, LightPosition ); glLightfv(GL_LIGHT1, GL_POSITION, LightPosition );
*/ */
glDisable(GL_LIGHTING);
glDisable(GL_FOG);
glColor4f( 255.0f/255.0f, 242.0f/255.0f, 231.0f/255.0f, 1.f ); glColor4f( 255.0f/255.0f, 242.0f/255.0f, 231.0f/255.0f, 1.f );
// debug line to locate the sun easier // debug line to locate the sun easier
Math3D::vector3 position = m_position; Math3D::vector3 position = m_position;
@@ -62,8 +60,6 @@ cSun::render() {
// radius is a result of scaling true distance down to 2km -- it's scaled by equal ratio // radius is a result of scaling true distance down to 2km -- it's scaled by equal ratio
gluSphere( sunsphere, (float)(m_body.distance * 9.359157), 12, 12 ); gluSphere( sunsphere, (float)(m_body.distance * 9.359157), 12, 12 );
glPopMatrix(); glPopMatrix();
glEnable(GL_FOG);
glEnable(GL_LIGHTING);
} }
Math3D::vector3 Math3D::vector3
@@ -115,8 +111,8 @@ void cSun::setPressure( float const Pressure ) {
void cSun::move() { void cSun::move() {
static double degrad = 57.295779513; // converts from radians to degrees static double radtodeg = 57.295779513; // converts from radians to degrees
static double raddeg = 0.0174532925; // converts from degrees to radians static double degtorad = 0.0174532925; // converts from degrees to radians
SYSTEMTIME localtime; // time for the calculation SYSTEMTIME localtime; // time for the calculation
time( &localtime ); time( &localtime );
@@ -128,48 +124,68 @@ void cSun::move() {
double ut = localtime.wHour double ut = localtime.wHour
+ localtime.wMinute / 60.0 // too low resolution, noticeable skips + localtime.wMinute / 60.0 // too low resolution, noticeable skips
+ localtime.wSecond / 3600.0; // good enough in normal circumstances + localtime.wSecond / 3600.0; // good enough in normal circumstances
/* /*
+ localtime.wMilliseconds / 3600000.0; // for really smooth movement + localtime.wMilliseconds / 3600000.0; // for really smooth movement
*/ */
double daynumber = 367 * localtime.wYear double daynumber = 367 * localtime.wYear
- 7 * ( localtime.wYear + ( localtime.wMonth + 9 ) /12 ) / 4 - 7 * ( localtime.wYear + ( localtime.wMonth + 9 ) / 12 ) / 4
+ 275 * localtime.wMonth / 9 + 275 * localtime.wMonth / 9
+ localtime.wDay + localtime.wDay
- 730530 - 730530
+ (ut / 24.0); + ( ut / 24.0 );
// Universal Coordinated (Greenwich standard) time // Universal Coordinated (Greenwich standard) time
m_observer.utime = ut * 3600.0; m_observer.utime = ut * 3600.0;
m_observer.utime = m_observer.utime / 3600.0 - m_observer.timezone; m_observer.utime = m_observer.utime / 3600.0 - m_observer.timezone;
// perihelion longitude
// mean longitude m_body.phlong = 282.9404 + 4.70935e-5 * daynumber; // w
m_body.mnlong = 280.460 + 0.9856474 * daynumber; // orbit eccentricity
m_body.mnlong -= 360.0 * (int) ( m_body.mnlong / 360.0 ); // clamp the range to 0-360 double const e = 0.016709 - 1.151e-9 * daynumber;
if( m_body.mnlong < 0.0 ) m_body.mnlong += 360.0;
// mean anomaly // mean anomaly
m_body.mnanom = 357.528 + 0.9856003 * daynumber; m_body.mnanom = 356.0470 + 0.9856002585 * daynumber; // M
m_body.mnanom -= 360.0 * (int) ( m_body.mnanom / 360.0 ); // clamp the range to 0-360 m_body.mnanom -= 360.0 * (int)( m_body.mnanom / 360.0 ); // clamp the range to 0-360
if( m_body.mnanom < 0.0 ) m_body.mnanom += 360.0; if( m_body.mnanom < 0.0 ) m_body.mnanom += 360.0;
// obliquity of the ecliptic
m_body.oblecl = 23.4393 - 3.563e-7 * daynumber;
// mean longitude
m_body.mnlong = m_body.phlong + m_body.mnanom; // L = w + M
m_body.mnlong -= 360.0 * (int)( m_body.mnlong / 360.0 ); // clamp the range to 0-360
if( m_body.mnlong < 0.0 ) m_body.mnlong += 360.0;
// eccentric anomaly
double const E = m_body.mnanom + radtodeg * e * std::sin( degtorad * m_body.mnanom ) * ( 1.0 + e * std::cos( degtorad * m_body.mnanom ) );
// ecliptic plane rectangular coordinates
double const xv = std::cos( degtorad * E ) - e;
double const yv = std::sin( degtorad * E ) * std::sqrt( 1.0 - e*e );
// distance
m_body.distance = std::sqrt( xv*xv + yv*yv ); // r
// true anomaly
m_body.tranom = radtodeg * std::atan2( yv, xv ); // v
// ecliptic longitude // ecliptic longitude
m_body.eclong = m_body.mnlong m_body.eclong = m_body.tranom + m_body.phlong; // lon = v + w
+ 1.915 * sin( m_body.mnanom * raddeg )
+ 0.020 * sin ( 2.0 * m_body.mnanom * raddeg );
m_body.eclong -= 360.0 * (int)( m_body.eclong / 360.0 ); m_body.eclong -= 360.0 * (int)( m_body.eclong / 360.0 );
if( m_body.eclong < 0.0 ) m_body.eclong += 360.0; // clamp the range to 0-360 if( m_body.eclong < 0.0 ) m_body.eclong += 360.0; // clamp the range to 0-360
/*
// obliquity of the ecliptic // ecliptic rectangular coordinates
m_body.ecobli = 23.439 - 4.0e-07 * daynumber; double const x = m_body.distance * std::cos( degtorad * m_body.eclong );
double const y = m_body.distance * std::sin( degtorad * m_body.eclong );
double const z = 0.0;
// equatorial rectangular coordinates
double const xequat = x;
double const yequat = y * std::cos( degtorad * m_body.oblecl ) - 0.0 * std::sin( degtorad * m_body.oblecl );
double const zequat = y * std::sin( degtorad * m_body.oblecl ) + 0.0 * std::cos( degtorad * m_body.oblecl );
// declination // declination
m_body.declin = degrad * asin( sin (m_body.ecobli * raddeg) * sin (m_body.eclong * raddeg) ); m_body.declin = radtodeg * std::atan2( zequat, std::sqrt( xequat*xequat + yequat*yequat ) );
// right ascension
m_body.rascen = radtodeg * std::atan2( yequat, xequat );
*/
// declination
m_body.declin = radtodeg * std::asin( std::sin( m_body.oblecl * degtorad ) * std::sin( m_body.eclong * degtorad ) );
// right ascension // right ascension
double top = cos ( raddeg * m_body.ecobli ) * sin ( raddeg * m_body.eclong ); double top = std::cos( degtorad * m_body.oblecl ) * std::sin( degtorad * m_body.eclong );
double bottom = cos ( raddeg * m_body.eclong ); double bottom = std::cos( degtorad * m_body.eclong );
m_body.rascen = degrad * atan2( top, bottom ); m_body.rascen = radtodeg * std::atan2( top, bottom );
if( m_body.rascen < 0.0 ) m_body.rascen += 360.0; // (make it a positive angle) if( m_body.rascen < 0.0 ) m_body.rascen += 360.0; // (make it a positive angle)
// Greenwich mean sidereal time // Greenwich mean sidereal time
@@ -192,29 +208,20 @@ void cSun::move() {
double cz; // cosine of the solar zenith angle double cz; // cosine of the solar zenith angle
double tdatcd = cos( raddeg * m_body.declin ); double tdatcd = std::cos( degtorad * m_body.declin );
double tdatch = cos( raddeg * m_body.hrang ); double tdatch = std::cos( degtorad * m_body.hrang );
double tdatcl = cos( raddeg * m_observer.latitude ); double tdatcl = std::cos( degtorad * m_observer.latitude );
double tdatsd = sin( raddeg * m_body.declin ); double tdatsd = std::sin( degtorad * m_body.declin );
double tdatsl = sin( raddeg * m_observer.latitude ); double tdatsl = std::sin( degtorad * m_observer.latitude );
cz = tdatsd * tdatsl + tdatcd * tdatcl * tdatch; cz = tdatsd * tdatsl + tdatcd * tdatcl * tdatch;
// (watch out for the roundoff errors) // (watch out for the roundoff errors)
if( fabs (cz) > 1.0 ) { cz >= 0.0 ? cz = 1.0 : cz = -1.0; } if( fabs( cz ) > 1.0 ) { cz >= 0.0 ? cz = 1.0 : cz = -1.0; }
m_body.zenetr = acos( cz ) * degrad; m_body.zenetr = std::acos( cz ) * radtodeg;
m_body.elevetr = 90.0 - m_body.zenetr; m_body.elevetr = 90.0 - m_body.zenetr;
refract(); refract();
// additional calculations for proper object sizing.
// orbit eccentricity
double e = 0.016709 - 1.151e-9 * daynumber;
// eccentric anomaly
double E = m_body.mnanom + e * degrad * sin(m_body.mnanom) * ( 1.0 + e * cos(m_body.mnanom) );
double xv = cos(E) - e;
double yv = sqrt(1.0 - e*e) * sin(E);
m_body.distance = sqrt( xv*xv + yv*yv );
} }
void cSun::refract() { void cSun::refract() {

4
sun.h
View File

@@ -67,10 +67,12 @@ protected:
struct celestialbody { // main planet parameters struct celestialbody { // main planet parameters
double dayang; // day angle (daynum*360/year-length) degrees double dayang; // day angle (daynum*360/year-length) degrees
double phlong; // longitude of perihelion
double mnlong; // mean longitude, degrees double mnlong; // mean longitude, degrees
double mnanom; // mean anomaly, degrees double mnanom; // mean anomaly, degrees
double tranom; // true anomaly, degrees
double eclong; // ecliptic longitude, degrees. double eclong; // ecliptic longitude, degrees.
double ecobli; // obliquity of ecliptic. double oblecl; // obliquity of ecliptic.
double declin; // declination--zenith angle of solar noon at equator, degrees NORTH. double declin; // declination--zenith angle of solar noon at equator, degrees NORTH.
double rascen; // right ascension, degrees double rascen; // right ascension, degrees
double hrang; // hour angle--hour of sun from solar noon, degrees WEST double hrang; // hour angle--hour of sun from solar noon, degrees WEST