Photon Engine 2.0.0-beta
A physically based renderer.
Loading...
Searching...
No Matches
SpiralScheduler.h
Go to the documentation of this file.
1#pragma once
2
4#include "Math/math.h"
5#include "Math/TVector2.h"
6
7#include <Common/assertion.h>
8
9#include <algorithm>
10#include <cmath>
11
12namespace ph
13{
14
21{
22public:
24
26 std::size_t numWorkers,
27 const WorkUnit& totalWorkUnit,
28 std::size_t tileSize);
29
31 std::size_t numWorkers,
32 const WorkUnit& totalWorkUnit,
33 const math::Vector2S& tileSize);
34
35private:
36 enum class EFacing
37 {
38 POSITIVE_X,
39 POSITIVE_Y,
40 NEGATIVE_X,
41 NEGATIVE_Y
42 };
43
44 math::TVector2<int64> m_headSize;
45 math::TVector2<int64> m_headPos;
46 EFacing m_headFacing;
47 std::size_t m_currentCycles;
48 std::size_t m_currentSteps;
49
50 void scheduleOne(WorkUnit* out_workUnit) override;
51};
52
53// In-header Implementations:
54
56
58
59 , m_headSize (0)
60 , m_headPos (0)
61 , m_headFacing (EFacing::POSITIVE_X)
62 , m_currentCycles(0)
63 , m_currentSteps (0)
64{}
65
67 const std::size_t numWorkers,
68 const WorkUnit& totalWorkUnit,
69 const std::size_t tileSize) :
70
72 numWorkers,
73 totalWorkUnit,
74 math::Vector2S(tileSize, tileSize))
75{}
76
78 const std::size_t numWorkers,
79 const WorkUnit& totalWorkUnit,
80 const math::Vector2S& tileSize) :
81
82 WorkScheduler(numWorkers, totalWorkUnit),
83
84 m_headSize (tileSize),
85 m_headPos (totalWorkUnit.getRegion().getCenter().sub(m_headSize / 2)),
86 m_headFacing (EFacing::POSITIVE_X),
87 m_currentCycles(0),
88 m_currentSteps (0)
89{}
90
91inline void SpiralScheduler::scheduleOne(WorkUnit* const out_workUnit)
92{
93 PH_ASSERT(out_workUnit);
94
95 Region headRegion(m_headPos, m_headPos.add(m_headSize));
96 headRegion.intersectWith(m_totalWorkUnit.getRegion());
97 if(headRegion.isArea())
98 {
99 *out_workUnit = WorkUnit(headRegion, m_totalWorkUnit.getDepth());
100 }
101 else
102 {
103 *out_workUnit = WorkUnit();
104 }
105
106 // prepare for next head region
107
108 const std::size_t maxSteps = m_currentCycles * 2;
109
110 ++m_currentSteps;
111 switch(m_headFacing)
112 {
113 // advancing to next cycle is only possible in this direction
114 case EFacing::POSITIVE_X:
115 m_headPos.x() += m_headSize.x();
116 if(m_currentSteps >= maxSteps)
117 {
118 m_headFacing = EFacing::POSITIVE_Y;
119 m_currentSteps = 0;
120 ++m_currentCycles;
121 }
122 break;
123
124 case EFacing::POSITIVE_Y:
125 if(m_currentSteps < maxSteps)
126 {
127 m_headPos.y() += m_headSize.y();
128 }
129 else
130 {
131 m_headPos.x() -= m_headSize.x();
132 m_headFacing = EFacing::NEGATIVE_X;
133 m_currentSteps = 0;
134 }
135 break;
136
137 case EFacing::NEGATIVE_X:
138 if(m_currentSteps < maxSteps)
139 {
140 m_headPos.x() -= m_headSize.x();
141 }
142 else
143 {
144 m_headPos.y() -= m_headSize.y();
145 m_headFacing = EFacing::NEGATIVE_Y;
146 m_currentSteps = 0;
147 }
148 break;
149
150 case EFacing::NEGATIVE_Y:
151 if(m_currentSteps < maxSteps)
152 {
153 m_headPos.y() -= m_headSize.y();
154 }
155 else
156 {
157 m_headPos.x() += m_headSize.x();
158 m_headFacing = EFacing::POSITIVE_X;
159 m_currentSteps = 0;
160 }
161 break;
162 }
163}
164
165}// end namespace ph
Definition SpiralScheduler.h:21
SpiralScheduler()
Definition SpiralScheduler.h:55
A manager that distributes a fixed amount of work to workers.
Definition WorkScheduler.h:21
WorkUnit m_totalWorkUnit
Definition WorkScheduler.h:55
Represents some amount of work.
Definition WorkUnit.h:17
Region getRegion() const
Definition WorkUnit.h:72
std::size_t getDepth() const
Definition WorkUnit.h:77
T & x()
Definition TVector2.ipp:38
T & y()
Definition TVector2.ipp:44
Derived add(const Derived &rhs) const
Definition TArithmeticArrayBase.ipp:26
Miscellaneous math utilities.
The root for all renderer implementations.
Definition EEngineProject.h:6