16 !
state.manualMouseCamLock && !
state.manualCameraRequested &&
17 !
state.mouseLeftPressed && !
state.mouseRightPressed &&
18 state.bssmCameraState==0 && !
state.diceCameraControlActive &&
19 !
state.desiredCameraInvalidatedLock && !
state.floatingCameraActive &&
29 !
state.manualMouseCamLock && !
state.manualCameraRequested &&
30 !
state.mouseLeftPressed && !
state.mouseRightPressed &&
31 state.bssmCameraState==0 && !
state.diceCameraControlActive &&
32 !
state.desiredCameraInvalidatedLock && !
state.floatingCameraActive &&
38 constexpr float Fov45 = 0.7853981633974483F;
39 constexpr std::array<engine::World3DCamera, 39>
Presets{{
40 engine::World3DCamera{{{242.9F, 1200.0F, 243.0F}}, {0.0045F, -0.99999F, 0.0F}, {1.0F, 0.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
41 engine::World3DCamera{{{-420.0F, 605.0F, 243.0F}}, {0.70710678F, -0.70710678F, 0.0F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
42 engine::World3DCamera{{{-370.0F, 645.0F, -370.0F}}, {0.54167522F, -0.64278761F, 0.54167522F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
43 engine::World3DCamera{{{-139.0F, 78.0F, 124.5F}}, {0.93358043F, -0.35836795F, 0.0F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
44 engine::World3DCamera{{{-139.0F, 78.0F, 243.0F}}, {0.93358043F, -0.35836795F, 0.0F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
45 engine::World3DCamera{{{-139.0F, 78.0F, 361.5F}}, {0.93358043F, -0.35836795F, 0.0F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
46 engine::World3DCamera{{{124.5F, 78.0F, 625.0F}}, {0.0F, -0.35836795F, -0.93358043F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
47 engine::World3DCamera{{{243.0F, 78.0F, 625.0F}}, {0.0F, -0.35836795F, -0.93358043F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
48 engine::World3DCamera{{{361.5F, 78.0F, 625.0F}}, {0.0F, -0.35836795F, -0.93358043F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
49 engine::World3DCamera{{{625.0F, 78.0F, 361.5F}}, {-0.93358043F, -0.35836795F, 0.0F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
50 engine::World3DCamera{{{625.0F, 78.0F, 243.0F}}, {-0.93358043F, -0.35836795F, 0.0F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
51 engine::World3DCamera{{{625.0F, 78.0F, 124.5F}}, {-0.93358043F, -0.35836795F, 0.0F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
52 engine::World3DCamera{{{361.5F, 78.0F, -139.0F}}, {0.0F, -0.35836795F, 0.93358043F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
53 engine::World3DCamera{{{243.0F, 78.0F, -139.0F}}, {0.0F, -0.35836795F, 0.93358043F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
54 engine::World3DCamera{{{124.5F, 78.0F, -139.0F}}, {0.0F, -0.35836795F, 0.93358043F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
55 engine::World3DCamera{{{-105.0F, 143.0F, -105.0F}}, {0.577096F, -0.577858F, 0.577096F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
56 engine::World3DCamera{{{-105.0F, 143.0F, 591.0F}}, {0.577096F, -0.577858F, -0.577096F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
57 engine::World3DCamera{{{591.0F, 143.0F, 591.0F}}, {-0.577096F, -0.577858F, -0.577096F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
58 engine::World3DCamera{{{591.0F, 143.0F, -105.0F}}, {-0.577096F, -0.577858F, 0.577096F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
59 engine::World3DCamera{{{-226.0F, 130.0F, 164.0F}}, {0.93358043F, -0.35836795F, 0.0F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
60 engine::World3DCamera{{{-226.0F, 130.0F, 322.0F}}, {0.93358043F, -0.35836795F, 0.0F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
61 engine::World3DCamera{{{164.0F, 130.0F, 712.0F}}, {0.0F, -0.35836795F, -0.93358043F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
62 engine::World3DCamera{{{322.0F, 130.0F, 712.0F}}, {0.0F, -0.35836795F, -0.93358043F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
63 engine::World3DCamera{{{712.0F, 130.0F, 322.0F}}, {-0.93358043F, -0.35836795F, 0.0F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
64 engine::World3DCamera{{{712.0F, 130.0F, 164.0F}}, {-0.93358043F, -0.35836795F, 0.0F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
65 engine::World3DCamera{{{322.0F, 130.0F, -226.0F}}, {0.0F, -0.35836795F, 0.93358043F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
66 engine::World3DCamera{{{164.0F, 130.0F, -226.0F}}, {0.0F, -0.35836795F, 0.93358043F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
67 engine::World3DCamera{{{-291.0F, 255.0F, -126.0F}}, {0.612372F, -0.5F, 0.612372F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
68 engine::World3DCamera{{{-280.0F, 285.0F, 337.0F}}, {0.81915204F, -0.57357644F, 0.0F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
69 engine::World3DCamera{{{-209.0F, 227.0F, 650.0F}}, {0.717968F, -0.5F, -0.484275F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
70 engine::World3DCamera{{{-126.0F, 255.0F, 777.0F}}, {0.612372F, -0.5F, -0.612372F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
71 engine::World3DCamera{{{337.0F, 285.0F, 766.0F}}, {0.0F, -0.57357644F, -0.81915204F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
72 engine::World3DCamera{{{650.0F, 227.0F, 695.0F}}, {-0.484275F, -0.5F, -0.717968F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
73 engine::World3DCamera{{{777.0F, 255.0F, 612.0F}}, {-0.612372F, -0.5F, -0.612372F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
74 engine::World3DCamera{{{766.0F, 285.0F, 149.0F}}, {-0.81915204F, -0.57357644F, 0.0F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
75 engine::World3DCamera{{{695.0F, 227.0F, -164.0F}}, {-0.717968F, -0.5F, 0.484275F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
76 engine::World3DCamera{{{612.0F, 255.0F, -291.0F}}, {-0.612372F, -0.5F, 0.612372F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
77 engine::World3DCamera{{{149.0F, 285.0F, -280.0F}}, {0.0F, -0.57357644F, 0.81915204F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
78 engine::World3DCamera{{{-164.0F, 227.0F, -209.0F}}, {0.484275F, -0.5F, 0.717968F}, {0.0F, 1.0F, 0.0F},
Fov45,
engine::MonopolyBoardNearPlane,
engine::MonopolyBoardFarPlane},
83 ratio = std::clamp(ratio, 0.0F, 1.0F);
84 constexpr float Pi = 3.14159265358979323846F;
86 return 0.5F - 0.5F * std::cos(ratio *
Pi);
87 return 0.5F + 0.5F * std::sin((ratio - 0.5F) *
Pi);
91 const std::array<float, 3>&
a,
const std::array<float, 3>&
b,
float t)
noexcept
93 return {
a[0] + (
b[0] -
a[0]) *
t,
94 a[1] + (
b[1] -
a[1]) *
t,
95 a[2] + (
b[2] -
a[2]) *
t};
99 const std::array<float, 3>&
p0,
100 const std::array<float, 3>&
p1,
101 const std::array<float, 3>&
p2,
102 const std::array<float, 3>&
p3,
float t)
noexcept
104 const float u = 1.0F -
t;
105 const float a = u * u * u;
106 const float b = 3.0F * u * u *
t;
107 const float c = 3.0F * u *
t *
t;
108 const float d =
t *
t *
t;
116 std::array<float, 3> v)
noexcept
118 const float length = std::sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
119 if (
length <= 0.00001F)
return {0.0F, 0.0F, 1.0F};
127 const auto index =
static_cast<std::size_t
>(view);
135 move_.start = current_;
136 move_.end = current_;
137 move_.startTick = tick;
138 move_.endTick = tick;
140 manualMouseActive_ =
false;
141 manualPresetRequested_ =
false;
145 std::uint64_t tick,
bool instant,
bool linear, std::uint64_t duration)
noexcept
147 move_.start = current_;
149 move_.startTick = tick;
150 move_.endTick =
instant ? tick : tick + duration;
152 move_.linear = linear;
153 move_.interruptible =
false;
154 move_.bezierPosition =
false;
160 engine::World3DCamera Controller::sample(
const Move& move,
161 std::uint64_t tick)
noexcept
163 if (!move.active || move.endTick == move.startTick)
return move.end;
164 const auto clamped = std::clamp(tick, move.startTick, move.endTick);
165 const float linear =
static_cast<float>(
clamped - move.startTick) /
166 static_cast<float>(move.endTick - move.startTick);
167 const float ratio = move.linear ? linear :
adjustedRatio(linear);
168 auto result = move.start;
169 result.location = move.bezierPosition ?
170 cubicBezier3(move.start.location, move.control1, move.control2,
171 move.end.location, ratio) :
172 lerp3(move.start.location, move.end.location, ratio);
173 result.forward =
lerp3(move.start.forward, move.end.forward, ratio);
174 result.up =
lerp3(move.start.up, move.end.up, ratio);
175 result.fieldOfView = move.start.fieldOfView +
176 (move.end.fieldOfView - move.start.fieldOfView) * ratio;
177 result.nearPlane = move.start.nearPlane +
178 (move.end.nearPlane - move.start.nearPlane) * ratio;
179 result.farPlane = move.start.farPlane +
180 (move.end.farPlane - move.start.farPlane) * ratio;
189 current_ = sample(move_, tick);
190 if (tick >= move_.endTick)
192 current_ = move_.end;
193 move_.active =
false;
194 update.completedMove =
true;
197 if (waiting_ && (!manualMouseActive_ || manualPresetRequested_) &&
198 (!move_.active || move_.interruptible))
200 const auto target = *waiting_;
202 if (manualPresetRequested_)
204 manualMouseActive_ =
false;
205 manualPresetRequested_ =
false;
207 startMove(
target, tick,
false);
208 update.startedWaitingMove =
true;
210 update.camera = current_;
221 manualPresetRequested_ =
false;
222 startMove(
target, tick,
true);
233 const auto base = endCamera();
234 const float ratioA = 0.30F +
242 -10.0F -
target.location[1], 243.0F -
target.location[2]});
243 target.up = {0.0F, 1.0F, 0.0F};
248 manualPresetRequested_ =
false;
252 std::uint64_t tick, std::uint64_t duration)
noexcept
255 manualPresetRequested_ =
false;
256 startMove(
preset(view), tick, duration == 0,
false, duration);
263 const auto anchor = current_;
264 manualPresetRequested_ =
false;
265 startMove(
anchor, tick,
false,
false, 100U);
266 move_.interruptible =
true;
267 move_.bezierPosition =
true;
276 std::int32_t deltaY,
bool verticalOrbit, std::uint64_t tick)
noexcept
278 if (!manualMouseActive_ && move_.active && !move_.interruptible)
return false;
280 constexpr float Pi = 3.14159265358979323846F;
281 constexpr std::array<float, 3> Center{243.0F, 10.0F, 243.0F};
282 auto target = manualMouseActive_ ? move_.end : current_;
284 auto relative = std::array<float, 3>{
285 target.location[0] - Center[0],
286 target.location[1] - Center[1],
287 target.location[2] - Center[2]};
292 if (deltaX > 40) deltaX = 50;
293 else if (deltaX < -40) deltaX = -50;
295 angle +=
static_cast<float>(deltaX) / 300.0F *
Pi;
301 target.location[1] - Center[1],
target.location[2] - Center[2]};
306 deltaY = std::clamp(deltaY, -50, 50);
318 deltaY = std::clamp(deltaY, -42, 42);
327 Center[1] -
target.location[1], Center[2] -
target.location[2]});
328 if (!manualMouseActive_)
330 manualMouseActive_ =
true;
332 manualPresetRequested_ =
false;
333 startMove(
target, tick,
false,
true);
335 else if (move_.active)
343 move_.startTick = tick;
344 move_.endTick = tick;
352 manualMouseActive_ =
false;
354 manualPresetRequested_ =
false;