ScummVM API documentation
dgVector.h
1 /* Copyright (c) <2003-2011> <Julio Jerez, Newton Game Dynamics>
2 *
3 * This software is provided 'as-is', without any express or implied
4 * warranty. In no event will the authors be held liable for any damages
5 * arising from the use of this software.
6 *
7 * Permission is granted to anyone to use this software for any purpose,
8 * including commercial applications, and to alter it and redistribute it
9 * freely, subject to the following restrictions:
10 *
11 * 1. The origin of this software must not be misrepresented; you must not
12 * claim that you wrote the original software. If you use this software
13 * in a product, an acknowledgment in the product documentation would be
14 * appreciated but is not required.
15 *
16 * 2. Altered source versions must be plainly marked as such, and must not be
17 * misrepresented as being the original software.
18 *
19 * 3. This notice may not be removed or altered from any source distribution.
20 */
21 
22 #ifndef __dgVector__
23 #define __dgVector__
24 
25 #include "dgStdafx.h"
26 #include "dgDebug.h"
27 #include "dgMemory.h"
28 #include "dgSimd_Instrutions.h"
29 
30 #define dgCheckVector(x) (dgCheckFloat(x[0]) && dgCheckFloat(x[1]) && dgCheckFloat(x[2]) && dgCheckFloat(x[3]))
31 //#define dgCheckVector(x) true
32 
33 template<class T>
35 public:
36  constexpr dgTemplateVector() : m_x(0), m_y(0), m_z(0), m_w(0) {}
37  dgTemplateVector(const T *ptr);
38  constexpr dgTemplateVector(T m_x, T m_y, T m_z, T m_w);
39  dgTemplateVector Scale(T s) const;
40  dgTemplateVector Scale4(T s) const;
41 
42  T &operator[](dgInt32 i);
43  const T &operator[](dgInt32 i) const;
44 
45  dgTemplateVector operator+ (const dgTemplateVector &A) const;
46  dgTemplateVector operator- (const dgTemplateVector &A) const;
47  dgTemplateVector &operator+= (const dgTemplateVector &A);
48  dgTemplateVector &operator-= (const dgTemplateVector &A);
49 
50  // return dot product
51  T operator% (const dgTemplateVector &A) const;
52 
53  // return cross product
54  dgTemplateVector operator* (const dgTemplateVector &B) const;
55 
56  // return dot 4d dot product
57  dgTemplateVector Add4(const dgTemplateVector &A) const;
58  dgTemplateVector Sub4(const dgTemplateVector &A) const;
59  T DotProduct4(const dgTemplateVector &A) const;
60  dgTemplateVector CrossProduct4(const dgTemplateVector &A, const dgTemplateVector &B) const;
61 
62  // component wise multiplication
63  dgTemplateVector CompProduct(const dgTemplateVector &A) const;
64 
65  // component wise multiplication
66  dgTemplateVector CompProduct4(const dgTemplateVector &A) const;
67 
68  // check validity of floats
69 #ifdef _DEBUG
70  void Trace() const {
71  dgTrace(("%f %f %f %f\n", m_x, m_y, m_z, m_w));
72  }
73 #endif
74 
75  DG_CLASS_ALLOCATOR(allocator)
76 
77  T m_x;
78  T m_y;
79  T m_z;
80  T m_w;
81 };
82 
83 class dgBigVector;
84 
85 DG_MSC_VECTOR_ALIGMENT
86 class dgVector: public dgTemplateVector<dgFloat32> {
87 public:
88  constexpr dgVector() = default;
89 #ifdef DG_BUILD_SIMD_CODE
90  dgVector(const simd_type &val);
91 #endif
93  dgVector(const dgFloat32 *ptr);
94  constexpr dgVector(dgFloat32 x, dgFloat32 y, dgFloat32 z, dgFloat32 w);
95  dgVector(const dgBigVector &copy);
96 
97  dgFloat32 DotProductSimd(const dgVector &A) const;
98  dgVector CrossProductSimd(const dgVector &A) const;
99  dgVector CompProductSimd(const dgVector &A) const;
100 
101 } DG_GCC_VECTOR_ALIGMENT;
102 
103 DG_MSC_VECTOR_ALIGMENT
104 class dgBigVector: public dgTemplateVector<dgFloat64> {
105 public:
106  dgBigVector();
107  dgBigVector(const dgVector &v);
109  dgBigVector(const dgFloat32 *ptr);
110 #ifndef __USE_DOUBLE_PRECISION__
111  dgBigVector(const dgFloat64 *ptr);
112 #endif
113  dgBigVector(dgFloat64 x, dgFloat64 y, dgFloat64 z, dgFloat64 w);
114 } DG_GCC_VECTOR_ALIGMENT;
115 
116 
117 template<class T>
119  : m_x(ptr[0]), m_y(ptr[1]), m_z(ptr[2]), m_w(0.0f) {
120 // NEWTON_ASSERT (dgCheckVector ((*this)));
121 }
122 
123 template<class T>
124 constexpr dgTemplateVector<T>::dgTemplateVector(T x, T y, T z, T w)
125  : m_x(x), m_y(y), m_z(z), m_w(w) {
126 }
127 
128 
129 template<class T>
130 T &dgTemplateVector<T>::operator[](dgInt32 i) {
131  NEWTON_ASSERT(i < 4);
132  NEWTON_ASSERT(i >= 0);
133  return (&m_x)[i];
134 }
135 
136 template<class T>
137 const T &dgTemplateVector<T>::operator[](dgInt32 i) const {
138  NEWTON_ASSERT(i < 4);
139  NEWTON_ASSERT(i >= 0);
140  return (&m_x)[i];
141 }
142 
143 template<class T>
145  return dgTemplateVector<T> (m_x * scale, m_y * scale, m_z * scale, m_w);
146 }
147 
148 template<class T>
150  return dgTemplateVector<T> (m_x * scale, m_y * scale, m_z * scale, m_w * scale);
151 }
152 
153 
154 template<class T>
156  return dgTemplateVector<T> (m_x + B.m_x, m_y + B.m_y, m_z + B.m_z, m_w);
157 }
158 
159 template<class T>
161  m_x += A.m_x;
162  m_y += A.m_y;
163  m_z += A.m_z;
164 // NEWTON_ASSERT (dgCheckVector ((*this)));
165  return *this;
166 }
167 
168 template<class T>
170  return dgTemplateVector<T> (m_x - A.m_x, m_y - A.m_y, m_z - A.m_z, m_w);
171 }
172 
173 template<class T>
175  m_x -= A.m_x;
176  m_y -= A.m_y;
177  m_z -= A.m_z;
178  NEWTON_ASSERT(dgCheckVector((*this)));
179  return *this;
180 }
181 
182 
183 template<class T>
185  return m_x * A.m_x + m_y * A.m_y + m_z * A.m_z;
186 }
187 
188 
189 template<class T>
191  return dgTemplateVector<T> (m_y * B.m_z - m_z * B.m_y,
192  m_z * B.m_x - m_x * B.m_z,
193  m_x * B.m_y - m_y * B.m_x, m_w);
194 }
195 
196 template<class T>
198  return dgTemplateVector<T> (m_x + A.m_x, m_y + A.m_y, m_z + A.m_z, m_w + A.m_w);
199 }
200 
201 template<class T>
203  return dgTemplateVector<T> (m_x - A.m_x, m_y - A.m_y, m_z - A.m_z, m_w - A.m_w);
204 }
205 
206 
207 // return dot 4d dot product
208 template<class T>
210  return m_x * A.m_x + m_y * A.m_y + m_z * A.m_z + m_w * A.m_w;
211 }
212 
213 template<class T>
215  T cofactor[3][3];
216  T array[4][4];
217 
218  const dgTemplateVector<T> &me = *this;
219  for (dgInt32 i = 0; i < 4; i ++) {
220  array[0][i] = me[i];
221  array[1][i] = A[i];
222  array[2][i] = B[i];
223  array[3][i] = T(1.0f);
224  }
225 
226  dgTemplateVector<T> normal;
227  T sign = T(-1.0f);
228  for (dgInt32 i = 0; i < 4; i ++) {
229 
230  for (dgInt32 j = 0; j < 3; j ++) {
231  dgInt32 k0 = 0;
232  for (dgInt32 k = 0; k < 4; k ++) {
233  if (k != i) {
234  cofactor[j][k0] = array[j][k];
235  k0 ++;
236  }
237  }
238  }
239  T x = cofactor[0][0] * (cofactor[1][1] * cofactor[2][2] - cofactor[1][2] * cofactor[2][1]);
240  T y = cofactor[0][1] * (cofactor[1][2] * cofactor[2][0] - cofactor[1][0] * cofactor[2][2]);
241  T z = cofactor[0][2] * (cofactor[1][0] * cofactor[2][1] - cofactor[1][1] * cofactor[2][0]);
242  T det = x + y + z;
243 
244  normal[i] = sign * det;
245  sign *= T(-1.0f);
246  }
247 
248  return normal;
249 }
250 
251 
252 
253 template<class T>
255  return dgTemplateVector<T> (m_x * A.m_x, m_y * A.m_y, m_z * A.m_z, A.m_w);
256 }
257 
258 template<class T>
260  return dgTemplateVector<T> (m_x * A.m_x, m_y * A.m_y, m_z * A.m_z, m_w * A.m_w);
261 }
262 
263 
264 
265 DG_INLINE dgVector::dgVector(const dgTemplateVector<dgFloat32> &v)
267  NEWTON_ASSERT(dgCheckVector((*this)));
268 }
269 
270 DG_INLINE dgVector::dgVector(const dgFloat32 *ptr)
272  NEWTON_ASSERT(dgCheckVector((*this)));
273 }
274 
275 DG_INLINE dgVector::dgVector(const dgBigVector &copy)
276  : dgTemplateVector<dgFloat32>(dgFloat32(copy.m_x), dgFloat32(copy.m_y), dgFloat32(copy.m_z), dgFloat32(copy.m_w)) {
277  NEWTON_ASSERT(dgCheckVector((*this)));
278 }
279 
280 #ifdef DG_BUILD_SIMD_CODE
281 DG_INLINE dgVector::dgVector(const simd_type &val) {
282  NEWTON_ASSERT((dgUnsigned64(this) & 0x0f) == 0);
283  (simd_type &) *this = val;
284  NEWTON_ASSERT(dgCheckVector((*this)));
285 }
286 #endif
287 
288 constexpr DG_INLINE dgVector::dgVector(dgFloat32 x, dgFloat32 y, dgFloat32 z, dgFloat32 w)
289  : dgTemplateVector<dgFloat32>(x, y, z, w) {
290 }
291 
292 DG_INLINE dgFloat32 dgVector::DotProductSimd(const dgVector &A) const {
293 #ifdef DG_BUILD_SIMD_CODE
294 // simd_type r0;
295 // dgFloat32 dot;
296  dgVector tmp;
297  (simd_type &) tmp = simd_mul_v((simd_type &) * this, (simd_type &)A);
298 // r0 = simd_add_v(r0, simd_move_hl_v (r0, r0));
299 // simd_store_s(simd_add_s(r0, simd_permut_v (r0, r0, PURMUT_MASK(3, 3, 3, 1))), &dot);
300 // return dot;
301  return tmp.m_x + tmp.m_y + tmp.m_z;
302 #else
303  return dgFloat32(0.0f);
304 #endif
305 }
306 
307 DG_INLINE dgVector dgVector::CrossProductSimd(const dgVector &e10) const {
308 #ifdef DG_BUILD_SIMD_CODE
309  const dgVector &e21 = *this;
310  return dgVector(simd_mul_sub_v(simd_mul_v(simd_permut_v((simd_type &)e21, (simd_type &)e21, PURMUT_MASK(3, 0, 2, 1)), simd_permut_v((simd_type &)e10, (simd_type &)e10, PURMUT_MASK(3, 1, 0, 2))),
311  simd_permut_v((simd_type &)e21, (simd_type &)e21, PURMUT_MASK(3, 1, 0, 2)), simd_permut_v((simd_type &)e10, (simd_type &)e10, PURMUT_MASK(3, 0, 2, 1))));
312 #else
313  return dgVector(dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f));
314 #endif
315 
316 }
317 
318 
319 DG_INLINE dgVector dgVector::CompProductSimd(const dgVector &A) const {
320 #ifdef DG_BUILD_SIMD_CODE
321  return dgVector(simd_mul_v((simd_type &) * this, (simd_type &)A));
322 #else
323  return dgVector(dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f));
324 #endif
325 }
326 
327 DG_INLINE dgBigVector::dgBigVector()
329 }
330 
331 DG_INLINE dgBigVector::dgBigVector(const dgVector &v)
332  : dgTemplateVector<dgFloat64>(v.m_x, v.m_y, v.m_z, v.m_w) {
333  NEWTON_ASSERT(dgCheckVector((*this)));
334 }
335 
336 DG_INLINE dgBigVector::dgBigVector(const dgTemplateVector<dgFloat64> &v)
338  NEWTON_ASSERT(dgCheckVector((*this)));
339 }
340 
341 DG_INLINE dgBigVector::dgBigVector(const dgFloat32 *ptr)
342  : dgTemplateVector<dgFloat64>(ptr[0], ptr[1], ptr[2], dgFloat64(0.0f)) {
343  NEWTON_ASSERT(dgCheckVector((*this)));
344 }
345 
346 #ifndef __USE_DOUBLE_PRECISION__
347 DG_INLINE dgBigVector::dgBigVector(const dgFloat64 *ptr)
349  NEWTON_ASSERT(dgCheckVector((*this)));
350 }
351 #endif
352 
353 DG_INLINE dgBigVector::dgBigVector(dgFloat64 x, dgFloat64 y, dgFloat64 z, dgFloat64 w)
354  : dgTemplateVector<dgFloat64>(x, y, z, w) {
355  NEWTON_ASSERT(dgCheckVector((*this)));
356 }
357 
358 
359 #endif
360 
Definition: dgVector.h:86
Definition: dgVector.h:34
Out copy(In first, In last, Out dst)
Definition: algorithm.h:52
Graphics::Surface * scale(const Graphics::Surface &srcImage, int xSize, int ySize)
Definition: dgVector.h:104