// light.hxx -- lighting routines // // Written by Curtis Olson, started April 1998. // // Copyright (C) 1998 Curtis L. Olson - http://www.flightgear.org/~curt // // 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. // // This program 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 // 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. // // $Id$ #ifndef _LIGHT_HXX #define _LIGHT_HXX #ifndef __cplusplus # error This library requires C++ #endif #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include // Define a structure containing the global lighting parameters class FGLight : public SGSubsystem { private: /* * Lighting look up tables (based on sun angle with local horizon) */ std::unique_ptr _ambient_tbl, _diffuse_tbl, _specular_tbl; std::unique_ptr _sky_tbl; /** * position of the sun and moon in various forms */ // in geocentric coordinates double _sun_lon = 0.0, _sun_lat = 0.0; double _moon_lon = 0.0, _moon_gc_lat = 0.0; // (in view coordinates) SGVec4f _sun_vec = {0, 0, 0, 0}; SGVec4f _moon_vec = {0, 0, 0, 0}; // inverse (in view coordinates) SGVec4f _sun_vec_inv = {0, 0, 0, 0}; SGVec4f _moon_vec_inv = {0, 0, 0, 0}; // the angle between the celestial object and the local horizontal // (in radians) double _sun_angle = 0.0 , _moon_angle = 0.0; double _prev_sun_angle = 0.0; // the rotation around our vertical axis of the sun (relative to // due south with positive numbers going in the counter clockwise // direction.) This is the direction we'd need to face if we // wanted to travel towards celestial object. double _sun_rotation = 0.0, _moon_rotation = 0.0; /** * Derived lighting values */ // ambient, diffuse and specular component SGVec4f _scene_ambient = {0, 0, 0, 0}; SGVec4f _scene_diffuse = {0, 0, 0, 0}; SGVec4f _scene_specular = {0, 0, 0, 0}; SGVec4f _scene_chrome = {0, 0, 0, 0}; // clear sky, fog and cloud color SGVec4f _sun_color = {1, 1, 1, 0}; SGVec4f _sky_color = {0, 0, 0, 0}; SGVec4f _fog_color = {0, 0, 0, 0}; SGVec4f _cloud_color = {0, 0, 0, 0}; // clear sky and fog color adjusted for sunset effects SGVec4f _adj_fog_color = {0, 0, 0, 0}; SGVec4f _adj_sky_color = {0, 0, 0, 0}; // input parameters affected by the weather system float _saturation = 1.0f; float _scattering = 0.8f; float _overcast = 0.0f; double _dt_total = 0.0; void update_sky_color (); void update_adj_fog_color (); // update all solar system bodies of interest void updateObjects(); // update the position of one solar system body void updateBodyPos(bool sun_not_moon, double& lon, double& lat, SGVec4f& vec, SGVec4f& vec_inv, double& angle, SGPropertyNode_ptr AngleRad, double& rotation); // properties for chrome light; not a tie because I want to fire // property listeners when the values change. SGPropertyNode_ptr _chromeProps[4]; SGPropertyNode_ptr _sunAngleRad; SGPropertyNode_ptr _moonAngleRad; SGPropertyNode_ptr _humidity; simgear::TiedPropertyList _tiedProperties; /** * Tied-properties helper, record nodes which are tied for easy un-tie-ing */ template void tie(SGPropertyNode* aNode, const char* aRelPath, const SGRawValue& aRawValue) { _tiedProperties.Tie(aNode->getNode(aRelPath, true), aRawValue); } public: FGLight () = default; virtual ~FGLight () = default; // Subsystem API. void bind() override; void init() override; void reinit() override; void unbind() override; void update(double dt) override; // Subsystem identification. static const char* staticSubsystemClassId() { return "lighting"; } // Color related functions inline const SGVec4f& scene_ambient () const { return _scene_ambient; } inline const SGVec4f& scene_diffuse () const { return _scene_diffuse; } inline const SGVec4f& scene_specular () const { return _scene_specular; } inline const SGVec4f& scene_chrome () const { return _scene_chrome; } inline const SGVec4f& sky_color () const { return _sky_color; } inline const SGVec4f& cloud_color () const { return _cloud_color; } inline const SGVec4f& adj_fog_color () const { return _adj_fog_color; } inline const SGVec4f& adj_sky_color () const { return _adj_sky_color; } // Sun related functions inline double get_sun_angle () const { return _sun_angle; } inline void set_sun_angle (double a) { _sun_angle = a; } inline double get_sun_rotation () const { return _sun_rotation; } inline void set_sun_rotation (double r) { _sun_rotation = r; } inline double get_sun_lon () const { return _sun_lon; } inline void set_sun_lon (double l) { _sun_lon = l; } inline double get_sun_lat () const { return _sun_lat; } inline void set_sun_lat (double l) { _sun_lat = l; } inline SGVec4f& sun_vec () { return _sun_vec; } inline SGVec4f& sun_vec_inv () { return _sun_vec_inv; } // Moon related functions inline double get_moon_angle () const { return _moon_angle; } inline void set_moon_angle (double a) { _moon_angle = a; } inline double get_moon_rotation () const { return _moon_rotation; } inline void set_moon_rotation (double r) { _moon_rotation = r; } inline double get_moon_lon () const { return _moon_lon; } inline void set_moon_lon (double l) { _moon_lon = l; } inline double get_moon_gc_lat () const { return _moon_gc_lat; } inline void set_moon_gc_lat (double l) { _moon_gc_lat = l; } inline const SGVec4f& moon_vec () const { return _moon_vec; } inline const SGVec4f& moon_vec_inv () const { return _moon_vec_inv; } }; #endif // _LIGHT_HXX