diff --git a/src/modules/graphic/ssggraph/grMoon.cpp b/src/modules/graphic/ssggraph/grMoon.cpp index 3e2c4132a..d85e0df9b 100644 --- a/src/modules/graphic/ssggraph/grMoon.cpp +++ b/src/modules/graphic/ssggraph/grMoon.cpp @@ -75,12 +75,12 @@ ssgBranch * cGrMoon::build( double moon_size ) moon_state->enable( GL_ALPHA_TEST ); moon_state->setAlphaClamp( 0.01 ); - cl = new ssgColourArray( 1 ); + moon_cl = new ssgColourArray( 1 ); sgVec4 color; sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 ); - cl->add( color ); + moon_cl->add( color ); - ssgBranch *moon = grMakeSphere( moon_state, cl, moon_size, 15, 15, + ssgBranch *moon = grMakeSphere( moon_state, moon_cl, moon_size, 15, 15, grMoonOrbPreDraw, grMoonOrbPostDraw ); repaint( 0.0 ); @@ -112,14 +112,14 @@ bool cGrMoon::repaint( double moon_angle ) grGammaCorrectRGB( color ); float *ptr; - ptr = cl->get( 0 ); + ptr = moon_cl->get( 0 ); sgCopyVec4( ptr, color ); } return true; } -bool cGrMoon::reposition(sgVec3 p, double moonangle, double moonrightAscension, double moondeclination, double moon_dist) +bool cGrMoon::reposition(sgVec3 p, double moon_angle, double moonrightAscension, double moondeclination, double moon_dist) { sgMat4 T1, T2, GST, RA, DEC; sgVec3 axis; @@ -128,11 +128,11 @@ bool cGrMoon::reposition(sgVec3 p, double moonangle, double moonrightAscension, sgMakeTransMat4( T1, p ); sgSetVec3( axis, 0.0, 0.0, -1.0 ); - sgMakeRotMat4( GST, (float)moonangle, axis ); + sgMakeRotMat4( GST, moon_angle, axis ); sgSetVec3( axis, 0.0, 0.0, 1.0 ); - sgMakeRotMat4( RA, ((float)moonrightAscension * SGD_RADIANS_TO_DEGREES) - 90.0, axis ); + sgMakeRotMat4( RA, (moonrightAscension * SGD_RADIANS_TO_DEGREES) - 90.0, axis ); sgSetVec3( axis, 1.0, 0.0, 0.0 ); - sgMakeRotMat4( DEC, (float)moondeclination * SGD_RADIANS_TO_DEGREES, axis ); + sgMakeRotMat4( DEC, moondeclination * SGD_RADIANS_TO_DEGREES, axis ); sgSetVec3( v, 0.0, moon_dist, 0.0 ); sgMakeTransMat4( T2, v ); diff --git a/src/modules/graphic/ssggraph/grSky.cpp b/src/modules/graphic/ssggraph/grSky.cpp index 6f12f82fc..74f1eb4f9 100644 --- a/src/modules/graphic/ssggraph/grSky.cpp +++ b/src/modules/graphic/ssggraph/grSky.cpp @@ -99,7 +99,7 @@ void cGrSky::build( double h_radius, double v_radius, sun->setSunDistance( sun_dist ); moon = new cGrMoon; - moon_transform ->addKid( sun->build( moon_size)); + moon_transform ->addKid( moon->build( moon_size)); moon->setMoonDist(moon_dist); planets = new cGrStars; @@ -150,6 +150,7 @@ bool cGrSky::repositionFlat( sgVec3 view_pos, double spin, double dt ) double rotation; sgCoord pos; + sun->reposition( view_pos, 0 ); moon->reposition( view_pos, 0 ); diff --git a/src/modules/graphic/ssggraph/grSky.h b/src/modules/graphic/ssggraph/grSky.h index c0dad37db..53aba1e87 100644 --- a/src/modules/graphic/ssggraph/grSky.h +++ b/src/modules/graphic/ssggraph/grSky.h @@ -143,12 +143,8 @@ class cGrMoon private: ssgTransform *moon_transform; ssgSimpleState *moon_state; - ssgSimpleState *halo_state; - ssgColourArray *cl; - - ssgVertexArray *halo_vl; - ssgTexCoordArray *halo_tl; + ssgColourArray *moon_cl; double prev_moon_angle; double moon_angle; @@ -174,12 +170,7 @@ public: // 0 degrees = high noon // 90 degrees = moon rise/set // 180 degrees = darkest midnight - - //bool repaint(double moon_angle); - - /*bool reposition( sgVec3 p, double angle, - double rightAscension, double declination, - double moon_dist );*/ + bool repaint(double moon_angle); bool reposition(sgVec3 p, double moon_angle) { @@ -187,9 +178,9 @@ public: } bool reposition(sgVec3 p, double moon_angle, double moonAscension, double moondeclination, double moon_dist); - bool repaint(double moon_angle); - void getMoonPosition (sgCoord* p) + + void getMoonPosition (sgCoord* p) { sgMat4 Xform; moon_transform->getTransform(Xform); @@ -224,11 +215,9 @@ private: ssgColourArray *ihalo_cl; ssgColourArray *ohalo_cl; - ssgVertexArray *sun_vl; ssgVertexArray *ihalo_vl; ssgVertexArray *ohalo_vl; - ssgTexCoordArray *sun_tl; ssgTexCoordArray *ihalo_tl; ssgTexCoordArray *ohalo_tl; diff --git a/src/modules/graphic/ssggraph/grSun.cpp b/src/modules/graphic/ssggraph/grSun.cpp index ea6f36cdc..5cf86ed84 100644 --- a/src/modules/graphic/ssggraph/grSun.cpp +++ b/src/modules/graphic/ssggraph/grSun.cpp @@ -1,415 +1,390 @@ -/*************************************************************************** - - file : grSun.cpp - copyright : (C) 2009 by Xavier Bertaux (based on ssgasky plib code) - web : http://www.speed-dreams.org - version : $Id: grSky.cpp 3162 2010-12-05 13:11:22Z pouillot $ - - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#include -#include -#include "grSky.h" -#include "grSphere.h" - -static float sun_exp2_punch_through; -static double visibility; - -// Set up sun rendering call backs -static int grSunPreDraw( ssgEntity *e ) -{ - ssgLeaf *f = (ssgLeaf *)e; - if ( f -> hasState () ) f->getState()->apply() ; - - glPushAttrib( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_FOG_BIT ); - glDisable( GL_DEPTH_TEST ); - glDisable( GL_FOG ); - glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ; - return true; -} - -static int grSunPostDraw( ssgEntity *e ) -{ - glPopAttrib(); - return true; -} - -static int grSunHaloPreDraw( ssgEntity *e ) -{ - ssgLeaf *f = (ssgLeaf *)e; - if ( f -> hasState () ) f->getState()->apply(); - - glPushAttrib( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_FOG_BIT ); - glDisable( GL_DEPTH_TEST ); - glFogf (GL_FOG_DENSITY, sun_exp2_punch_through); - glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ; - - return true; -} - -static int grSunHaloPostDraw( ssgEntity *e ) -{ - glPopAttrib(); - return true; -} - -// Constructor -cGrSun::cGrSun( void ) -{ - sun_transform = 0; - prev_sun_angle = -9999.0; - visibility = -9999.0; -} - -// Destructor -cGrSun::~cGrSun( void ) -{ - ssgDeRefDelete( sun_transform ); -} - -ssgBranch * cGrSun::build( double sun_size ) -{ - ssgDeRefDelete( sun_transform ); - - sun_transform = new ssgTransform; - sun_transform->ref(); - - sgVec4 color; - sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 ); - - sun_cl = new ssgColourArray( 1 ); - sun_cl->add( color ); - - ihalo_cl = new ssgColourArray( 1 ); - ihalo_cl->add( color ); - - ohalo_cl = new ssgColourArray( 1 ); - ohalo_cl->add( color ); - - //repaint( 0.0, 1.0 ); - - // set up the sun-state - sun_state = new ssgSimpleState(); - sun_state->setShadeModel( GL_SMOOTH ); - sun_state->disable( GL_LIGHTING ); - sun_state->disable( GL_CULL_FACE ); - sun_state->setTexture( "data/textures/inner_halo.png"); - sun_state->enable( GL_TEXTURE_2D ); - sun_state->enable( GL_COLOR_MATERIAL ); - sun_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE ); - sun_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 ); - sun_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 ); - sun_state->enable( GL_BLEND ); - sun_state->setAlphaClamp( 0.01 ); - sun_state->enable( GL_ALPHA_TEST ); - - // Build ssg structure - - sgVec3 va; - sun_vl = new ssgVertexArray; - sgSetVec3( va, -sun_size, 0.0, -sun_size ); - sun_vl->add( va ); - sgSetVec3( va, sun_size, 0.0, -sun_size ); - sun_vl->add( va ); - sgSetVec3( va, -sun_size, 0.0, sun_size ); - sun_vl->add( va ); - sgSetVec3( va, sun_size, 0.0, sun_size ); - sun_vl->add( va ); - - sgVec2 vb; - sun_tl = new ssgTexCoordArray; - sgSetVec2( vb, 0.0f, 0.0f ); - sun_tl->add( vb ); - sgSetVec2( vb, 1.0, 0.0 ); - sun_tl->add( vb ); - sgSetVec2( vb, 0.0, 1.0 ); - sun_tl->add( vb ); - sgSetVec2( vb, 1.0, 1.0 ); - sun_tl->add( vb ); - - ssgBranch *sun = grMakeSphere( sun_state, sun_cl, sun_size, 15, 15, - grSunPreDraw, grSunPostDraw ); - - repaint( 0.0, 1.0 ); - - ihalo_state = new ssgSimpleState(); - ihalo_state->setTexture( "data/textures/inner_halo.png" ); - ihalo_state->enable( GL_TEXTURE_2D ); - ihalo_state->disable( GL_LIGHTING ); - ihalo_state->setShadeModel( GL_SMOOTH ); - ihalo_state->disable( GL_CULL_FACE ); - ihalo_state->enable( GL_COLOR_MATERIAL ); - ihalo_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE ); - ihalo_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 ); - ihalo_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 ); - ihalo_state->enable( GL_ALPHA_TEST ); - ihalo_state->setAlphaClamp(0.01); - ihalo_state->enable ( GL_BLEND ) ; - - float ihalo_size = sun_size * 2.0; - sgVec3 vc; - ihalo_vl = new ssgVertexArray; - sgSetVec3( vc, -ihalo_size, 0.0, -ihalo_size ); - ihalo_vl->add( vc ); - sgSetVec3( vc, ihalo_size, 0.0, -ihalo_size ); - ihalo_vl->add( vc ); - sgSetVec3( vc, -ihalo_size, 0.0, ihalo_size ); - ihalo_vl->add( vc ); - sgSetVec3( vc, ihalo_size, 0.0, ihalo_size ); - ihalo_vl->add( vc ); - - sgVec2 vd; - ihalo_tl = new ssgTexCoordArray; - sgSetVec2( vd, 0.0f, 0.0f ); - ihalo_tl->add( vd ); - sgSetVec2( vd, 1.0, 0.0 ); - ihalo_tl->add( vd ); - sgSetVec2( vd, 0.0, 1.0 ); - ihalo_tl->add( vd ); - sgSetVec2( vd, 1.0, 1.0 ); - ihalo_tl->add( vd ); - - ssgLeaf *ihalo = new ssgVtxTable ( GL_TRIANGLE_STRIP, ihalo_vl, NULL, ihalo_tl, ihalo_cl ); - ihalo->setState( ihalo_state ); - - ohalo_state = new ssgSimpleState(); - ohalo_state->setTexture( "data/textures/outer_halo.png" ); - ohalo_state->enable( GL_TEXTURE_2D ); - ohalo_state->disable( GL_LIGHTING ); - ohalo_state->setShadeModel( GL_SMOOTH ); - ohalo_state->disable( GL_CULL_FACE ); - ohalo_state->enable( GL_COLOR_MATERIAL ); - ohalo_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE ); - ohalo_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 ); - ohalo_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 ); - ohalo_state->enable( GL_ALPHA_TEST ); - ohalo_state->setAlphaClamp(0.01); - ohalo_state->enable ( GL_BLEND ) ; - - float ohalo_size = (float)sun_size * 7.0; - sgVec3 ve; - ohalo_vl = new ssgVertexArray; - sgSetVec3( ve, -ohalo_size, 0.0, -ohalo_size ); - ohalo_vl->add( ve ); - sgSetVec3( ve, ohalo_size, 0.0, -ohalo_size ); - ohalo_vl->add( ve ); - sgSetVec3( ve, -ohalo_size, 0.0, ohalo_size ); - ohalo_vl->add( ve ); - sgSetVec3( ve, ohalo_size, 0.0, ohalo_size ); - ohalo_vl->add( ve ); - - sgVec2 vf; - ohalo_tl = new ssgTexCoordArray; - sgSetVec2( vf, 0.0f, 0.0f ); - ohalo_tl->add( vf ); - sgSetVec2( vf, 1.0, 0.0 ); - ohalo_tl->add( vf ); - sgSetVec2( vf, 0.0, 1.0 ); - ohalo_tl->add( vf ); - sgSetVec2( vf, 1.0, 1.0 ); - ohalo_tl->add( vf ); - - ssgLeaf *ohalo = new ssgVtxTable ( GL_TRIANGLE_STRIP, ohalo_vl, NULL, ohalo_tl, ohalo_cl ); - ohalo->setState( ohalo_state ); - - ihalo->setCallback( SSG_CALLBACK_PREDRAW, grSunHaloPreDraw ); - ihalo->setCallback( SSG_CALLBACK_POSTDRAW, grSunHaloPostDraw ); - ohalo->setCallback( SSG_CALLBACK_PREDRAW, grSunHaloPreDraw ); - ohalo->setCallback( SSG_CALLBACK_POSTDRAW, grSunHaloPostDraw ); - - sun_transform->addKid( ohalo ); - sun_transform->addKid( ihalo ); - sun_transform->addKid( sun ); - - return sun_transform; -} - -bool cGrSun::repaint( double sun_angle, double new_visibility ) -{ - if ( visibility != new_visibility ) - { - visibility = new_visibility; - - static const float sqrt_m_log01 = sqrt( -log( 0.01 ) ); - sun_exp2_punch_through = sqrt_m_log01 / ( visibility * 15 ); - } - - if ( prev_sun_angle != sun_angle ) - { - prev_sun_angle = sun_angle; - - float aerosol_factor; - if ( visibility < 100 ) - { - aerosol_factor = 8000; - } - else - { - aerosol_factor = 80.5 / log( visibility / 100 ); - } - - float rel_humidity, density_avg; - - /*if ( !env_node ) - {*/ - rel_humidity = 0.5; - density_avg = 0.7; - /*} - else - { - //rel_humidity = env_node->getFloatValue( "relative-humidity" ); - //density_avg = env_node->getFloatValue( "atmosphere/density-tropo-avg" ); - }*/ - - sgVec4 i_halo_color, o_halo_color, sun_color; - - float red_scat_f = ( aerosol_factor * path_distance * density_avg ) / 5E+07; - sun_color[0] = 1 - red_scat_f; - i_halo_color[0] = 1 - ( 1.1 * red_scat_f ); - o_halo_color[0] = 1 - ( 1.4 * red_scat_f ); - - // Green - 546.1 nm - float green_scat_f = ( aerosol_factor * path_distance * density_avg ) / 8.8938E+06; - sun_color[1] = 1 - green_scat_f; - i_halo_color[1] = 1 - ( 1.1 * green_scat_f ); - o_halo_color[1] = 1 - ( 1.4 * green_scat_f ); - - // Blue - 435.8 nm - float blue_scat_f = ( aerosol_factor * path_distance * density_avg ) / 3.607E+06; - sun_color[2] = 1 - blue_scat_f; - i_halo_color[2] = 1 - ( 1.1 * blue_scat_f ); - o_halo_color[2] = 1 - ( 1.4 * blue_scat_f ); - - // Alpha - sun_color[3] = 1; - i_halo_color[3] = 1; - - o_halo_color[3] = blue_scat_f; - if ( ( new_visibility < 10000 ) && ( blue_scat_f > 1 )) - { - o_halo_color[3] = 2 - blue_scat_f; - } - - float saturation = 1 - ( rel_humidity / 200 ); - sun_color[1] += (( 1 - saturation ) * ( 1 - sun_color[1] )); - sun_color[2] += (( 1 - saturation ) * ( 1 - sun_color[2] )); - - i_halo_color[1] += (( 1 - saturation ) * ( 1 - i_halo_color[1] )); - i_halo_color[2] += (( 1 - saturation ) * ( 1 - i_halo_color[2] )); - - o_halo_color[1] += (( 1 - saturation ) * ( 1 - o_halo_color[1] )); - o_halo_color[2] += (( 1 - saturation ) * ( 1 - o_halo_color[2] )); - - // just to make sure we're in the limits - if ( sun_color[0] < 0 ) sun_color[0] = 0; - else if ( sun_color[0] > 1) sun_color[0] = 1; - if ( i_halo_color[0] < 0 ) i_halo_color[0] = 0; - else if ( i_halo_color[0] > 1) i_halo_color[0] = 1; - if ( o_halo_color[0] < 0 ) o_halo_color[0] = 0; - else if ( o_halo_color[0] > 1) o_halo_color[0] = 1; - - if ( sun_color[1] < 0 ) sun_color[1] = 0; - else if ( sun_color[1] > 1) sun_color[1] = 1; - if ( i_halo_color[1] < 0 ) i_halo_color[1] = 0; - else if ( i_halo_color[1] > 1) i_halo_color[1] = 1; - if ( o_halo_color[1] < 0 ) o_halo_color[1] = 0; - else if ( o_halo_color[1] > 1) o_halo_color[1] = 1; - - if ( sun_color[2] < 0 ) sun_color[2] = 0; - else if ( sun_color[2] > 1) sun_color[2] = 1; - if ( i_halo_color[2] < 0 ) i_halo_color[2] = 0; - else if ( i_halo_color[2] > 1) i_halo_color[2] = 1; - if ( o_halo_color[2] < 0 ) o_halo_color[2] = 0; - else if ( o_halo_color[2] > 1) o_halo_color[2] = 1; - if ( o_halo_color[3] < 0 ) o_halo_color[2] = 0; - else if ( o_halo_color[3] > 1) o_halo_color[3] = 1; - - - grGammaCorrectRGB( i_halo_color ); - grGammaCorrectRGB( o_halo_color ); - grGammaCorrectRGB( sun_color ); - - - float *ptr; - ptr = sun_cl->get( 0 ); - sgCopyVec4( ptr, sun_color ); - ptr = ihalo_cl->get( 0 ); - sgCopyVec4( ptr, i_halo_color ); - ptr = ohalo_cl->get( 0 ); - sgCopyVec4( ptr, o_halo_color ); - } - - return true; -} - -bool cGrSun::reposition( sgVec3 p, double angle, double rightAscension, double declination, double sun_dist ) -{ - sgMat4 T1, T2, GST, RA, DEC; - sgVec3 axis; - sgVec3 v; - - sgMakeTransMat4( T1, p ); - sgSetVec3( axis, 0.0, 0.0, -1.0 ); - sgMakeRotMat4( GST, (float)angle, axis ); - sgSetVec3( axis, 0.0, 0.0, 1.0 ); - sgMakeRotMat4( RA, ((float)rightAscension * SGD_RADIANS_TO_DEGREES) - 90.0, axis ); - sgSetVec3( axis, 1.0, 0.0, 0.0 ); - sgMakeRotMat4( DEC, (float)declination * SGD_RADIANS_TO_DEGREES, axis ); - - sgSetVec3( v, 0.0, sun_dist, 0.0 ); - sgMakeTransMat4( T2, v ); - - sgMat4 TRANSFORM; - sgCopyMat4( TRANSFORM, T1 ); - sgPreMultMat4( TRANSFORM, GST ); - sgPreMultMat4( TRANSFORM, RA ); - sgPreMultMat4( TRANSFORM, DEC ); - sgPreMultMat4( TRANSFORM, T2 ); - - sgCoord skypos; - sgSetCoord( &skypos, TRANSFORM ); - - sun_transform->setTransform( &skypos ); - - if ( prev_sun_angle != sun_angle ) - { - if ( sun_angle == 0 ) sun_angle = 0.1; - const double r_earth_pole = 6356752.314; - const double r_tropo_pole = 6356752.314 + 8000; - const double epsilon_earth2 = 6.694380066E-3; - const double epsilon_tropo2 = 9.170014946E-3; - - double r_tropo = r_tropo_pole / sqrt ( 1 - ( epsilon_tropo2 * pow ( cos( 0.0 ), 2 ))); - double r_earth = r_earth_pole / sqrt ( 1 - ( epsilon_earth2 * pow ( cos( 0.0 ), 2 ))); - - double position_radius = r_earth; - - double gamma = SG_PI - sun_angle; - double sin_beta = ( position_radius * sin ( gamma ) ) / r_tropo; - double alpha = SG_PI - gamma - asin( sin_beta ); - - path_distance = sqrt( pow( position_radius, 2 ) + pow( r_tropo, 2 ) - - ( 2 * position_radius * r_tropo * cos( alpha ) )); - - double alt_half = sqrt( pow ( r_tropo, 2 ) + pow( path_distance / 2, 2 ) - r_tropo * path_distance * cos( asin( sin_beta )) ) - r_earth; - - if ( alt_half < 0.0 ) alt_half = 0.0; - - /*if ( env_node ) - { - //env_node->setDoubleValue( "atmosphere/altitude-troposphere-top", r_tropo - r_earth ); - //env_node->setDoubleValue( "atmosphere/altitude-half-to-sun", alt_half ); - }*/ - } - - return true; +/*************************************************************************** + + file : grSun.cpp + copyright : (C) 2009 by Xavier Bertaux (based on ssgasky plib code) + web : http://www.speed-dreams.org + version : $Id: grSky.cpp 3162 2010-12-05 13:11:22Z pouillot $ + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include +#include +#include "grSky.h" +#include "grSphere.h" + +static float sun_exp2_punch_through; +static double visibility; + +// Set up sun rendering call backs +static int grSunPreDraw( ssgEntity *e ) +{ + ssgLeaf *f = (ssgLeaf *)e; + if ( f -> hasState () ) f->getState()->apply() ; + + glPushAttrib( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_FOG_BIT ); + glDisable( GL_DEPTH_TEST ); + glDisable( GL_FOG ); + glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ; + return true; +} + +static int grSunPostDraw( ssgEntity *e ) +{ + glPopAttrib(); + return true; +} + +static int grSunHaloPreDraw( ssgEntity *e ) +{ + ssgLeaf *f = (ssgLeaf *)e; + if ( f -> hasState () ) f->getState()->apply(); + + glPushAttrib( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_FOG_BIT ); + glDisable( GL_DEPTH_TEST ); + glFogf (GL_FOG_DENSITY, sun_exp2_punch_through); + glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ; + + return true; +} + +static int grSunHaloPostDraw( ssgEntity *e ) +{ + glPopAttrib(); + return true; +} + +// Constructor +cGrSun::cGrSun( void ) +{ + sun_transform = 0; + prev_sun_angle = -9999.0; + visibility = -9999.0; +} + +// Destructor +cGrSun::~cGrSun( void ) +{ + ssgDeRefDelete( sun_transform ); +} + +ssgBranch * cGrSun::build( double sun_size ) +{ + ssgDeRefDelete( sun_transform ); + + sun_transform = new ssgTransform; + sun_transform->ref(); + + sgVec4 color; + sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 ); + + sun_cl = new ssgColourArray( 1 ); + sun_cl->add( color ); + + ihalo_cl = new ssgColourArray( 1 ); + ihalo_cl->add( color ); + + ohalo_cl = new ssgColourArray( 1 ); + ohalo_cl->add( color ); + + //repaint( 0.0, 1.0 ); + + // set up the sun-state + sun_state = new ssgSimpleState(); + sun_state->setShadeModel( GL_SMOOTH ); + sun_state->disable( GL_LIGHTING ); + sun_state->enable( GL_CULL_FACE ); + sun_state->disable( GL_TEXTURE_2D ); + sun_state->enable( GL_COLOR_MATERIAL ); + sun_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE ); + sun_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 ); + sun_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 ); + sun_state->disable( GL_BLEND ); + sun_state->setAlphaClamp( 0.01 ); + sun_state->disable( GL_ALPHA_TEST ); + + ssgBranch *sun = grMakeSphere( sun_state, sun_cl, sun_size, 15, 15, + grSunPreDraw, grSunPostDraw ); + + repaint( 0.0, 10000.0 ); + + ihalo_state = new ssgSimpleState(); + ihalo_state->setTexture( "data/textures/inner_halo.png" ); + ihalo_state->enable( GL_TEXTURE_2D ); + ihalo_state->disable( GL_LIGHTING ); + ihalo_state->setShadeModel( GL_SMOOTH ); + ihalo_state->disable( GL_CULL_FACE ); + ihalo_state->enable( GL_COLOR_MATERIAL ); + ihalo_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE ); + ihalo_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 ); + ihalo_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 ); + ihalo_state->enable( GL_ALPHA_TEST ); + ihalo_state->setAlphaClamp(0.01); + ihalo_state->enable ( GL_BLEND ) ; + + float ihalo_size = sun_size * 2.0; + sgVec3 vc; + ihalo_vl = new ssgVertexArray; + sgSetVec3( vc, -ihalo_size, 0.0, -ihalo_size ); + ihalo_vl->add( vc ); + sgSetVec3( vc, ihalo_size, 0.0, -ihalo_size ); + ihalo_vl->add( vc ); + sgSetVec3( vc, -ihalo_size, 0.0, ihalo_size ); + ihalo_vl->add( vc ); + sgSetVec3( vc, ihalo_size, 0.0, ihalo_size ); + ihalo_vl->add( vc ); + + sgVec2 vd; + ihalo_tl = new ssgTexCoordArray; + sgSetVec2( vd, 0.0f, 0.0f ); + ihalo_tl->add( vd ); + sgSetVec2( vd, 1.0, 0.0 ); + ihalo_tl->add( vd ); + sgSetVec2( vd, 0.0, 1.0 ); + ihalo_tl->add( vd ); + sgSetVec2( vd, 1.0, 1.0 ); + ihalo_tl->add( vd ); + + ssgLeaf *ihalo = new ssgVtxTable ( GL_TRIANGLE_STRIP, ihalo_vl, NULL, ihalo_tl, ihalo_cl ); + ihalo->setState( ihalo_state ); + + ohalo_state = new ssgSimpleState(); + ohalo_state->setTexture( "data/textures/outer_halo.png" ); + ohalo_state->enable( GL_TEXTURE_2D ); + ohalo_state->disable( GL_LIGHTING ); + ohalo_state->setShadeModel( GL_SMOOTH ); + ohalo_state->disable( GL_CULL_FACE ); + ohalo_state->enable( GL_COLOR_MATERIAL ); + ohalo_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE ); + ohalo_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 ); + ohalo_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 ); + ohalo_state->enable( GL_ALPHA_TEST ); + ohalo_state->setAlphaClamp(0.01); + ohalo_state->enable ( GL_BLEND ) ; + + float ohalo_size = (float)sun_size * 7.0; + sgVec3 ve; + ohalo_vl = new ssgVertexArray; + sgSetVec3( ve, -ohalo_size, 0.0, -ohalo_size ); + ohalo_vl->add( ve ); + sgSetVec3( ve, ohalo_size, 0.0, -ohalo_size ); + ohalo_vl->add( ve ); + sgSetVec3( ve, -ohalo_size, 0.0, ohalo_size ); + ohalo_vl->add( ve ); + sgSetVec3( ve, ohalo_size, 0.0, ohalo_size ); + ohalo_vl->add( ve ); + + sgVec2 vf; + ohalo_tl = new ssgTexCoordArray; + sgSetVec2( vf, 0.0f, 0.0f ); + ohalo_tl->add( vf ); + sgSetVec2( vf, 1.0, 0.0 ); + ohalo_tl->add( vf ); + sgSetVec2( vf, 0.0, 1.0 ); + ohalo_tl->add( vf ); + sgSetVec2( vf, 1.0, 1.0 ); + ohalo_tl->add( vf ); + + ssgLeaf *ohalo = new ssgVtxTable ( GL_TRIANGLE_STRIP, ohalo_vl, NULL, ohalo_tl, ohalo_cl ); + ohalo->setState( ohalo_state ); + + ihalo->setCallback( SSG_CALLBACK_PREDRAW, grSunHaloPreDraw ); + ihalo->setCallback( SSG_CALLBACK_POSTDRAW, grSunHaloPostDraw ); + ohalo->setCallback( SSG_CALLBACK_PREDRAW, grSunHaloPreDraw ); + ohalo->setCallback( SSG_CALLBACK_POSTDRAW, grSunHaloPostDraw ); + + sun_transform->addKid( ohalo ); + sun_transform->addKid( ihalo ); + sun_transform->addKid( sun ); + + return sun_transform; +} + +bool cGrSun::repaint( double sun_angle, double new_visibility ) +{ + if ( visibility != new_visibility ) + { + visibility = new_visibility; + + static const float sqrt_m_log01 = sqrt( -log( 0.01 ) ); + sun_exp2_punch_through = sqrt_m_log01 / ( visibility * 15 ); + } + + if ( prev_sun_angle != sun_angle ) + { + prev_sun_angle = sun_angle; + + float aerosol_factor; + if ( visibility < 100 ) + { + aerosol_factor = 8000; + } + else + { + aerosol_factor = 80.5 / log( visibility / 100 ); + } + + float rel_humidity, density_avg; + + /*if ( !env_node ) + {*/ + rel_humidity = 0.5; + density_avg = 0.7; + /*} + else + { + //rel_humidity = env_node->getFloatValue( "relative-humidity" ); + //density_avg = env_node->getFloatValue( "atmosphere/density-tropo-avg" ); + }*/ + + sgVec4 i_halo_color, o_halo_color, sun_color; + + float red_scat_f = ( aerosol_factor * path_distance * density_avg ) / 5E+07; + sun_color[0] = 1 - red_scat_f; + i_halo_color[0] = 1 - ( 1.1 * red_scat_f ); + o_halo_color[0] = 1 - ( 1.4 * red_scat_f ); + + // Green - 546.1 nm + float green_scat_f = ( aerosol_factor * path_distance * density_avg ) / 8.8938E+06; + sun_color[1] = 1 - green_scat_f; + i_halo_color[1] = 1 - ( 1.1 * green_scat_f ); + o_halo_color[1] = 1 - ( 1.4 * green_scat_f ); + + // Blue - 435.8 nm + float blue_scat_f = ( aerosol_factor * path_distance * density_avg ) / 3.607E+06; + sun_color[2] = 1 - blue_scat_f; + i_halo_color[2] = 1 - ( 1.1 * blue_scat_f ); + o_halo_color[2] = 1 - ( 1.4 * blue_scat_f ); + + // Alpha + sun_color[3] = 1; + i_halo_color[3] = 1; + + o_halo_color[3] = blue_scat_f; + if ( ( new_visibility < 10000 ) && ( blue_scat_f > 1 )) + { + o_halo_color[3] = 2 - blue_scat_f; + } + + float saturation = 1 - ( rel_humidity / 200 ); + sun_color[1] += (( 1 - saturation ) * ( 1 - sun_color[1] )); + sun_color[2] += (( 1 - saturation ) * ( 1 - sun_color[2] )); + + i_halo_color[1] += (( 1 - saturation ) * ( 1 - i_halo_color[1] )); + i_halo_color[2] += (( 1 - saturation ) * ( 1 - i_halo_color[2] )); + + o_halo_color[1] += (( 1 - saturation ) * ( 1 - o_halo_color[1] )); + o_halo_color[2] += (( 1 - saturation ) * ( 1 - o_halo_color[2] )); + + // just to make sure we're in the limits + if ( sun_color[0] < 0 ) sun_color[0] = 0; + else if ( sun_color[0] > 1) sun_color[0] = 1; + if ( i_halo_color[0] < 0 ) i_halo_color[0] = 0; + else if ( i_halo_color[0] > 1) i_halo_color[0] = 1; + if ( o_halo_color[0] < 0 ) o_halo_color[0] = 0; + else if ( o_halo_color[0] > 1) o_halo_color[0] = 1; + + if ( sun_color[1] < 0 ) sun_color[1] = 0; + else if ( sun_color[1] > 1) sun_color[1] = 1; + if ( i_halo_color[1] < 0 ) i_halo_color[1] = 0; + else if ( i_halo_color[1] > 1) i_halo_color[1] = 1; + if ( o_halo_color[1] < 0 ) o_halo_color[1] = 0; + else if ( o_halo_color[1] > 1) o_halo_color[1] = 1; + + if ( sun_color[2] < 0 ) sun_color[2] = 0; + else if ( sun_color[2] > 1) sun_color[2] = 1; + if ( i_halo_color[2] < 0 ) i_halo_color[2] = 0; + else if ( i_halo_color[2] > 1) i_halo_color[2] = 1; + if ( o_halo_color[2] < 0 ) o_halo_color[2] = 0; + else if ( o_halo_color[2] > 1) o_halo_color[2] = 1; + if ( o_halo_color[3] < 0 ) o_halo_color[2] = 0; + else if ( o_halo_color[3] > 1) o_halo_color[3] = 1; + + + grGammaCorrectRGB( i_halo_color ); + grGammaCorrectRGB( o_halo_color ); + grGammaCorrectRGB( sun_color ); + + + float *ptr; + ptr = sun_cl->get( 0 ); + sgCopyVec4( ptr, sun_color ); + ptr = ihalo_cl->get( 0 ); + sgCopyVec4( ptr, i_halo_color ); + ptr = ohalo_cl->get( 0 ); + sgCopyVec4( ptr, o_halo_color ); + } + + return true; +} + +bool cGrSun::reposition( sgVec3 p, double angle, double rightAscension, double declination, double sun_dist ) +{ + sgMat4 T1, T2, GST, RA, DEC; + sgVec3 axis; + sgVec3 v; + + sgMakeTransMat4( T1, p ); + sgSetVec3( axis, 0.0, 0.0, -1.0 ); + sgMakeRotMat4( GST, (float)angle, axis ); + sgSetVec3( axis, 0.0, 0.0, 1.0 ); + sgMakeRotMat4( RA, ((float)rightAscension * SGD_RADIANS_TO_DEGREES) - 90.0, axis ); + sgSetVec3( axis, 1.0, 0.0, 0.0 ); + sgMakeRotMat4( DEC, (float)declination * SGD_RADIANS_TO_DEGREES, axis ); + + sgSetVec3( v, 0.0, sun_dist, 0.0 ); + sgMakeTransMat4( T2, v ); + + sgMat4 TRANSFORM; + sgCopyMat4( TRANSFORM, T1 ); + sgPreMultMat4( TRANSFORM, GST ); + sgPreMultMat4( TRANSFORM, RA ); + sgPreMultMat4( TRANSFORM, DEC ); + sgPreMultMat4( TRANSFORM, T2 ); + + sgCoord skypos; + sgSetCoord( &skypos, TRANSFORM ); + + sun_transform->setTransform( &skypos ); + + if ( prev_sun_angle != sun_angle ) + { + if ( sun_angle == 0 ) sun_angle = 0.1; + const double r_earth_pole = 6356752.314; + const double r_tropo_pole = 6356752.314 + 8000; + const double epsilon_earth2 = 6.694380066E-3; + const double epsilon_tropo2 = 9.170014946E-3; + + double r_tropo = r_tropo_pole / sqrt ( 1 - ( epsilon_tropo2 * pow ( cos( 0.0 ), 2 ))); + double r_earth = r_earth_pole / sqrt ( 1 - ( epsilon_earth2 * pow ( cos( 0.0 ), 2 ))); + + double position_radius = r_earth; + + double gamma = SG_PI - sun_angle; + double sin_beta = ( position_radius * sin ( gamma ) ) / r_tropo; + double alpha = SG_PI - gamma - asin( sin_beta ); + + path_distance = sqrt( pow( position_radius, 2 ) + pow( r_tropo, 2 ) + - ( 2 * position_radius * r_tropo * cos( alpha ) )); + + double alt_half = sqrt( pow ( r_tropo, 2 ) + pow( path_distance / 2, 2 ) - r_tropo * path_distance * cos( asin( sin_beta )) ) - r_earth; + + if ( alt_half < 0.0 ) alt_half = 0.0; + + /*if ( env_node ) + { + //env_node->setDoubleValue( "atmosphere/altitude-troposphere-top", r_tropo - r_earth ); + //env_node->setDoubleValue( "atmosphere/altitude-half-to-sun", alt_half ); + }*/ + } + + return true; } \ No newline at end of file