ScummVM API documentation
angle.h
1/* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22#ifndef PHOENIXVR_ANGLE_H
23#define PHOENIXVR_ANGLE_H
24
25#include "common/util.h"
26#include "math/utils.h"
27#include "phoenixvr/math.h"
28
29namespace Common {
30class String;
31}
32
33namespace PhoenixVR {
34class Angle {
35protected:
36 float _angle;
37 float _min;
38 float _max;
39
40 float _rangeMin;
41 float _rangeMax;
42
43public:
44 Angle(float angle, float min, float max) : _min(min), _max(max) {
45 resetRange();
46 set(angle);
47 }
48
49 Angle &operator=(float angle) {
50 set(angle);
51 return *this;
52 }
53
54 float angle() const { return _angle; }
55
56 static float mod(float v, float min, float max) {
57 auto range = max - min;
58 auto a = fmod(v - min, range);
59 if (a < 0)
60 a += range;
61 return a + min;
62 }
63
64 float mod(float v) const {
65 return mod(v, _min, _max);
66 }
67
68 void set(float v) {
69 _angle = mod(v, _min, _max);
70 auto range = _max - _min;
71 auto min = _rangeMin, max = _rangeMax;
72 if (_angle >= min && _angle <= max)
73 return;
74 if (_angle >= min - range && _angle <= max - range)
75 return;
76 if (_angle >= min + range && _angle <= max + range)
77 return;
78
79 // out of bounds, find left or right
80 auto l0 = ABS(_angle - _rangeMin);
81 auto l1 = ABS(_angle - _rangeMin - range);
82 auto l = MIN(l0, l1);
83 auto r0 = ABS(_rangeMax - _angle);
84 auto r1 = ABS(range + _rangeMax - _angle);
85 auto r = MIN(r0, r1);
86 _angle = l < r ? _rangeMin : _rangeMax;
87 }
88
89 void add(float v) {
90 set(_angle + v);
91 }
92
93 float rangeMin() const {
94 return _rangeMin;
95 }
96
97 float rangeMax() const {
98 return _rangeMax;
99 }
100
101 void setRange(float min, float max) {
102 _rangeMin = min;
103 _rangeMax = max;
104 }
105
106 void resetRange() {
107 setRange(-INFINITY, INFINITY);
108 }
109};
110struct AngleX : Angle {
111 AngleX(float angle) : Angle(angle, 0, kTau) {}
112};
113
114struct AngleY : Angle {
115 AngleY(float angle) : Angle(angle, -kPi, -Math::epsilon) {
116 resetRange();
117 }
118 void setRange(float min, float max) {
119 static const float baseX = -kPi2;
120 Angle::setRange(baseX + min, baseX + max);
121 }
122 void resetRange() {
123 static constexpr auto defaultRange = kPi * 0.375f;
124 setRange(-defaultRange, defaultRange);
125 }
126 void add(float v) {
127 v += angle();
128 if (v <= _min)
129 v = _min + Math::epsilon;
130 if (v >= _max)
131 v = _max - Math::epsilon;
132 set(v);
133 }
134};
135} // namespace PhoenixVR
136
137#endif
Definition: angle.h:34
T ABS(T x)
Definition: util.h:60
T MIN(T a, T b)
Definition: util.h:63
Definition: algorithm.h:29
Definition: angle.h:110
Definition: angle.h:114