Panda3D
Loading...
Searching...
No Matches
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 */
36inline 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 */
49inline 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 */
80inline 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 */
94inline 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 */
106inline 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 */
118inline 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 */
128inline 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 */
140inline 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 */
166inline 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 */
178inline 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 */
190inline 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 */
206inline 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 */
220inline 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 */
232inline 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 */
243inline 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 */
255inline 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 */
279inline 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 */
294inline bool RPLight::get_casts_shadows() const {
295 return _casts_shadows;
296}
297
298/**
299 * @brief Sets the light's shadow map resolution
300 * @details This sets the light's 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.
304 * RPPointLight), this controls the resolution of each source. If the light
305 * has 6 shadow sources, and you use a resolution of 512x512, the light's
306 * shadow map will occupy a space of 6 * 512x512 maps in the shadow atlas.
307 *
308 * @param resolution Resolution of the shadow map in pixels
309 */
310inline 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 */
324inline 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 an
335 * RPPointLight, whereas for ies profiles which only cover the lower
336 * hemisphere you should use an RPSpotLight for the best performance.
337 *
338 * @param profile IES Profile handle
339 */
340inline void RPLight::set_ies_profile(int profile) {
341 _ies_profile = profile;
342 set_needs_update(true);
343}
344
345/**
346 * @brief Returns the light's 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 */
352inline 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 */
363inline 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 */
372inline 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().
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 */
389inline 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 light's 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 */
403inline float RPLight::get_near_plane() const {
404 return _near_plane;
405}
406
get_casts_shadows
Returns whether the light casts shadows.
Definition rpLight.h:96
get_energy
Returns the energy of the light.
Definition rpLight.h:89
void clear_shadow_sources()
Clears all shadow source.
Definition rpLight.I:60
ShadowSource * get_shadow_source(size_t index) const
Returns the n-th shadow source.
Definition rpLight.I:49
bool has_slot() const
Returns whether the light has a slot.
Definition rpLight.I:106
set_near_plane
Sets the near plane of the light.
Definition rpLight.h:111
clear_ies_profile
Clears the IES profile.
Definition rpLight.h:107
get_light_type
Returns the type of the light.
Definition rpLight.h:92
set_ies_profile
Sets the IES profile.
Definition rpLight.h:107
void assign_slot(int slot)
Assigns a slot to the light.
Definition rpLight.I:140
get_color
Returns the lights color.
Definition rpLight.h:83
size_t get_num_shadow_sources() const
RenderPipeline.
Definition rpLight.I:36
void invalidate_shadows()
Invalidates the shadows.
Definition rpLight.I:153
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
int get_slot() const
Returns the slot of the light.
Definition rpLight.I:118
get_near_plane
Returns the near plane of the light.
Definition rpLight.h:111
set_shadow_map_resolution
Sets the light's shadow map resolution.
Definition rpLight.h:100
get_pos
Returns the position of the light.
Definition rpLight.h:78
set_color
Sets the lights color.
Definition rpLight.h:83
get_ies_profile
Returns the light's IES profile.
Definition rpLight.h:107
has_ies_profile
Returns whether the light has an IES profile assigned.
Definition rpLight.h:107
set_energy
Sets the energy of the light.
Definition rpLight.h:89
set_casts_shadows
Controls whether the light casts shadows.
Definition rpLight.h:96
void remove_slot()
Removes the light slot.
Definition rpLight.I:128
LightType
Different types of light.
Definition rpLight.h:46
void set_needs_update(bool flag)
Sets whether the light needs an update.
Definition rpLight.I:80
bool get_needs_update() const
Returns whether the light needs an update.
Definition rpLight.I:94
RenderPipeline.