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