Panda3D
Loading...
Searching...
No Matches
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 */
38inline 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 */
49inline 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 */
61inline 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 */
73inline 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 */
88inline void ShadowSource::
89set_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 */
117inline 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 */
131inline 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 */
142inline 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 */
152inline 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 */
165inline 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 */
178inline 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 */
194inline 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 */
214inline 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 */
239inline 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}
This defines a bounding convex hexahedron.
This defines a bounding sphere, consisting of a center and a radius.
Class for storing data to be transferred to the GPU.
Definition gpuCommand.h:47
void push_vec4(const LVecBase4 &v)
Appends a 4-component floating point vector to the GPUCommand.
Definition gpuCommand.I:120
void push_mat4(const LMatrix4 &v)
Appends a floating point 4x4 matrix to the GPUCommand.
Definition gpuCommand.I:166
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
set_film_offset
Sets the horizontal and vertical offset amounts of this Lens.
Definition lens.h:87
void set_near_far(PN_stdfloat near_distance, PN_stdfloat far_distance)
Simultaneously changes the near and far planes.
Definition lens.I:419
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
A perspective-type lens: a normal camera.
size_t get_resolution() const
Returns the resolution of the source.
int get_slot() const
Returns the slot of the shadow source.
void set_resolution(size_t resolution)
Sets the resolution of the source.
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.
const LMatrix4 & get_mvp() const
Returns the View-Projection matrix of the source.
const LVecBase4i & get_region() const
Returns the assigned region of the source in atlas space.
bool has_region() const
Returns whether the source has a valid region.
const LVecBase4 & get_uv_region() const
Returns the assigned region of the source in UV space.
void set_slot(int slot)
Assigns the source a slot.
void set_region(const LVecBase4i &region, const LVecBase4 &region_uv)
Sets the assigned region of the source in atlas and uv space.
void write_to_command(GPUCommand &cmd) const
Writes the source to a GPUCommand.
const BoundingSphere & get_bounds() const
Returns the shadow sources bounds.
void clear_region()
Clears the assigned region of the source.
void set_needs_update(bool flag)
Sets the update flag of the source.
bool get_needs_update() const
RenderPipeline.
bool has_slot() const
Returns whether the source has a slot.
void set_matrix_lens(const LMatrix4 &mvp)
Sets a custom matrix for the source.