Overte C++ Documentation
ViewTask.h
1 //
2 // ViewTask.h
3 // libraries/workload/src/workload
4 //
5 // Created by Sam Gateau 2018.03.05
6 // Copyright 2018 High Fidelity, Inc.
7 //
8 // Distributed under the Apache License, Version 2.0.
9 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
10 //
11 #ifndef hifi_workload_ViewTask_h
12 #define hifi_workload_ViewTask_h
13 
14 #include "Engine.h"
15 
16 template <typename T>
17 QVariantList toVariantList(const QList<T> &list)
18 {
19  QVariantList newList;
20  foreach(const T &item, list)
21  newList << item;
22 
23  return newList;
24 }
25 
26 namespace workload {
27 
28  const std::vector<glm::vec2> MIN_VIEW_BACK_FRONTS = {
29  { 3.0f, 4.0f },
30  { 6.0f, 8.0f },
31  { 9.0f, 12.0f }
32  };
33 
34  const std::vector<glm::vec2> MAX_VIEW_BACK_FRONTS = {
35  { 100.0f, 1600.0f },
36  { 150.0f, 10000.0f },
37  { 250.0f, 16000.0f }
38  };
39 
40  const float RELATIVE_STEP_DOWN = 0.11f;
41  const float RELATIVE_STEP_UP = 0.09f;
42 
43  class SetupViewsConfig : public Job::Config{
44  Q_OBJECT
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)
54 
55  Q_PROPERTY(bool simulateSecondaryCamera READ simulateSecondaryCamera WRITE setSimulateSecondaryCamera NOTIFY dirty)
56 
57  public:
58 
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; }
65 
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(); }
72 
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(); }
79 
80  bool simulateSecondaryCamera() const { return data.simulateSecondaryCamera; }
81  void setSimulateSecondaryCamera(bool use) { data.simulateSecondaryCamera = use; emit dirty(); }
82 
83  struct Data {
84  float r1Back { MAX_VIEW_BACK_FRONTS[0].x };
85  float r1Front { MAX_VIEW_BACK_FRONTS[0].y };
86 
87  float r2Back{ MAX_VIEW_BACK_FRONTS[1].x };
88  float r2Front{ MAX_VIEW_BACK_FRONTS[1].y };
89 
90  float r3Back{ MAX_VIEW_BACK_FRONTS[2].x };
91  float r3Front{ MAX_VIEW_BACK_FRONTS[2].y };
92 
93  bool freezeViews{ false };
94  bool useAvatarView{ false };
95  bool forceViewHorizontal{ false };
96  bool simulateSecondaryCamera{ false };
97  } data;
98 
99  signals:
100  void dirty();
101  };
102 
103  class SetupViews {
104  public:
105  using Config = SetupViewsConfig;
106  using Input = Views;
107  using Output = Views;
108  using JobModel = Job::ModelIO<SetupViews, Input, Output, Config>;
109 
110  void configure(const Config& config);
111  void run(const workload::WorkloadContextPointer& renderContext, const Input& inputs, Output& outputs);
112 
113  protected:
114  Config::Data data;
115  Views _views;
116  };
117 
118  class AssignSpaceViews {
119  public:
120  using Input = Views;
121  using JobModel = Job::ModelI<AssignSpaceViews, Input>;
122 
123  void run(const workload::WorkloadContextPointer& renderContext, const Input& inputs);
124  };
125 
126 
127  class ControlViewsConfig : public workload::Job::Config {
128  Q_OBJECT
129  Q_PROPERTY(bool regulateViewRanges READ regulateViewRanges WRITE setRegulateViewRanges NOTIFY dirty)
130 
131 
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)
135 
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)
139 
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)
143  /*
144  Q_PROPERTY(float r1MinRangeBack READ r1MinRangeBack WRITE setR1MinRangeBack NOTIFY dirty)
145  Q_PROPERTY(float r2MinRangeBack READ r2MinRangeBack WRITE setR2MinRangeBack NOTIFY dirty)
146  Q_PROPERTY(float r3MinRangeBack READ r3MinRangeBack WRITE setR3MinRangeBack NOTIFY dirty)
147 
148  Q_PROPERTY(float r1MinRangeFront READ r1MinRangeFront WRITE setR1MinRangeFront NOTIFY dirty)
149  Q_PROPERTY(float r2MinRangeFront READ r2MinRangeFront WRITE setR2MinRangeFront NOTIFY dirty)
150  Q_PROPERTY(float r3MinRangeFront READ r3MinRangeFront WRITE setR3MinRangeFront NOTIFY dirty)
151 
152  Q_PROPERTY(float r1MaxRangeBack READ r1MaxRangeBack WRITE setR1MaxRangeBack NOTIFY dirty)
153  Q_PROPERTY(float r2MaxRangeBack READ r2MaxRangeBack WRITE setR2MaxRangeBack NOTIFY dirty)
154  Q_PROPERTY(float r3MaxRangeBack READ r3MaxRangeBack WRITE setR3MaxRangeBack NOTIFY dirty)
155 
156  Q_PROPERTY(float r1MaxRangeFront READ r1MaxRangeFront WRITE setR1MaxRangeFront NOTIFY dirty)
157  Q_PROPERTY(float r2MaxRangeFront READ r2MaxRangeFront WRITE setR2MaxRangeFront NOTIFY dirty)
158  Q_PROPERTY(float r3MaxRangeFront READ r3MaxRangeFront WRITE setR3MaxRangeFront NOTIFY dirty)
159 
160  Q_PROPERTY(float r1SpeedDownBack READ r1SpeedDownBack WRITE setR1SpeedDownBack NOTIFY dirty)
161  Q_PROPERTY(float r2SpeedDownBack READ r2SpeedDownBack WRITE setR2SpeedDownBack NOTIFY dirty)
162  Q_PROPERTY(float r3SpeedDownBack READ r3SpeedDownBack WRITE setR3SpeedDownBack NOTIFY dirty)
163 
164  Q_PROPERTY(float r1SpeedDownFront READ r1SpeedDownFront WRITE setR1SpeedDownFront NOTIFY dirty)
165  Q_PROPERTY(float r2SpeedDownFront READ r2SpeedDownFront WRITE setR2SpeedDownFront NOTIFY dirty)
166  Q_PROPERTY(float r3SpeedDownFront READ r3SpeedDownFront WRITE setR3SpeedDownFront NOTIFY dirty)
167 
168  Q_PROPERTY(float r1SpeedUpBack READ r1SpeedUpBack WRITE setR1SpeedUpBack NOTIFY dirty)
169  Q_PROPERTY(float r2SpeedUpBack READ r2SpeedUpBack WRITE setR2SpeedUpBack NOTIFY dirty)
170  Q_PROPERTY(float r3SpeedUpBack READ r3SpeedUpBack WRITE setR3SpeedUpBack NOTIFY dirty)
171 
172  Q_PROPERTY(float r1SpeedUpFront READ r1SpeedUpFront WRITE setR1SpeedUpFront NOTIFY dirty)
173  Q_PROPERTY(float r2SpeedUpFront READ r2SpeedUpFront WRITE setR2SpeedUpFront NOTIFY dirty)
174  Q_PROPERTY(float r3SpeedUpFront READ r3SpeedUpFront WRITE setR3SpeedUpFront NOTIFY dirty)*/
175 
176  public:
177 
178  bool regulateViewRanges() const { return data.regulateViewRanges; }
179  void setRegulateViewRanges(bool use) { data.regulateViewRanges = use; emit dirty(); }
180 
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]; }
184 
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; }
188 
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; }
192 
193 
194  struct Data {
195  bool regulateViewRanges{ true }; // regulation is ON by default
196  } data;
197 
198  struct DataExport {
199  static const int SIZE{ workload::Region::NUM_TRACKED_REGIONS };
200  float timings[SIZE];
201  glm::vec2 ranges[SIZE];
202  QList<qreal> _timings { 6, 2.0 };
203 
204  } dataExport;
205 
206  void emitDirty() { emit dirty(); }
207 
208  public slots:
209  Q_INVOKABLE QVariantList getTimings() const { return toVariantList(dataExport._timings); }
210  signals:
211  void dirty();
212  };
213 
214  struct Regulator {
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 };
222 
223  Regulator() {}
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) :
229  _minRange(minRange),
230  _maxRange(maxRange),
231  _relativeStepDown(relativeStepDown),
232  _relativeStepUp(relativeStepUp),
233  _budget(budget_ns),
234  _measuredTimeAverage(budget_ns.count()),
235  _measuredTimeNoiseSquared(0.0f)
236  {}
237 
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;
241  };
242 
243  class ControlViews {
244  public:
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>;
249 
250  ControlViews();
251 
252  void configure(const Config& config);
253  void run(const workload::WorkloadContextPointer& runContext, const Input& inputs, Output& outputs);
254 
255  std::array<glm::vec2, workload::Region::NUM_TRACKED_REGIONS> regionBackFronts;
256  std::array<Regulator, workload::Region::NUM_TRACKED_REGIONS> regionRegulators;
257 
258  void regulateViews(workload::Views& views, const workload::Timings& timings);
259  void enforceRegionContainment();
260 
261  protected:
262  Config::Data _data;
263  Config::DataExport _dataExport;
264  };
265 
266 } // namespace workload
267 
268 #endif // hifi_workload_ViewTask_h