91 explicit MatrixStack(uint32_t in_offset = 0) :
95 matrixStack.emplace(dmat4());
99 using value_type = double;
101 std::stack<dmat4> matrixStack;
105 MatrixStack& operator=(
const MatrixStack& rhs)
107 matrixStack = rhs.matrixStack;
114 inline void set(
const mat4& matrix)
117 matrixStack.emplace(matrix);
121 inline void set(
const dmat4& matrix)
124 matrixStack.emplace(matrix);
128 inline void push(
const mat4& matrix)
130 matrixStack.emplace(matrix);
133 inline void push(
const dmat4& matrix)
135 matrixStack.emplace(matrix);
138 inline void push(
const Transform& transform)
140 matrixStack.emplace(transform.transform(matrixStack.top()));
146 matrixStack.emplace(matrixStack.top() * transform.matrix);
150 const dmat4& top()
const {
return matrixStack.top(); }
162 auto pipeline = commandBuffer.getCurrentPipelineLayout();
163 auto stageFlags = commandBuffer.getCurrentPushConstantStageFlags();
166 if (pipeline == 0 || stageFlags == 0)
172 mat4 newmatrix(matrixStack.top());
173 vkCmdPushConstants(commandBuffer, pipeline, stageFlags, offset,
sizeof(newmatrix), newmatrix.data());
182 using value_type = MatrixStack::value_type;
185 Plane face[POLYTOPE_SIZE];
190 face[0].set(1.0, 0.0, 0.0, 1.0);
191 face[1].set(-1.0, 0.0, 0.0, 1.0);
192 face[2].set(0.0, -1.0, 0.0, 1.0);
193 face[3].set(0.0, 1.0, 0.0, 1.0);
194 if constexpr (POLYTOPE_SIZE >= 5) face[4].set(0.0, 0.0, 1.0, 0.0);
195 if constexpr (POLYTOPE_SIZE >= 6) face[5].set(0.0, 0.0, -1.0, 1.0);
199 Frustum(
const Frustum& pt,
const M& matrix)
201 face[0] = pt.face[0] * matrix;
202 face[1] = pt.face[1] * matrix;
203 face[2] = pt.face[2] * matrix;
204 face[3] = pt.face[3] * matrix;
205 if constexpr (POLYTOPE_SIZE >= 5) face[4] = pt.face[4] * matrix;
206 if constexpr (POLYTOPE_SIZE >= 6) face[5] = pt.face[5] * matrix;
210 void set(
const Frustum& pt,
const M& matrix)
212 face[0] = pt.face[0] * matrix;
213 face[1] = pt.face[1] * matrix;
214 face[2] = pt.face[2] * matrix;
215 face[3] = pt.face[3] * matrix;
216 if constexpr (POLYTOPE_SIZE >= 5) face[4] = pt.face[4] * matrix;
217 if constexpr (POLYTOPE_SIZE >= 6) face[5] = pt.face[5] * matrix;
221 void computeLodScale(
const M& proj,
const M& mv)
223 value_type f = -proj[1][1];
224 value_type sc = f * std::sqrt(square(mv[0][0]) + square(mv[1][0]) + square(mv[2][0]) + square(mv[0][1]) + square(mv[1][1]) + square(mv[2][1])) * 0.5;
225 value_type inv_scale = value_type(1.0) / sc;
226 lodScale.set(mv[0][2] * inv_scale,
227 mv[1][2] * inv_scale,
228 mv[2][2] * inv_scale,
229 mv[3][2] * inv_scale);
235 auto negative_radius = -s.radius;
236 if (distance(face[0], s.center) < negative_radius)
return false;
237 if (distance(face[1], s.center) < negative_radius)
return false;
238 if (distance(face[2], s.center) < negative_radius)
return false;
239 if (distance(face[3], s.center) < negative_radius)
return false;
240 if constexpr (POLYTOPE_SIZE >= 5)
241 if (distance(face[4], s.center) < negative_radius)
return false;
242 if constexpr (POLYTOPE_SIZE >= 6)
243 if (distance(face[5], s.center) < negative_radius)
return false;
249 class VSG_DECLSPEC State :
public Inherit<Object, State>
252 explicit State(
const Slots& in_maxSlots);
255 using StateStacks = std::vector<StateCommandStack>;
262 using FrustumStack = std::stack<Frustum>;
263 FrustumStack _frustumStack;
267 bool inheritViewForLODScaling =
false;
268 dmat4 inheritedProjectionMatrix;
269 dmat4 inheritedViewMatrix;
270 dmat4 inheritedViewTransform;
273 uint32_t activeMaxStateSlot = 0;
275 StateStacks stateStacks;
277 uint32_t viewportStateHint = 0;
282 void reserve(
const Slots& in_maxSlots);
290 INHERIT_STATE = (1 << 0),
291 INHERIT_VIEWPORT_STATE_HINT = (1 << 1),
292 INHERIT_VIEW_SETTINGS = (1 << 2),
293 INHERIT_MATRICES = (1 << 4),
294 INHERIT_ALL = INHERIT_STATE | INHERIT_VIEWPORT_STATE_HINT | INHERIT_VIEW_SETTINGS | INHERIT_MATRICES
297 InheritanceMask inheritanceMask = InheritanceMask::INHERIT_ALL;
299 void inherit(
const State& state);
301 inline void dirtyStateStacks()
304 for (
auto& stateStack : stateStacks)
310 void setInhertiedViewProjectionAndViewMatrix(
const dmat4& projMatrix,
const dmat4& viewMatrix)
312 inheritedProjectionMatrix = projMatrix;
313 inheritedViewMatrix = viewMatrix;
316 void setProjectionAndViewMatrix(
const dmat4& projMatrix,
const dmat4& viewMatrix)
318 projectionMatrixStack.set(projMatrix);
320 const auto& proj = projectionMatrixStack.top();
322 _frustumProjected.set(_frustumUnit, proj);
324 modelviewMatrixStack.set(viewMatrix);
327 while (!_frustumStack.empty()) _frustumStack.pop();
329 if (inheritViewForLODScaling)
331 inheritedViewTransform = inheritedViewMatrix * inverse(viewMatrix);
342 for (uint32_t slot = 0; slot <= activeMaxStateSlot; ++slot)
344 stateStacks[slot].record(*_commandBuffer);
348 activeMaxStateSlot = maxSlots.state;
350 projectionMatrixStack.record(*_commandBuffer);
351 modelviewMatrixStack.record(*_commandBuffer);
357 template<
typename Iterator>
358 inline void push(Iterator begin, Iterator end)
360 for (
auto itr = begin; itr != end; ++itr)
362 stateStacks[(*itr)->slot].push((*itr));
367 inline void push(
const StateCommands& commands)
369 push(commands.begin(), commands.end());
372 template<
typename Iterator>
373 inline void pop(Iterator begin, Iterator end)
375 for (
auto itr = begin; itr != end; ++itr)
377 stateStacks[(*itr)->slot].pop();
382 inline void pop(
const StateCommands& commands)
384 pop(commands.begin(), commands.end());
389 stateStacks[command->slot].push(command);
395 stateStacks[command->slot].pop();
403 void pushView(
const View& view);
405 void popView(
const View& view);
407 inline void pushFrustum()
409 _frustumStack.push(
Frustum(_frustumProjected, modelviewMatrixStack.top()));
410 if (inheritViewForLODScaling)
411 _frustumStack.top().computeLodScale(inheritedProjectionMatrix, inheritedViewTransform * modelviewMatrixStack.top());
413 _frustumStack.top().computeLodScale(projectionMatrixStack.top(), modelviewMatrixStack.top());
416 inline void applyFrustum()
418 _frustumStack.top().set(_frustumProjected, modelviewMatrixStack.top());
419 _frustumStack.top().computeLodScale(projectionMatrixStack.top(), modelviewMatrixStack.top());
422 inline void popFrustum()
430 return _frustumStack.top().intersect(s);
436 const auto& frustum = _frustumStack.top();
437 if (!frustum.intersect(s))
return -1.0;
439 const auto& lodScale = frustum.lodScale;
440 return std::abs(lodScale[0] * s.x + lodScale[1] * s.y + lodScale[2] * s.z + lodScale[3]);