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