Divide Framework 0.1
A free and open-source 3D Framework under heavy development
Loading...
Searching...
No Matches
EnvironmentProbeComponent.cpp
Go to the documentation of this file.
1
2
5
7
18
19namespace Divide {
20
21namespace TypeUtil {
24 }
25
28 if (strcmp(name, EnvironmentProbeComponent::Names::updateType[i]) == 0) {
29 return static_cast<EnvironmentProbeComponent::UpdateType>(i);
30 }
31 }
32
34 }
35}
36
40{
41 Scene& parentScene = sgn->sceneGraph()->parentScene();
42
43 EditorComponentField layerField = {};
44 layerField._name = "RT Layer index";
45 layerField._data = &_rtLayerIndex;
47 layerField._readOnly = true;
48 layerField._serialise = false;
51
52 editorComponent().registerField(MOV(layerField));
53
54 EditorComponentField typeField = {};
55 typeField._name = "Is Local";
56 typeField._dataGetter = [this](void* dataOut) {
57 *static_cast<bool*>(dataOut) = _probeType == ProbeType::TYPE_LOCAL;
58 };
59 typeField._dataSetter = [this](const void* data) {
60 _probeType = *static_cast<const bool*>(data) ? ProbeType::TYPE_LOCAL : ProbeType::TYPE_INFINITE;
61 };
63 typeField._readOnly = false;
65
66 editorComponent().registerField(MOV(typeField));
67
68 EditorComponentField bbField = {};
69 bbField._name = "Bounding Box";
70 bbField._data = &_refaabb;
72 bbField._readOnly = false;
73 editorComponent().registerField(MOV(bbField));
74
75 EditorComponentField updateRateField = {};
76 updateRateField._name = "Update Rate";
77 updateRateField._tooltip = "[0...TARGET_FPS]. Every Nth frame. 0 = disabled;";
78 updateRateField._data = &_updateRate;
80 updateRateField._readOnly = false;
81 updateRateField._range = { 0.f, Config::TARGET_FRAME_RATE };
82 updateRateField._basicType = PushConstantType::UINT;
83 updateRateField._basicTypeSize = PushConstantSize::BYTE;
84
85 editorComponent().registerField(MOV(updateRateField));
86
87 EditorComponentField updateTypeField = {};
88 updateTypeField._name = "Update Type";
90 updateTypeField._readOnly = false;
91 updateTypeField._range = { 0u, to_U8(UpdateType::COUNT) };
92 updateTypeField._dataGetter = [this](void* dataOut) {
93 *static_cast<U8*>(dataOut) = to_U8(updateType());
94 };
95 updateTypeField._dataSetter = [this](const void* data) noexcept {
96 updateType(*static_cast<const UpdateType*>(data));
97 };
98 updateTypeField._displayNameGetter = [](const U8 index) noexcept {
99 return TypeUtil::EnvProveUpdateTypeToString(static_cast<UpdateType>(index));
100 };
101
102 editorComponent().registerField(MOV(updateTypeField));
103
104 EditorComponentField showBoxField = {};
105 showBoxField._name = "Show parallax correction AABB";
106 showBoxField._data = &_showParallaxAABB;
108 showBoxField._readOnly = false;
109 showBoxField._basicType = PushConstantType::BOOL;
110
111 editorComponent().registerField(MOV(showBoxField));
112
113 EditorComponentField updateProbeNowButton = {};
114 updateProbeNowButton._name = "Update Now";
115 updateProbeNowButton._type = EditorComponentFieldType::BUTTON;
116 updateProbeNowButton._readOnly = false; //disabled/enabled
117 editorComponent().registerField(MOV(updateProbeNowButton));
118
119 editorComponent().onChangedCbk([this](std::string_view field) {
120 if (field == "Update Now") {
121 dirty(true);
122 queueRefresh();
123 } else {
124 const vec3<F32> pos = _parentSGN->get<TransformComponent>()->getWorldPosition();
125 setBounds(_refaabb.getMin() + pos, _refaabb.getMax() + pos);
126 }
127 });
128
130 enabled(true);
131}
132
134{
135 Attorney::SceneEnvironmentProbeComponent::unregisterProbe(&_parentSGN->sceneGraph()->parentScene(), this);
136 enabled(false);
137}
138
140{
141 //If we are not a root-level probe. Avoid rendering our parent and children into the reflection
142 if (parentSGN()->parent() != nullptr)
143 {
144 SceneGraphNode* parent = parentSGN()->parent();
145 while (parent != nullptr)
146 {
147 if ( parent->getNode().type() != SceneNodeType::TYPE_TRANSFORM)
148 {
149 return parent;
150 }
151
152 // Keep walking up
153 parent = parent->parent();
154 }
155 }
156
157 return nullptr;
158}
159
161 if (!dirty() && updateType() == UpdateType::ON_DIRTY && _aabb.collision(sphere)) {
162 dirty(true);
163 }
164
165 return dirty();
166}
167
169 if (!dirty()) {
170 return false;
171 }
172 dirty(false);
173 _queueRefresh = false;
174
176
178 {
179 rtLayerIndex(SceneEnvironmentProbePool::AllocateSlice(false));
180 if ( rtLayerIndex() == Config::MAX_REFLECTIVE_PROBES_PER_PASS)
181 {
182 if constexpr ( Config::Build::IS_DEBUG_BUILD )
183 {
185 }
186
187 return false;
188 }
189 }
190
191 auto cmd = GFX::EnqueueCommand<GFX::BeginDebugScopeCommand>(bufferInOut);
192 Util::StringFormat( cmd->_scopeName, "EnvironmentProbePass Id: [ {} ]", rtLayerIndex() ),
193 cmd->_scopeId = rtLayerIndex();
194
195 RenderPassParams params
196 {
199 // Probes come after reflective nodes in buffer positions and array layers for management reasons (rate of update and so on)
200 ._stagePass =
201 {
202 ._stage = RenderStage::REFLECTION,
203 ._passType = RenderPassType::COUNT,
204 ._index = to_U16(rtLayerIndex() + Config::MAX_REFLECTIVE_NODES_IN_VIEW),
205 ._variant = static_cast<RenderStagePass::VariantType>(ReflectorType::CUBE)
206 },
207 };
208
209 params._targetDescriptorPrePass._drawMask[to_base( RTColourAttachmentSlot::SLOT_0 )] = false;
210 params._clearDescriptorPrePass[RT_DEPTH_ATTACHMENT_IDX] = DEFAULT_CLEAR_ENTRY;
211 params._targetDescriptorMainPass._drawMask[to_base( RTColourAttachmentSlot::SLOT_0 )] = true;
212 params._clearDescriptorMainPass[to_base( RTColourAttachmentSlot::SLOT_0 )] = { DefaultColours::BLUE, true };
213 params._drawMask &= ~(1u << to_base( RenderPassParams::Flags::DRAW_DYNAMIC_NODES ));
214 params._drawMask &= ~(1u << to_base( RenderPassParams::Flags::DRAW_TRANSLUCENT_NODES ));
215
216 _context.gfx().generateCubeMap(params,
217 rtLayerIndex(),
220 bufferInOut,
221 memCmdInOut);
222
223
224 GFX::EnqueueCommand<GFX::EndDebugScopeCommand>(bufferInOut);
225
227
229 return true;
230}
231
233{
234 return Parent::enabled();
235}
236
238{
239 Parent::enabled(state);
240 const auto& sceneData = _context.gfx().sceneData();
241 if (sceneData != nullptr)
242 {
243 sceneData->probeState(poolIndex(), state);
244 }
245}
246
248 const auto& sceneData = _context.gfx().sceneData();
249 sceneData->probeData(poolIndex(), _aabb.getCenter(), _aabb.getHalfExtent());
250}
251
252void EnvironmentProbeComponent::poolIndex(const U16 index) noexcept {
253 _poolIndex = index;
254 updateProbeData();
255}
256
257void EnvironmentProbeComponent::setBounds(const vec3<F32>& min, const vec3<F32>& max) noexcept {
258 _aabb.set(min, max);
259 updateProbeData();
260}
261
262void EnvironmentProbeComponent::setBounds(const vec3<F32>& center, const F32 radius) noexcept {
263 _aabb.createFromSphere(center, radius);
264 updateProbeData();
265}
266
268 if (updateType() == type){
269 return;
270 }
271
273 {
274 // Release slice if we switch to on-demand updates
276 }
277
278 _updateType = type;
279 if (type == UpdateType::ALWAYS)
280 {
281 const U16 newSlice = SceneEnvironmentProbePool::AllocateSlice(true);
283 {
284 rtLayerIndex(newSlice);
285 }
286 else
287 {
288 if constexpr (Config::Build::IS_DEBUG_BUILD)
289 {
291 }
292
293 // Failed to allocate a slice. Fallback to manual updates
295 }
296 }
297}
298
300 return _aabb.getCenter().distanceSquared(pos);
301}
302
305
307 const vec3<F32> pos = _parentSGN->get<TransformComponent>()->getWorldPosition();
308 setBounds(_refaabb.getMin() + pos, _refaabb.getMax() + pos);
310 const SceneGraphNode::Flags flag = static_cast<SceneGraphNode::Flags>(data._flag);
312 _drawImpostor = data._dataPair._first == 1u;
313 }
314 }
315}
316
317void EnvironmentProbeComponent::loadFromXML(const boost::property_tree::ptree& pt) {
320}
321
322} //namespace Divide
#define MOV(...)
#define DIVIDE_UNEXPECTED_CALL()
static void unregisterProbe(Scene *scene, const EnvironmentProbeComponent *const probe)
Definition: Scene.cpp:2419
static void registerProbe(Scene *scene, EnvironmentProbeComponent *probe)
Definition: Scene.cpp:2412
vec3< F32 > getCenter() const noexcept
const vec3< F32 > & getMax() const noexcept
const vec3< F32 > & getMin() const noexcept
vec3< F32 > getHalfExtent() const noexcept
bool checkCollisionAndQueueUpdate(const BoundingSphere &sphere) noexcept
Checks if the given bounding sphere has collided with the probe's AABB and if so, mark it for update ...
void OnData(const ECS::CustomEvent &data) override
void loadFromXML(const boost::property_tree::ptree &pt) override
bool refresh(GFX::CommandBuffer &bufferInOut, GFX::MemoryBarrierCommand &memCmdInOut)
Returns true if the probe was updated, false if skipped.
SceneGraphNode * findNodeToIgnore() const noexcept
EnvironmentProbeComponent(SceneGraphNode *sgn, PlatformContext &context)
F32 distanceSqTo(const vec3< F32 > &pos) const noexcept
void setBounds(const vec3< F32 > &min, const vec3< F32 > &max) noexcept
Utility class that adds basic GUID management to objects.
Definition: GUIDWrapper.h:44
ProjectManager & parent() noexcept
virtual void loadFromXML(const boost::property_tree::ptree &pt)
virtual void OnData(const ECS::CustomEvent &data)
Scene & parentScene() noexcept
static RenderTargetHandle ReflectionTarget() noexcept
static void UnlockSlice(U16 slice) noexcept
static void ProcessEnvironmentMap(U16 layerID, bool highPriority)
SceneGraph * sceneGraph() noexcept
Return a reference to the parent graph. Operator= should be disabled.
T length() const noexcept
return the vector's length
Definition: MathVectors.h:747
void get(T *v) const noexcept
constexpr bool IS_DEBUG_BUILD
Definition: config.h:55
constexpr U16 TARGET_FRAME_RATE
Application desired framerate for physics and input simulations.
Definition: config.h:97
constexpr U8 MAX_REFLECTIVE_NODES_IN_VIEW
Definition: config.h:135
constexpr U8 MAX_REFLECTIVE_PROBES_PER_PASS
Maximum number of environment probes we are allowed to update per frame.
Definition: config.h:141
EnvironmentProbeComponent::UpdateType StringToEnvProveUpdateType(const char *name) noexcept
const char * EnvProveUpdateTypeToString(const EnvironmentProbeComponent::UpdateType type) noexcept
Str StringFormat(const char *fmt, Args &&...args)
Handle console commands that start with a forward slash.
Definition: AIProcessor.cpp:7
static constexpr U32 RT_DEPTH_ATTACHMENT_IDX
Definition: RTAttachment.h:71
constexpr U16 to_U16(const T value)
uint8_t U8
Project & parent
Definition: DefaultScene.h:41
uint16_t U16
SGNComponent::Registrar< T, C > BaseComponentType
Definition: SGNComponent.h:207
constexpr U8 to_U8(const T value)
RTClearEntry DEFAULT_CLEAR_ENTRY
@ DROPDOWN_TYPE
Only U8 types supported!
constexpr auto to_base(const Type value) -> Type
DELEGATE_STD< void, void * > _dataGetter
DELEGATE_STD< void, const void * > _dataSetter
vec2< F32 > _range
Used by slider_type as a min / max range or dropdown as selected_index / count.
DELEGATE_STD< const char *, U8 > _displayNameGetter
EditorComponentFieldType _type
const SceneGraphNode * _sourceNode
RenderTargetID _targetID
Definition: RenderTarget.h:47
DataPair _dataPair
Definition: SGNComponent.h:77
Divide::U32 _flag
Definition: SGNComponent.h:67