Line data Source code
1 : /* Copyright (C) 2022 Wildfire Games.
2 : * This file is part of 0 A.D.
3 : *
4 : * 0 A.D. is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 2 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * 0 A.D. is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16 : */
17 :
18 : #ifndef INCLUDED_VECTOR2D
19 : #define INCLUDED_VECTOR2D
20 :
21 : #include "ps/containers/Span.h"
22 :
23 : #include <math.h>
24 :
25 : class CSize2D;
26 :
27 : /*
28 : * Provides an interface for a vector in R2 and allows vector and
29 : * scalar operations on it.
30 : */
31 : class CVector2D
32 : {
33 : public:
34 2265 : CVector2D() : X(0.0f), Y(0.0f) {}
35 1749 : CVector2D(float x, float y) : X(x), Y(y) {}
36 : CVector2D(const CSize2D& size);
37 :
38 : operator float*()
39 : {
40 : return &X;
41 : }
42 :
43 : operator const float*() const
44 : {
45 : return &X;
46 : }
47 :
48 : bool operator==(const CVector2D& v) const;
49 : bool operator!=(const CVector2D& v) const;
50 :
51 : CVector2D operator-() const
52 : {
53 : return CVector2D(-X, -Y);
54 : }
55 :
56 112 : CVector2D operator+(const CVector2D& t) const
57 : {
58 112 : return CVector2D(X + t.X, Y + t.Y);
59 : }
60 :
61 0 : CVector2D operator-(const CVector2D& t) const
62 : {
63 0 : return CVector2D(X - t.X, Y - t.Y);
64 : }
65 :
66 112 : CVector2D operator*(float f) const
67 : {
68 112 : return CVector2D(X * f, Y * f);
69 : }
70 :
71 0 : CVector2D operator/(float f) const
72 : {
73 0 : float inv = 1.0f / f;
74 0 : return CVector2D(X * inv, Y * inv);
75 : }
76 :
77 0 : CVector2D& operator+=(const CVector2D& t)
78 : {
79 0 : X += t.X;
80 0 : Y += t.Y;
81 0 : return *this;
82 : }
83 :
84 0 : CVector2D& operator-=(const CVector2D& t)
85 : {
86 0 : X -= t.X;
87 0 : Y -= t.Y;
88 0 : return *this;
89 : }
90 :
91 : CVector2D& operator*=(float f)
92 : {
93 : X *= f;
94 : Y *= f;
95 : return *this;
96 : }
97 :
98 0 : CVector2D& operator/=(float f)
99 : {
100 0 : float invf = 1.0f / f;
101 0 : X *= invf;
102 0 : Y *= invf;
103 0 : return *this;
104 : }
105 :
106 0 : float Dot(const CVector2D& a) const
107 : {
108 0 : return X * a.X + Y * a.Y;
109 : }
110 :
111 0 : float LengthSquared() const
112 : {
113 0 : return Dot(*this);
114 : }
115 :
116 0 : float Length() const
117 : {
118 0 : return (float)sqrt(LengthSquared());
119 : }
120 :
121 : void Normalize()
122 : {
123 : float mag = Length();
124 : X /= mag;
125 : Y /= mag;
126 : }
127 :
128 0 : CVector2D Normalized() const
129 : {
130 0 : float mag = Length();
131 0 : return CVector2D(X / mag, Y / mag);
132 : }
133 :
134 : /**
135 : * Returns a version of this vector rotated counterclockwise by @p angle radians.
136 : */
137 0 : CVector2D Rotated(float angle) const
138 : {
139 0 : float c = cosf(angle);
140 0 : float s = sinf(angle);
141 0 : return CVector2D(
142 0 : c*X - s*Y,
143 0 : s*X + c*Y
144 0 : );
145 : }
146 :
147 : /**
148 : * Rotates this vector counterclockwise by @p angle radians.
149 : */
150 0 : void Rotate(float angle)
151 : {
152 0 : float c = cosf(angle);
153 0 : float s = sinf(angle);
154 0 : float newX = c*X - s*Y;
155 0 : float newY = s*X + c*Y;
156 0 : X = newX;
157 0 : Y = newY;
158 0 : }
159 :
160 : CVector2D operator+(const CSize2D& size) const;
161 : CVector2D operator-(const CSize2D& size) const;
162 :
163 : void operator+=(const CSize2D& size);
164 : void operator-=(const CSize2D& size);
165 :
166 : // Returns 2 element array of floats, e.g. for vec2 uniforms.
167 0 : PS::span<const float> AsFloatArray() const
168 : {
169 : // Additional check to prevent a weird compiler having a different
170 : // alignement for an array and a class members.
171 : static_assert(
172 : sizeof(CVector2D) == sizeof(float) * 2u &&
173 : offsetof(CVector2D, X) == 0 &&
174 : offsetof(CVector2D, Y) == sizeof(float),
175 : "Vector2D should be properly layouted to use AsFloatArray");
176 0 : return PS::span<const float>(&X, 2);
177 : }
178 :
179 : public:
180 : float X, Y;
181 : };
182 :
183 : #endif // INCLUDED_VECTOR2D
|