From e3c5a95e7a46ce9cd49eb62fe7cc678562bdf72a Mon Sep 17 00:00:00 2001 From: torcs-ng Date: Sun, 24 Feb 2013 18:30:45 +0000 Subject: [PATCH] update OsgGraph with last work by Gaetan and Xavier git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@5196 30fe4595-0a0c-4342-8851-515496e4dcbd Former-commit-id: 72a9bb414e2f90f05144b71a6086de40c48fb68c Former-commit-id: 66b016241be759979967b9c493621c954354d652 --- src/modules/graphic/osggraph/AccException.h | 18 ++ src/modules/graphic/osggraph/CMakeLists.txt | 7 +- src/modules/graphic/osggraph/OsgAtomic.h | 147 +++++++++ src/modules/graphic/osggraph/OsgDome.cpp | 298 +++++++---------- src/modules/graphic/osggraph/OsgDome.h | 76 ++--- src/modules/graphic/osggraph/OsgMain.cpp | 22 +- src/modules/graphic/osggraph/OsgMath.h | 16 + src/modules/graphic/osggraph/OsgMoon.cpp | 52 +-- src/modules/graphic/osggraph/OsgMoon.h | 70 ++++ src/modules/graphic/osggraph/OsgReferenced.h | 50 +++ src/modules/graphic/osggraph/OsgRender.cpp | 142 ++++++++- src/modules/graphic/osggraph/OsgRender.h | 11 + src/modules/graphic/osggraph/OsgSharedPtr.h | 99 ++++++ src/modules/graphic/osggraph/OsgSky.cpp | 299 ++++++++++++++++++ src/modules/graphic/osggraph/OsgSky.h | 182 +++++++++++ src/modules/graphic/osggraph/OsgSphere.cpp | 123 ++++--- src/modules/graphic/osggraph/OsgSphere.h | 11 +- src/modules/graphic/osggraph/OsgStars.cpp | 82 ++--- src/modules/graphic/osggraph/OsgStars.h | 44 +++ src/modules/graphic/osggraph/OsgSun.cpp | 200 +++++++----- src/modules/graphic/osggraph/OsgSun.h | 81 +++++ .../graphic/osggraph/OsgVectorArrayAdapter.h | 4 +- .../graphic/osggraph/ReaderWriterACC.cpp | 20 +- 23 files changed, 1559 insertions(+), 495 deletions(-) create mode 100644 src/modules/graphic/osggraph/OsgAtomic.h create mode 100644 src/modules/graphic/osggraph/OsgMoon.h create mode 100644 src/modules/graphic/osggraph/OsgReferenced.h create mode 100644 src/modules/graphic/osggraph/OsgSharedPtr.h create mode 100644 src/modules/graphic/osggraph/OsgSky.cpp create mode 100644 src/modules/graphic/osggraph/OsgSky.h create mode 100644 src/modules/graphic/osggraph/OsgStars.h create mode 100644 src/modules/graphic/osggraph/OsgSun.h diff --git a/src/modules/graphic/osggraph/AccException.h b/src/modules/graphic/osggraph/AccException.h index de35a9ec0..b4ca9667f 100644 --- a/src/modules/graphic/osggraph/AccException.h +++ b/src/modules/graphic/osggraph/AccException.h @@ -1,3 +1,21 @@ +/*************************************************************************** + + file : OsgException.h + created : Mon Dec 31 10:24:02 CEST 2012 + copyright : (C) 2012 by Gaëtan André + email : gaetan.andre@gmail.com + version : $Id$ + +***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ #ifndef AC3D_EXCEPTION #define AC3D_EXCEPTION 1 diff --git a/src/modules/graphic/osggraph/CMakeLists.txt b/src/modules/graphic/osggraph/CMakeLists.txt index 98a8e5101..f4d16fd22 100644 --- a/src/modules/graphic/osggraph/CMakeLists.txt +++ b/src/modules/graphic/osggraph/CMakeLists.txt @@ -1,12 +1,15 @@ INCLUDE(../../../../cmake/macros.cmake) -SET(OSGGRAPH_HEADERS OsgVectorArrayAdapter.h OsgColor.h +SET(OSGGRAPH_HEADERS OsgVectorArrayAdapter.h OsgColor.h OsgAtomic.h + OsgReferenced.h OsgSharedPtr.h + OsgSphere.h OsgSun.h OsgMoon.h OsgStars.h OsgSky.h AccGeode.h AccException.h ReaderWriterACC.h OsgLoader.h OsgScenery.h OsgRender.h OsgMath.h OsgMain.h OsgView.h OsgGraph.h OsgCar.h OsgWheel.h OsgBrake.h) -SET(OSGGRAPH_SOURCES AccGeode.cpp AccException.cpp ReaderWriterACC.cpp +SET(OSGGRAPH_SOURCES OsgSphere.cpp OsgSun.cpp OsgMoon.cpp OsgStars.cpp OsgSky.cpp + AccGeode.cpp AccException.cpp ReaderWriterACC.cpp OsgLoader.cpp OsgBackground.cpp OsgScenery.cpp OsgView.cpp OsgRender.cpp OsgMath.cpp OsgMain.cpp OsgGraph.cpp OsgCar.cpp OsgWheel.cpp diff --git a/src/modules/graphic/osggraph/OsgAtomic.h b/src/modules/graphic/osggraph/OsgAtomic.h new file mode 100644 index 000000000..1129d10e0 --- /dev/null +++ b/src/modules/graphic/osggraph/OsgAtomic.h @@ -0,0 +1,147 @@ +/*************************************************************************** + + file : OsgAtomic.h + created : Sun Jan 20 10:24:02 CEST 2013 + copyright : (C) 2013 by Xavier Bertaux + email : bertauxx@yahoo.fr + version : $Id$ + +***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef OsgAtomic_H +#define OsgAtomic_H + +#if defined(__GNUC__) && ((4 < __GNUC__)||(4 == __GNUC__ && 1 <= __GNUC_MINOR__)) && defined(__x86_64__) +// No need to include something. Is a Compiler API ... +# define SDATOMIC_USE_GCC4_BUILTINS +#elif defined(__GNUC__) && defined(__i386__) +# define SDATOMIC_USE_LIBRARY_FUNCTIONS +#elif defined(__sgi) && defined(_COMPILER_VERSION) && (_COMPILER_VERSION>=730) +// No need to include something. Is a Compiler API ... +# define SDATOMIC_USE_MIPSPRO_BUILTINS +#elif defined(_WIN32) +# define SDATOMIC_USE_LIBRARY_FUNCTIONS +/*#else +The sledge hammer ... +# define SDATOMIC_USE_LIBRARY_FUNCTIONS +# define SDATOMIC_USE_MUTEX +# include */ +#endif*/ + +class SDAtomic +{ +public: + SDAtomic(unsigned value = 0) : mValue(value) + { } + +#if defined(SDATOMIC_USE_LIBRARY_FUNCTIONS) + unsigned operator++(); +#else + unsigned operator++() + { +# if defined(SDATOMIC_USE_GCC4_BUILTINS) + return __sync_add_and_fetch(&mValue, 1); +# elif defined(SDATOMIC_USE_MIPOSPRO_BUILTINS) + return __add_and_fetch(&mValue, 1); +# else +# error +# endif + } +#endif + +#if defined(SDATOMIC_USE_LIBRARY_FUNCTIONS) + unsigned operator--(); +#else + unsigned operator--() + { +# if defined(SDATOMIC_USE_GCC4_BUILTINS) + return __sync_sub_and_fetch(&mValue, 1); +# elif defined(SDATOMIC_USE_MIPOSPRO_BUILTINS) + return __sub_and_fetch(&mValue, 1); +# else +# error +# endif + } +#endif + +#if defined(SDATOMIC_USE_LIBRARY_FUNCTIONS) + operator unsigned() const; +#else + operator unsigned() const + { +# if defined(SDATOMIC_USE_GCC4_BUILTINS) + __sync_synchronize(); + return mValue; +# elif defined(SDATOMIC_USE_MIPOSPRO_BUILTINS) + __synchronize(); + return mValue; +# else +# error +# endif + } +#endif + +#if defined(SDATOMIC_USE_LIBRARY_FUNCTIONS) + bool compareAndExchange(unsigned oldValue, unsigned newValue); +#else + bool compareAndExchange(unsigned oldValue, unsigned newValue) + { +# if defined(SDATOMIC_USE_GCC4_BUILTINS) + return __sync_bool_compare_and_swap(&mValue, oldValue, newValue); +# elif defined(SDATOMIC_USE_MIPOSPRO_BUILTINS) + return __compare_and_swap(&mValue, oldValue, newValue); +# else +# error +# endif + } +#endif + +private: + SDAtomic(const SDAtomic&); + SDAtomic& operator=(const SDAtomic&); + +/*#if defined(SGATOMIC_USE_MUTEX) + mutable SGMutex mMutex; +#endif*/ + unsigned mValue; +}; + +namespace speeddreams +{ +// Typesafe wrapper around SGSwappable +template +class Swappable : private SDAtomic +{ +public: + Swappable(const T& value) : SDAtomic(static_cast(value)) + { + } + T operator() () const + { + return static_cast(SDAtomic::operator unsigned ()); + } + Swappable& operator=(const Swappable& rhs) + { + for (unsigned oldval = unsigned(*this); + !compareAndExchange(oldval, unsigned(rhs)); + oldval = unsigned(*this)) + ; + return *this; + } + bool compareAndSwap(const T& oldVal, const T& newVal) + { + return SDAtomic::compareAndExchange(static_cast(oldVal), + static_cast(newVal)); + } +}; +} +#endif diff --git a/src/modules/graphic/osggraph/OsgDome.cpp b/src/modules/graphic/osggraph/OsgDome.cpp index ff4251eef..6cdfa0a60 100644 --- a/src/modules/graphic/osggraph/OsgDome.cpp +++ b/src/modules/graphic/osggraph/OsgDome.cpp @@ -1,27 +1,23 @@ -// dome.cxx -- model sky with an upside down "bowl" -// -// Written by Curtis Olson, started December 1997. -// SSG-ified by Curtis Olson, February 2000. -// -// Copyright (C) 1997-2000 Curtis L. Olson - http://www.flightgear.org/~curt -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +/*************************************************************************** -#include -#include + file : OsgDome.cpp + created : Mon Aug 21 18:24:02 CEST 2012 + copyright : (C) 2012 by Xavier Bertaux + email : bertauxx@yahoo.fr + version : $Id$ +***************************************************************************/ + +/*************************************************************************** + * * + * 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 #include @@ -31,73 +27,56 @@ #include #include #include -#include -#include -#include -#include -#include -#include - -#include "dome.h" +#include "OsgVectorArrayAdapter.h" +#include "OsgDome.h" +#include "OsgMath.h" using namespace osg; using namespace osggraph; -// proportions of max dimensions fed to the build() routine static const float center_elev = 1.0; namespace { +struct DomeParam +{ + float radius; + float elev; +} domeParams[] = {{.5, .8660}, {.8660, .5}, {0.9701, 0.2425}, {0.9960, 0.0885}, + {1.0, 0.0}, {0.9922, -0.1240}}; -const int numRings = 64; -const int numBands = 64; -const int halfBands = numBands / 2; - -// Make dome a bit over half sphere -const float domeAngle = 120.0; - -const float bandDelta = 360.0 / numBands; -const float ringDelta = domeAngle / (numRings+1); - -// Which band is at horizon -const int halfRings = numRings * (90.0 / domeAngle); -const int upperRings = numRings * (60.0 / domeAngle); // top half -const int middleRings = numRings * (15.0 / domeAngle); - +const int numRings = sizeof(domeParams) / sizeof(domeParams[0]); +const int numBands = 12; +const int halfBands = numBands/2; } -static const float upper_radius = 0.9701; // (.6, 0.15) +static const float upper_radius = 0.9701; static const float upper_elev = 0.2425; -static const float middle_radius = 0.9960; // (.9, .08) +static const float middle_radius = 0.9960; static const float middle_elev = 0.0885; static const float lower_radius = 1.0; static const float lower_elev = 0.0; -static const float bottom_radius = 0.9922; // (.8, -.1) +static const float bottom_radius = 0.9922; static const float bottom_elev = -0.1240; - // Constructor -SGSkyDome::SGSkyDome( void ) { +SDSkyDome::SDSkyDome( void ) +{ asl = 0; } // Destructor -SGSkyDome::~SGSkyDome( void ) { +SDSkyDome::~SDSkyDome( void ) +{ } -// Generate indices for a dome mesh. Assume a center vertex at 0, then -// rings of vertices. Each ring's vertices are stored together. An -// even number of longitudinal bands are assumed. - namespace { -// Calculate the index of a vertex in the grid by using its address in -// the array that holds its location. struct GridIndex { VectorArrayAdapter gridAdapter; @@ -112,40 +91,40 @@ struct GridIndex } }; } -void SGSkyDome::makeDome(int rings, int bands, DrawElementsUShort& elements) +void SDSkyDome::makeDome(int rings, int bands, DrawElementsUShort& elements) { std::back_insert_iterator pusher = std::back_inserter(elements); GridIndex grid(*dome_vl, numBands, 1); - for (int i = 0; i < bands; i++) + for (int i = 0; i < bands; i += 2) { - *pusher = 0; *pusher = grid(0, i+1); *pusher = grid(0, i); - // down a band + *pusher = 0; *pusher = grid(0, i); *pusher = grid(0, i + 1); + for (int j = 0; j < rings - 1; ++j) { - *pusher = grid(j, i); *pusher = grid(j, (i + 1)%bands); - *pusher = grid(j + 1, (i + 1)%bands); - *pusher = grid(j, i); *pusher = grid(j + 1, (i + 1)%bands); + *pusher = grid(j, i); *pusher = grid(j, i + 1); + *pusher = grid(j + 1, i + 1); + *pusher = grid(j, i); *pusher = grid(j + 1, i + 1); *pusher = grid(j + 1, i); } - + + for (int j = rings - 1; j > 0; --j) + { + *pusher = grid(j, i + 1); *pusher = grid(j - 1, i + 1); + *pusher = grid(j, (i + 2) % bands); + *pusher = grid(j, (i + 2) % bands); *pusher = grid(j - 1, i + 1); + *pusher = grid(j - 1, (i + 2) % bands); + } + + *pusher = grid(0, i + 1); *pusher = 0; + *pusher = grid(0, (i + 2) % bands); } } -// initialize the sky object and connect it into our scene graph -osg::Node* -SGSkyDome::build( double hscale, double vscale ) { +osg::Node* SDSkyDome::build( double hscale, double vscale ) +{ + osg::Geode* geode = new osg::Geode; - EffectGeode* geode = new EffectGeode; - - geode->setName("Skydome"); - geode->setCullingActive(false); // Prevent skydome from being culled away - - Effect *effect = makeEffect("Effects/skydome", true); - if(effect) - geode->setEffect(effect); - - // set up the state osg::StateSet* stateSet = geode->getOrCreateStateSet(); stateSet->setRenderBinDetails(-10, "RenderBin"); @@ -155,37 +134,32 @@ SGSkyDome::build( double hscale, double vscale ) { stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF); stateSet->setMode(GL_FOG, osg::StateAttribute::OFF); stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF); - stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::ON); + stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::OFF); stateSet->setMode(GL_BLEND, osg::StateAttribute::OFF); stateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::OFF); - - stateSet->setAttribute(new osg::CullFace(osg::CullFace::BACK)); - osg::Material* material = new osg::Material; stateSet->setAttribute(material); dome_vl = new osg::Vec3Array(1 + numRings * numBands); dome_cl = new osg::Vec3Array(1 + numRings * numBands); - // generate the raw vertex data (*dome_vl)[0].set(0.0, 0.0, center_elev * vscale); - simgear::VectorArrayAdapter vertices(*dome_vl, numBands, 1); + osggraph::VectorArrayAdapter vertices(*dome_vl, numBands, 1); for ( int i = 0; i < numBands; ++i ) { - double theta = (i * bandDelta) * SGD_DEGREES_TO_RADIANS; + double theta = (i * 30) * SD_DEGREES_TO_RADIANS; double sTheta = hscale*sin(theta); double cTheta = hscale*cos(theta); for (int j = 0; j < numRings; ++j) { - vertices(j, i).set(cTheta * sin((j+1)*ringDelta*SGD_DEGREES_TO_RADIANS), - sTheta * sin((j+1)*ringDelta*SGD_DEGREES_TO_RADIANS), - vscale * cos((j+1)*ringDelta*SGD_DEGREES_TO_RADIANS)); + vertices(j, i).set(cTheta * domeParams[j].radius, + sTheta * domeParams[j].radius, + domeParams[j].elev * vscale); } } - DrawElementsUShort* domeElements - = new osg::DrawElementsUShort(GL_TRIANGLES); + DrawElementsUShort* domeElements = new osg::DrawElementsUShort(GL_TRIANGLES); makeDome(numRings, numBands, *domeElements); osg::Geometry* geom = new Geometry; geom->setName("Dome Elements"); @@ -196,15 +170,16 @@ SGSkyDome::build( double hscale, double vscale ) { geom->setNormalBinding(osg::Geometry::BIND_OFF); geom->addPrimitiveSet(domeElements); geode->addDrawable(geom); - // force a repaint of the sky colors with ugly defaults - repaint(SGVec3f(1, 1, 1), SGVec3f(1, 1, 1), SGVec3f(1, 1, 1), 0.0, 5000.0 ); + + repaint(osg::Vec3(1, 1, 1), osg::Vec3(1, 1, 1), osg::Vec3(1, 1, 1), 0.0, 5000.0 ); dome_transform = new osg::MatrixTransform; dome_transform->addChild(geode); return dome_transform.get(); } -static void fade_to_black(osg::Vec3 sky_color[], float asl, int count) { +static void sd_fade_to_black(osg::Vec3 sky_color[], float asl, int count) +{ const float ref_asl = 10000.0f; const float d = exp( - asl / ref_asl ); for(int i = 0; i < count ; i++) @@ -218,143 +193,90 @@ inline void clampColor(osg::Vec3& color) color.z() = osg::clampTo(color.z(), 0.0f, 1.0f); } -// repaint the sky colors based on current value of sun_angle, sky, -// and fog colors. This updates the color arrays for ssgVtxTable. -// sun angle in degrees relative to verticle -// 0 degrees = high noon -// 90 degrees = sun rise/set -// 180 degrees = darkest midnight -bool -SGSkyDome::repaint( const SGVec3f& sun_color, const SGVec3f& sky_color, - const SGVec3f& fog_color, double sun_angle, double vis ) +bool SDSkyDome::repaint( const osg::Vec3f& sun_color, const osg::Vec3f& sky_color, + const osg::Vec3f& fog_color, double sun_angle, double vis ) { - SGVec3f outer_param, outer_diff; - SGVec3f middle_param, middle_diff; + osg::Vec3f outer_param, outer_diff; + osg::Vec3f middle_param, middle_diff; - // Check for sunrise/sunset condition if (sun_angle > 80) { double sunAngleFactor = 10.0 - fabs(90.0 - sun_angle); - static const SGVec3f outerConstant(1.0 / 20.0, 1.0 / 40.0, -1.0 / 30.0); - static const SGVec3f middleConstant(1.0 / 40.0, 1.0 / 80.0, 0.0); + static const osg::Vec3f outerConstant(1.0 / 20.0, 1.0 / 40.0, -1.0 / 30.0); + static const osg::Vec3f middleConstant(1.0 / 40.0, 1.0 / 80.0, 0.0); outer_param = sunAngleFactor * outerConstant; middle_param = sunAngleFactor * middleConstant; - outer_diff = (1.0 / numRings) * outer_param; - middle_diff = (1.0 / numRings) * middle_param; + outer_diff = (1.0 / 6.0) * outer_param; + middle_diff = (1.0 / 6.0) * middle_param; } else { - outer_param = SGVec3f(0, 0, 0); - middle_param = SGVec3f(0, 0, 0); - outer_diff = SGVec3f(0, 0, 0); - middle_diff = SGVec3f(0, 0, 0); + outer_param = osg::Vec3f(0, 0, 0); + middle_param = osg::Vec3f(0, 0, 0); + outer_diff = osg::Vec3f(0, 0, 0); + middle_diff = osg::Vec3f(0, 0, 0); } + + osg::Vec3f outer_amt = outer_param; + osg::Vec3f middle_amt = middle_param; - // calculate transition colors between sky and fog - SGVec3f outer_amt = outer_param; - SGVec3f middle_amt = middle_param; - - // - // First, recalulate the basic colors - // - - // Magic factors for coloring the sky according visibility and - // zenith angle. const double cvf = osg::clampBelow(vis, 45000.0); const double vis_factor = osg::clampTo((vis - 1000.0) / 2000.0, 0.0, 1.0); const float upperVisFactor = 1.0 - vis_factor * (0.7 + 0.3 * cvf/45000); const float middleVisFactor = 1.0 - vis_factor * (0.1 + 0.85 * cvf/45000); - // Dome top is always sky_color (*dome_cl)[0] = toOsg(sky_color); - simgear::VectorArrayAdapter colors(*dome_cl, numBands, 1); - const double saif = sun_angle/SG_PI; - static const SGVec3f blueShift(0.8, 1.0, 1.2); - const SGVec3f skyFogDelta = sky_color - fog_color; - const SGVec3f sunSkyDelta = sun_color - sky_color; - - // For now the colors of the upper two rings are linearly - // interpolated between the zenith color and the first horizon - // ring color. Means angles from top to 30 degrees - + osggraph::VectorArrayAdapter colors(*dome_cl, numBands, 1); + const double saif = sun_angle/SD_PI; + static const osg::Vec3f blueShift(0.8, 1.0, 1.2); + const osg::Vec3f skyFogDelta = sky_color - fog_color; + const osg::Vec3f sunSkyDelta = sun_color - sky_color; + for (int i = 0; i < halfBands+1; i++) { - SGVec3f diff = mult(skyFogDelta, blueShift); - diff *= (0.8 + saif - ((halfBands-i)/(float)(numBands-2))); - - // Color the ~60 deg ring - colors(upperRings, i) = toOsg(sky_color - upperVisFactor * diff); - - int j=0; - // Color top half by linear interpolation (90...60 degrees) - for (; j < upperRings; j++) - colors(j, i) = simgear::math::lerp(toOsg(sky_color), colors(upperRings, i), j / (float)upperRings); - - j++; // Skip the 60 deg ring - // From 60 to ~85 degrees - for (int l = 0; j < upperRings + middleRings + 1; j++, l++) - colors(j, i) = simgear::math::lerp(colors(upperRings, i), - toOsg(sky_color - middleVisFactor * diff + middle_amt), l / (float)middleRings); - - // 85 to 90 degrees - for (int l = 0; j < halfRings; j++, l++) - colors(j, i) = simgear::math::lerp(colors(upperRings + middleRings, i), toOsg(fog_color + outer_amt), - l / (float)(halfRings - upperRings - middleRings)); - + osg::Vec3f diff = mult(skyFogDelta, blueShift); + diff *= (0.8 + saif - ((halfBands-i)/10)); + colors(2, i) = toOsg(sky_color - upperVisFactor * diff); + colors(3, i) = toOsg(sky_color - middleVisFactor * diff + middle_amt); + colors(4, i) = toOsg(fog_color + outer_amt); + //colors(0, i) = simgear::math::lerp(toOsg(sky_color), colors(2, i), .3942); + //colors(1, i) = simgear::math::lerp(toOsg(sky_color), colors(2, i), .7885); for (int j = 0; j < numRings - 1; ++j) clampColor(colors(j, i)); - outer_amt -= outer_diff; middle_amt -= middle_diff; } - // Other side of dome is mirror of the other for (int i = halfBands+1; i < numBands; ++i) - for (int j = 0; j < numRings-1; ++j) + for (int j = 0; j < 5; ++j) colors(j, i) = colors(j, numBands - i); - // Fade colors to black when going to space - // Center of dome is blackest and then fade decreases towards horizon - fade_to_black(&(*dome_cl)[0], asl * center_elev, 1); - for (int i = 0; i < numRings - 1; ++i) - { - float fadeValue = (asl+0.05f) * cos(i*ringDelta*SGD_DEGREES_TO_RADIANS); - if(fadeValue < 0.0) fadeValue = 0.0; - fade_to_black(&colors(i, 0), fadeValue, numBands); - } - - // All rings below horizon are fog color - for ( int i = halfRings; i < numRings; i++) - for ( int j = 0; j < numBands; j++ ) - colors(i, j) = toOsg(fog_color); + sd_fade_to_black(&(*dome_cl)[0], asl * center_elev, 1); + + for (int i = 0; i < numRings - 1; ++i) + sd_fade_to_black(&colors(i, 0), (asl+0.05f) * domeParams[i].elev, + numBands); + for ( int i = 0; i < numBands; i++ ) + colors(numRings - 1, i) = toOsg(fog_color); + dome_cl->dirty(); + return true; } - -// reposition the sky at the specified origin and orientation -// lon specifies a rotation about the Z axis -// lat specifies a rotation about the new Y axis -// spin specifies a rotation about the new Z axis (and orients the -// sunrise/set effects -bool -SGSkyDome::reposition( const SGVec3f& p, double _asl, +bool SDSkyDome::reposition( const osg::Vec3f& p, double _asl, double lon, double lat, double spin ) { asl = _asl; osg::Matrix T, LON, LAT, SPIN; - // Translate to view position - // Point3D zero_elev = current_view.get_cur_zero_elev(); - // xglTranslatef( zero_elev.x(), zero_elev.y(), zero_elev.z() ); T.makeTranslate( toOsg(p) ); - - // Rotate to proper orientation LON.makeRotate(lon, osg::Vec3(0, 0, 1)); - LAT.makeRotate(90.0 * SGD_DEGREES_TO_RADIANS - lat, osg::Vec3(0, 1, 0)); + LAT.makeRotate(90.0 * SD_DEGREES_TO_RADIANS - lat, osg::Vec3(0, 1, 0)); SPIN.makeRotate(spin, osg::Vec3(0, 0, 1)); dome_transform->setMatrix( SPIN*LAT*LON*T ); + return true; } diff --git a/src/modules/graphic/osggraph/OsgDome.h b/src/modules/graphic/osggraph/OsgDome.h index eb3f01b2f..3037170d1 100644 --- a/src/modules/graphic/osggraph/OsgDome.h +++ b/src/modules/graphic/osggraph/OsgDome.h @@ -1,40 +1,35 @@ -// dome.hxx -- model sky with an upside down "bowl" -// -// Written by Curtis Olson, started December 1997. -// SSG-ified by Curtis Olson, February 2000. -// -// Copyright (C) 1997-2000 Curtis L. Olson - http://www.flightgear.org/~curt -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +/*************************************************************************** -#ifndef _SKYDOME_H -#define _SKYDOME_H + file : OsgDome.h + created : Mon Aug 21 18:24:02 CEST 2012 + copyright : (C) 2012 by Xavier Bertaux + email : bertauxx@yahoo.fr + version : $Id$ + +***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef _OSGSKYDOME_H +#define _OSGSKYDOME_H #include #include #include -#include -#include - namespace osg { - class DrawElementsUShort; +class DrawElementsUShort; } -class SGSkyDome : public SGReferenced +class SDSkyDome { osg::ref_ptr dome_transform; double asl; @@ -44,35 +39,20 @@ class SGSkyDome : public SGReferenced public: // Constructor - SGSkyDome( void ); + SDSkyDome( void ); // Destructor - ~SGSkyDome( void ); + ~SDSkyDome( void ); - // initialize the sky object and connect it into our scene graph - // root osg::Node *build( double hscale = 80000.0, double vscale = 80000.0 ); - // repaint the sky colors based on current value of sun_angle, - // sky, and fog colors. This updates the color arrays for - // ssgVtxTable. - // sun angle in degrees relative to verticle - // 0 degrees = high noon - // 90 degrees = sun rise/set - // 180 degrees = darkest midnight - bool repaint( const SGVec3f& sun_color, const SGVec3f& sky_color, - const SGVec3f& fog_color, double sun_angle, double vis ); + bool repaint( const osg::Vec3f& sun_color, const osg::Vec3f& sky_color, + const osg::Vec3f& fog_color, double sun_angle, double vis ); - // reposition the sky at the specified origin and orientation - // lon specifies a rotation about the Z axis - // lat specifies a rotation about the new Y axis - // spin specifies a rotation about the new Z axis (and orients the - // sunrise/set effects - bool reposition( const SGVec3f& p, double asl, + bool reposition( const osg::Vec3f& p, double asl, double lon, double lat, double spin ); private: void makeDome(int rings, int bands, osg::DrawElementsUShort& elements); }; - -#endif // _SKYDOME_H +#endif // _OSGSKYDOME_H diff --git a/src/modules/graphic/osggraph/OsgMain.cpp b/src/modules/graphic/osggraph/OsgMain.cpp index 2a1a4462b..d18d99256 100644 --- a/src/modules/graphic/osggraph/OsgMain.cpp +++ b/src/modules/graphic/osggraph/OsgMain.cpp @@ -767,6 +767,8 @@ initCars(tSituation *s) void shutdownCars(void) { + delete cars; + /* int i; GfOut("-- shutdownCars\n"); @@ -849,11 +851,13 @@ int initCars(tSituation *s) return 0; } -/*void +void shutdownTrack(void) { // Do the real track termination job. - grShutdownScene(); + delete scenery; + //delete m_sceneroot; + //grShutdownScene(); if (grTrackHandle) { @@ -862,19 +866,21 @@ shutdownTrack(void) } // And then the context termination job (should not be there, see initTrack). - options.endLoad(); + //options.endLoad(); - grShutdownState(); -}*/ + //grShutdownState(); +} -/*void +void shutdownView(void) { - for (int i = 0; i < GR_NB_MAX_SCREEN; i++) + /*for (int i = 0; i < GR_NB_MAX_SCREEN; i++) { delete grScreens[i]; grScreens[i] = 0; - } + }*/ + delete render; + delete viewer; } //void SsgGraph::bendCar(int index, sgVec3 poc, sgVec3 force, int count) diff --git a/src/modules/graphic/osggraph/OsgMath.h b/src/modules/graphic/osggraph/OsgMath.h index 53c5e97b4..52edd3520 100644 --- a/src/modules/graphic/osggraph/OsgMath.h +++ b/src/modules/graphic/osggraph/OsgMath.h @@ -17,6 +17,7 @@ * * ***************************************************************************/ +#include #ifndef _OSGMATH_H_ #define _OSGMATH_H_ @@ -38,6 +39,15 @@ #define SD_PI ((float) SD_PI) #endif +/** PI / 2 */ +#ifdef M_PI_2 +# define SD_PI_2 M_PI_2 +#else +# define SD_PI_2 1.57079632679489661923 +#endif + +#define SD_2PI (float)SD_PI * (float)SD_PI + #define SD_DEGREES_TO_RADIANS (SD_PI/SD_180) #define SD_RADIANS_TO_DEGREES (SD_180/SD_PI) @@ -70,5 +80,11 @@ inline float sdCos ( float s ) inline float sdTan ( float s ) { return (float)tan (s * SD_DEGREES_TO_RADIANS) ; } +// return a random number between [0.0, 1.0) +inline double SDRandom(void) +{ + return(rand() / (double)RAND_MAX); +} + #endif /* _OSGMATH_H_ */ diff --git a/src/modules/graphic/osggraph/OsgMoon.cpp b/src/modules/graphic/osggraph/OsgMoon.cpp index 419a054b9..48fd0b791 100644 --- a/src/modules/graphic/osggraph/OsgMoon.cpp +++ b/src/modules/graphic/osggraph/OsgMoon.cpp @@ -1,11 +1,12 @@ /*************************************************************************** - file : OsgMoon.cpp - copyright : (C) 2012 by Xavier Bertaux (based on SimGear code) - web : http://www.speed-dreams.org - version : $Id: OsgMoon.cpp 3162 2012-12-03 13:11:22Z torcs-ng $ + file : OsgMoon.cpp + created : Mon Aug 21 18:24:02 CEST 2012 + copyright : (C) 2012 by Xavier Bertaux + email : bertauxx@yahoo.fr + version : $Id$ - ***************************************************************************/ +***************************************************************************/ /*************************************************************************** * * @@ -29,12 +30,12 @@ #include #include #include -#include +#include -#include "OsgSphere.h" -#include "OsgSky.h" #include "OsgMath.h" #include "OsgColor.h" +#include "OsgSphere.h" +#include "OsgMoon.h" // Constructor SDMoon::SDMoon( void ) : @@ -42,25 +43,22 @@ SDMoon::SDMoon( void ) : { } - // Destructor SDMoon::~SDMoon( void ) { } - // build the moon object -osg::Node* SDMoon::build( const std::string path, double moon_size ) +osg::Node* SDMoon::build( std::string path, double moon_size ) { + std::string TmpPath = path; osg::Node* orb = SDMakeSphere(moon_size, 15, 15); osg::StateSet* stateSet = orb->getOrCreateStateSet(); stateSet->setRenderBinDetails(-5, "RenderBin"); - // set up the orb state - osg::ref_ptr options - = makeOptionsFromPath(path); - - osg::Texture2D* texture = SGLoadTexture2D("moon.png", options.get()); + path = TmpPath+"moon.png"; + osg::ref_ptr image = osgDB::readImageFile(path); + osg::ref_ptr texture = new osg::Texture2D(image.get()); stateSet->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON); osg::TexEnv* texEnv = new osg::TexEnv; texEnv->setMode(osg::TexEnv::MODULATE); @@ -68,10 +66,14 @@ osg::Node* SDMoon::build( const std::string path, double moon_size ) orb_material = new osg::Material; orb_material->setColorMode(osg::Material::DIFFUSE); - orb_material->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(1, 1, 1, 1)); - orb_material->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4(0, 0, 0, 1)); - orb_material->setEmission(osg::Material::FRONT_AND_BACK,osg::Vec4(0, 0, 0, 1)); - orb_material->setSpecular(osg::Material::FRONT_AND_BACK,osg::Vec4(0, 0, 0, 1)); + orb_material->setDiffuse(osg::Material::FRONT_AND_BACK, + osg::Vec4(1, 1, 1, 1)); + orb_material->setAmbient(osg::Material::FRONT_AND_BACK, + osg::Vec4(0, 0, 0, 1)); + orb_material->setEmission(osg::Material::FRONT_AND_BACK, + osg::Vec4(0, 0, 0, 1)); + orb_material->setSpecular(osg::Material::FRONT_AND_BACK, + osg::Vec4(0, 0, 0, 1)); orb_material->setShininess(osg::Material::FRONT_AND_BACK, 0); stateSet->setAttribute(orb_material.get()); stateSet->setMode(GL_LIGHTING, osg::StateAttribute::ON); @@ -109,11 +111,11 @@ bool SDMoon::repaint( double moon_angle ) prev_moon_angle = moon_angle; - float moon_factor = 4 * cos(moon_angle); + float moon_factor = 4*cos(moon_angle); if (moon_factor > 1) moon_factor = 1.0; if (moon_factor < -1) moon_factor = -1.0; - moon_factor = moon_factor / 2 + 0.5; + moon_factor = (moon_factor/2) + 0.5f; osg::Vec4 color; color[1] = sqrt(moon_factor); @@ -129,11 +131,13 @@ bool SDMoon::repaint( double moon_angle ) return true; } -bool SDMoon::reposition( double rightAscension, double declination, double moon_dist ) +bool SDMoon::reposition( double rightAscension, double declination, + double moon_dist ) { osg::Matrix T2, RA, DEC; - RA.makeRotate(rightAscension - 90.0 * SGD_DEGREES_TO_RADIANS, osg::Vec3(0, 0, 1)); + RA.makeRotate(rightAscension - 90.0 * SD_DEGREES_TO_RADIANS, + osg::Vec3(0, 0, 1)); DEC.makeRotate(declination, osg::Vec3(1, 0, 0)); T2.makeTranslate(osg::Vec3(0, moon_dist, 0)); diff --git a/src/modules/graphic/osggraph/OsgMoon.h b/src/modules/graphic/osggraph/OsgMoon.h new file mode 100644 index 000000000..5715ba34e --- /dev/null +++ b/src/modules/graphic/osggraph/OsgMoon.h @@ -0,0 +1,70 @@ +/*************************************************************************** + + file : OsgMoon.h + created : Mon Aug 21 18:24:02 CEST 2012 + copyright : (C) 2012 by Xavier Bertaux + email : bertauxx@yahoo.fr + version : $Id$ + +***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef _OSGMOON_H +#define _OSGMOON_H + +#include +#include +#include + +class SDMoon +{ + osg::ref_ptr moon_transform; + osg::ref_ptr orb_material; + + double prev_moon_angle; + double moon_angle; + double moon_rotation; + double moon_size; + double moon_dist; + double moonAscension; + double moondeclination; + +public: + + // Constructor + SDMoon( void ); + + // Destructor + ~SDMoon( void ); + + // build the moon object + osg::Node *build( std::string path, double moon_size ); + + bool repaint( double moon_angle ); + bool reposition( double rightAscension, double declination, double moon_dist ); + + void setMoonAngle (double angle) { moon_angle = angle; } + double getMoonAngle () { return moon_angle; } + + void setMoonRotation (double rotation) { moon_rotation = rotation; } + double getMoonRotation () { return moon_rotation; } + + void setMoonRightAscension ( double ra ) { moonAscension = ra; } + double getMoonRightAscension () { return moonAscension; } + + void setMoonDeclination ( double decl ) { moondeclination = decl; } + double getMoonDeclination () { return moondeclination; } + + void setMoonDist ( double dist ) { moon_dist = dist; } + double getMoonDist() { return moon_dist; } +}; + +#endif // _OSGMOON_H diff --git a/src/modules/graphic/osggraph/OsgReferenced.h b/src/modules/graphic/osggraph/OsgReferenced.h new file mode 100644 index 000000000..7b33e265d --- /dev/null +++ b/src/modules/graphic/osggraph/OsgReferenced.h @@ -0,0 +1,50 @@ +/*************************************************************************** + + file : OsgReferenced.h + created : Sun Jan 20 10:24:02 CEST 2013 + copyright : (C) 2013 by Xavier Bertaux + email : bertauxx@yahoo.fr + version : $Id$ + +***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef OsgReferenced_H +#define OsgReferenced_H + +#include "OsgAtomic.h" + +class SDReferenced +{ +public: + SDReferenced(void) : _refcount(0u) + {} + /// Do not copy reference counts. Each new object has it's own counter + SDReferenced(const SDReferenced&) : _refcount(0u) + {} + /// Do not copy reference counts. Each object has it's own counter + SDReferenced& operator=(const SDReferenced&) + { return *this; } + + static unsigned get(const SDReferenced* ref) + { if (ref) return ++(ref->_refcount); else return ~0u; } + static unsigned put(const SDReferenced* ref) + { if (ref) return --(ref->_refcount); else return ~0u; } + static unsigned count(const SDReferenced* ref) + { if (ref) return ref->_refcount; else return ~0u; } + static bool shared(const SDReferenced* ref) + { if (ref) return 1u < ref->_refcount; else return false; } + +private: + mutable SDAtomic _refcount; +}; + +#endif diff --git a/src/modules/graphic/osggraph/OsgRender.cpp b/src/modules/graphic/osggraph/OsgRender.cpp index 63923ee97..895f95227 100644 --- a/src/modules/graphic/osggraph/OsgRender.cpp +++ b/src/modules/graphic/osggraph/OsgRender.cpp @@ -22,19 +22,42 @@ #include #include #include +#include #include #include #include #include + #include "OsgMain.h" #include "OsgRender.h" +#include "OsgSky.h" +#include "OsgMath.h" #include //gluXXX #include //RtXXX() + +static const double m_log01 = -log( 0.01 ); +static const double sqrt_m_log01 = sqrt( m_log01 ); +const GLfloat fog_exp2_density = sqrt_m_log01 / 11000; + +SDSky *thesky = NULL; +tTrack *grTrack; + +unsigned SDSkyDomeDistance = 0; +static unsigned SDNbCloudLayers = 0; + +// Some private global variables. +//static int grDynamicWeather = 0; +static bool SDDynamicSkyDome = false; +static float SDSunDeclination = 0.0f; +static float SDMoonDeclination = 0.0f; +static float SDMax_Visibility = 0.0f; +static double SDVisibility = 0.0f; + #define MAX_BODIES 2 #define MAX_CLOUDS 3 -#define NSTARS 1000 +#define NMaxStars 1000 #define NPLANETS 0 //No planets displayed #define NB_BG_FACES 36 //Background faces #define BG_DIST 1.0f @@ -44,6 +67,9 @@ #define SCARCE_CLOUD 5 #define COVERAGE_CLOUD 8 +static osg::Vec3d *AStarsData = NULL; +static osg::Vec3d *APlanetsData = NULL; + static osg::ref_ptr RealRoot = new osg::Group; SDRender::SDRender(void) @@ -62,26 +88,118 @@ SDRender::~SDRender(void) */ void SDRender::Init(osg::ref_ptr viewer) { + char buf[256]; + void *hndl = grTrackHandle; + + std::string path = "/opt/share/games/speed-dreams-2/data/"; + thesky = new SDSky; + GfOut("SDSky class\n"); + int grSkyDomeDistance = 12000; + + int NStars = NMaxStars; + //if (AStarsData) + delete [] AStarsData; + AStarsData = new osg::Vec3d[NStars]; + for(int i= 0; i < NStars; i++) + { + AStarsData[i][0] = SDRandom() * PI; + AStarsData[i][1] = SDRandom() * PI; + AStarsData[i][2] = SDRandom(); + }//for i + + GfLogInfo(" Stars (random) : %d\n", NStars); + + int NPlanets = 0; + APlanetsData = NULL; + + const int timeOfDay = (int)grTrack->local.timeofday; + const double domeSizeRatio = SDSkyDomeDistance / 80000.0; + + thesky->build(path, SDSkyDomeDistance, SDSkyDomeDistance, 2000 * domeSizeRatio, SDSkyDomeDistance, 2000 * domeSizeRatio, SDSkyDomeDistance, + NPlanets, APlanetsData, NStars, AStarsData ); + GfOut("Build SKY\n"); + GLfloat sunAscension = grTrack->local.sunascension; + SDSunDeclination = (float)(15 * (double)timeOfDay / 3600 - 90.0); + + thesky->setSD( DEG2RAD(SDSunDeclination)); + thesky->setSRA( sunAscension ); + + GfLogInfo(" Sun : time of day = %02d:%02d:%02d (declination = %.1f deg), " + "ascension = %.1f deg\n", timeOfDay / 3600, (timeOfDay % 3600) / 60, timeOfDay % 60, + SDSunDeclination, RAD2DEG(sunAscension)); + + if ( SDSunDeclination > 180 ) + SDMoonDeclination = 3.0 + (rand() % 40); + else + SDMoonDeclination = (rand() % 270); + + //SDMoonDeclination = grUpdateMoonPos(timeOfDay); + SDMoonDeclination = (rand() % 270); + + const float moonAscension = grTrack->local.sunascension; + + thesky->setMD( DEG2RAD(SDMoonDeclination) ); + thesky->setMRA( DEG2RAD(moonAscension) ); + + GfLogInfo(" Moon : declination = %.1f deg, ascension = %.1f deg\n", + SDMoonDeclination, moonAscension); + + // Set up the light source to the Sun position. + sgCoord sunPosition; + //TheSky->getSunPos(&sunPosition); + //light->setPosition(sunPosition.xyz); + + // Initialize the whole sky dome. + osg::Vec3 viewPos; + //sgSetVec3(viewPos, grWrldX/2, grWrldY/2, 0); + //TheSky->repositionFlat( viewPos, 0, 0);*/ + RealRoot = dynamic_cast(viewer->getSceneData()); osg::StateSet* rootStateSet = RealRoot->getOrCreateStateSet(); RealRoot->setStateSet(rootStateSet); osg::Group* lightGroup = new osg::Group; + + //SDUpdateLight(); osg::Light* myLight2 = new osg::Light; myLight2->setLightNum(1); - myLight2->setPosition(osg::Vec4(-100.0f, -3220.0f, -100.0f, 1.0f)); + myLight2->setPosition(osg::Vec4(-100.0f, -100.0f, -3220.0f, 1.0f)); myLight2->setAmbient(osg::Vec4(0.2f, 0.2f, 0.2f, 1.0f)); - myLight2->setDiffuse(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f)); - myLight2->setSpecular(osg::Vec4(0.5f, 0.5f, 0.5f, 1.0f)); - myLight2->setConstantAttenuation(1.0f); + myLight2->setDiffuse(osg::Vec4(0.8f, 0.8f, 0.8f, 1.0f)); + myLight2->setSpecular(osg::Vec4(0.2f, 0.2f, 0.2f, 1.0f)); + myLight2->setConstantAttenuation(0.9f); - osg::LightSource* lightS1 = new osg::LightSource; - lightS1->setLight(myLight2); - lightS1->setLocalStateSetModes(osg::StateAttribute::ON); - lightS1->setStateSetModes(*rootStateSet, osg::StateAttribute::ON); - lightGroup->addChild(lightS1); - - RealRoot->addChild(lightGroup); + //GfOut("Light\n"); + osg::LightSource* sunLight = new osg::LightSource; + //sunLight->getLight()->setDataVariance(Object::DYNAMIC); + sunLight->setLight(myLight2); + sunLight->setLocalStateSetModes(osg::StateAttribute::ON); + sunLight->setStateSetModes(*rootStateSet, osg::StateAttribute::ON); + lightGroup->addChild(sunLight); + + //GfOut("SunLight"); + + osg::Group *skyGroup = new osg::Group; + osg::StateSet* skySS = skyGroup->getOrCreateStateSet(); + skySS->setMode(GL_LIGHT0, osg::StateAttribute::OFF); + skyGroup->addChild(thesky->getPreRoot()); + //sunLight->addChild(skyGroup); + /*mRoot->addChild(sceneGroup); + mRoot->addChild(sunLight);*/ + + osg::Group *mRoot = new osg::Group; + mRoot->addChild(RealRoot); + mRoot->addChild(sunLight); + mRoot->addChild(lightGroup); + + osg::Fog* mFog = new osg::Fog; + mFog->setMode( osg::Fog::EXP2 ); + mFog->setColor( osg::Vec4( 0.8, 0.8, 0.8, 1) ); + mFog->setDensity( fog_exp2_density ); + //rootStateSet->SetState->setMode( mFog, osg::StateAttribute::ON ); + rootStateSet->setAttributeAndModes(mFog); + rootStateSet->setMode( GL_FOG, osg::StateAttribute::ON ); + viewer->setSceneData(mRoot); GfOut("LE POINTEUR %d\n",m_carroot.get()); diff --git a/src/modules/graphic/osggraph/OsgRender.h b/src/modules/graphic/osggraph/OsgRender.h index 6f8ee0fc9..163ae0ab8 100644 --- a/src/modules/graphic/osggraph/OsgRender.h +++ b/src/modules/graphic/osggraph/OsgRender.h @@ -25,11 +25,22 @@ #include //tTrack #include // tSituation +class SDSky; + class SDRender { private: osg::ref_ptr m_sceneroot; osg::ref_ptr m_carroot; + + osg::Vec4 SkyColor; + osg::Vec4 BaseFogColor; + osg::Vec4 FogColor; + osg::Vec4 CloudsColor; + + osg::Vec4 SceneAmbiant; + osg::Vec4 SceneDiffuse; + osg::Vec4 SceneSpecular; public: SDRender(void); diff --git a/src/modules/graphic/osggraph/OsgSharedPtr.h b/src/modules/graphic/osggraph/OsgSharedPtr.h new file mode 100644 index 000000000..e898a43ed --- /dev/null +++ b/src/modules/graphic/osggraph/OsgSharedPtr.h @@ -0,0 +1,99 @@ +/*************************************************************************** + + file : OsgSharedPtr.h + created : Sun Jan 20 10:24:02 CEST 2013 + copyright : (C) 2013 by Xavier Bertaux + email : bertauxx@yahoo.fr + version : $Id$ + +***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef OsgSharedPtr_H +#define OsgSharedPtr_H + +#include "OsgReferenced.h" + +template +class SDWeakPtr; + +template +class SDSharedPtr +{ +public: + typedef T element_type; + + SDSharedPtr(void) : _ptr(0) + {} + SDSharedPtr(T* ptr) : _ptr(ptr) + { get(_ptr); } + SDSharedPtr(const SDSharedPtr& p) : _ptr(p.get()) + { get(_ptr); } + template + SDSharedPtr(const SDSharedPtr& p) : _ptr(p.get()) + { get(_ptr); } + ~SDSharedPtr(void) + { put(); } + + SDSharedPtr& operator=(const SDSharedPtr& p) + { assign(p.get()); return *this; } + template + SDSharedPtr& operator=(const SDSharedPtr& p) + { assign(p.get()); return *this; } + template + SDSharedPtr& operator=(U* p) + { assign(p); return *this; } + + T* operator->(void) const + { return _ptr; } + T& operator*(void) const + { return *_ptr; } + operator T*(void) const + { return _ptr; } + T* ptr(void) const + { return _ptr; } + T* get(void) const + { return _ptr; } + T* release() + { T* tmp = _ptr; _ptr = 0; T::put(tmp); return tmp; } + + bool isShared(void) const + { return T::shared(_ptr); } + unsigned getNumRefs(void) const + { return T::count(_ptr); } + + bool valid(void) const + { return _ptr != (T*)0; } + + void clear() + { put(); } + void swap(SDSharedPtr& sharedPtr) + { T* tmp = _ptr; _ptr = sharedPtr._ptr; sharedPtr._ptr = tmp; } + +private: + void assign(T* p) + { get(p); put(); _ptr = p; } + void assignNonRef(T* p) + { put(); _ptr = p; } + + void get(const T* p) const + { T::get(p); } + void put(void) + { if (!T::put(_ptr)) delete _ptr; _ptr = 0; } + + // The reference itself. + T* _ptr; + + template + friend class SDWeakPtr; +}; + +#endif diff --git a/src/modules/graphic/osggraph/OsgSky.cpp b/src/modules/graphic/osggraph/OsgSky.cpp new file mode 100644 index 000000000..29865e326 --- /dev/null +++ b/src/modules/graphic/osggraph/OsgSky.cpp @@ -0,0 +1,299 @@ +/*************************************************************************** + + file : OsgSky.cpp + created : Mon Aug 21 18:24:02 CEST 2012 + copyright : (C) 2012 by Xavier Bertaux + email : bertauxx@yahoo.fr + version : $Id$ + +***************************************************************************/ + +/*************************************************************************** + * * + * 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 "OsgSky.h" +//#include "OsgCloudfield.h" +//#include "OsgNewcloud.h" + +#include +#include + +// Constructor +SDSky::SDSky( void ) +{ + effective_visibility = visibility = 10000.0; + in_puff = false; + puff_length = 0; + puff_progression = 0; + ramp_up = 0.15; + ramp_down = 0.15; + in_cloud = -1; + + //dome = 0; + sun = 0; + moon = 0; + planets = 0; + stars = 0; + pre_root = 0; + //post_root = 0; + + //clouds_3d_enabled = false; + //clouds_3d_density = 0.8; + + pre_root = new osg::Group; + //pre_root->setNodeMask(simgear::BACKGROUND_BIT); + osg::StateSet* preStateSet = new osg::StateSet; + preStateSet->setAttribute(new osg::Depth(osg::Depth::LESS, 0.0, 1.0, false)); + pre_root->setStateSet(preStateSet); + //cloud_root = new osg::Group; + //cloud_root->setNodeMask(simgear::MODEL_BIT); + + pre_selector = new osg::Switch; + pre_transform = new osg::Group; + //_ephTransform = new osg::MatrixTransform; +} + +// Destructor +SDSky::~SDSky( void ) +{ + //delete dome; + delete sun; + delete moon; + delete planets; + delete stars; + //delete pre_transform; + //delete post_root; +} + +// initialize the sky and connect the components to the scene graph at +// the provided branch +/*void SDSky::build( double h_radius_m, double v_radius_m, + double sun_size, double moon_size, + const SGEphemeris& eph )*/ +void SDSky::build( std::string tex_path, double h_radius, double v_radius, double sun_size, double sun_dist, + double moon_size, double moon_dist, int nplanets, osg::Vec3d *planet_data, + int nstars, osg::Vec3d *star_data ) +{ + /*dome = new SDSkyDome; + pre_transform->addChild( dome->build( h_radius_m, v_radius_m ));*/ + + //pre_transform->addChild(_ephTransform.get()); + planets = new SDStars; + pre_transform->addChild( planets->build(nplanets, planet_data, h_radius)); + //_ephTransform->addChild( planets->build(eph.getNumPlanets(), eph.getPlanets(), h_radius)); + + stars = new SDStars; + pre_transform->addChild( stars->build(nstars, star_data, h_radius)); + //_ephTransform->addChild( stars->build(eph.getNumStars(), eph.getStars(), h_radius)); + + moon = new SDMoon; + pre_transform->addChild( moon->build( tex_path, moon_size)); + //_ephTransform->addChild( moon->build(tex_path, moon_size) ); + + sun = new SDSun; + pre_transform->addChild( sun->build( tex_path, moon_size)); + //_ephTransform->addChild( oursun->build(tex_path, sun_size, property_tree_node ) ); + + pre_selector->addChild( pre_transform.get()); + pre_root->addChild( pre_selector.get()); +} + +//bool SDSky::repaint( const SDSkyColor &sc, const SDEphemeris& eph ) +bool SDSky::repaint( osg::Vec4d sky_color, osg::Vec4d fog_color, osg::Vec4d cloud_color, double sol_angle, + double moon_angle, int nplanets, osg::Vec3d *planet_data, + int nstars, osg::Vec3d *star_data ) +{ + if ( effective_visibility > 1000.0 ) + { + enable(); + /*dome->repaint( sc.adj_sky_color, sc.sky_color, sc.fog_color, + sc.sun_angle, effective_visibility );*/ + + planets->repaint( sol_angle, nplanets, planet_data ); + stars->repaint( sol_angle, nstars, star_data); + sun->repaint( sol_angle, effective_visibility ); + moon->repaint( moon_angle ); + + /*for ( unsigned i = 0; i < cloud_layers.size(); ++i ) + { + if (cloud_layers[i]->getCoverage() != SGCloudLayer::SG_CLOUD_CLEAR) + { + cloud_layers[i]->repaint( sc.cloud_color ); + } + }*/ + } else + { + // turn off sky + disable(); + } + /*SGCloudField::updateFog((double)effective_visibility, + osg::Vec4f(toOsg(sc.fog_color), 1.0f));*/ + return true; +} + +bool SDSky::reposition( osg::Vec3 view_pos, osg::Vec3 zero_elev, osg::Vec3 view_up, double lon, double lat, double alt, double spin, double gst, double dt ) +{ + double angle = gst * 15; + //double angleRad = SGMiscd::deg2rad(angle); + + //osg::Vec3f zero_elev, view_up; + //double lon, lat, alt; + + /*SGGeod geodZeroViewPos = SGGeod::fromGeodM(st.pos_geod, 0); + zero_elev = toVec3f( SGVec3d::fromGeod(geodZeroViewPos) ); + + SGQuatd hlOr = SGQuatd::fromLonLat(st.pos_geod); + view_up = toVec3f(hlOr.backTransform(-SGVec3d::e3())); + + lon = st.pos_geod.getLongitudeRad(); + lat = st.pos_geod.getLatitudeRad(); + alt = st.pos_geod.getElevationM();*/ + + //dome->reposition( zero_elev, alt, lon, lat, st.spin ); + + /*osg::Matrix m = osg::Matrix::rotate(angleRad, osg::Vec3(0, 0, -1)); + m.postMultTranslate(toOsg(st.pos)); + _ephTransform->setMatrix(m); + + double sun_ra = eph.getSunRightAscension(); + double sun_dec = eph.getSunDeclination(); + sun->reposition( sun_ra, sun_dec, st.sun_dist, lat, alt, st.sun_angle ); + + double moon_ra = getMoonRightAscension(); + double moon_dec = getMoonDeclination(); + moon->reposition( moon_ra, moon_dec, st.moon_dist );*/ + + /*for ( unsigned i = 0; i < cloud_layers.size(); ++i ) + { + if ( cloud_layers[i]->getCoverage() != SGCloudLayer::SG_CLOUD_CLEAR ) + { + cloud_layers[i]->reposition( zero_elev, view_up, lon, lat, alt, dt); + } else + cloud_layers[i]->getNode()->setAllChildrenOff(); + }*/ + + return true; +} + +/*void SDSky::add_cloud_layer( SDCloudLayer * layer ) +{ + cloud_layers.push_back(layer); + cloud_root->addChild(layer->getNode()); + + layer->set_enable3dClouds(clouds_3d_enabled); +} + +const SDCloudLayer * SDSky::get_cloud_layer (int i) const +{ + return cloud_layers[i]; +} + +SDCloudLayer *SDSky::get_cloud_layer (int i) +{ + return cloud_layers[i]; +} + +int SDSky::get_cloud_layer_count () const +{ + return cloud_layers.size(); +} + +double SDSky::get_3dCloudDensity() const +{ + return SGNewCloud::getDensity(); +} + +void SDSky::set_3dCloudDensity(double density) +{ + SDNewCloud::setDensity(density); +} + +float SDSky::get_3dCloudVisRange() const +{ + return SGCloudField::getVisRange(); +} + +void SDSky::set_3dCloudVisRange(float vis) +{ + SDCloudField::setVisRange(vis); + for ( int i = 0; i < (int)cloud_layers.size(); ++i ) + { + cloud_layers[i]->get_layer3D()->applyVisRange(); + } +} + +void SDSky::texture_path( const string& path ) +{ + tex_path = SGPath( path ); +}*/ + +void SDSky::modify_vis( float alt, float time_factor ) +{ + float effvis = visibility; + + /*for ( int i = 0; i < (int)cloud_layers.size(); ++i ) + { + float asl = cloud_layers[i]->getElevation_m(); + float thickness = cloud_layers[i]->getThickness_m(); + float transition = cloud_layers[i]->getTransition_m();*/ + + double ratio = 1.0; + + /*if ( cloud_layers[i]->getCoverage() == SGCloudLayer::SG_CLOUD_CLEAR ) + { + // less than 50% coverage -- assume we're in the clear for now + ratio = 1.0; + } else if ( alt < asl - transition ) + { + // below cloud layer + ratio = 1.0; + } else if ( alt < asl ) + { + // in lower transition + ratio = (asl - alt) / transition; + } else if ( alt < asl + thickness ) + { + // in cloud layer + ratio = 0.0; + } else if ( alt < asl + thickness + transition ) + { + // in upper transition + ratio = (alt - (asl + thickness)) / transition; + } else + { + // above cloud layer + ratio = 1.0; + } + + if ( cloud_layers[i]->getCoverage() == SGCloudLayer::SG_CLOUD_CLEAR || + cloud_layers[i]->get_layer3D()->defined3D) + { + } else if ( (cloud_layers[i]->getCoverage() == + SGCloudLayer::SG_CLOUD_FEW) + || (cloud_layers[i]->getCoverage() == + SGCloudLayer::SG_CLOUD_SCATTERED) ) + { + float temp = ratio * 2.0; + if ( temp > 1.0 ) { temp = 1.0; } + cloud_layers[i]->setAlpha( temp ); + } else + { + cloud_layers[i]->setAlpha( 1.0 ); + effvis *= ratio; + }*/ + + if ( effvis <= 25.0 ) + { + effvis = 25.0; + } + + //} + + effective_visibility = effvis; +} diff --git a/src/modules/graphic/osggraph/OsgSky.h b/src/modules/graphic/osggraph/OsgSky.h new file mode 100644 index 000000000..093188e34 --- /dev/null +++ b/src/modules/graphic/osggraph/OsgSky.h @@ -0,0 +1,182 @@ +/*************************************************************************** + + file : OsgSky.h + created : Mon Aug 21 18:24:02 CEST 2012 + copyright : (C) 2012 by Xavier Bertaux + email : bertauxx@yahoo.fr + version : $Id$ + +***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef _OSGSKY_H +#define _OSGSKY_H + +#include +#include +#include +#include +#include +#include + +//#include "OsgDome.h" +#include "OsgMoon.h" +#include "OsgSun.h" +#include "OsgStars.h" +#include "OsgSharedPtr.h" + +using std::vector; + +//class SDCloudLayer; +//class SDCloudLayerList; +class SDSun; +class SDMoon; +class SDStars; +class SDSkyDome; +class SDSky; + +typedef struct +{ + osg::Vec3d pos; + double spin; + double gst; + double sun_dist; + double moon_dist; + double sun_angle; +} SDSkyState; + +typedef struct +{ + osg::Vec3f sky_color; + osg::Vec3f adj_sky_color; + osg::Vec3f fog_color; + osg::Vec3f cloud_color; + double sun_angle, moon_angle; +} SDSkyColor; + +class SDSky +{ +private: + //typedef std::vector > layer_list_type; + //typedef layer_list_type::iterator layer_list_iterator; + //typedef layer_list_type::const_iterator layer_list_const_iterator; + + // components of the sky + //SDSharedPtr dome; + SDSun* sun; + SDMoon* moon; + SDStars* planets; + SDStars* stars; + //layer_list_type cloud_layers; + + osg::ref_ptr pre_root, cloud_root; + osg::ref_ptr pre_selector; + osg::ref_ptr pre_transform; + //osg::ref_ptr _ephTransform; + + // visibility + float visibility; + float effective_visibility; + + int in_cloud; + int cur_layer_pos; + + bool in_puff; + double puff_length; + double puff_progression; + double ramp_up; + double ramp_down; + + // 3D clouds enabled + //bool clouds_3d_enabled; + + // 3D cloud density + //double clouds_3d_density; + +public: + + /** Constructor */ + SDSky( void ); + + /** Destructor */ + ~SDSky( void ); + + void build( std::string tex_path, double h_radius, double v_radius, double sun_size, double sun_dist, + double moon_size, double moon_dist, int nplanets, osg::Vec3d *planet_data, + int nstars, osg::Vec3d *star_data ); + + /*void build( double h_radius_m, double v_radius_m, + double sun_size, double moon_size, + const SGEphemeris& eph);*/ + + //bool repaint( const SDSkyColor &sc/*, const SDEphemeris& eph*/ ); + bool repaint (osg::Vec4d sky_color, osg::Vec4d fog_color, osg::Vec4d cloud_color, double sol_angle, + double moon_angle, int nplanets, osg::Vec3d *planet_data, + int nstars, osg::Vec3d *star_data); + //bool reposition( const SDSkyState &st/*, const SDEphemeris& eph*/, double dt = 0.0 ); + bool reposition(osg::Vec3 view_pos, osg::Vec3 zero_elev, osg::Vec3 view_up, double lon, double lat, double alt, double spin, double gst, double dt); + + void modify_vis( float alt, float time_factor ); + + osg::Node* getPreRoot() { return pre_root.get(); } + osg::Node* getCloudRoot() { return cloud_root.get(); } + + void texture_path( const std::string& path ); + + inline void enable() { pre_selector->setValue(0, 1); } + inline void disable() { pre_selector->setValue(0, 0); } + inline osg::Vec4f get_sun_color() { return sun->get_color(); } + inline osg::Vec4f get_scene_color() { return sun->get_scene_color(); } + + //void add_cloud_layer (SGCloudLayer * layer); + //const SGCloudLayer * get_cloud_layer (int i) const; + //SGCloudLayer * get_cloud_layer (int i); + //int get_cloud_layer_count () const; + + void setMA(double angle) { moon->setMoonAngle(angle); } + double getMA() { return moon->getMoonAngle(); } + + void setMR(double rotation) { moon->setMoonRotation( rotation); } + double getMR() { return moon->getMoonRotation(); } + void setMRA( double ra ) { moon->setMoonRightAscension( ra ); } + double getMRA() { return moon->getMoonRightAscension(); } + + void setMD( double decl ) { moon->setMoonDeclination( decl ); } + double getMD() { return moon->getMoonDeclination(); } + + void setMDist( double dist ) { moon->setMoonDist(dist); } + double getMDist() { return moon->getMoonDist(); } + + void setSA(double angle) { sun->setSunAngle(angle); } + double getSA() { return sun->getSunAngle(); } + + void setSR(double rotation) { sun->setSunRotation( rotation ); } + double getSR() { return sun->getSunRotation(); } + + void setSRA(double ra) { sun->setSunRightAscension( ra ); } + double getSRA() { return sun->getSunRightAscension(); } + + void setSD( double decl ) { sun->setSunDeclination( decl ); } + double getSD() { return sun->getSunDeclination(); } + + void setSDistance( double dist ) { sun->setSunDistance( dist ); } + double getSDistance() { return sun->getSunDistance(); } + + inline float get_visibility() const { return effective_visibility; } + inline void set_visibility( float v ) { effective_visibility = visibility = (v <= 25.0) ? 25.0 : v; } + + //virtual double get_3dCloudDensity() const; + //virtual void set_3dCloudDensity(double density); + //virtual float get_3dCloudVisRange() const; + //virtual void set_3dCloudVisRange(float vis); +}; + +#endif // _OSGSKY_H diff --git a/src/modules/graphic/osggraph/OsgSphere.cpp b/src/modules/graphic/osggraph/OsgSphere.cpp index bfd2df0b0..5b9845e8f 100644 --- a/src/modules/graphic/osggraph/OsgSphere.cpp +++ b/src/modules/graphic/osggraph/OsgSphere.cpp @@ -1,11 +1,12 @@ /*************************************************************************** - file : OsgSphere.cpp - copyright : (C) 2012 by Xavier Bertaux (based on SimGear code) - web : bertauxx@yahoo.fr - version : $Id: OsgSphere.cpp 3162 2012-12-03 13:11:22Z torcs-ng $ + file : OsgSphere.cpp + created : Mon Aug 21 18:24:02 CEST 2012 + copyright : (C) 2012 by Xavier Bertaux + email : bertauxx@yahoo.fr + version : $Id$ - ***************************************************************************/ +***************************************************************************/ /*************************************************************************** * * @@ -15,9 +16,8 @@ * (at your option) any later version. * * * ***************************************************************************/ - +#include #include -#include #include #include @@ -25,87 +25,86 @@ #include #include "OsgMath.h" +#include "OsgSphere.h" osg::Node* SDMakeSphere(double radius, int slices, int stacks) { - float rho, drho, dtheta; - float s, t, ds, dt; - int i, j, imin, imax; - float nsign = 1.0; - osg::Geode* geode = new osg::Geode; + float rho, drho, dtheta; + float s, t, ds, dt; + int i, j, imin, imax; + float nsign = 1.0; + osg::Geode* geode = new osg::Geode; - drho = SGD_PI / (float) stacks; - dtheta = SGD_2PI / (float) slices; + drho = SD_PI / (float) stacks; + dtheta = SD_2PI / (float) slices; - ds = 1.0 / slices; - dt = 1.0 / stacks; - t = 1.0; - imin = 0; - imax = stacks; + ds = 1.0 / slices; + dt = 1.0 / stacks; + t = 1.0; + imin = 0; + imax = stacks; - for ( i = imin; i < imax; i++ ) - { - osg::Geometry* geometry = new osg::Geometry; - osg::Vec3Array* vl = new osg::Vec3Array; - osg::Vec3Array* nl = new osg::Vec3Array; - osg::Vec2Array* tl = new osg::Vec2Array; + for ( i = imin; i < imax; i++ ) + { + osg::Geometry* geometry = new osg::Geometry; + osg::Vec3Array* vl = new osg::Vec3Array; + osg::Vec3Array* nl = new osg::Vec3Array; + osg::Vec2Array* tl = new osg::Vec2Array; rho = i * drho; s = 0.0; for ( j = 0; j <= slices; j++ ) { - double theta = (j == slices) ? 0.0 : j * dtheta; - double x = -sin(theta) * sin(rho); - double y = cos(theta) * sin(rho); - double z = nsign * cos(rho); + double theta = (j == slices) ? 0.0 : j * dtheta; + double x = -sin(theta) * sin(rho); + double y = cos(theta) * sin(rho); + double z = nsign * cos(rho); - osg::Vec3 normal(x*nsign, y*nsign, z*nsign); - normal.normalize(); - - nl->push_back(normal); - tl->push_back(osg::Vec2(s, t)); - vl->push_back(osg::Vec3(x*radius, y*radius, z*radius)); + osg::Vec3 normal(x*nsign, y*nsign, z*nsign); + normal.normalize(); + nl->push_back(normal); - x = -sin(theta) * sin(rho+drho); - y = cos(theta) * sin(rho+drho); - z = nsign * cos(rho+drho); + tl->push_back(osg::Vec2(s, t)); + vl->push_back(osg::Vec3(x*radius, y*radius, z*radius)); - normal = osg::Vec3(x*nsign, y*nsign, z*nsign); - normal.normalize(); - - nl->push_back(normal); - tl->push_back(osg::Vec2(s, t-dt)); - - s += ds; + x = -sin(theta) * sin(rho+drho); + y = cos(theta) * sin(rho+drho); + z = nsign * cos(rho+drho); - vl->push_back(osg::Vec3(x*radius, y*radius, z*radius)); + normal = osg::Vec3(x*nsign, y*nsign, z*nsign); + normal.normalize(); + nl->push_back(normal); + + tl->push_back(osg::Vec2(s, t-dt)); + s += ds; + + vl->push_back(osg::Vec3(x*radius, y*radius, z*radius)); } if ( vl->size() != nl->size() ) { - GfOut("bad sphere1\n"); - exit(-1); + GfOut("bad sphere1\n"); + //return -1; } if ( vl->size() != tl->size() ) { - GfOut("bad sphere2\n"); - exit(-1); + GfOut("bad sphere2\n"); + //return -1; } - // colors - osg::Vec4Array* cl = new osg::Vec4Array; - cl->push_back(osg::Vec4(1, 1, 1, 1)); + osg::Vec4Array* cl = new osg::Vec4Array; + cl->push_back(osg::Vec4(1, 1, 1, 1)); - geometry->setUseDisplayList(false); - geometry->setVertexArray(vl); - geometry->setNormalArray(nl); - geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); - geometry->setTexCoordArray(0, tl); - geometry->setColorArray(cl); - geometry->setColorBinding(osg::Geometry::BIND_OVERALL); - geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP, 0, vl->size())); - geode->addDrawable(geometry); + geometry->setUseDisplayList(false); + geometry->setVertexArray(vl); + geometry->setNormalArray(nl); + geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); + geometry->setTexCoordArray(0, tl); + geometry->setColorArray(cl); + geometry->setColorBinding(osg::Geometry::BIND_OVERALL); + geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP, 0, vl->size())); + geode->addDrawable(geometry); t -= dt; } diff --git a/src/modules/graphic/osggraph/OsgSphere.h b/src/modules/graphic/osggraph/OsgSphere.h index 929dd1e4e..dc3348c0e 100644 --- a/src/modules/graphic/osggraph/OsgSphere.h +++ b/src/modules/graphic/osggraph/OsgSphere.h @@ -1,11 +1,12 @@ /*************************************************************************** - file : OsgSphere.h - copyright : (C) 2012 by Xavier Bertaux (based on SimGear code) - web : bertauxx@yahoo.fr - version : $Id: OsgSphere.h 3162 2012-12-03 13:11:22Z torcs-ng $ + file : OsgSphere.h + created : Mon Aug 21 18:24:02 CEST 2012 + copyright : (C) 2012 by Xavier Bertaux + email : bertauxx@yahoo.fr + version : $Id$ - ***************************************************************************/ +***************************************************************************/ /*************************************************************************** * * diff --git a/src/modules/graphic/osggraph/OsgStars.cpp b/src/modules/graphic/osggraph/OsgStars.cpp index 5ebce0a26..54080796e 100644 --- a/src/modules/graphic/osggraph/OsgStars.cpp +++ b/src/modules/graphic/osggraph/OsgStars.cpp @@ -1,11 +1,12 @@ /*************************************************************************** - file : SDStars.cpp - copyright : (C) 2012 by Xavier Bertaux (based on SimGear code) - web : http://www.speed-dreams.org - version : $Id: SDStars.cpp 3162 2010-12-05 13:11:22Z pouillot $ + file : OsgStars.cpp + created : Mon Aug 21 18:24:02 CEST 2012 + copyright : (C) 2012 by Xavier Bertaux + email : bertauxx@yahoo.fr + version : $Id$ - ***************************************************************************/ +***************************************************************************/ /*************************************************************************** * * @@ -29,11 +30,11 @@ #include #include -#include "SDSky.h" - -#define SD_2PI 6.28318530717958647692 -#define SD_PI_2 1.57079632679489661923 +//#include "OsgConstants.h" +#include "OsgStars.h" +#include "OsgMath.h" +// Constructor SDStars::SDStars( void ) : old_phase(-1) { @@ -44,12 +45,14 @@ SDStars::~SDStars( void ) { } -osg::Node* SDStars::build( int num, const osg::Vec3 star_data[], double star_dist ) +// initialize the stars object and connect it into our scene graph root +osg::Node* SDStars::build( int num, const osg::Vec3d star_data[], double star_dist ) { osg::Geode* geode = new osg::Geode; osg::StateSet* stateSet = geode->getOrCreateStateSet(); stateSet->setRenderBinDetails(-9, "RenderBin"); + // set up the star state osg::BlendFunc* blendFunc = new osg::BlendFunc; blendFunc->setFunction(osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::ONE_MINUS_SRC_ALPHA); @@ -70,7 +73,6 @@ osg::Node* SDStars::build( int num, const osg::Vec3 star_data[], double star_dis star_dist * sin( star_data[i][0]) * cos( star_data[i][1] ), star_dist * sin( star_data[i][1]))); - cl->push_back(osg::Vec4(1, 1, 1, 1)); } @@ -86,76 +88,47 @@ osg::Node* SDStars::build( int num, const osg::Vec3 star_data[], double star_dis return geode; } -bool SDStars::reposition( osg::Vec3f& p, double angle ) -{ - sgMat4 T1, GST; - sgVec3 axis; - - sgMakeTransMat4( T1, p ); - - sgSetVec3( axis, 0.0, 0.0, -1.0 ); - sgMakeRotMat4( GST, (float)angle, axis ); - - sgMat4 TRANSFORM; - sgCopyMat4( TRANSFORM, T1 ); - sgPreMultMat4( TRANSFORM, GST ); - - sgCoord skypos; - sgSetCoord( &skypos, TRANSFORM ); - - stars_transform->setTransform( &skypos ); - - return true; -} - -bool SDStars::repaint( double sun_angle, int num, const osg::Vec3 star_data[] ) +bool SDStars::repaint( double sun_angle, int num, const osg::Vec3d star_data[] ) { double mag, nmag, alpha, factor, cutoff; - int phase; - if ( sun_angle > (SGD_PI_2 + 10.0 * SGD_DEGREES_TO_RADIANS ) ) + if ( sun_angle > (SD_PI_2 + 10.0 * SD_DEGREES_TO_RADIANS ) ) { factor = 1.0; cutoff = 4.5; phase = 0; - } - else if ( sun_angle > (SGD_PI_2 + 8.8 * SGD_DEGREES_TO_RADIANS ) ) + } else if ( sun_angle > (SD_PI_2 + 8.8 * SD_DEGREES_TO_RADIANS ) ) { factor = 1.0; cutoff = 3.8; phase = 1; - } - else if ( sun_angle > (SGD_PI_2 + 7.5 * SGD_DEGREES_TO_RADIANS ) ) + } else if ( sun_angle > (SD_PI_2 + 7.5 * SD_DEGREES_TO_RADIANS ) ) { factor = 0.95; cutoff = 3.1; phase = 2; - } - else if ( sun_angle > (SGD_PI_2 + 7.0 * SGD_DEGREES_TO_RADIANS ) ) + } else if ( sun_angle > (SD_PI_2 + 7.0 * SD_DEGREES_TO_RADIANS ) ) { factor = 0.9; cutoff = 2.4; phase = 3; - } - else if ( sun_angle > (SGD_PI_2 + 6.5 * SGD_DEGREES_TO_RADIANS ) ) + } else if ( sun_angle > (SD_PI_2 + 6.5 * SD_DEGREES_TO_RADIANS ) ) { factor = 0.85; cutoff = 1.8; phase = 4; - } - else if ( sun_angle > (SGD_PI_2 + 6.0 * SGD_DEGREES_TO_RADIANS ) ) + } else if ( sun_angle > (SD_PI_2 + 6.0 * SD_DEGREES_TO_RADIANS ) ) { factor = 0.8; cutoff = 1.2; phase = 5; - } - else if ( sun_angle > (SGD_PI_2 + 5.5 * SGD_DEGREES_TO_RADIANS ) ) + } else if ( sun_angle > (SD_PI_2 + 5.5 * SD_DEGREES_TO_RADIANS ) ) { factor = 0.75; cutoff = 0.6; phase = 6; - } else + } else { factor = 0.7; cutoff = 0.0; @@ -166,15 +139,15 @@ bool SDStars::repaint( double sun_angle, int num, const osg::Vec3 star_data[] ) { old_phase = phase; for ( int i = 0; i < num; ++i ) - { + { mag = star_data[i][2]; if ( mag < cutoff ) - { + { nmag = ( 4.5 - mag ) / 5.5; alpha = nmag * 0.85 + 0.15; alpha *= factor; } else - { + { alpha = 0.0; } @@ -182,11 +155,12 @@ bool SDStars::repaint( double sun_angle, int num, const osg::Vec3 star_data[] ) if (alpha < 0.0) { alpha = 0.0; } (*cl)[i] = osg::Vec4(1, 1, 1, alpha); + } cl->dirty(); - } - else + } else { + // cout << " no phase change, skipping" << endl; } return true; diff --git a/src/modules/graphic/osggraph/OsgStars.h b/src/modules/graphic/osggraph/OsgStars.h new file mode 100644 index 000000000..44784c8c6 --- /dev/null +++ b/src/modules/graphic/osggraph/OsgStars.h @@ -0,0 +1,44 @@ +/*************************************************************************** + + file : OsgStars.h + created : Mon Aug 21 18:24:02 CEST 2012 + copyright : (C) 2012 by Xavier Bertaux + email : bertauxx@yahoo.fr + version : $Id$ + +***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef _OSGSTARS_H_ +#define _OSGSTARS_H_ + +#include + +class SDStars +{ + osg::ref_ptr cl; + int old_phase; + +public: + + // Constructor + SDStars( void ); + + // Destructor + ~SDStars( void ); + + // initialize the stars structure + osg::Node* build( int num, const osg::Vec3d star_data[], double star_dist ); + + bool repaint( double sun_angle, int num, const osg::Vec3d star_data[] ); +}; + +#endif // _OSGSTARS_H_ diff --git a/src/modules/graphic/osggraph/OsgSun.cpp b/src/modules/graphic/osggraph/OsgSun.cpp index fad34bdb7..422962a21 100644 --- a/src/modules/graphic/osggraph/OsgSun.cpp +++ b/src/modules/graphic/osggraph/OsgSun.cpp @@ -1,11 +1,12 @@ /*************************************************************************** - file : OsgSun.cpp - copyright : (C) 2012 by Xavier Bertaux (based on SimGear code) - web : http://www.speed-dreams.org - version : $Id: OsgSun.cpp 3162 2012-12-03 13:11:22Z torcs-ng $ + file : OsgSun.cpp + created : Mon Aug 21 18:24:02 CEST 2012 + copyright : (C) 2012 by Xavier Bertaux + email : bertauxx@yahoo.fr + version : $Id$ - ***************************************************************************/ +***************************************************************************/ /*************************************************************************** * * @@ -16,6 +17,7 @@ * * ***************************************************************************/ +#include #include #include #include @@ -27,9 +29,10 @@ #include #include -#include "OsgSky.h" -#include "OsgColors.h" +#include "OsgColor.h" +#include "OsgSun.h" #include "OsgMath.h" +#include "OsgSphere.h" // Constructor SDSun::SDSun( void ) : @@ -39,19 +42,14 @@ SDSun::SDSun( void ) : } - // Destructor SDSun::~SDSun( void ) { } - -// initialize the sun object and connect it into our scene graph root -osg::Node* SDSun::build( const std::string path, double sun_size ) +osg::Node* SDSun::build( std::string path, double sun_size ) { - osg::ref_ptr options - = makeOptionsFromPath(path); - + std::string TmpPath = path; sun_transform = new osg::MatrixTransform; osg::StateSet* stateSet = sun_transform->getOrCreateStateSet(); @@ -83,22 +81,23 @@ osg::Node* SDSun::build( const std::string path, double sun_size ) stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::OFF); stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF); - osg::Geode* geode = new osg::Geode; - stateSet = geode->getOrCreateStateSet(); + osg::Node* sun = SDMakeSphere(sun_size, 15, 15); + stateSet = sun->getOrCreateStateSet(); stateSet->setRenderBinDetails(-6, "RenderBin"); - osg::Texture2D* texture = SGLoadTexture2D("sun.png", options.get()); + path = TmpPath+"sun.png"; + osg::ref_ptr image = osgDB::readImageFile(path); + osg::ref_ptr texture = new osg::Texture2D(image.get()); stateSet->setTextureAttributeAndModes(0, texture); - // Build scenegraph sun_cl = new osg::Vec4Array; sun_cl->push_back(osg::Vec4(1, 1, 1, 1)); scene_cl = new osg::Vec4Array; scene_cl->push_back(osg::Vec4(1, 1, 1, 1)); - osg::Vec3Array* sun_vl = new osg::Vec3Array; + /*osg::Vec3Array* sun_vl = new osg::Vec3Array; sun_vl->push_back(osg::Vec3(-sun_size, 0, -sun_size)); sun_vl->push_back(osg::Vec3(sun_size, 0, -sun_size)); sun_vl->push_back(osg::Vec3(-sun_size, 0, sun_size)); @@ -118,17 +117,18 @@ osg::Node* SDSun::build( const std::string path, double sun_size ) geometry->setNormalBinding(osg::Geometry::BIND_OFF); geometry->setTexCoordArray(0, sun_tl); geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP, 0, 4)); - geode->addDrawable(geometry); + geode->addDrawable(geometry);*/ - sun_transform->addChild( geode ); + sun_transform->addChild( sun ); - // set up the inner-halo state - geode = new osg::Geode; + osg::Geode* geode = new osg::Geode; stateSet = geode->getOrCreateStateSet(); stateSet->setRenderBinDetails(-7, "RenderBin"); - texture = SGLoadTexture2D("inner_halo.png", options.get()); - stateSet->setTextureAttributeAndModes(0, texture); + path = TmpPath+"inner_halo.png"; + osg::ref_ptr image2 = osgDB::readImageFile(path); + osg::ref_ptr texture2 = new osg::Texture2D(image2.get()); + stateSet->setTextureAttributeAndModes(0, texture2); ihalo_cl = new osg::Vec4Array; ihalo_cl->push_back(osg::Vec4(1, 1, 1, 1)); @@ -146,7 +146,7 @@ osg::Node* SDSun::build( const std::string path, double sun_size ) ihalo_tl->push_back(osg::Vec2(0, 1)); ihalo_tl->push_back(osg::Vec2(1, 1)); - geometry = new osg::Geometry; + osg::Geometry* geometry = new osg::Geometry; geometry->setUseDisplayList(false); geometry->setVertexArray(ihalo_vl); geometry->setColorArray(ihalo_cl.get()); @@ -162,13 +162,15 @@ osg::Node* SDSun::build( const std::string path, double sun_size ) stateSet = geode->getOrCreateStateSet(); stateSet->setRenderBinDetails(-8, "RenderBin"); - texture = SGLoadTexture2D("outer_halo.png", options.get()); - stateSet->setTextureAttributeAndModes(0, texture); + path = TmpPath+"outer_halo.png"; + osg::ref_ptr image3 = osgDB::readImageFile(path); + osg::ref_ptr texture3 = new osg::Texture2D(image3.get()); + stateSet->setTextureAttributeAndModes(0, texture3); ohalo_cl = new osg::Vec4Array; ohalo_cl->push_back(osg::Vec4(1, 1, 1, 1)); - double ohalo_size = sun_size * 8.0; + double ohalo_size = sun_size * 10.0; osg::Vec3Array* ohalo_vl = new osg::Vec3Array; ohalo_vl->push_back(osg::Vec3(-ohalo_size, 0, -ohalo_size)); ohalo_vl->push_back(osg::Vec3(ohalo_size, 0, -ohalo_size)); @@ -205,7 +207,10 @@ bool SDSun::repaint( double sun_angle, double new_visibility ) if (new_visibility < 100.0) new_visibility = 100.0; else if (new_visibility > 45000.0) new_visibility = 45000.0; visibility = new_visibility; - sun_exp2_punch_through = 2.0/log(visibility); + + static const float sqrt_m_log01 = sqrt( -log( 0.01 ) ); + sun_exp2_punch_through = sqrt_m_log01 / ( visibility * 15 ); + //sun_exp2_punch_through = 2.0/log(visibility); } if ( prev_sun_angle != sun_angle ) @@ -223,17 +228,14 @@ bool SDSun::repaint( double sun_angle, double new_visibility ) } double rel_humidity, density_avg; + rel_humidity = 0.5; + density_avg = 0.7; - if ( !env_node ) - { - rel_humidity = 0.5; - density_avg = 0.7; - } - else + /*else { rel_humidity = env_node->getFloatValue( "relative-humidity" ); density_avg = env_node->getFloatValue( "atmosphere/density-tropo-avg" ); - } + }*/ osg::Vec4 i_halo_color, o_halo_color, scene_color, sun_color; @@ -241,38 +243,55 @@ bool SDSun::repaint( double sun_angle, double new_visibility ) red_scat_f = (aerosol_factor * path_distance * density_avg)/5E+07; red_scat_corr_f = sun_exp2_punch_through / (1 - red_scat_f); - sun_color[0] = 1; + 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); scene_color[0] = 1 - red_scat_f; - green_scat_f = (aerosol_factor * path_distance * density_avg)/8.8938E+06; - sun_color[1] = 1 - green_scat_f * red_scat_corr_f; - scene_color[1] = 1 - green_scat_f; + // Green - 546.1 nm + if (sun_declination > 5.0 || sun_declination < 2.0) + { + green_scat_f = ( aerosol_factor * path_distance * density_avg ) / 5E+07; + } + else + green_scat_f = ( aerosol_factor * path_distance * density_avg ) / 8.8938E+06; + sun_color[1] = 1 - green_scat_f * red_scat_corr_f; + i_halo_color[1] = 1 - (1.1 * (green_scat_f * red_scat_corr_f)); + o_halo_color[1] = 1 - (1.4 * (green_scat_f * red_scat_corr_f)); + scene_color[1] = 1 - green_scat_f; + + // Blue - 435.8 nm blue_scat_f = (aerosol_factor * path_distance * density_avg)/3.607E+06; sun_color[2] = 1 - blue_scat_f * red_scat_corr_f; + i_halo_color[1] = 1 - (1.1 * (blue_scat_f * red_scat_corr_f)); + o_halo_color[1] = 1 - (1.4 * (blue_scat_f * red_scat_corr_f)); scene_color[2] = 1 - blue_scat_f; + // Alpha sun_color[3] = 1; + i_halo_color[3] = 1; scene_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; + } + double 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] )); + scene_color[1] += (( 1 - saturation ) * ( 1 - scene_color[1] )); scene_color[2] += (( 1 - saturation ) * ( 1 - scene_color[2] )); - if (sun_color[0] > 1.0) sun_color[0] = 1.0; - if (sun_color[0] < 0.0) sun_color[0] = 0.0; - if (sun_color[1] > 1.0) sun_color[1] = 1.0; - if (sun_color[1] < 0.0) sun_color[1] = 0.0; - if (sun_color[2] > 1.0) sun_color[2] = 1.0; - if (sun_color[2] < 0.0) sun_color[2] = 0.0; - - if (scene_color[0] > 1.0) scene_color[0] = 1.0; - if (scene_color[0] < 0.0) scene_color[0] = 0.0; - if (scene_color[1] > 1.0) scene_color[1] = 1.0; - if (scene_color[1] < 0.0) scene_color[1] = 0.0; - if (scene_color[2] > 1.0) scene_color[2] = 1.0; - if (scene_color[2] < 0.0) scene_color[2] = 0.0; - double scene_f = 0.5 * (1 / (1 - red_scat_f)); double sun_f = 1.0 - scene_f; i_halo_color[0] = sun_f * sun_color[0] + scene_f * scene_color[0]; @@ -284,14 +303,48 @@ bool SDSun::repaint( double sun_angle, double new_visibility ) o_halo_color[1] = 0.2 * sun_color[1] + 0.8 * scene_color[1]; o_halo_color[2] = 0.2 * sun_color[2] + 0.8 * scene_color[2]; o_halo_color[3] = blue_scat_f; + if ((visibility < 10000) && (blue_scat_f > 1)) - { + { o_halo_color[3] = 2 - blue_scat_f; } - + if (o_halo_color[3] > 1) o_halo_color[3] = 1; if (o_halo_color[3] < 0) o_halo_color[3] = 0; + // 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 (scene_color[0] < 0) scene_color[0] = 0; + else if (scene_color[0] > 1) scene_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[0] > 1) o_halo_color[1] = 1; + if (scene_color[1] < 0) scene_color[1] = 0; + else if (scene_color[1] > 1) scene_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[3] = 0; + else if ( o_halo_color[3] > 1) o_halo_color[3] = 1; + if (scene_color[2] < 0) scene_color[2] = 0; + else if (scene_color[2] > 1) scene_color[2] = 1; + if (scene_color[3] < 0) scene_color[3] = 0; + else if (scene_color[3] > 1) scene_color[3] = 1; + + sd_gamma_correct_rgb( i_halo_color._v ); sd_gamma_correct_rgb( o_halo_color._v ); sd_gamma_correct_rgb( scene_color._v ); @@ -313,17 +366,10 @@ bool SDSun::repaint( double sun_angle, double new_visibility ) bool SDSun::reposition( double rightAscension, double declination, double sun_dist, double lat, double alt_asl, double sun_angle) { - // GST - GMT sidereal time osg::Matrix T2, RA, DEC; - // xglRotatef( ((SGD_RADIANS_TO_DEGREES * rightAscension)- 90.0), - // 0.0, 0.0, 1.0); - RA.makeRotate(rightAscension - 90*SGD_DEGREES_TO_RADIANS, osg::Vec3(0, 0, 1)); - - // xglRotatef((SGD_RADIANS_TO_DEGREES * declination), 1.0, 0.0, 0.0); + RA.makeRotate(rightAscension - 90*SD_DEGREES_TO_RADIANS, osg::Vec3(0, 0, 1)); DEC.makeRotate(declination, osg::Vec3(1, 0, 0)); - - // xglTranslatef(0,sun_dist); T2.makeTranslate(osg::Vec3(0, sun_dist, 0)); sun_transform->setMatrix(T2*DEC*RA); @@ -332,7 +378,6 @@ bool SDSun::reposition( double rightAscension, double declination, 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; @@ -341,42 +386,37 @@ bool SDSun::reposition( double rightAscension, double declination, double r_tropo = r_tropo_pole / sqrt ( 1 - ( epsilon_tropo2 * pow ( cos( lat ), 2 ))); double r_earth = r_earth_pole / sqrt ( 1 - ( epsilon_earth2 * pow ( cos( lat ), 2 ))); - double position_radius = r_earth + alt_asl; + double position_radius = r_earth; - double gamma = SG_PI - sun_angle; + double gamma = SD_PI - sun_angle; double sin_beta = ( position_radius * sin ( gamma ) ) / r_tropo; if (sin_beta > 1.0) sin_beta = 1.0; - double alpha = SG_PI - gamma - asin( sin_beta ); + double alpha = SD_PI - gamma - asin( sin_beta ); - // OK, now let's calculate the distance the light travels 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; - - // Push the data to the property tree, so it can be used in the enviromental code - if ( env_node ) + /*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; } -SGVec4f -SDSun::get_color() +osg::Vec4f SDSun::get_color() { - return SGVec4f((*sun_cl)[0][0], (*sun_cl)[0][1], (*sun_cl)[0][2], (*sun_cl)[0][3]); + return osg::Vec4f((*sun_cl)[0][0], (*sun_cl)[0][1], (*sun_cl)[0][2], (*sun_cl)[0][3]); } -SGVec4f -SDSun::get_scene_color() +osg::Vec4f SDSun::get_scene_color() { - return SGVec4f((*scene_cl)[0][0], (*scene_cl)[0][1], (*scene_cl)[0][2], (*scene_cl)[0][3]); + return osg::Vec4f((*scene_cl)[0][0], (*scene_cl)[0][1], (*scene_cl)[0][2], (*scene_cl)[0][3]); } diff --git a/src/modules/graphic/osggraph/OsgSun.h b/src/modules/graphic/osggraph/OsgSun.h new file mode 100644 index 000000000..6201d2eac --- /dev/null +++ b/src/modules/graphic/osggraph/OsgSun.h @@ -0,0 +1,81 @@ +/*************************************************************************** + + file : OsgSun.h + created : Mon Aug 21 18:24:02 CEST 2012 + copyright : (C) 2012 by Xavier Bertaux + email : bertauxx@yahoo.fr + version : $Id$ + +***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef _OSGSUN_H_ +#define _OSGSUN_H_ + +#include +#include +#include + +class SDSun +{ + osg::ref_ptr sun_transform; + + osg::ref_ptr sun_cl; + osg::ref_ptr scene_cl; + osg::ref_ptr ihalo_cl; + osg::ref_ptr ohalo_cl; + + double visibility; + double prev_sun_angle; + double sun_angle; + double sun_rotation; + + // used by reposition + double sun_right_ascension; + double sun_declination; + double sun_dist; + double path_distance; + double sun_exp2_punch_through; + +public: + + // Constructor + SDSun( void ); + + // Destructor + ~SDSun( void ); + + osg::Node* build( std::string path, double sun_size ); + + bool repaint( double sun_angle, double new_visibility ); + bool reposition( double rightAscension, double declination, + double sun_dist, double lat, double alt_asl, double sun_angle ); + + osg::Vec4f get_color(); + osg::Vec4f get_scene_color(); + + void setSunAngle(double angle) { sun_angle = angle; } + double getSunAngle() { return sun_angle; } + + void setSunRotation(double rotation) { sun_rotation = rotation; } + double getSunRotation() { return sun_rotation; } + + void setSunRightAscension(double ra) { sun_right_ascension = ra; } + double getSunRightAscension() { return sun_right_ascension; } + + void setSunDeclination( double decl ) { sun_declination = decl; } + double getSunDeclination() { return sun_declination; } + + void setSunDistance( double dist ) { sun_dist = dist; } + double getSunDistance() { return sun_dist; } +}; + +#endif // _OSGSUN_H_ diff --git a/src/modules/graphic/osggraph/OsgVectorArrayAdapter.h b/src/modules/graphic/osggraph/OsgVectorArrayAdapter.h index ab90b7249..49ef64dff 100644 --- a/src/modules/graphic/osggraph/OsgVectorArrayAdapter.h +++ b/src/modules/graphic/osggraph/OsgVectorArrayAdapter.h @@ -23,11 +23,11 @@ namespace osggraph { template -class VectorArrayAdapter +class SDVectorArrayAdapter { public: - VectorArrayAdapter(Vector& v, int rowStride, int baseOffset = 0, + SDVectorArrayAdapter(Vector& v, int rowStride, int baseOffset = 0, int rowOffset = 0): _v(v), _rowStride(rowStride), _baseOffset(baseOffset), _rowOffset(rowOffset) diff --git a/src/modules/graphic/osggraph/ReaderWriterACC.cpp b/src/modules/graphic/osggraph/ReaderWriterACC.cpp index 2a8f2d550..82c524c71 100644 --- a/src/modules/graphic/osggraph/ReaderWriterACC.cpp +++ b/src/modules/graphic/osggraph/ReaderWriterACC.cpp @@ -198,7 +198,7 @@ osg::Node* ReaderWriterACC::readObject(std::istream& stream, FileData& fileData, bool b; if (strName == "GRILL1_s_0") b = true; - if (!strncmp(strName.c_str(), "WI", 2)) + if (!strncmp(strName.c_str(), "WI", 2)) { group = m_transparentGroup; m_bBlockTransparent = false; @@ -374,7 +374,7 @@ osg::Node* ReaderWriterACC::readObject(std::istream& stream, FileData& fileData, if (primitiveBins.size() <= matIdx) { osg::notify(osg::FATAL) << "osgDB TORCS reader: invalid material number while reading object \"" - << group->getName() << "\"" << std::endl; + << group->getName() << "\"1" << std::endl; return group.release(); } @@ -384,7 +384,7 @@ osg::Node* ReaderWriterACC::readObject(std::istream& stream, FileData& fileData, if (!primitiveBin) { osg::notify(osg::FATAL) << "osgDB TORCS reader: unexpected primitive flags while reading object \"" - << group->getName() << "\"" << std::endl; + << group->getName() << "\"2" << std::endl; return group.release(); } @@ -393,7 +393,7 @@ osg::Node* ReaderWriterACC::readObject(std::istream& stream, FileData& fileData, if (token != "refs") { osg::notify(osg::FATAL) << "osgDB TORCS reader: expected refs line while reading object \"" - << group->getName() << "\"" << std::endl; + << group->getName() << "\"3" << std::endl; return group.release(); } @@ -402,7 +402,7 @@ osg::Node* ReaderWriterACC::readObject(std::istream& stream, FileData& fileData, if (!stream) { osg::notify(osg::FATAL) << "osgDB TORCS reader: could not read number of refs while reading object \"" - << group->getName() << "\"" << std::endl; + << group->getName() << "\"4" << std::endl; return group.release(); } @@ -419,7 +419,7 @@ osg::Node* ReaderWriterACC::readObject(std::istream& stream, FileData& fileData, if (vertexSet->size() <= index) { osg::notify(osg::FATAL) << "osgDB TORCS reader: invalid ref vertex index while reading object \"" - << group->getName() << "\"" << std::endl; + << group->getName() << "\"5" << std::endl; return group.release(); } @@ -544,8 +544,8 @@ osg::Node* ReaderWriterACC::readObject(std::istream& stream, FileData& fileData, else { std::string strUnknown = token; - osg::notify(osg::WARN) << "osgDB TORCS reader: unknown token refs line while reading object \"" - <<" token:"<