1 //  SuperTux
2 //  Copyright (C) 2018 Ingo Ruhnke <grumbel@gmail.com>
3 //
4 //  This program is free software: you can redistribute it and/or modify
5 //  it under the terms of the GNU General Public License as published by
6 //  the Free Software Foundation, either version 3 of the License, or
7 //  (at your option) any later version.
8 //
9 //  This program is distributed in the hope that it will be useful,
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //  GNU General Public License for more details.
13 //
14 //  You should have received a copy of the GNU General Public License
15 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 
17 #include "object/ambient_light.hpp"
18 
19 #include <sexp/io.hpp>
20 #include <sexp/value.hpp>
21 
22 #include "util/log.hpp"
23 #include "util/reader_mapping.hpp"
24 #include "util/writer.hpp"
25 #include "video/drawing_context.hpp"
26 
AmbientLight(const Color & color)27 AmbientLight::AmbientLight(const Color& color) :
28   m_ambient_light(color),
29   m_ambient_light_fading(false),
30   m_source_ambient_light(color),
31   m_target_ambient_light(color),
32   m_ambient_light_fade_duration(0.0f),
33   m_ambient_light_fade_accum(0.0f)
34 {
35 }
36 
AmbientLight(const ReaderMapping & mapping)37 AmbientLight::AmbientLight(const ReaderMapping& mapping) :
38   m_ambient_light(1.0f, 1.0f, 1.0f, 1.0f),
39   m_ambient_light_fading(false),
40   m_source_ambient_light(1.0f, 1.0f, 1.0f, 1.0f),
41   m_target_ambient_light(1.0f, 1.0f, 1.0f, 1.0f),
42   m_ambient_light_fade_duration(0.0f),
43   m_ambient_light_fade_accum(0.0f)
44 {
45   std::vector<float> color_vec;
46   if (mapping.get("color", color_vec))
47   {
48     if (color_vec.size() < 3) {
49       log_warning << "ambient-light requires three float arguments" << std::endl;
50     } else {
51       m_ambient_light = Color(color_vec);
52     }
53   }
54 }
55 
56 void
update(float dt_sec)57 AmbientLight::update(float dt_sec)
58 {
59   if (m_ambient_light_fading)
60   {
61     m_ambient_light_fade_accum += dt_sec;
62     float percent_done = m_ambient_light_fade_accum / m_ambient_light_fade_duration * 1.0f;
63     float r = (1.0f - percent_done) * m_source_ambient_light.red + percent_done * m_target_ambient_light.red;
64     float g = (1.0f - percent_done) * m_source_ambient_light.green + percent_done * m_target_ambient_light.green;
65     float b = (1.0f - percent_done) * m_source_ambient_light.blue + percent_done * m_target_ambient_light.blue;
66 
67     if (r > 1.0f)
68       r = 1.0;
69     if (g > 1.0f)
70       g = 1.0;
71     if (b > 1.0f)
72       b = 1.0;
73 
74     if (r < 0)
75       r = 0;
76     if (g < 0)
77       g = 0;
78     if (b < 0)
79       b = 0;
80 
81     m_ambient_light = Color(r, g, b);
82 
83     if (m_ambient_light_fade_accum >= m_ambient_light_fade_duration)
84     {
85       m_ambient_light = m_target_ambient_light;
86       m_ambient_light_fading = false;
87       m_ambient_light_fade_accum = 0;
88     }
89   }
90 }
91 
92 void
draw(DrawingContext & context)93 AmbientLight::draw(DrawingContext& context)
94 {
95   context.set_ambient_color(m_ambient_light);
96 }
97 
98 void
set_ambient_light(const Color & ambient_light)99 AmbientLight::set_ambient_light(const Color& ambient_light)
100 {
101   m_ambient_light = ambient_light;
102 }
103 
104 Color
get_ambient_light() const105 AmbientLight::get_ambient_light() const
106 {
107   return m_ambient_light;
108 }
109 
110 void
fade_to_ambient_light(float red,float green,float blue,float seconds)111 AmbientLight::fade_to_ambient_light(float red, float green, float blue, float seconds)
112 {
113   if (seconds == 0)
114   {
115     m_ambient_light = Color(red, green, blue);
116     return;
117   }
118 
119   m_ambient_light_fading = true;
120   m_ambient_light_fade_accum = 0;
121   m_ambient_light_fade_duration = seconds;
122   m_source_ambient_light = m_ambient_light;
123   m_target_ambient_light = Color(red, green, blue);
124 }
125 
126 ObjectSettings
get_settings()127 AmbientLight::get_settings()
128 {
129   ObjectSettings result = GameObject::get_settings();
130 
131   result.add_color(_("Color"), &m_ambient_light, "color");
132 
133   return result;
134 }
135 
136 /* EOF */
137