15 #include <vsg/maths/plane.h>
16 #include <vsg/maths/transform.h>
17 #include <vsg/nodes/MatrixTransform.h>
18 #include <vsg/state/PushConstants.h>
19 #include <vsg/vk/CommandBuffer.h>
28 #define POLYTOPE_SIZE 5
38 using Stack = std::stack<ref_ptr<const T>>;
50 inline void push(R* value)
59 dirty = !stack.empty();
61 size_t size()
const {
return stack.size(); }
62 const T* top()
const {
return stack.top(); }
68 stack.top()->record(commandBuffer);
82 matrixStack.emplace(
dmat4());
86 using value_type = double;
88 std::stack<dmat4> matrixStack;
92 inline void set(
const mat4& matrix)
95 matrixStack.emplace(matrix);
99 inline void set(
const dmat4& matrix)
102 matrixStack.emplace(matrix);
106 inline void push(
const mat4& matrix)
108 matrixStack.emplace(matrix);
111 inline void push(
const dmat4& matrix)
113 matrixStack.emplace(matrix);
116 inline void push(
const Transform& transform)
118 matrixStack.emplace(transform.transform(matrixStack.top()));
124 matrixStack.emplace(matrixStack.top() * transform.matrix);
128 const dmat4& top()
const {
return matrixStack.top(); }
140 auto pipeline = commandBuffer.getCurrentPipelineLayout();
141 auto stageFlags = commandBuffer.getCurrentPushConstantStageFlags();
144 if (pipeline == 0 || stageFlags == 0)
150 mat4 newmatrix(matrixStack.top());
151 vkCmdPushConstants(commandBuffer, pipeline, stageFlags, offset,
sizeof(newmatrix), newmatrix.data());
160 using value_type = MatrixStack::value_type;
163 Plane face[POLYTOPE_SIZE];
168 face[0].set(1.0, 0.0, 0.0, 1.0);
169 face[1].set(-1.0, 0.0, 0.0, 1.0);
170 face[2].set(0.0, -1.0, 0.0, 1.0);
171 face[3].set(0.0, 1.0, 0.0, 1.0);
172 if constexpr (POLYTOPE_SIZE >= 5) face[4].set(0.0, 0.0, 1.0, 0.0);
173 if constexpr (POLYTOPE_SIZE >= 6) face[5].set(0.0, 0.0, -1.0, 1.0);
179 face[0] = pt.face[0] * matrix;
180 face[1] = pt.face[1] * matrix;
181 face[2] = pt.face[2] * matrix;
182 face[3] = pt.face[3] * matrix;
183 if constexpr (POLYTOPE_SIZE >= 5) face[4] = pt.face[4] * matrix;
184 if constexpr (POLYTOPE_SIZE >= 6) face[5] = pt.face[5] * matrix;
188 void set(
const Frustum& pt,
const M& matrix)
190 face[0] = pt.face[0] * matrix;
191 face[1] = pt.face[1] * matrix;
192 face[2] = pt.face[2] * matrix;
193 face[3] = pt.face[3] * matrix;
194 if constexpr (POLYTOPE_SIZE >= 5) face[4] = pt.face[4] * matrix;
195 if constexpr (POLYTOPE_SIZE >= 6) face[5] = pt.face[5] * matrix;
199 void computeLodScale(
const M& proj,
const M& mv)
201 value_type f = -proj[1][1];
202 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;
203 value_type inv_scale = value_type(1.0) / sc;
204 lodScale.set(mv[0][2] * inv_scale,
205 mv[1][2] * inv_scale,
206 mv[2][2] * inv_scale,
207 mv[3][2] * inv_scale);
213 auto negative_radius = -s.radius;
214 if (distance(face[0], s.center) < negative_radius)
return false;
215 if (distance(face[1], s.center) < negative_radius)
return false;
216 if (distance(face[2], s.center) < negative_radius)
return false;
217 if (distance(face[3], s.center) < negative_radius)
return false;
218 if constexpr (POLYTOPE_SIZE >= 5)
219 if (distance(face[4], s.center) < negative_radius)
return false;
220 if constexpr (POLYTOPE_SIZE >= 6)
221 if (distance(face[5], s.center) < negative_radius)
return false;
230 explicit State(uint32_t maxSlot) :
232 stateStacks(maxSlot + 1)
236 using StateStacks = std::vector<StateStack<StateCommand>>;
243 using FrustumStack = std::stack<Frustum>;
244 FrustumStack _frustumStack;
248 bool inheritViewForLODScaling =
false;
249 dmat4 inheritedProjectionMatrix;
250 dmat4 inheritedViewMatrix;
251 dmat4 inheritedViewTransform;
253 StateStacks stateStacks;
258 void setInhertiedViewProjectionAndViewMatrix(
const dmat4& projMatrix,
const dmat4& viewMatrix)
260 inheritedProjectionMatrix = projMatrix;
261 inheritedViewMatrix = viewMatrix;
264 void setProjectionAndViewMatrix(
const dmat4& projMatrix,
const dmat4& viewMatrix)
266 projectionMatrixStack.set(projMatrix);
268 const auto& proj = projectionMatrixStack.top();
270 _frustumProjected.set(_frustumUnit, proj);
272 modelviewMatrixStack.set(viewMatrix);
275 while (!_frustumStack.empty()) _frustumStack.pop();
277 if (inheritViewForLODScaling)
279 inheritedViewTransform = inheritedViewMatrix * inverse(viewMatrix);
290 for (
auto& stateStack : stateStacks)
292 stateStack.record(*_commandBuffer);
295 projectionMatrixStack.record(*_commandBuffer);
296 modelviewMatrixStack.record(*_commandBuffer);
302 inline void pushFrustum()
304 _frustumStack.push(
Frustum(_frustumProjected, modelviewMatrixStack.top()));
305 if (inheritViewForLODScaling)
306 _frustumStack.top().computeLodScale(inheritedProjectionMatrix, inheritedViewTransform * modelviewMatrixStack.top());
308 _frustumStack.top().computeLodScale(projectionMatrixStack.top(), modelviewMatrixStack.top());
311 inline void applyFrustum()
313 _frustumStack.top().set(_frustumProjected, modelviewMatrixStack.top());
314 _frustumStack.top().computeLodScale(projectionMatrixStack.top(), modelviewMatrixStack.top());
317 inline void popFrustum()
325 return _frustumStack.top().intersect(s);
331 const auto& frustum = _frustumStack.top();
332 if (!frustum.intersect(s))
return -1.0;
334 const auto& lodScale = frustum.lodScale;
335 return std::abs(lodScale[0] * s.x + lodScale[1] * s.y + lodScale[2] * s.z + lodScale[3]);
CommandBuffer encapsulates VkCommandBuffer.
Definition: CommandBuffer.h:27
MatrixStack used internally by vsg::State to manage stack of projection or modelview matrices.
Definition: State.h:76
StateStack used internally by vsg::State to manage stack of vsg::StateCommand.
Definition: State.h:33
vsg::State is used by vsg::RecordTraversal to manage state stacks, projection and modelview matrices ...
Definition: State.h:228
Frustum used internally by vsg::State to manage view fustum culling during vsg::RecordTraversal.
Definition: State.h:159
template sphere class
Definition: sphere.h:34