• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef RENDER_SERVICE_CLIENT_CORE_COMMON_RS_VECTOR4_H
17 #define RENDER_SERVICE_CLIENT_CORE_COMMON_RS_VECTOR4_H
18 
19 #include <algorithm>
20 #include <cmath>
21 
22 #include "common/rs_common_def.h"
23 
24 namespace OHOS {
25 namespace Rosen {
26 template<typename T>
27 class Vector4 {
28 public:
29     union {
30         struct {
31             T x_;
32             T y_;
33             T z_;
34             T w_;
35         };
36         T data_[4];
37     };
38 
39     Vector4();
40     Vector4(T x, T y, T z, T w);
41     explicit Vector4(const T* array);
42     ~Vector4();
43 
44     Vector4 Normalized() const;
45     T Dot(const Vector4<T>& other) const;
46     T GetSqrLength() const;
47     T GetLength() const;
48     T Normalize();
49     void Identity();
50     bool IsInfinite() const;
51     bool IsIdentity() const;
52     void SetValues(T x, T y, T z, T w);
53     void SetZero();
54     Vector4 operator-() const;
55     Vector4 operator-(const Vector4<T>& other) const;
56     Vector4 operator+(const Vector4<T>& other) const;
57     Vector4 operator/(T scale) const;
58     Vector4 operator*(T scale) const;
59     Vector4 operator*(const Vector4<T>& other) const;
60     Vector4& operator*=(const Vector4<T>& other);
61     Vector4& operator=(const Vector4<T>& other);
62     bool operator==(const Vector4& other) const;
63     bool operator!=(const Vector4& other) const;
64 
65     T operator[](int index) const;
66     T& operator[](int index);
67     T* GetData();
68 
69     void Scale(T arg);
70     void Sub(const Vector4<T>& arg);
71     void Add(const Vector4<T>& arg);
72     void Multiply(const Vector4<T>& arg);
73     void Div(const Vector4<T>& arg);
74     void Negate();
75     void Absolute();
76     static void Min(const Vector4<T>& a, const Vector4<T>& b, Vector4<T>& result);
77     static void Max(const Vector4<T>& a, const Vector4<T>& b, Vector4<T>& result);
78     static void Mix(const Vector4<T>& min, const Vector4<T>& max, T a, Vector4<T>& result);
79 };
80 
81 typedef Vector4<float> Vector4f;
82 typedef Vector4<double> Vector4d;
83 
84 class Quaternion : public Vector4f {
85 public:
Quaternion()86     Quaternion() : Vector4f() {}
Quaternion(float x,float y,float z,float w)87     Quaternion(float x, float y, float z, float w) : Vector4f(x, y, z, w) {}
Quaternion(const Vector4f & other)88     Quaternion(const Vector4f& other) : Vector4f(other) {}
Quaternion(const Vector4f && other)89     Quaternion(const Vector4f&& other) : Vector4f(other) {}
90     Quaternion Slerp(const Quaternion& to, float t);
91     Quaternion Flip() const;
92 };
93 
94 template<typename T>
Vector4()95 Vector4<T>::Vector4()
96 {
97     Identity();
98 }
99 
100 template<typename T>
Vector4(T x,T y,T z,T w)101 Vector4<T>::Vector4(T x, T y, T z, T w)
102 {
103     data_[0] = x;
104     data_[1] = y;
105     data_[2] = z;
106     data_[3] = w;
107 }
108 
109 template<typename T>
Vector4(const T * array)110 Vector4<T>::Vector4(const T* array)
111 {
112     std::copy_n(array, std::size(data_), data_);
113 }
114 
115 template<typename T>
~Vector4()116 Vector4<T>::~Vector4()
117 {}
118 
Flip()119 inline Quaternion Quaternion::Flip() const
120 {
121     return { -data_[0], -data_[1], -data_[2], -data_[3] };
122 }
123 
Slerp(const Quaternion & to,float t)124 inline Quaternion Quaternion::Slerp(const Quaternion& to, float t)
125 {
126     constexpr double SLERP_EPSILON = 1e-5;
127     if (t < 0.0 || t > 1.0) {
128         return *this;
129     }
130 
131     auto from = *this;
132 
133     double cosHalfAngle = from.x_ * to.x_ + from.y_ * to.y_ + from.z_ * to.z_ + from.w_ * to.w_;
134     if (cosHalfAngle < 0.0) {
135         // Since the half angle is > 90 degrees, the full rotation angle would
136         // exceed 180 degrees. The quaternions (x, y, z, w) and (-x, -y, -z, -w)
137         // represent the same rotation. Flipping the orientation of either
138         // quaternion ensures that the half angle is less than 90 and that we are
139         // taking the shortest path.
140         from = from.Flip();
141         cosHalfAngle = -cosHalfAngle;
142     }
143 
144     // Ensure that acos is well behaved at the boundary.
145     if (cosHalfAngle > 1.0) {
146         cosHalfAngle = 1.0;
147     }
148 
149     double sinHalfAngle = std::sqrt(1.0 - cosHalfAngle * cosHalfAngle);
150     if (sinHalfAngle < SLERP_EPSILON) {
151         // Quaternions share common axis and angle.
152         return *this;
153     }
154 
155     double half_angle = std::acos(cosHalfAngle);
156 
157     float scaleA = std::sin((1.0 - t) * half_angle) / sinHalfAngle;
158     float scaleB = std::sin(t * half_angle) / sinHalfAngle;
159 
160     return (from * scaleA) + (to * scaleB);
161 }
162 
163 template<typename T>
Normalized()164 Vector4<T> Vector4<T>::Normalized() const
165 {
166     Vector4<T> rNormalize(*this);
167     rNormalize.Normalize();
168     return rNormalize;
169 }
170 
171 template<typename T>
Dot(const Vector4<T> & other)172 T Vector4<T>::Dot(const Vector4<T>& other) const
173 {
174     const T* oData = other.data_;
175     T sum = data_[0] * oData[0];
176     sum += data_[1] * oData[1];
177     sum += data_[2] * oData[2];
178     sum += data_[3] * oData[3];
179     return sum;
180 }
181 
182 template<typename T>
GetSqrLength()183 T Vector4<T>::GetSqrLength() const
184 {
185     T sum = data_[0] * data_[0];
186     sum += data_[1] * data_[1];
187     sum += data_[2] * data_[2];
188     sum += data_[3] * data_[3];
189     return sum;
190 }
191 
192 template<typename T>
GetLength()193 T Vector4<T>::GetLength() const
194 {
195     return sqrt(GetSqrLength());
196 }
197 
198 template<typename T>
Normalize()199 T Vector4<T>::Normalize()
200 {
201     T l = GetLength();
202     if (ROSEN_EQ<T>(l, 0.0)) {
203         return (T)0.0;
204     }
205 
206     const T d = 1.0f / l;
207     data_[0] *= d;
208     data_[1] *= d;
209     data_[2] *= d;
210     data_[3] *= d;
211     return l;
212 }
213 
214 template<typename T>
Min(const Vector4<T> & a,const Vector4<T> & b,Vector4<T> & result)215 void Vector4<T>::Min(const Vector4<T>& a, const Vector4<T>& b, Vector4<T>& result)
216 {
217     T* resultData = result.data_;
218     const T* aData = a.data_;
219     const T* bData = b.data_;
220     resultData[3] = std::min(aData[3], bData[3]);
221     resultData[2] = std::min(aData[2], bData[2]);
222     resultData[1] = std::min(aData[1], bData[1]);
223     resultData[0] = std::min(aData[0], bData[0]);
224 }
225 
226 template<typename T>
Max(const Vector4<T> & a,const Vector4<T> & b,Vector4<T> & result)227 void Vector4<T>::Max(const Vector4<T>& a, const Vector4<T>& b, Vector4<T>& result)
228 {
229     T* resultData = result.data_;
230     const T* aData = a.data_;
231     const T* bData = b.data_;
232     resultData[3] = std::max(aData[3], bData[3]);
233     resultData[2] = std::max(aData[2], bData[2]);
234     resultData[1] = std::max(aData[1], bData[1]);
235     resultData[0] = std::max(aData[0], bData[0]);
236 }
237 
238 template<typename T>
Mix(const Vector4<T> & min,const Vector4<T> & max,T a,Vector4<T> & result)239 void Vector4<T>::Mix(const Vector4<T>& min, const Vector4<T>& max, T a, Vector4<T>& result)
240 {
241     T* resultData = result.data_;
242     const T* minData = min.data_;
243     const T* maxData = max.data_;
244     resultData[3] = minData[3] + a * (maxData[3] - minData[3]);
245     resultData[2] = minData[2] + a * (maxData[2] - minData[2]);
246     resultData[1] = minData[1] + a * (maxData[1] - minData[1]);
247     resultData[0] = minData[0] + a * (maxData[0] - minData[0]);
248 }
249 
250 template<typename T>
GetData()251 inline T* Vector4<T>::GetData()
252 {
253     return data_;
254 }
255 
256 template<typename T>
Identity()257 void Vector4<T>::Identity()
258 {
259     SetValues(0.f, 0.f, 0.f, 1.f);
260 }
261 
262 template<typename T>
IsIdentity()263 bool Vector4<T>::IsIdentity() const
264 {
265     return operator==(Vector4<T>(0.f, 0.f, 0.f, 1.f));
266 }
267 
268 template<typename T>
SetValues(T x,T y,T z,T w)269 void Vector4<T>::SetValues(T x, T y, T z, T w)
270 {
271     data_[0] = x;
272     data_[1] = y;
273     data_[2] = z;
274     data_[3] = w;
275 }
276 
277 template<typename T>
SetZero()278 void Vector4<T>::SetZero()
279 {
280     SetValues(0.f, 0.f, 0.f, 0.f);
281 }
282 
283 template<typename T>
284 Vector4<T> Vector4<T>::operator-(const Vector4<T>& other) const
285 {
286     const T* otherData = other.data_;
287 
288     return Vector4<T>(
289         data_[0] - otherData[0], data_[1] - otherData[1], data_[2] - otherData[2], data_[3] - otherData[3]);
290 }
291 
292 template<typename T>
293 Vector4<T> Vector4<T>::operator+(const Vector4<T>& other) const
294 {
295     const T* thisData = data_;
296     const T* otherData = other.data_;
297 
298     return Vector4<T>(
299         thisData[0] + otherData[0], thisData[1] + otherData[1], thisData[2] + otherData[2], thisData[3] + otherData[3]);
300 }
301 
302 template<typename T>
303 Vector4<T> Vector4<T>::operator/(T scale) const
304 {
305     if (ROSEN_EQ(scale, 0)) {
306         return *this;
307     }
308     Vector4<T> clone(data_);
309     clone.Scale(1.0f / scale);
310     return clone;
311 }
312 
313 template<typename T>
314 Vector4<T> Vector4<T>::operator*(T scale) const
315 {
316     Vector4<T> clone(data_);
317     clone.Scale(scale);
318     return clone;
319 }
320 
321 template<typename T>
322 Vector4<T> Vector4<T>::operator*(const Vector4<T>& other) const
323 {
324     Vector4<T> rMult;
325     T* rData = rMult.data_;
326     const T* oData = other.data_;
327     rData[0] = data_[0] * oData[0];
328     rData[1] = data_[1] * oData[1];
329     rData[2] = data_[2] * oData[2];
330     rData[3] = data_[3] * oData[3];
331     return rMult;
332 }
333 
334 template<typename T>
335 Vector4<T>& Vector4<T>::operator*=(const Vector4<T>& other)
336 {
337     const T* oData = other.data_;
338     data_[0] *= oData[0];
339     data_[1] *= oData[1];
340     data_[2] *= oData[2];
341     data_[3] *= oData[3];
342     return *this;
343 }
344 
345 template<typename T>
346 Vector4<T>& Vector4<T>::operator=(const Vector4<T>& other)
347 {
348     const T* oData = other.data_;
349     data_[0] = oData[0];
350     data_[1] = oData[1];
351     data_[2] = oData[2];
352     data_[3] = oData[3];
353     return *this;
354 }
355 
356 template<typename T>
357 inline bool Vector4<T>::operator==(const Vector4& other) const
358 {
359     const T* oData = other.data_;
360 
361     return (ROSEN_EQ<T>(data_[0], oData[0])) && (ROSEN_EQ<T>(data_[1], oData[1])) &&
362            (ROSEN_EQ<T>(data_[2], oData[2])) && (ROSEN_EQ<T>(data_[3], oData[3]));
363 }
364 
365 template<typename T>
366 inline bool Vector4<T>::operator!=(const Vector4& other) const
367 {
368     return !operator==(other);
369 }
370 
371 template<typename T>
372 Vector4<T> Vector4<T>::operator-() const
373 {
374     return Vector4<T>(-data_[0], -data_[1], -data_[2], -data_[3]);
375 }
376 
377 template<typename T>
378 T Vector4<T>::operator[](int index) const
379 {
380     return data_[index];
381 }
382 
383 template<typename T>
384 T& Vector4<T>::operator[](int index)
385 {
386     return data_[index];
387 }
388 
389 template<typename T>
Scale(T arg)390 void Vector4<T>::Scale(T arg)
391 {
392     data_[3] *= arg;
393     data_[2] *= arg;
394     data_[1] *= arg;
395     data_[0] *= arg;
396 }
397 
398 template<typename T>
Sub(const Vector4<T> & arg)399 void Vector4<T>::Sub(const Vector4<T>& arg)
400 {
401     const T* argData = arg.data_;
402     data_[3] -= argData[3];
403     data_[2] -= argData[2];
404     data_[1] -= argData[1];
405     data_[0] -= argData[0];
406 }
407 
408 template<typename T>
Add(const Vector4<T> & arg)409 void Vector4<T>::Add(const Vector4<T>& arg)
410 {
411     const T* argData = arg.data_;
412     data_[3] += argData[3];
413     data_[2] += argData[2];
414     data_[1] += argData[1];
415     data_[0] += argData[0];
416 }
417 
418 template<typename T>
Multiply(const Vector4<T> & arg)419 void Vector4<T>::Multiply(const Vector4<T>& arg)
420 {
421     const T* argData = arg.data_;
422     data_[3] *= argData[3];
423     data_[2] *= argData[2];
424     data_[1] *= argData[1];
425     data_[0] *= argData[0];
426 }
427 
428 template<typename T>
Div(const Vector4<T> & arg)429 void Vector4<T>::Div(const Vector4<T>& arg)
430 {
431     const T* argData = arg.data_;
432     data_[3] /= argData[3];
433     data_[2] /= argData[2];
434     data_[1] /= argData[1];
435     data_[0] /= argData[0];
436 }
437 
438 template<typename T>
Negate()439 void Vector4<T>::Negate()
440 {
441     data_[3] = -data_[3];
442     data_[2] = -data_[2];
443     data_[1] = -data_[1];
444     data_[0] = -data_[0];
445 }
446 
447 template<typename T>
Absolute()448 void Vector4<T>::Absolute()
449 {
450     data_[3] = abs(data_[3]);
451     data_[2] = abs(data_[2]);
452     data_[1] = abs(data_[1]);
453     data_[0] = abs(data_[0]);
454 }
455 
456 template<typename T>
IsInfinite()457 bool Vector4<T>::IsInfinite() const
458 {
459     return std::isinf(data_[0]) || std::isinf(data_[1]) ||
460         std::isinf(data_[2]) || std::isinf(data_[3]);
461 }
462 } // namespace Rosen
463 } // namespace OHOS
464 #endif // RENDER_SERVICE_CLIENT_CORE_COMMON_RS_VECTOR4_H
465