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