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_VECTOR3_H
17 #define RENDER_SERVICE_CLIENT_CORE_COMMON_RS_VECTOR3_H
18 #include <cmath>
19 
20 #include "common/rs_common_def.h"
21 
22 namespace OHOS {
23 namespace Rosen {
24 template<typename T>
25 class Vector3 {
26 public:
27     union {
28         struct {
29             T x_;
30             T y_;
31             T z_;
32         };
33         T data_[3];
34     };
35 
36     Vector3();
37     Vector3(T x, T y, T z);
38     explicit Vector3(T* v);
39     ~Vector3();
40 
41     Vector3 Normalized() const;
42     T Dot(const Vector3<T>& other) const;
43     Vector3 Cross(const Vector3<T>& other) const;
44     T GetSqrLength() const;
45     T GetLength() const;
46     void SetZero();
47     void SetValues(T x, T y, T z);
48     T Normalize();
49 
50     Vector3& operator*=(const Vector3<T>& other);
51     Vector3& operator*=(T s);
52     Vector3 operator*(T s) const;
53     Vector3 operator+(const Vector3<T>& other) const;
54     Vector3& operator+=(const Vector3<T>& other);
55     Vector3& operator=(const Vector3<T>& other);
56     Vector3 operator-(const Vector3<T>& other) const;
57     T operator[](int index) const;
58     T& operator[](int index);
59     bool operator==(const Vector3& other) const;
60     T* GetData();
61 
62     static const Vector3 ZERO;
63 };
64 
65 typedef Vector3<float> Vector3f;
66 typedef Vector3<double> Vector3d;
67 template<typename T>
68 const Vector3<T> Vector3<T>::ZERO(0.0, 0.0, 0.0);
69 
70 template<typename T>
Vector3()71 Vector3<T>::Vector3()
72 {
73     data_[0] = 0.0;
74     data_[1] = 0.0;
75     data_[2] = 0.0;
76 }
77 
78 template<typename T>
Vector3(T x,T y,T z)79 Vector3<T>::Vector3(T x, T y, T z)
80 {
81     data_[0] = x;
82     data_[1] = y;
83     data_[2] = z;
84 }
85 
86 template<typename T>
Vector3(T * v)87 Vector3<T>::Vector3(T* v)
88 {
89     data_[0] = v[0];
90     data_[1] = v[1];
91     data_[2] = v[2];
92 }
93 
94 template<typename T>
~Vector3()95 Vector3<T>::~Vector3()
96 {}
97 
98 template<typename T>
Normalized()99 Vector3<T> Vector3<T>::Normalized() const
100 {
101     Vector3<T> rNormalize(*this);
102     rNormalize.Normalize();
103     return rNormalize;
104 }
105 
106 template<typename T>
Dot(const Vector3<T> & other)107 T Vector3<T>::Dot(const Vector3<T>& other) const
108 {
109     const T* oData = other.data_;
110     T sum = data_[0] * oData[0];
111     sum += data_[1] * oData[1];
112     sum += data_[2] * oData[2];
113     return sum;
114 }
115 
116 template<typename T>
Cross(const Vector3<T> & other)117 Vector3<T> Vector3<T>::Cross(const Vector3<T>& other) const
118 {
119     T x = data_[0];
120     T y = data_[1];
121     T z = data_[2];
122     const T* oData = other.data_;
123     T oX = oData[0];
124     T oY = oData[1];
125     T oZ = oData[2];
126     Vector3<T> rCross;
127     rCross.SetValues(y * oZ - z * oY, z * oX - x * oZ, x * oY - y * oX);
128     return rCross;
129 }
130 
131 template<typename T>
GetSqrLength()132 T Vector3<T>::GetSqrLength() const
133 {
134     T x = data_[0];
135     T y = data_[1];
136     T z = data_[2];
137     return (x * x) + (y * y) + (z * z);
138 }
139 
140 template<typename T>
GetLength()141 T Vector3<T>::GetLength() const
142 {
143     return sqrt(GetSqrLength());
144 }
145 
146 template<typename T>
SetZero()147 void Vector3<T>::SetZero()
148 {
149     *this = ZERO;
150 }
151 
152 template<typename T>
SetValues(T x,T y,T z)153 void Vector3<T>::SetValues(T x, T y, T z)
154 {
155     data_[0] = x;
156     data_[1] = y;
157     data_[2] = z;
158 }
159 
160 template<typename T>
Normalize()161 T Vector3<T>::Normalize()
162 {
163     T l = GetLength();
164     if (ROSEN_EQ<T>(l, 0.0)) {
165         return 0.0;
166     }
167 
168     const T d = 1.0f / l;
169     data_[0] *= d;
170     data_[1] *= d;
171     data_[2] *= d;
172     return l;
173 }
174 
175 template<typename T>
176 Vector3<T>& Vector3<T>::operator*=(const Vector3<T>& other)
177 {
178     const T* oData = other.data_;
179     data_[0] *= oData[0];
180     data_[1] *= oData[1];
181     data_[2] *= oData[2];
182     return *this;
183 }
184 
185 template<typename T>
186 Vector3<T>& Vector3<T>::operator*=(T s)
187 {
188     data_[0] *= s;
189     data_[1] *= s;
190     data_[2] *= s;
191     return *this;
192 }
193 
194 template<typename T>
195 Vector3<T> Vector3<T>::operator*(T s) const
196 {
197     Vector3<T> rMulti(*this);
198     T* rData = rMulti.data_;
199 
200     rData[0] *= s;
201     rData[1] *= s;
202     rData[2] *= s;
203     return rMulti;
204 }
205 
206 template<typename T>
207 Vector3<T> Vector3<T>::operator+(const Vector3<T>& other) const
208 {
209     Vector3<T> rVec = *this;
210     rVec += other;
211     return rVec;
212 }
213 
214 template<typename T>
215 Vector3<T>& Vector3<T>::operator+=(const Vector3<T>& other)
216 {
217     data_[0] += other.data_[0];
218     data_[1] += other.data_[1];
219     data_[2] += other.data_[2];
220     return *this;
221 }
222 
223 template<typename T>
224 Vector3<T>& Vector3<T>::operator=(const Vector3<T>& other)
225 {
226     data_[0] = other.data_[0];
227     data_[1] = other.data_[1];
228     data_[2] = other.data_[2];
229     return *this;
230 }
231 
232 template<typename T>
233 Vector3<T> Vector3<T>::operator-(const Vector3<T>& other) const
234 {
235     Vector3<T> rSub(*this);
236     T* rData = rSub.data_;
237     const T* oData = other.data_;
238     rData[0] -= oData[0];
239     rData[1] -= oData[1];
240     rData[2] -= oData[2];
241     return rSub;
242 }
243 
244 template<typename T>
245 T Vector3<T>::operator[](int index) const
246 {
247     return data_[index];
248 }
249 
250 template<typename T>
251 T& Vector3<T>::operator[](int index)
252 {
253     return data_[index];
254 }
255 
256 template<typename T>
257 inline bool Vector3<T>::operator==(const Vector3& other) const
258 {
259     const T* oData = other.data_;
260 
261     return (ROSEN_EQ<T>(data_[0], oData[0])) && (ROSEN_EQ<T>(data_[1], oData[1])) && (ROSEN_EQ<T>(data_[2], oData[2]));
262 }
263 
264 template<typename T>
GetData()265 inline T* Vector3<T>::GetData()
266 {
267     return data_;
268 }
269 } // namespace Rosen
270 } // namespace OHOS
271 
272 #endif // RENDER_SERVICE_CLIENT_CORE_COMMON_RS_VECTOR3_H
273