From 57138b5fb742487e6a73984525a05ffa3801bd90 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 29 May 2018 14:21:16 -0700 Subject: [PATCH] disable workload region regulation by default also set default region radiuses large --- interface/src/workload/GameWorkload.cpp | 110 ----------------- interface/src/workload/GameWorkload.h | 123 ------------------- libraries/workload/src/workload/View.h | 2 +- libraries/workload/src/workload/ViewTask.cpp | 47 ++++--- libraries/workload/src/workload/ViewTask.h | 48 +++++--- 5 files changed, 59 insertions(+), 271 deletions(-) diff --git a/interface/src/workload/GameWorkload.cpp b/interface/src/workload/GameWorkload.cpp index c609eb7bff..87bf093224 100644 --- a/interface/src/workload/GameWorkload.cpp +++ b/interface/src/workload/GameWorkload.cpp @@ -15,116 +15,6 @@ #include "PhysicsBoundary.h" -const glm::vec2 DEFAULT_R1_BACK_FRONT = { 50.0f, 100.0f }; -const glm::vec2 DEFAULT_R2_BACK_FRONT = { 75.0f, 150.0f }; -const glm::vec2 DEFAULT_R3_BACK_FRONT = { 100.0f, 250.0f }; - -ControlViews::ControlViews() { - regionBackFronts[0] = DEFAULT_R1_BACK_FRONT; - regionBackFronts[1] = DEFAULT_R2_BACK_FRONT; - regionBackFronts[2] = DEFAULT_R3_BACK_FRONT; - - const int32_t TIME_BUDGET_MSEC = 2; - const float MIN_BACK_FRONT_SCALE_FACTOR = 0.05f; - const float MAX_BACK_FRONT_SCALE_FACTOR = 2.0f; - const float MIN_NUM_STEPS_DOWN = 250.0f; - const float MIN_NUM_STEPS_UP = 375.0f; - - for (int32_t i = 0; i < workload::Region::NUM_VIEW_REGIONS; ++i) { - glm::vec2 minBackFront = MIN_BACK_FRONT_SCALE_FACTOR * regionBackFronts[i]; - glm::vec2 maxBackFront = MAX_BACK_FRONT_SCALE_FACTOR * regionBackFronts[i]; - glm::vec2 stepDown = (maxBackFront - minBackFront) / MIN_NUM_STEPS_DOWN; - glm::vec2 stepUp = (maxBackFront - minBackFront) / MIN_NUM_STEPS_UP; - regionRegulators[i] = Regulator(std::chrono::milliseconds(TIME_BUDGET_MSEC), minBackFront, maxBackFront, stepDown, stepUp); - } -} - -void ControlViews::configure(const Config& config) { - _data = config.data; -} - -void ControlViews::run(const workload::WorkloadContextPointer& runContext, const Input& inputs, Output& outputs) { - const auto& inViews = inputs.get0(); - const auto& inTimings = inputs.get1(); - auto& outViews = outputs; - outViews.clear(); - outViews = inViews; - - if (_data.regulateViewRanges && inTimings.size()) { - regulateViews(outViews, inTimings); - - auto config = std::static_pointer_cast(runContext->jobConfig); - config->dataExport = _dataExport; - config->emitDirty(); - } else { - for (auto& outView : outViews) { - outView.regionBackFronts[workload::Region::R1] = regionBackFronts[workload::Region::R1]; - outView.regionBackFronts[workload::Region::R2] = regionBackFronts[workload::Region::R2]; - outView.regionBackFronts[workload::Region::R3] = regionBackFronts[workload::Region::R3]; - workload::View::updateRegionsFromBackFronts(outView); - } - } -} - -glm::vec2 Regulator::run(const Timing_ns& regulationDuration, const Timing_ns& measured, const glm::vec2& current) { - // Regulate next value based on current moving toward the goal budget - float error_ms = std::chrono::duration(_budget - measured).count(); - float coef = error_ms / std::chrono::duration(regulationDuration).count(); - return current + coef * (error_ms < 0.0f ? _stepDown : _stepUp); -} - -glm::vec2 Regulator::clamp(const glm::vec2& backFront) const { - return glm::clamp(backFront, _minRange, _maxRange); -} - -void ControlViews::regulateViews(workload::Views& outViews, const workload::Timings& timings) { - - for (auto& outView : outViews) { - for (int32_t r = 0; r < workload::Region::NUM_VIEW_REGIONS; r++) { - outView.regionBackFronts[r] = regionBackFronts[r]; - } - } - - auto loopDuration = std::chrono::nanoseconds{ std::chrono::milliseconds(16) }; - regionBackFronts[workload::Region::R1] = regionRegulators[workload::Region::R1].run(loopDuration, timings[0], regionBackFronts[workload::Region::R1]); - regionBackFronts[workload::Region::R2] = regionRegulators[workload::Region::R2].run(loopDuration, timings[0], regionBackFronts[workload::Region::R2]); - regionBackFronts[workload::Region::R3] = regionRegulators[workload::Region::R3].run(loopDuration, timings[1], regionBackFronts[workload::Region::R3]); - - enforceRegionContainment(); - - _dataExport.ranges[workload::Region::R1] = regionBackFronts[workload::Region::R1]; - _dataExport.ranges[workload::Region::R2] = regionBackFronts[workload::Region::R2]; - _dataExport.ranges[workload::Region::R3] = regionBackFronts[workload::Region::R3]; - - _dataExport.timings[workload::Region::R1] = std::chrono::duration(timings[0]).count(); - _dataExport.timings[workload::Region::R2] = _dataExport.timings[workload::Region::R1]; - _dataExport.timings[workload::Region::R3] = std::chrono::duration(timings[1]).count(); - - for (auto& outView : outViews) { - outView.regionBackFronts[workload::Region::R1] = regionBackFronts[workload::Region::R1]; - outView.regionBackFronts[workload::Region::R2] = regionBackFronts[workload::Region::R2]; - outView.regionBackFronts[workload::Region::R3] = regionBackFronts[workload::Region::R3]; - - workload::View::updateRegionsFromBackFronts(outView); - } -} - -void ControlViews::enforceRegionContainment() { - // inner regions should never overreach outer - // and each region should never exceed its min/max limits - const glm::vec2 MIN_REGION_GAP = { 1.0f, 2.0f }; - // enforce outside --> in - for (int32_t i = workload::Region::NUM_VIEW_REGIONS - 2; i >= 0; --i) { - int32_t j = i + 1; - regionBackFronts[i] = regionRegulators[i].clamp(glm::min(regionBackFronts[i], regionBackFronts[j] - MIN_REGION_GAP)); - } - // enforce inside --> out - for (int32_t i = 1; i < workload::Region::NUM_VIEW_REGIONS; ++i) { - int32_t j = i - 1; - regionBackFronts[i] = regionRegulators[i].clamp(glm::max(regionBackFronts[i], regionBackFronts[j] + MIN_REGION_GAP)); - } -} - class WorkloadEngineBuilder { public: public: diff --git a/interface/src/workload/GameWorkload.h b/interface/src/workload/GameWorkload.h index 37cd0f4a2f..4b08be8a56 100644 --- a/interface/src/workload/GameWorkload.h +++ b/interface/src/workload/GameWorkload.h @@ -42,127 +42,4 @@ public: workload::EnginePointer _engine; }; - -class ControlViewsConfig : public workload::Job::Config { - Q_OBJECT - Q_PROPERTY(bool regulateViewRanges READ regulateViewRanges WRITE setRegulateViewRanges NOTIFY dirty) - - Q_PROPERTY(float r1Timing READ r1Timing NOTIFY dirty) - Q_PROPERTY(float r2Timing READ r2Timing NOTIFY dirty) - Q_PROPERTY(float r3Timing READ r3Timing NOTIFY dirty) - - Q_PROPERTY(float r1RangeBack READ r1RangeBack NOTIFY dirty) - Q_PROPERTY(float r2RangeBack READ r2RangeBack NOTIFY dirty) - Q_PROPERTY(float r3RangeBack READ r3RangeBack NOTIFY dirty) - - Q_PROPERTY(float r1RangeFront READ r1RangeFront NOTIFY dirty) - Q_PROPERTY(float r2RangeFront READ r2RangeFront NOTIFY dirty) - Q_PROPERTY(float r3RangeFront READ r3RangeFront NOTIFY dirty) -/* - Q_PROPERTY(float r1MinRangeBack READ r1MinRangeBack WRITE setR1MinRangeBack NOTIFY dirty) - Q_PROPERTY(float r2MinRangeBack READ r2MinRangeBack WRITE setR2MinRangeBack NOTIFY dirty) - Q_PROPERTY(float r3MinRangeBack READ r3MinRangeBack WRITE setR3MinRangeBack NOTIFY dirty) - - Q_PROPERTY(float r1MinRangeFront READ r1MinRangeFront WRITE setR1MinRangeFront NOTIFY dirty) - Q_PROPERTY(float r2MinRangeFront READ r2MinRangeFront WRITE setR2MinRangeFront NOTIFY dirty) - Q_PROPERTY(float r3MinRangeFront READ r3MinRangeFront WRITE setR3MinRangeFront NOTIFY dirty) - - Q_PROPERTY(float r1MaxRangeBack READ r1MaxRangeBack WRITE setR1MaxRangeBack NOTIFY dirty) - Q_PROPERTY(float r2MaxRangeBack READ r2MaxRangeBack WRITE setR2MaxRangeBack NOTIFY dirty) - Q_PROPERTY(float r3MaxRangeBack READ r3MaxRangeBack WRITE setR3MaxRangeBack NOTIFY dirty) - - Q_PROPERTY(float r1MaxRangeFront READ r1MaxRangeFront WRITE setR1MaxRangeFront NOTIFY dirty) - Q_PROPERTY(float r2MaxRangeFront READ r2MaxRangeFront WRITE setR2MaxRangeFront NOTIFY dirty) - Q_PROPERTY(float r3MaxRangeFront READ r3MaxRangeFront WRITE setR3MaxRangeFront NOTIFY dirty) - - Q_PROPERTY(float r1SpeedDownBack READ r1SpeedDownBack WRITE setR1SpeedDownBack NOTIFY dirty) - Q_PROPERTY(float r2SpeedDownBack READ r2SpeedDownBack WRITE setR2SpeedDownBack NOTIFY dirty) - Q_PROPERTY(float r3SpeedDownBack READ r3SpeedDownBack WRITE setR3SpeedDownBack NOTIFY dirty) - - Q_PROPERTY(float r1SpeedDownFront READ r1SpeedDownFront WRITE setR1SpeedDownFront NOTIFY dirty) - Q_PROPERTY(float r2SpeedDownFront READ r2SpeedDownFront WRITE setR2SpeedDownFront NOTIFY dirty) - Q_PROPERTY(float r3SpeedDownFront READ r3SpeedDownFront WRITE setR3SpeedDownFront NOTIFY dirty) - - Q_PROPERTY(float r1SpeedUpBack READ r1SpeedUpBack WRITE setR1SpeedUpBack NOTIFY dirty) - Q_PROPERTY(float r2SpeedUpBack READ r2SpeedUpBack WRITE setR2SpeedUpBack NOTIFY dirty) - Q_PROPERTY(float r3SpeedUpBack READ r3SpeedUpBack WRITE setR3SpeedUpBack NOTIFY dirty) - - Q_PROPERTY(float r1SpeedUpFront READ r1SpeedUpFront WRITE setR1SpeedUpFront NOTIFY dirty) - Q_PROPERTY(float r2SpeedUpFront READ r2SpeedUpFront WRITE setR2SpeedUpFront NOTIFY dirty) - Q_PROPERTY(float r3SpeedUpFront READ r3SpeedUpFront WRITE setR3SpeedUpFront NOTIFY dirty)*/ - -public: - - bool regulateViewRanges() const { return data.regulateViewRanges; } - void setRegulateViewRanges(bool use) { data.regulateViewRanges = use; emit dirty(); } - - float r1Timing() const { return dataExport.timings[workload::Region::R1]; } - float r2Timing() const { return dataExport.timings[workload::Region::R2]; } - float r3Timing() const { return dataExport.timings[workload::Region::R3]; } - - float r1RangeBack() const { return dataExport.ranges[workload::Region::R1].x; } - float r2RangeBack() const { return dataExport.ranges[workload::Region::R2].x; } - float r3RangeBack() const { return dataExport.ranges[workload::Region::R3].x; } - - float r1RangeFront() const { return dataExport.ranges[workload::Region::R1].y; } - float r2RangeFront() const { return dataExport.ranges[workload::Region::R2].y; } - float r3RangeFront() const { return dataExport.ranges[workload::Region::R3].y; } - - struct Data { - bool regulateViewRanges{ false }; - } data; - - struct DataExport { - static const int SIZE{ workload::Region::NUM_VIEW_REGIONS }; - float timings[SIZE]; - glm::vec2 ranges[SIZE]; - } dataExport; - - void emitDirty() { emit dirty(); } -signals: - void dirty(); -}; - -struct Regulator { - using Timing_ns = std::chrono::nanoseconds; - Timing_ns _budget{ std::chrono::milliseconds(2) }; - glm::vec2 _minRange{ 2.0f, 5.0f }; - glm::vec2 _maxRange{ 50.0f, 100.0f }; - - glm::vec2 _stepDown{ 0.2f }; - glm::vec2 _stepUp{ 0.1f }; - - - Regulator() {} - Regulator(const Timing_ns& budget_ns, const glm::vec2& minRange, const glm::vec2& maxRange, const glm::vec2& stepDown, const glm::vec2& speedUp) : - _budget(budget_ns), _minRange(minRange), _maxRange(maxRange), _stepDown(stepDown), _stepUp(speedUp) {} - - glm::vec2 run(const Timing_ns& regulationDuration, const Timing_ns& measured, const glm::vec2& current); - glm::vec2 clamp(const glm::vec2& backFront) const; -}; - -class ControlViews { -public: - using Config = ControlViewsConfig; - using Input = workload::VaryingSet2; - using Output = workload::Views; - using JobModel = workload::Job::ModelIO; - - ControlViews(); - - void configure(const Config& config); - void run(const workload::WorkloadContextPointer& runContext, const Input& inputs, Output& outputs); - - std::array regionBackFronts; - std::array regionRegulators; - - void regulateViews(workload::Views& views, const workload::Timings& timings); - -protected: - void enforceRegionContainment(); - - Config::Data _data; - Config::DataExport _dataExport; -}; - #endif // hifi_GameWorkload_h diff --git a/libraries/workload/src/workload/View.h b/libraries/workload/src/workload/View.h index fa60aaef29..972caf5101 100644 --- a/libraries/workload/src/workload/View.h +++ b/libraries/workload/src/workload/View.h @@ -41,7 +41,7 @@ public: // Fov stores the half field of view angle, and tan/cos/sin ready to go, default is fov of 90deg glm::vec4 fov_halfAngle_tan_cos_sin { glm::quarter_pi(), 1.0f, glm::root_two() * 0.5f, glm::root_two() * 0.5f}; - // Origin position + // Origin position glm::vec3 origin{ 0.0f }; // Origin radius diff --git a/libraries/workload/src/workload/ViewTask.cpp b/libraries/workload/src/workload/ViewTask.cpp index 4562f06aa9..4b77733c52 100644 --- a/libraries/workload/src/workload/ViewTask.cpp +++ b/libraries/workload/src/workload/ViewTask.cpp @@ -69,14 +69,11 @@ void SetupViews::run(const WorkloadContextPointer& renderContext, const Input& i } - ControlViews::ControlViews() { - regionBackFronts[0] = glm::vec2(1.0f, 3.0f); - regionBackFronts[1] = glm::vec2(1.0f, 5.0f); - regionBackFronts[2] = glm::vec2(1.0f, 10.0f); - regionRegulators[0] = Regulator(std::chrono::milliseconds(2), regionBackFronts[0], 5.0f * regionBackFronts[0], glm::vec2(0.4f, 0.2f), 0.5f * glm::vec2(0.3f, 0.2f)); - regionRegulators[1] = Regulator(std::chrono::milliseconds(2), regionBackFronts[1], 8.0f * regionBackFronts[1], glm::vec2(0.4f, 0.2f), 0.5f * glm::vec2(0.3f, 0.2f)); - regionRegulators[2] = Regulator(std::chrono::milliseconds(2), regionBackFronts[2], 10.0f * regionBackFronts[2], glm::vec2(0.4f, 0.2f), 0.5f * glm::vec2(0.3f, 0.2f)); + for (int32_t i = 0; i < workload::Region::NUM_VIEW_REGIONS; i++) { + regionBackFronts[i] = MIN_VIEW_BACK_FRONTS[i]; + regionRegulators[i] = Regulator(std::chrono::milliseconds(2), MIN_VIEW_BACK_FRONTS[i], MAX_VIEW_BACK_FRONTS[i], glm::vec2(RELATIVE_STEP_DOWN), glm::vec2(RELATIVE_STEP_UP)); + } } void ControlViews::configure(const Config& config) { @@ -107,14 +104,10 @@ void ControlViews::run(const workload::WorkloadContextPointer& runContext, const } glm::vec2 Regulator::run(const Timing_ns& regulationDuration, const Timing_ns& measured, const glm::vec2& current) { - glm::vec2 next = current; - // Regulate next value based on current moving toward the goal budget float error_ms = std::chrono::duration(_budget - measured).count(); - float coef = error_ms / std::chrono::duration(regulationDuration).count(); - next += coef * (error_ms < 0.0f ? _speedDown : _speedUp); - - return next; + float coef = glm::clamp(error_ms / std::chrono::duration(regulationDuration).count(), -1.0f, 1.0f); + return current * (1.0f + coef * (error_ms < 0.0f ? _relativeStepDown : _relativeStepUp)); } glm::vec2 Regulator::clamp(const glm::vec2& backFront) const { @@ -122,21 +115,21 @@ glm::vec2 Regulator::clamp(const glm::vec2& backFront) const { return glm::clamp(backFront, _minRange, _maxRange); } - void ControlViews::regulateViews(workload::Views& outViews, const workload::Timings& timings) { for (auto& outView : outViews) { - for (int r = 0; r < workload::Region::NUM_VIEW_REGIONS; r++) { + for (int32_t r = 0; r < workload::Region::NUM_VIEW_REGIONS; r++) { outView.regionBackFronts[r] = regionBackFronts[r]; } } auto loopDuration = std::chrono::nanoseconds{ std::chrono::milliseconds(16) }; - regionBackFronts[workload::Region::R1] = regionRegulators[workload::Region::R1].clamp(regionRegulators[workload::Region::R1].run(loopDuration, timings[0], regionBackFronts[workload::Region::R1])); - regionBackFronts[workload::Region::R2] = regionRegulators[workload::Region::R2].clamp(regionRegulators[workload::Region::R2].run(loopDuration, timings[0], regionBackFronts[workload::Region::R2])); - regionBackFronts[workload::Region::R3] = regionRegulators[workload::Region::R3].clamp(regionRegulators[workload::Region::R3].run(loopDuration, timings[1], regionBackFronts[workload::Region::R3])); + regionBackFronts[workload::Region::R1] = regionRegulators[workload::Region::R1].run(loopDuration, timings[0], regionBackFronts[workload::Region::R1]); + regionBackFronts[workload::Region::R2] = regionRegulators[workload::Region::R2].run(loopDuration, timings[0], regionBackFronts[workload::Region::R2]); + regionBackFronts[workload::Region::R3] = regionRegulators[workload::Region::R3].run(loopDuration, timings[1], regionBackFronts[workload::Region::R3]); + + enforceRegionContainment(); - // Export data config _dataExport.ranges[workload::Region::R1] = regionBackFronts[workload::Region::R1]; _dataExport.ranges[workload::Region::R2] = regionBackFronts[workload::Region::R2]; _dataExport.ranges[workload::Region::R3] = regionBackFronts[workload::Region::R3]; @@ -149,3 +142,19 @@ void ControlViews::regulateViews(workload::Views& outViews, const workload::Timi workload::View::updateRegionsFromBackFronts(outView); } } + +void ControlViews::enforceRegionContainment() { + // inner regions should never overreach outer + // and each region should never exceed its min/max limits + const glm::vec2 MIN_REGION_GAP = { 1.0f, 2.0f }; + // enforce outside --> in + for (int32_t i = workload::Region::NUM_VIEW_REGIONS - 2; i >= 0; --i) { + int32_t j = i + 1; + regionBackFronts[i] = regionRegulators[i].clamp(glm::min(regionBackFronts[i], regionBackFronts[j] - MIN_REGION_GAP)); + } + // enforce inside --> out + for (int32_t i = 1; i < workload::Region::NUM_VIEW_REGIONS; ++i) { + int32_t j = i - 1; + regionBackFronts[i] = regionRegulators[i].clamp(glm::max(regionBackFronts[i], regionBackFronts[j] + MIN_REGION_GAP)); + } +} diff --git a/libraries/workload/src/workload/ViewTask.h b/libraries/workload/src/workload/ViewTask.h index 93035503c7..867f22d534 100644 --- a/libraries/workload/src/workload/ViewTask.h +++ b/libraries/workload/src/workload/ViewTask.h @@ -24,9 +24,21 @@ QVariantList toVariantList(const QList &list) } namespace workload { - const glm::vec2 DEFAULT_R1_BACK_FRONT = { 50.0f, 100.0f }; - const glm::vec2 DEFAULT_R2_BACK_FRONT = { 75.0f, 150.0f }; - const glm::vec2 DEFAULT_R3_BACK_FRONT = { 100.0f, 250.0f }; + + const std::vector MIN_VIEW_BACK_FRONTS = { + { 3.0f, 4.0f }, + { 6.0f, 8.0f }, + { 9.0f, 12.0f } + }; + + const std::vector MAX_VIEW_BACK_FRONTS = { + { 100.0f, 200.0f }, + { 150.0f, 300.0f }, + { 250.0f, 500.0f } + }; + + const float RELATIVE_STEP_DOWN = 0.05f; + const float RELATIVE_STEP_UP = 0.04f; class SetupViewsConfig : public Job::Config{ Q_OBJECT @@ -44,7 +56,6 @@ namespace workload { public: - float getR1Front() const { return data.r1Front; } float getR1Back() const { return data.r1Back; } float getR2Front() const { return data.r2Front; } @@ -70,14 +81,14 @@ namespace workload { void setSimulateSecondaryCamera(bool use) { data.simulateSecondaryCamera = use; emit dirty(); } struct Data { - float r1Back { DEFAULT_R1_BACK_FRONT.x }; - float r1Front { DEFAULT_R1_BACK_FRONT.y }; + float r1Back { MAX_VIEW_BACK_FRONTS[0].x }; + float r1Front { MAX_VIEW_BACK_FRONTS[0].y }; - float r2Back{ DEFAULT_R2_BACK_FRONT.x }; - float r2Front{ DEFAULT_R2_BACK_FRONT.y }; + float r2Back{ MAX_VIEW_BACK_FRONTS[1].x }; + float r2Front{ MAX_VIEW_BACK_FRONTS[1].y }; - float r3Back{ DEFAULT_R3_BACK_FRONT.x }; - float r3Front{ DEFAULT_R3_BACK_FRONT.y }; + float r3Back{ MAX_VIEW_BACK_FRONTS[2].x }; + float r3Front{ MAX_VIEW_BACK_FRONTS[2].y }; bool freezeViews{ false }; bool useAvatarView{ false }; @@ -181,7 +192,7 @@ namespace workload { struct Data { - bool regulateViewRanges{ true }; + bool regulateViewRanges{ false }; } data; struct DataExport { @@ -203,16 +214,16 @@ namespace workload { struct Regulator { using Timing_ns = std::chrono::nanoseconds; Timing_ns _budget{ std::chrono::milliseconds(2) }; - glm::vec2 _minRange{ 2.0f, 5.0f }; - glm::vec2 _maxRange{ 50.0f, 100.0f }; + glm::vec2 _minRange{ MIN_VIEW_BACK_FRONTS[0] }; + glm::vec2 _maxRange{ MAX_VIEW_BACK_FRONTS[0] }; - glm::vec2 _speedDown{ 0.2f }; - glm::vec2 _speedUp{ 0.1f }; + glm::vec2 _relativeStepDown{ RELATIVE_STEP_DOWN }; + glm::vec2 _relativeStepUp{ RELATIVE_STEP_UP }; Regulator() {} - Regulator(const Timing_ns& budget_ns, const glm::vec2& minRange, const glm::vec2& maxRange, const glm::vec2& speedDown, const glm::vec2& speedUp) : - _budget(budget_ns), _minRange(minRange), _maxRange(maxRange), _speedDown(speedDown), _speedUp(speedUp) {} + Regulator(const Timing_ns& budget_ns, const glm::vec2& minRange, const glm::vec2& maxRange, const glm::vec2& relativeStepDown, const glm::vec2& relativeStepUp) : + _budget(budget_ns), _minRange(minRange), _maxRange(maxRange), _relativeStepDown(relativeStepDown), _relativeStepUp(relativeStepUp) {} glm::vec2 run(const Timing_ns& regulationDuration, const Timing_ns& measured, const glm::vec2& current); glm::vec2 clamp(const glm::vec2& backFront) const; @@ -234,6 +245,7 @@ namespace workload { std::array regionRegulators; void regulateViews(workload::Views& views, const workload::Timings& timings); + void enforceRegionContainment(); protected: Config::Data _data; @@ -242,4 +254,4 @@ namespace workload { } // namespace workload -#endif // hifi_workload_ViewTask_h \ No newline at end of file +#endif // hifi_workload_ViewTask_h