MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ from() [2/3]

static Scissor MayaFlux::Kinesis::Scissor::from ( const AABB3D &  world_bounds,
const ViewTransform &  view 
)
inlinestaticnoexcept

Project a world-space AABB3D through a ViewTransform and take the NDC bounding box of its projected corners.

Projects all 8 corners through projection * view, divides by clip-space w, and takes the min/max of the resulting NDC x/y, clamped to [-1,1]. A corner behind the eye (w <= 0) is skipped rather than let it fold the bounding box onto itself, so an object crossing the near plane still resolves from whichever corners are in front of the camera. A box with no corner in front of the camera at all returns the full-screen Scissor: there is nothing visible to clip to, and the caller almost certainly should not be drawing it this frame regardless of what the scissor rect says.

Definition at line 63 of file Scissor.hpp.

64 {
65 const glm::mat4 view_projection = view.projection * view.view;
66
67 glm::vec2 lo { 1.F, 1.F };
68 glm::vec2 hi { -1.F, -1.F };
69 bool any_in_front = false;
70
71 for (int i = 0; i < 8; ++i) {
72 const glm::vec3 corner {
73 (i & 1) ? world_bounds.max.x : world_bounds.min.x,
74 (i & 2) ? world_bounds.max.y : world_bounds.min.y,
75 (i & 4) ? world_bounds.max.z : world_bounds.min.z,
76 };
77
78 const glm::vec4 clip = view_projection * glm::vec4(corner, 1.F);
79 if (clip.w <= 0.F)
80 continue;
81
82 const glm::vec2 ndc { clip.x / clip.w, clip.y / clip.w };
83 lo = glm::min(lo, ndc);
84 hi = glm::max(hi, ndc);
85 any_in_front = true;
86 }
87
88 if (!any_in_front)
89 return {};
90
91 return { .bounds = {
92 .min = glm::clamp(lo, glm::vec2(-1.F), glm::vec2(1.F)),
93 .max = glm::clamp(hi, glm::vec2(-1.F), glm::vec2(1.F)),
94 } };
95 }
glm::ivec3 min
glm::ivec3 max