Panda3D
rpLight.I
1 /**
2  *
3  * RenderPipeline
4  *
5  * Copyright (c) 2014-2016 tobspr <tobias.springer1@gmail.com>
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23  * THE SOFTWARE.
24  *
25  */
26 
27 
28 /**
29  * @brief Returns the amount of shadow sources
30  * @details This returns the amount of shadow sources attached to this light.
31  * In case the light has no shadows enabled, or the light was not attached
32  * yet, this returns 0.
33  *
34  * @return Amount of shadow sources
35  */
36 inline size_t RPLight::get_num_shadow_sources() const {
37  return _shadow_sources.size();
38 }
39 
40 /**
41  * @brief Returns the n-th shadow source
42  * @details This returns the n-th attached shadow source. This ranges from
43  * 0 .. RPLight::get_num_shadow_sources(). If an invalid index is passed,
44  * an assertion is thrown.
45  *
46  * @param index Index of the source
47  * @return Handle to the shadow source
48  */
49 inline ShadowSource* RPLight::get_shadow_source(size_t index) const {
50  nassertr(index < _shadow_sources.size(), nullptr); // Invalid shadow source index
51  return _shadow_sources[index];
52 }
53 
54 /**
55  * @brief Clears all shadow source
56  * @details This removes and destructs all shadow sources attached to this light.
57  * This usually gets called when the light gets detached or destructed.
58  * All shadows sources are freed, and then removed from the shadow source list.
59  */
61  for (size_t i = 0; i < _shadow_sources.size(); ++i) {
62  delete _shadow_sources[i];
63  }
64  _shadow_sources.clear();
65 }
66 
67 /**
68  * @brief Sets whether the light needs an update
69  * @details This controls whether the light needs to get an update. This is the
70  * case when a property of the light changed, e.g. position or color. It does
71  * not affect the shadows (For that use RPLight::invalidate_shadows()).
72  * When this flag is set to true, the light will get resubmitted to the GPU
73  * in the next update cycle.
74  *
75  * You should usually never set the flag to false manually. The
76  * InternalLightManager will do this when the data got sucessfully updated.
77  *
78  * @param flag Update-Flag
79  */
80 inline void RPLight::set_needs_update(bool flag) {
81  _needs_update = flag;
82 }
83 
84 /**
85  * @brief Returns whether the light needs an update
86  * @details This returns whether the light needs an update. This might be the
87  * case when a property of the light was changed, e.g. position or color.
88  * It does not affect the shadows, you have to query the update flag of each
89  * individual source for that.
90  * The return value is the value previously set with RPLight::set_needs_update.
91  *
92  * @return Update-flag
93  */
94 inline bool RPLight::get_needs_update() const {
95  return _needs_update;
96 }
97 
98 /**
99  * @brief Returns whether the light has a slot
100  * @details This returns wheter the light currently is attached, and thus has
101  * a slot in the InternalLightManagers light list. When the light is attached,
102  * this returns true, otherwise it will return false.
103  *
104  * @return true if the light has a slot, false otherwise
105  */
106 inline bool RPLight::has_slot() const {
107  return _slot >= 0;
108 }
109 
110 /**
111  * @brief Returns the slot of the light
112  * @details This returns the slot of the light. This is the space on the GPU
113  * where the light is stored. If the light is not attached yet, this will
114  * return -1, otherwise the index of the light.
115  *
116  * @return Light-Slot
117  */
118 inline int RPLight::get_slot() const {
119  return _slot;
120 }
121 
122 /**
123  * @brief Removes the light slot
124  * @details This is an internal method to remove the slot of the light. It gets
125  * called by the InternalLightManager when a light gets detached. It internally
126  * sets the slot to -1 to indicate the light is no longer attached.
127  */
128 inline void RPLight::remove_slot() {
129  _slot = -1;
130 }
131 
132 /**
133  * @brief Assigns a slot to the light
134  * @details This assigns a slot to the light, marking it as attached. The slot
135  * relates to the index in the GPU's storage of lights. This is an internal
136  * method called by the InternalLightManager when the light got attached.
137  *
138  * @param slot Slot of the light
139  */
140 inline void RPLight::assign_slot(int slot) {
141  _slot = slot;
142 }
143 
144 /**
145  * @brief Invalidates the shadows
146  * @details This invalidates all shadows of the light, causing them to get
147  * regenerated. This might be the case when the lights position or similar
148  * changed. This will cause all shadow sources to be updated, emitting a
149  * shadow update. Be careful when calling this method if you don't want all
150  * sources to get updated. If you only have to invalidate a single shadow source,
151  * use get_shadow_source(n)->set_needs_update(true).
152  */
154  for (size_t i = 0; i < _shadow_sources.size(); ++i) {
155  _shadow_sources[i]->set_needs_update(true);
156  }
157 }
158 
159 /**
160  * @brief Sets the position of the light
161  * @details This sets the position of the light in world space. It will cause
162  * the light to get invalidated, and resubmitted to the GPU.
163  *
164  * @param pos Position in world space
165  */
166 inline void RPLight::set_pos(const LVecBase3 &pos) {
167  set_pos(pos.get_x(), pos.get_y(), pos.get_z());
168 }
169 
170 /**
171  * @brief Sets the position of the light
172  * @details @copydetails RPLight::set_pos(const LVecBase3 &pos)
173  *
174  * @param x X-component of the position
175  * @param y Y-component of the position
176  * @param z Z-component of the position
177  */
178 inline void RPLight::set_pos(float x, float y, float z) {
179  _position.set(x, y, z);
180  set_needs_update(true);
182 }
183 
184 /**
185  * @brief Returns the position of the light
186  * @details This returns the position of the light previously set with
187  * RPLight::set_pos(). The returned position is in world space.
188  * @return Light-position
189  */
190 inline const LVecBase3& RPLight::get_pos() const {
191  return _position;
192 }
193 
194 /**
195  * @brief Sets the lights color
196  * @details This sets the lights color. The color should not include the brightness
197  * of the light, you should control that with the energy. The color specifies
198  * the lights "tint" and will get multiplied with its specular and diffuse
199  * contribution.
200  *
201  * The color will be normalized by dividing by the colors luminance. Setting
202  * higher values than 1.0 will have no effect.
203  *
204  * @param color Light color
205  */
206 inline void RPLight::set_color(const LVecBase3 &color) {
207  _color = color;
208  _color /= 0.2126 * color.get_x() + 0.7152 * color.get_y() + 0.0722 * color.get_z();
209  set_needs_update(true);
210 }
211 
212 /**
213  * @brief Sets the lights color
214  * @details @copydetails RPLight::set_color(const LVecBase3 &color)
215  *
216  * @param r Red-component of the color
217  * @param g Green-component of the color
218  * @param b Blue-component of the color
219  */
220 inline void RPLight::set_color(float r, float g, float b) {
221  set_color(LVecBase3(r, g, b));
222 }
223 
224 /**
225  * @brief Returns the lights color
226  * @details This returns the light color, previously set with RPLight::set_color.
227  * This does not include the energy of the light. It might differ from what
228  * was set with set_color, because the color is normalized by dividing it
229  * by its luminance.
230  * @return Light-color
231  */
232 inline const LVecBase3& RPLight::get_color() const {
233  return _color;
234 }
235 
236 /**
237  * @brief Sets the energy of the light
238  * @details This sets the energy of the light, which can be seen as the brightness
239  * of the light. It will get multiplied with the normalized color.
240  *
241  * @param energy energy of the light
242  */
243 inline void RPLight::set_energy(float energy) {
244  _energy = energy;
245  set_needs_update(true);
246 }
247 
248 /**
249  * @brief Returns the energy of the light
250  * @details This returns the energy of the light, previously set with
251  * RPLight::set_energy.
252  *
253  * @return energy of the light
254  */
255 inline float RPLight::get_energy() const {
256  return _energy;
257 }
258 
259 /**
260  * @brief Returns the type of the light
261  * @details This returns the internal type of the light, which was specified
262  * in the lights constructor. This can be used to distinguish between light
263  * types.
264  * @return Type of the light
265  */
267  return _light_type;
268 }
269 
270 /**
271  * @brief Controls whether the light casts shadows
272  * @details This sets whether the light casts shadows. You can not change this
273  * while the light is attached. When flag is set to true, the light will be
274  * setup to cast shadows, spawning shadow sources based on the lights type.
275  * If the flag is set to false, the light will be inddicated to cast no shadows.
276  *
277  * @param flag Whether the light casts shadows
278  */
279 inline void RPLight::set_casts_shadows(bool flag) {
280  if (has_slot()) {
281  std::cerr << "Light is already attached, can not call set_casts_shadows!" << std::endl;
282  return;
283  }
284  _casts_shadows = flag;
285 }
286 
287 /**
288  * @brief Returns whether the light casts shadows
289  * @details This returns whether the light casts shadows, the returned value
290  * is the one previously set with RPLight::set_casts_shadows.
291  *
292  * @return true if the light casts shadows, false otherwise
293  */
294 inline bool RPLight::get_casts_shadows() const {
295  return _casts_shadows;
296 }
297 
298 /**
299  * @brief Sets the lights shadow map resolution
300  * @details This sets the lights shadow map resolution. This has no effect
301  * when the light is not told to cast shadows (Use RPLight::set_casts_shadows).
302  *
303  * When calling this on a light with multiple shadow sources (e.g. PointLight),
304  * this controls the resolution of each source. If the light has 6 shadow sources,
305  * and you use a resolution of 512x512, the lights shadow map will occur a
306  * space of 6 * 512x512 maps in the shadow atlas.
307  *
308  * @param resolution Resolution of the shadow map in pixels
309  */
310 inline void RPLight::set_shadow_map_resolution(size_t resolution) {
311  nassertv(resolution >= 32 && resolution <= 16384);
312  _source_resolution = resolution;
314 }
315 
316 /**
317  * @brief Returns the shadow map resolution
318  * @details This returns the shadow map resolution of each source of the light.
319  * If the light is not setup to cast shadows, this value is meaningless.
320  * The returned value is the one previously set with RPLight::set_shadow_map_resolution.
321  *
322  * @return Shadow map resolution in pixels
323  */
324 inline size_t RPLight::get_shadow_map_resolution() const {
325  return _source_resolution;
326 }
327 
328 /**
329  * @brief Sets the ies profile
330  * @details This sets the ies profile of the light. The parameter should be a
331  * handle previously returned by RenderPipeline.load_ies_profile. Using a
332  * value of -1 indicates no ies profile.
333  *
334  * Notice that for ies profiles which cover a whole range, you should use
335  * PointLights, whereas for ies profiles which only cover the lower hemisphere
336  * you should use SpotLights for the best performance.
337  *
338  * @param profile IES Profile handle
339  */
340 inline void RPLight::set_ies_profile(int profile) {
341  _ies_profile = profile;
342  set_needs_update(true);
343 }
344 
345 /**
346  * @brief Returns the lights ies profile
347  * @details This returns the ies profile of a light, previously set with
348  * RPLight::set_ies_profile. In case no ies profile was set, returns -1.
349  *
350  * @return IES Profile handle
351  */
352 inline int RPLight::get_ies_profile() const {
353  return _ies_profile;
354 }
355 
356 /**
357  * @brief Returns whether the light has an ies profile assigned
358  * @details This returns whether the light has an ies profile assigned,
359  * previously done with RPLight::set_ies_profile.
360  *
361  * @return true if the light has an ies profile assigned, false otherwise
362  */
363 inline bool RPLight::has_ies_profile() const {
364  return _ies_profile >= 0;
365 }
366 
367 /**
368  * @brief Clears the ies profile
369  * @details This clears the ies profile of the light, telling it to no longer
370  * use an ies profile, and instead use the default attenuation.
371  */
372 inline void RPLight::clear_ies_profile() {
373  set_ies_profile(-1);
374 }
375 
376 /**
377  * @brief Sets the near plane of the light
378  * @details This sets the near plane of all shadow sources of the light. It has
379  * no effects if the light does not cast shadows. This prevents artifacts from
380  * objects near to the light. It behaves like Lens::set_near_plane.
381  *
382  * It can also help increasing shadow map precision, low near planes will
383  * cause the precision to suffer. Try setting the near plane as big as possible.
384  *
385  * If a negative or zero near plane is passed, an assertion is thrown.
386  *
387  * @param near_plane Near-plane
388  */
389 inline void RPLight::set_near_plane(float near_plane) {
390  nassertv(near_plane > 0.00001);
391  _near_plane = near_plane;
393 }
394 
395 /**
396  * @brief Returns the near plane of the light
397  * @details This returns the lights near plane, previously set with
398  * RPLight::set_near_plane. If the light does not cast shadows, this value
399  * is meaningless.
400  *
401  * @return Near-plane
402  */
403 inline float RPLight::get_near_plane() const {
404  return _near_plane;
405 }
406 
RenderPipeline.
Definition: shadowSource.h:51
get_ies_profile
Returns the lights ies profile.
Definition: rpLight.h:107
set_energy
Sets the energy of the light.
Definition: rpLight.h:89
get_light_type
Returns the type of the light.
Definition: rpLight.h:92
set_pos
Sets the position of the light.
Definition: rpLight.h:78
get_shadow_map_resolution
Returns the shadow map resolution.
Definition: rpLight.h:100
void invalidate_shadows()
Invalidates the shadows.
Definition: rpLight.I:153
void set_needs_update(bool flag)
Sets whether the light needs an update.
Definition: rpLight.I:80
set_casts_shadows
Controls whether the light casts shadows.
Definition: rpLight.h:96
set_ies_profile
Sets the ies profile.
Definition: rpLight.h:107
size_t get_num_shadow_sources() const
RenderPipeline.
Definition: rpLight.I:36
get_casts_shadows
Returns whether the light casts shadows.
Definition: rpLight.h:96
ShadowSource * get_shadow_source(size_t index) const
Returns the n-th shadow source.
Definition: rpLight.I:49
bool get_needs_update() const
Returns whether the light needs an update.
Definition: rpLight.I:94
set_near_plane
Sets the near plane of the light.
Definition: rpLight.h:111
set_color
Sets the lights color.
Definition: rpLight.h:83
set_shadow_map_resolution
Sets the lights shadow map resolution.
Definition: rpLight.h:100
get_energy
Returns the energy of the light.
Definition: rpLight.h:89
void clear_shadow_sources()
Clears all shadow source.
Definition: rpLight.I:60
get_color
Returns the lights color.
Definition: rpLight.h:83
bool has_slot() const
Returns whether the light has a slot.
Definition: rpLight.I:106
LightType
Different types of light.
Definition: rpLight.h:46
void remove_slot()
Removes the light slot.
Definition: rpLight.I:128
get_pos
Returns the position of the light.
Definition: rpLight.h:78
void assign_slot(int slot)
Assigns a slot to the light.
Definition: rpLight.I:140
int get_slot() const
Returns the slot of the light.
Definition: rpLight.I:118
has_ies_profile
Returns whether the light has an ies profile assigned.
Definition: rpLight.h:107
clear_ies_profile
Clears the ies profile.
Definition: rpLight.h:107
get_near_plane
Returns the near plane of the light.
Definition: rpLight.h:111