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