Line data Source code
1 : /**
2 : Copyright 2013 BlackBerry Inc.
3 : Copyright (c) 2014-2015 Chukong Technologies
4 : Copyright (c) 2017-2022 Roman Katuntsev <sbkarr@stappler.org>
5 : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
6 :
7 : Licensed under the Apache License, Version 2.0 (the "License");
8 : you may not use this file except in compliance with the License.
9 : You may obtain a copy of the License at
10 :
11 : http://www.apache.org/licenses/LICENSE-2.0
12 :
13 : Unless required by applicable law or agreed to in writing, software
14 : distributed under the License is distributed on an "AS IS" BASIS,
15 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 : See the License for the specific language governing permissions and
17 : limitations under the License.
18 :
19 : Original file from GamePlay3D: http://gameplay3d.org
20 :
21 : This file was modified to fit the cocos2d-x project
22 : This file was modified for stappler project
23 : */
24 :
25 : #ifndef STAPPLER_GEOM_SPVEC3_H_
26 : #define STAPPLER_GEOM_SPVEC3_H_
27 :
28 : #include "SPSIMD.h"
29 : #include "SPVec2.h"
30 :
31 : namespace STAPPLER_VERSIONIZED stappler::geom {
32 :
33 : class Mat4;
34 : class Quaternion;
35 : struct Size3;
36 : struct Extent3;
37 :
38 : class Vec3 {
39 : public:
40 : static constexpr size_t Dimansions = 2;
41 :
42 : static const Vec3 ZERO;
43 : static const Vec3 ONE;
44 : static const Vec3 UNIT_X;
45 : static const Vec3 UNIT_Y;
46 : static const Vec3 UNIT_Z;
47 :
48 4518 : static constexpr void add(const Vec3& v1, const Vec3& v2, Vec3* dst) {
49 4518 : dst->x = v1.x + v2.x; dst->y = v1.y + v2.y; dst->z = v1.z + v2.z;
50 4518 : }
51 :
52 125 : static constexpr void subtract(const Vec3& v1, const Vec3& v2, Vec3* dst) {
53 125 : dst->x = v1.x - v2.x; dst->y = v1.y - v2.y; dst->z = v1.z - v2.z;
54 125 : }
55 :
56 : static constexpr void scale(const Vec3& v1, const Vec3& v2, Vec3* dst) {
57 : dst->x = v1.x * v2.x; dst->y = v1.y * v2.y; dst->z = v1.z * v2.z;
58 : }
59 :
60 : static constexpr void unscale(const Vec3& v1, const Vec3& v2, Vec3* dst) {
61 : dst->x = v1.x / v2.x; dst->y = v1.y / v2.y; dst->z = v1.z / v2.z;
62 : }
63 :
64 200 : static void cross(const Vec3& v1, const Vec3& v2, Vec3* dst) {
65 200 : simd::crossVec3(&v1.x, &v2.x, &dst->x);
66 200 : }
67 :
68 325 : static constexpr float dot(const Vec3& v1, const Vec3& v2) {
69 325 : return (v1.x * v2.x + v1.y * v2.y + v1.z * v2.z);
70 : }
71 :
72 : static float angle(const Vec3& v1, const Vec3& v2);
73 :
74 : static void clamp(const Vec3& v, const Vec3& min, const Vec3& max, Vec3* dst);
75 :
76 : template <typename Functor>
77 : static constexpr std::bitset<3> bitop(const Vec3& v, const Functor &f) {
78 : std::bitset<3> ret;
79 : ret.set(0, f(v.x));
80 : ret.set(1, f(v.y));
81 : ret.set(2, f(v.z));
82 : return ret;
83 : }
84 :
85 : template <typename Functor>
86 : static constexpr std::bitset<3> bitop(const Vec3& v1, const Vec3& v2, const Functor &f) {
87 : std::bitset<3> ret;
88 : ret.set(0, f(v1.x, v2.x));
89 : ret.set(1, f(v1.y, v2.y));
90 : ret.set(2, f(v1.z, v2.z));
91 : return ret;
92 : }
93 :
94 : static constexpr Vec3 fill(float v) {
95 : return Vec3(v, v, v);
96 : }
97 :
98 : float x;
99 : float y;
100 : float z;
101 :
102 17932 : constexpr Vec3() : x(0.0f), y(0.0f), z(0.0f) { }
103 2571730 : constexpr Vec3(float xx, float yy, float zz) : x(xx), y(yy), z(zz) { }
104 : constexpr Vec3(const Vec2 &pt, float zz) : x(pt.x), y(pt.y), z(zz) { }
105 :
106 50 : constexpr Vec3(const Vec3 &p1, const Vec3 &p2) : x(p2.x - p1.x), y(p2.y - p1.y), z(p2.z - p1.z) { }
107 :
108 : template <typename Functor>
109 50 : constexpr Vec3(const Vec3 &v, const Functor &f) : x(f(v.x)), y(f(v.y)), z(f(v.z)) { }
110 :
111 : template <typename Functor>
112 : constexpr Vec3(const Vec3 &v1, const Vec3 &v2, const Functor &f) : x(f(v1.x, v2.x)), y(f(v1.y, v2.y)), z(f(v1.z, v2.z)) { }
113 :
114 : constexpr Vec3(const Vec3 ©) = default;
115 :
116 : explicit Vec3(const Size3 &);
117 : explicit Vec3(const Extent3 &);
118 :
119 : constexpr bool isValid() const { return !std::isnan(x) && !std::isnan(y) && !std::isnan(z); }
120 :
121 12 : constexpr Vec2 xy() const {
122 12 : return Vec2(x, y);
123 : }
124 :
125 : constexpr void add(const float &v) {
126 : x += v; y += v; z += v;
127 : }
128 :
129 : constexpr void add(const Vec3 &v) {
130 : x += v.x; y += v.y; z += v.z;
131 : }
132 :
133 : constexpr void subtract(const float &v) {
134 : x -= v; y -= v; z -= v;
135 : }
136 :
137 : constexpr void subtract(const Vec3 &v) {
138 : x -= v.x; y -= v.y; z -= v.z;
139 : }
140 :
141 22325 : constexpr void scale(const float &v) {
142 22325 : x *= v; y *= v; z *= v;
143 22325 : }
144 :
145 : constexpr void scale(const Vec3 &v) {
146 : x *= v.x; y *= v.y; z *= v.z;
147 : }
148 :
149 : constexpr void unscale(const float &v) {
150 : x /= v; y /= v; z /= v;
151 : }
152 :
153 : constexpr void unscale(const Vec3 &v) {
154 : x /= v.x; y /= v.y; z /= v.z;
155 : }
156 :
157 : void clamp(const Vec3& min, const Vec3& max);
158 :
159 : constexpr float distanceSquared(const Vec3& v) const {
160 : const float dx = v.x - x;
161 : const float dy = v.y - y;
162 : const float dz = v.z - z;
163 :
164 : return (dx * dx + dy * dy + dz * dz);
165 : }
166 :
167 2453324 : constexpr float lengthSquared() const {
168 2453324 : return (x * x + y * y + z * z);
169 : }
170 :
171 : constexpr float distance(const Vec3& other) const { return std::sqrt(distanceSquared(other)); }
172 :
173 2453170 : constexpr float length() const { return std::sqrt(lengthSquared()); }
174 :
175 : constexpr bool isWithinDistance(const Vec3& v, float val) const {
176 : return distanceSquared(v) < val * val;
177 : }
178 :
179 : constexpr float dot(const Vec3& v) const { return (x * v.x + y * v.y + z * v.z); }
180 :
181 : void cross(const Vec3& v) { cross(*this, v, this); }
182 :
183 : constexpr void negate() { x = -x; y = -y; z = -z; }
184 :
185 : constexpr Vec3 & normalize();
186 :
187 : Vec3 getNormalized() const;
188 :
189 218 : constexpr bool fuzzyEquals(const Vec3& b, float var = NumericLimits<float>::epsilon()) const {
190 218 : return (x - var <= b.x && b.x <= x + var) && (y - var <= b.y && b.y <= y + var)
191 436 : && (z - var <= b.z && b.z <= z + var);
192 : }
193 :
194 : constexpr Vec3& operator+=(const float &v) {
195 : add(v);
196 : return *this;
197 : }
198 :
199 : constexpr Vec3& operator+=(const Vec3& v) {
200 : add(v);
201 : return *this;
202 : }
203 :
204 : constexpr Vec3& operator-=(const float &v) {
205 : subtract(v);
206 : return *this;
207 : }
208 :
209 : constexpr Vec3& operator-=(const Vec3& v) {
210 : subtract(v);
211 : return *this;
212 : }
213 :
214 : constexpr Vec3& operator*=(const float &v) {
215 : scale(v);
216 : return *this;
217 : }
218 :
219 : constexpr Vec3& operator*=(const Vec3 &s) {
220 : scale(s);
221 : return *this;
222 : }
223 :
224 : constexpr Vec3& operator/=(const float &v) {
225 : unscale(v);
226 : return *this;
227 : }
228 :
229 : constexpr Vec3& operator/=(const Vec3 &s) {
230 : unscale(s);
231 : return *this;
232 : }
233 :
234 : SP_THREE_WAY_COMPARISON_FRIEND_CONSTEXPR(Vec3)
235 : };
236 :
237 575 : constexpr inline Vec3 & Vec3::normalize() {
238 575 : float n = x * x + y * y + z * z;
239 : // Already normalized.
240 575 : if (n == 1.0f) {
241 125 : return *this;
242 : }
243 :
244 450 : n = std::sqrt(n);
245 : // Too close to zero.
246 450 : if (n < math::MATH_TOLERANCE) {
247 0 : return *this;
248 : }
249 :
250 450 : n = 1.0f / n;
251 450 : x *= n;
252 450 : y *= n;
253 450 : z *= n;
254 :
255 450 : return *this;
256 : }
257 :
258 : #ifndef __LCC__
259 :
260 : constexpr const Vec3 Vec3::ZERO(0.0f, 0.0f, 0.0f);
261 : constexpr const Vec3 Vec3::ONE(1.0f, 1.0f, 1.0f);
262 : constexpr const Vec3 Vec3::UNIT_X(1.0f, 0.0f, 0.0f);
263 : constexpr const Vec3 Vec3::UNIT_Y(0.0f, 1.0f, 0.0f);
264 : constexpr const Vec3 Vec3::UNIT_Z(0.0f, 0.0f, 1.0f);
265 :
266 : #endif
267 :
268 4518 : constexpr inline const Vec3 operator+(const Vec3 &l, const Vec3 &r) {
269 4518 : Vec3 result;
270 4518 : Vec3::add(l, r, &result);
271 4518 : return result;
272 : }
273 :
274 : constexpr inline const Vec3 operator+(const Vec3 &l, const float &r) {
275 : Vec3 result(l);
276 : result.add(r);
277 : return result;
278 : }
279 :
280 : constexpr inline const Vec3 operator+(const float &l, const Vec3 &r) {
281 : Vec3 result(r);
282 : result.add(l);
283 : return result;
284 : }
285 :
286 25 : constexpr inline const Vec3 operator-(const Vec3 &l, const Vec3 &r) {
287 25 : Vec3 result;
288 25 : Vec3::subtract(l, r, &result);
289 25 : return result;
290 : }
291 :
292 : constexpr inline const Vec3 operator-(const Vec3 &l, const float &r) {
293 : Vec3 result(l);
294 : result.subtract(r);
295 : return result;
296 : }
297 :
298 : constexpr inline const Vec3 operator*(const Vec3 &l, const Vec3 &r) {
299 : Vec3 result;
300 : Vec3::scale(l, r, &result);
301 : return result;
302 : }
303 :
304 22325 : constexpr inline const Vec3 operator*(const Vec3 &l, const float &r) {
305 22325 : Vec3 result(l);
306 22325 : result.scale(r);
307 22325 : return result;
308 : }
309 :
310 : constexpr inline const Vec3 operator*(const float &l, const Vec3 &r) {
311 : Vec3 result(r);
312 : result.scale(l);
313 : return result;
314 : }
315 :
316 : constexpr inline const Vec3 operator/(const Vec3 &l, const Vec3 &r) {
317 : Vec3 result;
318 : Vec3::unscale(l, r, &result);
319 : return result;
320 : }
321 :
322 : constexpr inline const Vec3 operator/(const Vec3 &l, const float &r) {
323 : Vec3 result(l);
324 : result.unscale(r);
325 : return result;
326 : }
327 :
328 : constexpr Vec3 operator-(const Vec3& v) {
329 : Vec3 result(v);
330 : result.negate();
331 : return result;
332 : }
333 :
334 : inline std::basic_ostream<char> &
335 : operator << (std::basic_ostream<char> & os, const Vec3 & vec) {
336 : os << "(x: " << vec.x << "; y: " << vec.y << "; z: " << vec.z << ")";
337 : return os;
338 : }
339 :
340 : }
341 :
342 : #endif /* STAPPLER_GEOM_SPVEC3_H_ */
|