Panda3D
shadowSource.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 /**
30  * @brief Returns whether the shadow source needs an update.
31  * @details This returns the update flag, which was previously set with
32  * ShadowSource::set_needs_update. If the value is true, it means that the
33  * ShadowSource is invalid and should be regenerated. This can either be the
34  * case because the scene changed and affected the shadow source, or the light
35  * moved.
36  * @return Update-Flag
37  */
38 inline bool ShadowSource::get_needs_update() const {
39  return !has_region() || _needs_update;
40 }
41 
42 /**
43  * @brief Returns the slot of the shadow source.
44  * @details This returns the assigned slot of the ShadowSource, or -1 if no slot
45  * was assigned yet. You can check if a slot exists with ShadowSource::has_slot.
46  * The slot is the index of the ShadowSource in the global source buffer.
47  * @return Slot, or -1 to indicate no slot.
48  */
49 inline int ShadowSource::get_slot() const {
50  return _slot;
51 }
52 
53 /**
54  * @brief Returns whether the source has a slot.
55  * @details This returns whether the ShadowSource currently has an assigned slot.
56  * If the source has a slot assigned, this returns true, otherwise false. Cases
57  * where the source has no slot might be when the source just got attached, but
58  * never got rendered yet.
59  * @return [description]
60  */
61 inline bool ShadowSource::has_slot() const {
62  return _slot >= 0;
63 }
64 
65 /**
66  * @brief Assigns the source a slot
67  * @details This assigns a slot to the ShadowSource. This is called from the
68  * ShadowManager, when the source gets attached first time. This should not
69  * get called by the user.
70  *
71  * @param slot Slot of the source, or -1 to indicate no slot.
72  */
73 inline void ShadowSource::set_slot(int slot) {
74  _slot = slot;
75 }
76 
77 /**
78  * @brief Setups a perspective lens for the source.
79  * @details This makes the shadow source behave like a perspective lens. The
80  * parameters are similar to the ones of a PerspectiveLens.
81  *
82  * @param fov FoV of the lens
83  * @param near_plane The near plane of the lens, to avoid artifacts at low distance
84  * @param far_plane The far plane of the lens
85  * @param pos Position of the lens, in world space
86  * @param direction Direction (Orientation) of the lens
87  */
88 inline void ShadowSource::
89 set_perspective_lens(PN_stdfloat fov, PN_stdfloat near_plane,
90  PN_stdfloat far_plane, LVecBase3 pos,
91  LVecBase3 direction) {
92  // Construct the transfo*rmation matrix
93  LMatrix4 transform_mat = LMatrix4::translate_mat(-pos);
94 
95  // Construct a temporary lens to generate the lens matrix
96  PerspectiveLens temp_lens = PerspectiveLens(fov, fov);
97  temp_lens.set_film_offset(0, 0);
98  temp_lens.set_near_far(near_plane, far_plane);
99  temp_lens.set_view_vector(direction, LVector3::up());
100  set_matrix_lens(transform_mat * temp_lens.get_projection_mat());
101 
102  // Set new bounds, approximate with sphere
103  CPT(BoundingHexahedron) hexahedron = DCAST(BoundingHexahedron, temp_lens.make_bounds());
104  LPoint3 center = (hexahedron->get_min() + hexahedron->get_max()) * 0.5f;
105  _bounds = BoundingSphere(pos + center, (hexahedron->get_max() - center).length());
106 }
107 
108 /**
109  * @brief Sets a custom matrix for the source.
110  * @details This tells the source to use a custom matrix for rendering, just like
111  * the matrix lens. The matrix should include all transformations, rotations and
112  * scales. No other matrices will be used for rendering this shadow source (not
113  * even a coordinate system conversion).
114  *
115  * @param mvp Custom View-Projection matrix
116  */
117 inline void ShadowSource::set_matrix_lens(const LMatrix4& mvp) {
118  _mvp = mvp;
119  set_needs_update(true);
120 }
121 
122 /**
123  * @brief Sets the update flag of the source.
124  * @details Sets whether the source is still valid, or needs to get regenerated.
125  * Usually you only want to flag the shadow source as invalid, by passing
126  * true as the flag. However, the ShadowManager will set the flag to false
127  * after updating the source.
128  *
129  * @param flag The update flag
130  */
131 inline void ShadowSource::set_needs_update(bool flag) {
132  _needs_update = flag;
133 }
134 
135 /**
136  * @brief Returns whether the source has a valid region.
137  * @details This returns whether the ShadowSource has a valid shadow atlas region
138  * assigned. This might be not the case when the source never was rendered yet,
139  * or is about to get updated.
140  * @return true if the source has a valid region, else false.
141  */
142 inline bool ShadowSource::has_region() const {
143  return _region.get_x() >= 0 && _region.get_y() >= 0 && _region.get_z() >= 0 && _region.get_w() >= 0;
144 }
145 
146 /**
147  * @brief Returns the resolution of the source.
148  * @details Returns the shadow map resolution of source, in pixels. This is the
149  * space the source takes in the shadow atlas, in pixels.
150  * @return Resolution in pixels
151  */
152 inline size_t ShadowSource::get_resolution() const {
153  return _resolution;
154 }
155 
156 /**
157  * @brief Returns the assigned region of the source in atlas space.
158  * @details This returns the region of the source, in atlas space. This is the
159  * region set by ShadowSource::set_region. If no region was set yet, returns
160  * a 4-component integer vector with all components set to -1. To check this,
161  * you should call ShadowSource::has_region() first.
162  *
163  * @return [description]
164  */
165 inline const LVecBase4i& ShadowSource::get_region() const {
166  return _region;
167 }
168 
169 /**
170  * @brief Returns the assigned region of the source in UV space.
171  * @details This returns the region of the source, in UV space. This is the
172  * region set by ShadowSource::set_region. If no region was set yet, returns
173  * a 4-component integer vector with all components set to -1. To check this,
174  * you should call ShadowSource::has_region() first.
175  *
176  * @return [description]
177  */
178 inline const LVecBase4& ShadowSource::get_uv_region() const {
179  return _region_uv;
180 }
181 
182 /**
183  * @brief Sets the assigned region of the source in atlas and uv space.
184  * @details This sets the assigned region of the ShadowSource. The region in
185  * atlas space should be the region returned from the
186  * ShadowAtlas::find_and_reserve_region. The uv-region should be the same region,
187  * but in the 0 .. 1 range (can be converted with ShadowAtlas::region_to_uv).
188  * This is required for the shaders, because they expect coordinates in the
189  * 0 .. 1 range for sampling.
190  *
191  * @param region Atlas-Space region
192  * @param region_uv UV-Space region
193  */
194 inline void ShadowSource::set_region(const LVecBase4i& region, const LVecBase4& region_uv) {
195  _region = region;
196  _region_uv = region_uv;
197 }
198 
199 /**
200  * @brief Returns the View-Projection matrix of the source.
201  * @details This returns the current view-projection matrix of the ShadowSource.
202  * If no matrix was set yet, returns a matrix with all components zero.
203  * If a matrix was set with ShadowSource::set_matrix_lens, returns the matrix
204  * set by that function call.
205  *
206  * If a matrix was set with ShadowSource::set_perspective_lens, returns a
207  * perspective view-projection matrix setup by those parameters.
208  *
209  * The matrix returned is the matrix used for rendering the shadow map, and
210  * includes the camera transform as well as the projection matrix.
211  *
212  * @return View-Projection matrix.
213  */
214 inline const LMatrix4& ShadowSource::get_mvp() const {
215  return _mvp;
216 }
217 
218 /**
219  * @brief Writes the source to a GPUCommand.
220  * @details This writes the ShadowSource to a GPUCommand. This stores the
221  * mvp and the uv-region in the command.
222  *
223  * @param cmd GPUCommand to write to.
224  */
226  // When storing on the gpu, we should already have a valid slot
227  nassertv(_slot >= 0);
228  cmd.push_mat4(_mvp);
229  cmd.push_vec4(_region_uv);
230 }
231 
232 /**
233  * @brief Sets the resolution of the source.
234  * @details This sets the resolution of the ShadowSource, in pixels. It should be
235  * a multiple of the tile size of the ShadowAtlas, and greater than zero.
236  *
237  * @param resolution [description]
238  */
239 inline void ShadowSource::set_resolution(size_t resolution) {
240  nassertv(resolution > 0);
241  _resolution = resolution;
242  set_needs_update(true);
243 }
244 
245 /**
246  * @brief Returns the shadow sources bounds
247  * @details This returns the bounds of the shadow source, approximated as a sphere
248  * @return Bounds as a BoundingSphere
249  */
251  return _bounds;
252 }
253 
254 /**
255  * @brief Clears the assigned region of the source
256  * @details This unassigns any shadow atlas region from the source, previously
257  * set with set_region
258  */
260  _region.fill(-1);
261  _region_uv.fill(0);
262 }
void write_to_command(GPUCommand &cmd) const
Writes the source to a GPUCommand.
Definition: shadowSource.I:225
void set_needs_update(bool flag)
Sets the update flag of the source.
Definition: shadowSource.I:131
int get_slot() const
Returns the slot of the shadow source.
Definition: shadowSource.I:49
This defines a bounding sphere, consisting of a center and a radius.
void push_vec4(const LVecBase4 &v)
Appends a 4-component floating point vector to the GPUCommand.
Definition: gpuCommand.I:120
size_t get_resolution() const
Returns the resolution of the source.
Definition: shadowSource.I:152
const BoundingSphere & get_bounds() const
Returns the shadow sources bounds.
Definition: shadowSource.I:250
void set_slot(int slot)
Assigns the source a slot.
Definition: shadowSource.I:73
bool has_slot() const
Returns whether the source has a slot.
Definition: shadowSource.I:61
const LVecBase4i & get_region() const
Returns the assigned region of the source in atlas space.
Definition: shadowSource.I:165
void set_near_far(PN_stdfloat near_distance, PN_stdfloat far_distance)
Simultaneously changes the near and far planes.
Definition: lens.I:419
void set_perspective_lens(PN_stdfloat fov, PN_stdfloat near_plane, PN_stdfloat far_plane, LVecBase3 pos, LVecBase3 direction)
Setups a perspective lens for the source.
Definition: shadowSource.I:89
const LVecBase4 & get_uv_region() const
Returns the assigned region of the source in UV space.
Definition: shadowSource.I:178
void set_matrix_lens(const LMatrix4 &mvp)
Sets a custom matrix for the source.
Definition: shadowSource.I:117
bool get_needs_update() const
RenderPipeline.
Definition: shadowSource.I:38
void push_mat4(const LMatrix4 &v)
Appends a floating point 4x4 matrix to the GPUCommand.
Definition: gpuCommand.I:166
set_film_offset
Sets the horizontal and vertical offset amounts of this Lens.
Definition: lens.h:87
A perspective-type lens: a normal camera.
const LMatrix4 & get_projection_mat(StereoChannel channel=SC_mono) const
Returns the complete transformation matrix from a 3-d point in space to a point on the film,...
Definition: lens.I:563
bool has_region() const
Returns whether the source has a valid region.
Definition: shadowSource.I:142
void set_resolution(size_t resolution)
Sets the resolution of the source.
Definition: shadowSource.I:239
Class for storing data to be transferred to the GPU.
Definition: gpuCommand.h:47
void set_region(const LVecBase4i &region, const LVecBase4 &region_uv)
Sets the assigned region of the source in atlas and uv space.
Definition: shadowSource.I:194
void set_view_vector(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z, PN_stdfloat i, PN_stdfloat j, PN_stdfloat k)
Specifies the direction in which the lens is facing by giving an axis to look along,...
Definition: lens.I:442
This defines a bounding convex hexahedron.
const LMatrix4 & get_mvp() const
Returns the View-Projection matrix of the source.
Definition: shadowSource.I:214
void clear_region()
Clears the assigned region of the source.
Definition: shadowSource.I:259