• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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     static constexpr uint32_t V4SIZE = 4;
30     union {
31         struct {
32             T x_;
33             T y_;
34             T z_;
35             T w_;
36         };
37         T data_[4];
38     };
39 
40     Vector4();
41     Vector4(T value);
42     Vector4(const Vector4<T>& value);
43     Vector4(T x, T y, T z, T w);
44     explicit Vector4(const T* array);
45     ~Vector4();
46 
47     Vector4 Normalized() const;
48     T Dot(const Vector4<T>& other) const;
49     T GetSqrLength() const;
50     T GetLength() const;
51     T Normalize();
52     void Identity();
53     bool IsInfinite() const;
54     bool IsIdentity() const;
55     bool IsZero() const;
56     void SetValues(T x, T y, T z, T w);
57     void SetZero();
58     uint32_t Size();
59     Vector4 operator-() const;
60     Vector4 operator-(const Vector4<T>& other) const;
61     Vector4 operator+(const Vector4<T>& other) const;
62     Vector4 operator/(float scale) const;
63     Vector4 operator*(float scale) const;
64     Vector4 operator*(const Vector4<T>& other) const;
65     Vector4& operator*=(const Vector4<T>& other);
66     Vector4& operator+=(const Vector4<T>& other);
67     Vector4& operator=(const Vector4<T>& other);
68     bool operator==(const Vector4& other) const;
69     bool operator!=(const Vector4& other) const;
70     bool IsNearEqual(const Vector4& other, T threshold = std::numeric_limits<T>::epsilon()) const;
71 
72     T operator[](int index) const;
73     T& operator[](int index);
74     T* GetData();
75 
76     void Scale(float arg);
77     void Sub(const Vector4<T>& arg);
78     void Add(const Vector4<T>& arg);
79     void Multiply(const Vector4<T>& arg);
80     void Negate();
81     void Absolute();
82     static void Min(const Vector4<T>& a, const Vector4<T>& b, Vector4<T>& result);
83     static void Max(const Vector4<T>& a, const Vector4<T>& b, Vector4<T>& result);
84     static void Mix(const Vector4<T>& min, const Vector4<T>& max, T a, Vector4<T>& result);
85 };
86 
87 typedef Vector4<float> Vector4f;
88 typedef Vector4<double> Vector4d;
89 
90 class Quaternion : public Vector4f {
91 public:
Quaternion()92     Quaternion()
93     {
94         Identity();
95     }
Quaternion(float x,float y,float z,float w)96     Quaternion(float x, float y, float z, float w) : Vector4f(x, y, z, w) {}
Quaternion(const Vector4f & other)97     Quaternion(const Vector4f& other) : Vector4f(other) {}
Quaternion(const Vector4f && other)98     Quaternion(const Vector4f&& other) : Vector4f(other) {}
99     Quaternion Slerp(const Quaternion& to, float t);
100     Quaternion Flip() const;
101 };
102 
103 template<typename T>
Vector4()104 Vector4<T>::Vector4()
105 {
106     SetZero();
107 }
108 
109 template<typename T>
Vector4(T value)110 Vector4<T>::Vector4(T value)
111 {
112     data_[0] = value;
113     data_[1] = value;
114     data_[2] = value;
115     data_[3] = value;
116 }
117 
118 template<typename T>
Vector4(const Vector4<T> & value)119 Vector4<T>::Vector4(const Vector4<T>& value)
120 {
121     T data0 = value[0];
122     T data1 = value[1];
123     T data2 = value[2];
124     T data3 = value[3];
125     data_[0] = data0;
126     data_[1] = data1;
127     data_[2] = data2;
128     data_[3] = data3;
129 }
130 
131 template<typename T>
Vector4(T x,T y,T z,T w)132 Vector4<T>::Vector4(T x, T y, T z, T w)
133 {
134     data_[0] = x;
135     data_[1] = y;
136     data_[2] = z;
137     data_[3] = w;
138 }
139 
140 template<typename T>
Vector4(const T * array)141 Vector4<T>::Vector4(const T* array)
142 {
143     std::copy_n(array, std::size(data_), data_);
144 }
145 
146 template<typename T>
~Vector4()147 Vector4<T>::~Vector4()
148 {}
149 
Flip()150 inline Quaternion Quaternion::Flip() const
151 {
152     return { -data_[0], -data_[1], -data_[2], -data_[3] };
153 }
154 
Slerp(const Quaternion & to,float t)155 inline Quaternion Quaternion::Slerp(const Quaternion& to, float t)
156 {
157     constexpr double SLERP_EPSILON = 1e-5;
158     if (t < 0.0 || t > 1.0) {
159         return *this;
160     }
161 
162     auto from = *this;
163 
164     double cosHalfAngle = from.x_ * to.x_ + from.y_ * to.y_ + from.z_ * to.z_ + from.w_ * to.w_;
165     if (cosHalfAngle < 0.0) {
166         // Since the half angle is > 90 degrees, the full rotation angle would
167         // exceed 180 degrees. The quaternions (x, y, z, w) and (-x, -y, -z, -w)
168         // represent the same rotation. Flipping the orientation of either
169         // quaternion ensures that the half angle is less than 90 and that we are
170         // taking the shortest path.
171         from = from.Flip();
172         cosHalfAngle = -cosHalfAngle;
173     }
174 
175     // Ensure that acos is well behaved at the boundary.
176     if (cosHalfAngle > 1.0) {
177         cosHalfAngle = 1.0;
178     }
179 
180     double sinHalfAngle = std::sqrt(1.0 - cosHalfAngle * cosHalfAngle);
181     if (sinHalfAngle < SLERP_EPSILON) {
182         // Quaternions share common axis and angle.
183         return *this;
184     }
185 
186     double half_angle = std::acos(cosHalfAngle);
187 
188     float scaleA = std::sin((1.0 - t) * half_angle) / sinHalfAngle;
189     float scaleB = std::sin(t * half_angle) / sinHalfAngle;
190 
191     return (from * scaleA) + (to * scaleB);
192 }
193 
194 template<typename T>
Normalized()195 Vector4<T> Vector4<T>::Normalized() const
196 {
197     Vector4<T> rNormalize(*this);
198     rNormalize.Normalize();
199     return rNormalize;
200 }
201 
202 template<typename T>
Dot(const Vector4<T> & other)203 T Vector4<T>::Dot(const Vector4<T>& other) const
204 {
205     const T* oData = other.data_;
206     T sum = data_[0] * oData[0];
207     sum += data_[1] * oData[1];
208     sum += data_[2] * oData[2];
209     sum += data_[3] * oData[3];
210     return sum;
211 }
212 
213 template<typename T>
GetSqrLength()214 T Vector4<T>::GetSqrLength() const
215 {
216     T sum = data_[0] * data_[0];
217     sum += data_[1] * data_[1];
218     sum += data_[2] * data_[2];
219     sum += data_[3] * data_[3];
220     return sum;
221 }
222 
223 template<typename T>
GetLength()224 T Vector4<T>::GetLength() const
225 {
226     return sqrt(GetSqrLength());
227 }
228 
229 template<typename T>
Normalize()230 T Vector4<T>::Normalize()
231 {
232     T l = GetLength();
233     if (ROSEN_EQ<T>(l, 0.0)) {
234         return (T)0.0;
235     }
236 
237     const T d = 1.0f / l;
238     data_[0] *= d;
239     data_[1] *= d;
240     data_[2] *= d;
241     data_[3] *= d;
242     return l;
243 }
244 
245 template<typename T>
Min(const Vector4<T> & a,const Vector4<T> & b,Vector4<T> & result)246 void Vector4<T>::Min(const Vector4<T>& a, const Vector4<T>& b, Vector4<T>& result)
247 {
248     T* resultData = result.data_;
249     const T* aData = a.data_;
250     const T* bData = b.data_;
251     T aData3 = aData[3];
252     T aData2 = aData[2];
253     T aData1 = aData[1];
254     T aData0 = aData[0];
255     T bData3 = bData[3];
256     T bData2 = bData[2];
257     T bData1 = bData[1];
258     T bData0 = bData[0];
259     resultData[3] = std::min(aData3, bData3);
260     resultData[2] = std::min(aData2, bData2);
261     resultData[1] = std::min(aData1, bData1);
262     resultData[0] = std::min(aData0, bData0);
263 }
264 
265 template<typename T>
Max(const Vector4<T> & a,const Vector4<T> & b,Vector4<T> & result)266 void Vector4<T>::Max(const Vector4<T>& a, const Vector4<T>& b, Vector4<T>& result)
267 {
268     T* resultData = result.data_;
269     const T* aData = a.data_;
270     const T* bData = b.data_;
271     T aData3 = aData[3];
272     T aData2 = aData[2];
273     T aData1 = aData[1];
274     T aData0 = aData[0];
275     T bData3 = bData[3];
276     T bData2 = bData[2];
277     T bData1 = bData[1];
278     T bData0 = bData[0];
279     resultData[3] = std::max(aData3, bData3);
280     resultData[2] = std::max(aData2, bData2);
281     resultData[1] = std::max(aData1, bData1);
282     resultData[0] = std::max(aData0, bData0);
283 }
284 
285 template<typename T>
Mix(const Vector4<T> & min,const Vector4<T> & max,T a,Vector4<T> & result)286 void Vector4<T>::Mix(const Vector4<T>& min, const Vector4<T>& max, T a, Vector4<T>& result)
287 {
288     T* resultData = result.data_;
289     const T* minData = min.data_;
290     const T* maxData = max.data_;
291     T minData3 = minData[3];
292     T minData2 = minData[2];
293     T minData1 = minData[1];
294     T minData0 = minData[0];
295     T maxData3 = maxData[3];
296     T maxData2 = maxData[2];
297     T maxData1 = maxData[1];
298     T maxData0 = maxData[0];
299     resultData[3] = minData3 + a * (maxData3 - minData3);
300     resultData[2] = minData2 + a * (maxData2 - minData2);
301     resultData[1] = minData1 + a * (maxData1 - minData1);
302     resultData[0] = minData0 + a * (maxData0 - minData0);
303 }
304 
305 template<typename T>
GetData()306 inline T* Vector4<T>::GetData()
307 {
308     return data_;
309 }
310 
311 template<typename T>
Identity()312 void Vector4<T>::Identity()
313 {
314     SetValues(0.f, 0.f, 0.f, 1.f);
315 }
316 
317 template<typename T>
IsIdentity()318 bool Vector4<T>::IsIdentity() const
319 {
320     return operator==(Vector4<T>(0.f, 0.f, 0.f, 1.f));
321 }
322 
323 template<typename T>
IsZero()324 bool Vector4<T>::IsZero() const
325 {
326     return ROSEN_EQ<T>(data_[0], 0.f) && ROSEN_EQ<T>(data_[1], 0.f) &&
327            ROSEN_EQ<T>(data_[2], 0.f) && ROSEN_EQ<T>(data_[3], 0.f);
328 }
329 
330 template<typename T>
SetValues(T x,T y,T z,T w)331 void Vector4<T>::SetValues(T x, T y, T z, T w)
332 {
333     data_[0] = x;
334     data_[1] = y;
335     data_[2] = z;
336     data_[3] = w;
337 }
338 
339 template<typename T>
SetZero()340 void Vector4<T>::SetZero()
341 {
342     SetValues(T(0.f), T(0.f), T(0.f), T(0.f));
343 }
344 
345 template<typename T>
Size()346 uint32_t Vector4<T>::Size()
347 {
348     return V4SIZE;
349 }
350 
351 template<typename T>
352 Vector4<T> Vector4<T>::operator-(const Vector4<T>& other) const
353 {
354     const T* otherData = other.data_;
355 
356     return Vector4<T>(
357         data_[0] - otherData[0], data_[1] - otherData[1], data_[2] - otherData[2], data_[3] - otherData[3]);
358 }
359 
360 template<typename T>
361 Vector4<T> Vector4<T>::operator+(const Vector4<T>& other) const
362 {
363     const T* thisData = data_;
364     const T* otherData = other.data_;
365 
366     return Vector4<T>(
367         thisData[0] + otherData[0], thisData[1] + otherData[1], thisData[2] + otherData[2], thisData[3] + otherData[3]);
368 }
369 
370 template<typename T>
371 Vector4<T> Vector4<T>::operator/(float scale) const
372 {
373     if (ROSEN_EQ<float>(scale, 0)) {
374         return *this;
375     }
376     Vector4<T> clone(data_);
377     clone.Scale(1.0f / scale);
378     return clone;
379 }
380 
381 template<typename T>
382 Vector4<T> Vector4<T>::operator*(float scale) const
383 {
384     Vector4<T> clone(data_);
385     clone.Scale(scale);
386     return clone;
387 }
388 
389 template<typename T>
390 Vector4<T> Vector4<T>::operator*(const Vector4<T>& other) const
391 {
392     Vector4<T> rMult(data_);
393     return rMult *= other;
394 }
395 
396 template<typename T>
397 Vector4<T>& Vector4<T>::operator*=(const Vector4<T>& other)
398 {
399     const T* oData = other.data_;
400     T data3 = oData[3];
401     T data2 = oData[2];
402     T data1 = oData[1];
403     T data0 = oData[0];
404     data_[0] *= data0;
405     data_[1] *= data1;
406     data_[2] *= data2;
407     data_[3] *= data3;
408     return *this;
409 }
410 
411 template<typename T>
412 Vector4<T>& Vector4<T>::operator+=(const Vector4<T>& other)
413 {
414     const T* oData = other.data_;
415     data_[0] += oData[0]; // 0, x component of the quaternion
416     data_[1] += oData[1]; // 1, y component of the quaternion
417     data_[2] += oData[2]; // 2, z component of the quaternion
418     data_[3] += oData[3]; // 3, w component of the quaternion
419     return *this;
420 }
421 
422 template<typename T>
423 Vector4<T>& Vector4<T>::operator=(const Vector4<T>& other)
424 {
425     const T* oData = other.data_;
426     T data3 = oData[3];
427     T data2 = oData[2];
428     T data1 = oData[1];
429     T data0 = oData[0];
430     data_[0] = data0;
431     data_[1] = data1;
432     data_[2] = data2;
433     data_[3] = data3;
434     return *this;
435 }
436 
437 template<typename T>
438 inline bool Vector4<T>::operator==(const Vector4& other) const
439 {
440     const T* oData = other.data_;
441 
442     return (ROSEN_EQ<T>(data_[0], oData[0])) && (ROSEN_EQ<T>(data_[1], oData[1])) &&
443            (ROSEN_EQ<T>(data_[2], oData[2])) && (ROSEN_EQ<T>(data_[3], oData[3]));
444 }
445 
446 template<typename T>
447 inline bool Vector4<T>::operator!=(const Vector4& other) const
448 {
449     return !operator==(other);
450 }
451 
452 template<typename T>
IsNearEqual(const Vector4 & other,T threshold)453 bool Vector4<T>::IsNearEqual(const Vector4& other, T threshold) const
454 {
455     const T* value = other.data_;
456 
457     return (ROSEN_EQ<T>(data_[0], value[0], threshold)) && (ROSEN_EQ<T>(data_[1], value[1], threshold)) &&
458            (ROSEN_EQ<T>(data_[2], value[2], threshold)) && (ROSEN_EQ<T>(data_[3], value[3], threshold));
459 }
460 
461 template<typename T>
462 Vector4<T> Vector4<T>::operator-() const
463 {
464     return Vector4<T>(-data_[0], -data_[1], -data_[2], -data_[3]);
465 }
466 
467 template<typename T>
468 T Vector4<T>::operator[](int index) const
469 {
470     return data_[index];
471 }
472 
473 template<typename T>
474 T& Vector4<T>::operator[](int index)
475 {
476     return data_[index];
477 }
478 
479 template<typename T>
Scale(float arg)480 void Vector4<T>::Scale(float arg)
481 {
482     data_[3] *= arg;
483     data_[2] *= arg;
484     data_[1] *= arg;
485     data_[0] *= arg;
486 }
487 
488 template<typename T>
Sub(const Vector4<T> & arg)489 void Vector4<T>::Sub(const Vector4<T>& arg)
490 {
491     const T* argData = arg.data_;
492     T data3 = argData[3];
493     T data2 = argData[2];
494     T data1 = argData[1];
495     T data0 = argData[0];
496     data_[3] -= data3;
497     data_[2] -= data2;
498     data_[1] -= data1;
499     data_[0] -= data0;
500 }
501 
502 template<typename T>
Add(const Vector4<T> & arg)503 void Vector4<T>::Add(const Vector4<T>& arg)
504 {
505     const T* argData = arg.data_;
506     T data3 = argData[3];
507     T data2 = argData[2];
508     T data1 = argData[1];
509     T data0 = argData[0];
510     data_[3] += data3;
511     data_[2] += data2;
512     data_[1] += data1;
513     data_[0] += data0;
514 }
515 
516 template<typename T>
Multiply(const Vector4<T> & arg)517 void Vector4<T>::Multiply(const Vector4<T>& arg)
518 {
519     const T* argData = arg.data_;
520     T data3 = argData[3];
521     T data2 = argData[2];
522     T data1 = argData[1];
523     T data0 = argData[0];
524     data_[3] *= data3;
525     data_[2] *= data2;
526     data_[1] *= data1;
527     data_[0] *= data0;
528 }
529 
530 template<typename T>
Negate()531 void Vector4<T>::Negate()
532 {
533     data_[3] = -data_[3];
534     data_[2] = -data_[2];
535     data_[1] = -data_[1];
536     data_[0] = -data_[0];
537 }
538 
539 template<typename T>
Absolute()540 void Vector4<T>::Absolute()
541 {
542     data_[3] = abs(data_[3]);
543     data_[2] = abs(data_[2]);
544     data_[1] = abs(data_[1]);
545     data_[0] = abs(data_[0]);
546 }
547 
548 template<typename T>
IsInfinite()549 bool Vector4<T>::IsInfinite() const
550 {
551     return std::isinf(data_[0]) || std::isinf(data_[1]) ||
552         std::isinf(data_[2]) || std::isinf(data_[3]);
553 }
554 } // namespace Rosen
555 } // namespace OHOS
556 #endif // RENDER_SERVICE_CLIENT_CORE_COMMON_RS_VECTOR4_H
557