11 #ifndef hifi_workload_ViewTask_h
12 #define hifi_workload_ViewTask_h
17 QVariantList toVariantList(
const QList<T> &list)
20 foreach(
const T &item, list)
28 const std::vector<glm::vec2> MIN_VIEW_BACK_FRONTS = {
34 const std::vector<glm::vec2> MAX_VIEW_BACK_FRONTS = {
40 const float RELATIVE_STEP_DOWN = 0.11f;
41 const float RELATIVE_STEP_UP = 0.09f;
43 class SetupViewsConfig :
public Job::Config{
45 Q_PROPERTY(
float r1Front READ getR1Front WRITE setR1Front NOTIFY dirty)
46 Q_PROPERTY(
float r1Back READ getR1Back WRITE setR1Back NOTIFY dirty)
47 Q_PROPERTY(
float r2Front READ getR2Front WRITE setR2Front NOTIFY dirty)
48 Q_PROPERTY(
float r2Back READ getR2Back WRITE setR2Back NOTIFY dirty)
49 Q_PROPERTY(
float r3Front READ getR3Front WRITE setR3Front NOTIFY dirty)
50 Q_PROPERTY(
float r3Back READ getR3Back WRITE setR3Back NOTIFY dirty)
51 Q_PROPERTY(
bool freezeViews READ getFreezeView WRITE setFreezeView NOTIFY dirty)
52 Q_PROPERTY(
bool useAvatarView READ useAvatarView WRITE setUseAvatarView NOTIFY dirty)
53 Q_PROPERTY(
bool forceViewHorizontal READ forceViewHorizontal WRITE setForceViewHorizontal NOTIFY dirty)
55 Q_PROPERTY(
bool simulateSecondaryCamera READ simulateSecondaryCamera WRITE setSimulateSecondaryCamera NOTIFY dirty)
59 float getR1Front()
const {
return data.r1Front; }
60 float getR1Back()
const {
return data.r1Back; }
61 float getR2Front()
const {
return data.r2Front; }
62 float getR2Back()
const {
return data.r2Back; }
63 float getR3Front()
const {
return data.r3Front; }
64 float getR3Back()
const {
return data.r3Back; }
66 void setR1Front(
float d) { data.r1Front = d; emit dirty(); }
67 void setR1Back(
float d) { data.r1Back = d; emit dirty(); }
68 void setR2Front(
float d) { data.r2Front = d; emit dirty(); }
69 void setR2Back(
float d) { data.r2Back = d; emit dirty(); }
70 void setR3Front(
float d) { data.r3Front = d; emit dirty(); }
71 void setR3Back(
float d) { data.r3Back = d; emit dirty(); }
73 bool getFreezeView()
const {
return data.freezeViews; }
74 void setFreezeView(
bool freeze) { data.freezeViews = freeze; emit dirty(); }
75 bool useAvatarView()
const {
return data.useAvatarView; }
76 void setUseAvatarView(
bool use) { data.useAvatarView = use; emit dirty(); }
77 bool forceViewHorizontal()
const {
return data.forceViewHorizontal; }
78 void setForceViewHorizontal(
bool use) { data.forceViewHorizontal = use; emit dirty(); }
80 bool simulateSecondaryCamera()
const {
return data.simulateSecondaryCamera; }
81 void setSimulateSecondaryCamera(
bool use) { data.simulateSecondaryCamera = use; emit dirty(); }
84 float r1Back { MAX_VIEW_BACK_FRONTS[0].x };
85 float r1Front { MAX_VIEW_BACK_FRONTS[0].y };
87 float r2Back{ MAX_VIEW_BACK_FRONTS[1].x };
88 float r2Front{ MAX_VIEW_BACK_FRONTS[1].y };
90 float r3Back{ MAX_VIEW_BACK_FRONTS[2].x };
91 float r3Front{ MAX_VIEW_BACK_FRONTS[2].y };
93 bool freezeViews{
false };
94 bool useAvatarView{
false };
95 bool forceViewHorizontal{
false };
96 bool simulateSecondaryCamera{
false };
105 using Config = SetupViewsConfig;
107 using Output = Views;
108 using JobModel = Job::ModelIO<SetupViews, Input, Output, Config>;
110 void configure(
const Config& config);
111 void run(
const workload::WorkloadContextPointer& renderContext,
const Input& inputs, Output& outputs);
118 class AssignSpaceViews {
121 using JobModel = Job::ModelI<AssignSpaceViews, Input>;
123 void run(
const workload::WorkloadContextPointer& renderContext,
const Input& inputs);
127 class ControlViewsConfig :
public workload::Job::Config {
129 Q_PROPERTY(
bool regulateViewRanges READ regulateViewRanges WRITE setRegulateViewRanges NOTIFY dirty)
132 Q_PROPERTY(
float r1Timing READ r1Timing NOTIFY dirty)
133 Q_PROPERTY(
float r2Timing READ r2Timing NOTIFY dirty)
134 Q_PROPERTY(
float r3Timing READ r3Timing NOTIFY dirty)
136 Q_PROPERTY(
float r1RangeBack READ r1RangeBack NOTIFY dirty)
137 Q_PROPERTY(
float r2RangeBack READ r2RangeBack NOTIFY dirty)
138 Q_PROPERTY(
float r3RangeBack READ r3RangeBack NOTIFY dirty)
140 Q_PROPERTY(
float r1RangeFront READ r1RangeFront NOTIFY dirty)
141 Q_PROPERTY(
float r2RangeFront READ r2RangeFront NOTIFY dirty)
142 Q_PROPERTY(
float r3RangeFront READ r3RangeFront NOTIFY dirty)
178 bool regulateViewRanges()
const {
return data.regulateViewRanges; }
179 void setRegulateViewRanges(
bool use) { data.regulateViewRanges = use; emit dirty(); }
181 float r1Timing()
const {
return dataExport.timings[workload::Region::R1]; }
182 float r2Timing()
const {
return dataExport.timings[workload::Region::R2]; }
183 float r3Timing()
const {
return dataExport.timings[workload::Region::R3]; }
185 float r1RangeBack()
const {
return dataExport.ranges[workload::Region::R1].x; }
186 float r2RangeBack()
const {
return dataExport.ranges[workload::Region::R2].x; }
187 float r3RangeBack()
const {
return dataExport.ranges[workload::Region::R3].x; }
189 float r1RangeFront()
const {
return dataExport.ranges[workload::Region::R1].y; }
190 float r2RangeFront()
const {
return dataExport.ranges[workload::Region::R2].y; }
191 float r3RangeFront()
const {
return dataExport.ranges[workload::Region::R3].y; }
195 bool regulateViewRanges{
true };
199 static const int SIZE{ workload::Region::NUM_TRACKED_REGIONS };
201 glm::vec2 ranges[SIZE];
202 QList<qreal> _timings { 6, 2.0 };
206 void emitDirty() { emit dirty(); }
209 Q_INVOKABLE QVariantList getTimings()
const {
return toVariantList(dataExport._timings); }
215 glm::vec2 _minRange{ MIN_VIEW_BACK_FRONTS[0] };
216 glm::vec2 _maxRange{ MAX_VIEW_BACK_FRONTS[0] };
217 glm::vec2 _relativeStepDown{ RELATIVE_STEP_DOWN };
218 glm::vec2 _relativeStepUp{ RELATIVE_STEP_UP };
219 Timing_ns _budget{ std::chrono::milliseconds(2) };
220 float _measuredTimeAverage { 0.0f };
221 float _measuredTimeNoiseSquared { 0.0f };
224 Regulator(
const Timing_ns& budget_ns,
225 const glm::vec2& minRange,
226 const glm::vec2& maxRange,
227 const glm::vec2& relativeStepDown,
228 const glm::vec2& relativeStepUp) :
231 _relativeStepDown(relativeStepDown),
232 _relativeStepUp(relativeStepUp),
234 _measuredTimeAverage(budget_ns.count()),
235 _measuredTimeNoiseSquared(0.0f)
238 void setBudget(
const Timing_ns& budget) { _budget = budget; }
239 glm::vec2 run(
const Timing_ns& deltaTime,
const Timing_ns& measuredTime,
const glm::vec2& currentFrontBack);
240 glm::vec2 clamp(
const glm::vec2& backFront)
const;
245 using Config = ControlViewsConfig;
246 using Input = workload::VaryingSet2<workload::Views, workload::Timings>;
247 using Output = workload::Views;
248 using JobModel = workload::Job::ModelIO<ControlViews, Input, Output, Config>;
252 void configure(
const Config& config);
253 void run(
const workload::WorkloadContextPointer& runContext,
const Input& inputs, Output& outputs);
255 std::array<glm::vec2, workload::Region::NUM_TRACKED_REGIONS> regionBackFronts;
256 std::array<Regulator, workload::Region::NUM_TRACKED_REGIONS> regionRegulators;
258 void regulateViews(workload::Views& views,
const workload::Timings& timings);
259 void enforceRegionContainment();
263 Config::DataExport _dataExport;