-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathworld_state.cpp
91 lines (79 loc) · 2.34 KB
/
world_state.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include "world_state.h"
#include "PlaybackTracer.h"
#include "config.h"
#include "utils.h"
WorldState::WorldState(DbAlbumCollection& db) : db(db) {
pfc::string8 selected;
sessionSelectedCover.get(selected);
targetPos.key = selected.c_str();
centeredPos = targetPos;
}
const DBPos& WorldState::getTarget() {
return targetPos;
}
void WorldState::setTarget(DBPos target) {
targetPos = target;
if (!rendering) {
lastMovement = time() - 0.02;
rendering = true;
}
sessionSelectedCover.set(target.key.c_str());
}
void WorldState::update() {
if (db.empty())
return;
double currentTime = time();
if (isMoving()) {
float dist = db.difference(db.iterFromPos(targetPos).value(),
db.iterFromPos(centeredPos).value()) -
centeredOffset;
auto dTime = float(currentTime - lastMovement);
float speed = abs(targetDist2moveDist(dist));
if (lastSpeed < speed) {
float accel = (speed - lastSpeed) / dTime;
accel = sqrt(accel);
speed = lastSpeed + accel * dTime;
}
speed = std::max(0.1f, speed); // minimum speed
float moveDist = (dist > 0 ? 1.0f : -1.0f) * speed * dTime;
if (dTime > 1 || abs(moveDist) > abs(dist) || abs(moveDist - dist) < 0.001f) {
centeredPos = targetPos;
centeredOffset = 0.0f;
lastSpeed = 0.0f;
} else {
lastSpeed = speed;
int moveSteps = int(floor(moveDist));
centeredOffset += (moveDist - moveSteps);
if (centeredOffset >= 1.0f) {
centeredOffset -= 1.0f;
moveSteps += 1;
} else if (centeredOffset < 0.0f) {
centeredOffset += 1.0f;
moveSteps -= 1;
}
centeredPos = db.movePosBy(centeredPos, moveSteps);
}
}
if (!isMoving()) {
rendering = false;
}
lastMovement = currentTime;
}
float WorldState::targetDist2moveDist(float targetDist) {
bool goRight = (targetDist > 0.0f);
targetDist = abs(targetDist);
return (goRight ? 1 : -1) *
((0.1f * targetDist * targetDist) + (0.9f * targetDist) + 2.0f);
}
bool WorldState::isMoving() {
return (centeredPos != targetPos) || (centeredOffset != 0);
}
const DBPos& WorldState::getCenteredPos() const {
return centeredPos;
}
float WorldState::getCenteredOffset() const {
return centeredOffset;
}
void WorldState::hardSetCenteredPos(DBPos pos) {
centeredPos = std::move(pos);
}