Version
menu_open
Wwise SDK 2023.1.4
AkVectors.h
Go to the documentation of this file.
1 /*******************************************************************************
2 The content of this file includes portions of the AUDIOKINETIC Wwise Technology
3 released in source code form as part of the SDK installer package.
4 
5 Commercial License Usage
6 
7 Licensees holding valid commercial licenses to the AUDIOKINETIC Wwise Technology
8 may use this file in accordance with the end user license agreement provided
9 with the software or, alternatively, in accordance with the terms contained in a
10 written agreement between you and Audiokinetic Inc.
11 
12 Apache License Usage
13 
14 Alternatively, this file may be used under the Apache License, Version 2.0 (the
15 "Apache License"); you may not use this file except in compliance with the
16 Apache License. You may obtain a copy of the Apache License at
17 http://www.apache.org/licenses/LICENSE-2.0.
18 
19 Unless required by applicable law or agreed to in writing, software distributed
20 under the Apache License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
21 OR CONDITIONS OF ANY KIND, either express or implied. See the Apache License for
22 the specific language governing permissions and limitations under the License.
23 
24  Copyright (c) 2024 Audiokinetic Inc.
25 *******************************************************************************/
26 
27 // AkVectors.h
28 //
29 
30 #pragma once
31 
38 
39 #include <math.h>
40 #include <stdio.h>
41 #include <float.h>
42 
43 //#define AKVBAP_DEBUG 1
44 //#define AKPORTALS_DEBUG
45 
46 #define AKVECTORS_PI (3.1415926535897932384626433832795f)
47 #define AKVECTORS_TWOPI (6.283185307179586476925286766559f)
48 #define AKVECTORS_PIOVERTWO (1.5707963267948966192313216916398f)
49 #define AKVECTORS_EPSILON (1.0e-38f) // epsilon value for fast log(0)
50 
52 {
53 public:
54  //-----------------------------------------------------------
55  // Constructor/Destructor functions
57  {
58  v[0] = 0.0f;
59  v[1] = 0.0f;
60  v[2] = 0.0f;
61  v[3] = 0.0f;
62  }
63 
64  Ak4DVector(const AkVector& b)
65  {
66  v[0] = b.X;
67  v[1] = b.Y;
68  v[2] = b.Z;
69  v[3] = 1;
70  }
71 
72  //-----------------------------------------------------------
73  // Basic vector operators
75  {
76  v[0] = b.v[0];
77  v[1] = b.v[1];
78  v[2] = b.v[2];
79  v[3] = b.v[3];
80 
81  return *this;
82  }
83 
85  {
86  v[0] = v[0] / f;
87  v[1] = v[1] / f;
88  v[2] = v[2] / f;
89  v[3] = v[3] / f;
90 
91  return *this;
92  }
93 
95  {
96  Ak4DVector p;
97 
98  p.v[0] = v[0] - b.v[0];
99  p.v[1] = v[1] - b.v[1];
100  p.v[2] = v[2] - b.v[2];
101  p.v[3] = v[3] - b.v[3];
102 
103  return p;
104  }
105 
107 };
108 
110 {
111 public:
112  Ak3DIntVector() = default;
113 
115  X(x),
116  Y(y),
117  Z(z)
118  {
119  }
120 
121  AkInt32 X; ///< X Position
122  AkInt32 Y; ///< Y Position
123  AkInt32 Z; ///< Z Position
124 };
125 
126 ///
127 /// Specialization must provide these methods. Could enforce that through static_assert...
128 /// static TDataType Cos(TDataType in_value) const;
129 /// static TDataType Sin(TDataType in_value) const;
130 /// static TDataType Sqrt(TDataType in_value) const;
131 /// static constexpr TDataType POSITIVE_EPSILON;
132 /// static constexpr TDataType VECTOR_EPSILON;
133 ///
134 template<typename TDataType> class RealPrecision;
135 
136 template<>
138 {
139 public:
140  static AkReal32 Cos(AkReal32 in_value) { return cosf(in_value); }
141  static AkReal32 Sin(AkReal32 in_value) { return sinf(in_value); }
142  static AkReal32 Sqrt(AkReal32 in_value) { return sqrtf(in_value); }
143  static AkReal32 ACos(AkReal32 in_value) { return acosf(in_value); }
144  static bool IsFinite(AkReal32 in_val)
145  {
146  // Purposely not using std::isnan() or isfinite because fastmath on clang & gcc may optimize them to be false always.
147  return !(((*(AkUInt32*)&in_val) & 0x7fffffff) >= 0x7f800000);
148  }
149 
150  static constexpr AkReal32 POSITIVE_EPSILON = 0.00001f;
151  static constexpr AkReal32 VECTOR_EPSILON = AKVECTORS_EPSILON;
152 
153  static constexpr AkReal32 MAX_VALUE = FLT_MAX;
154 };
155 
156 template<>
158 {
159 public:
160  static AkReal64 Cos(AkReal64 in_value) { return cos(in_value); }
161  static AkReal64 Sin(AkReal64 in_value) { return sin(in_value); }
162  static AkReal64 Sqrt(AkReal64 in_value) { return sqrt(in_value); }
163  static AkReal64 ACos(AkReal64 in_value) { return acos(in_value); }
164  static bool IsFinite(AkReal64 in_val)
165  {
166  // Purposely not using std::isnan() or isfinite because fastmath on clang & gcc may optimize them to be false always.
167  return !(((*(AkUInt64*)&in_val) & 0x7fffffffffffffff) >= 0x7ff0000000000000);
168  }
169 
170  static constexpr AkReal64 POSITIVE_EPSILON = 0.000000000001f;
171  static constexpr AkReal64 VECTOR_EPSILON = AKVECTORS_EPSILON;
172 
173  static constexpr AkReal64 MAX_VALUE = DBL_MAX;
174 };
175 
176 // AkImplicitConversion
177 // Permits automatic conversion from any real type to any other real type.
178 // May result in loss of precision.
180 {
181 public:
182  template<typename TFromReal, typename TToReal>
183  AkForceInline void Convert(TToReal& out_to, TFromReal in_from)
184  {
185  out_to = static_cast<TToReal>(in_from);
186  }
187 };
188 
189 // AkSafeConversion
190 // Permits automatic conversion only from 32-bit to 64-bit types.
191 // Conversion from 64-bit to 32-bit is not permitted and will generate and error.
193 {
194 public:
195  AkForceInline void Convert(AkReal64& out_to, AkReal32 in_from)
196  {
197  out_to = in_from;
198  }
199  template<typename TReal>
200  AkForceInline void Convert(TReal& out_to, TReal in_from)
201  {
202  out_to = in_from;
203  }
204 };
205 
206 // T3DVector<>
207 // Template 3D vector class, to support both 32 and 64-bit vector types.
208 // Ak3DVector32 and Ak3DVector64 typedefs are provided below for convenience.
209 template<typename TDataType>
211 {
212 public:
213  /// Expose the data type
214  ///
215  typedef TDataType data_type;
216 
217  // Conversion policy for conversions between 32 and 64 bit types.
219 
220 public:
221 
222  //-----------------------------------------------------------
223  // Constructor/Destructor functions
224 
226  X(static_cast<TDataType>(0.0)),
227  Y(static_cast<TDataType>(0.0)),
228  Z(static_cast<TDataType>(0.0))
229  {}
230 
231  T3DVector(TDataType in_x, TDataType in_y, TDataType in_z) :
232  X(in_x),
233  Y(in_y),
234  Z(in_z)
235  {}
236 
237  // Construct from another T3DVector<> type.
238  // Conversion is (only) permitted in accordance to the conversion policy.
239  template<typename TFromDataType>
241  {
242  TTypeConverter converter;
243  converter.Convert(X, in_vector.X);
244  converter.Convert(Y, in_vector.Y);
245  converter.Convert(Z, in_vector.Z);
246  }
247 
248  // Construct from an AkVector type.
249  // Conversion is (only) permitted in accordance to the conversion policy.
250  T3DVector(const AkVector& in_vector)
251  {
252  TTypeConverter converter;
253  converter.Convert(X, in_vector.X);
254  converter.Convert(Y, in_vector.Y);
255  converter.Convert(Z, in_vector.Z);
256  }
257 
258  // Construct from an AkVector64 type.
259  // Conversion is (only) permitted in accordance to the conversion policy.
260  T3DVector(const AkVector64& in_vector)
261  {
262  TTypeConverter converter;
263  converter.Convert(X, in_vector.X);
264  converter.Convert(Y, in_vector.Y);
265  converter.Convert(Z, in_vector.Z);
266  }
267 
268  // Implicit conversion to AkVector type, it the conversion policy permits it.
269  operator</span> AkVector() const
270  {
271  AkVector v;
272  TTypeConverter converter;
273  converter.Convert(v.X, X);
274  converter.Convert(v.Y, Y);
275  converter.Convert(v.Z, Z);
276  return v;
277  }
278 
279  // Implicit conversion to AkVector64 type, it the conversion policy permits it.
280  operator</span> AkVector64() const
281  {
282  AkVector64 v;
283  TTypeConverter converter;
284  converter.Convert(v.X, X);
285  converter.Convert(v.Y, Y);
286  converter.Convert(v.Z, Z);
287  return v;
288  }
289 
290  // Casting method for explicit conversion to another vector type.s
291  template<typename TVectorType>
292  TVectorType Cast() const;
293 
294  // Construct a vector from a scalar.
295  explicit T3DVector(TDataType in_scalar)
296  : X(in_scalar)
297  , Y(in_scalar)
298  , Z(in_scalar)
299  {}
300 
301  // Convert from a vector from a AKSIMD_V4F32.
302  explicit T3DVector(const AKSIMD_V4F32& in_v4f32)
303  {
304  X = static_cast<TDataType>(AKSIMD_GETELEMENT_V4F32(in_v4f32, 0));
305  Y = static_cast<TDataType>(AKSIMD_GETELEMENT_V4F32(in_v4f32, 1));
306  Z = static_cast<TDataType>(AKSIMD_GETELEMENT_V4F32(in_v4f32, 2));
307  }
308 
310  {
311  AKSIMD_V4F32 v4f32;
312  AKSIMD_GETELEMENT_V4F32(v4f32, 0) = static_cast<AkReal32>(X);
313  AKSIMD_GETELEMENT_V4F32(v4f32, 1) = static_cast<AkReal32>(Y);
314  AKSIMD_GETELEMENT_V4F32(v4f32, 2) = static_cast<AkReal32>(Z);
315  AKSIMD_GETELEMENT_V4F32(v4f32, 3) = 1.f;
316  return v4f32;
317  }
318 
320  {
321  AKSIMD_V4F32 v4f32;
322  AKSIMD_GETELEMENT_V4F32(v4f32, 0) = static_cast<TDataType>(X);
323  AKSIMD_GETELEMENT_V4F32(v4f32, 1) = static_cast<TDataType>(Y);
324  AKSIMD_GETELEMENT_V4F32(v4f32, 2) = static_cast<TDataType>(Z);
325  AKSIMD_GETELEMENT_V4F32(v4f32, 3) = static_cast<TDataType>(0.0);
326  return v4f32;
327  }
328 
329  void Zero()
330  {
331  X = static_cast<TDataType>(0.0);
332  Y = static_cast<TDataType>(0.0);
333  Z = static_cast<TDataType>(0.0);
334  }
335 
336  //-----------------------------------------------------------
337  // Basic vector operators
338  AkForceInline bool operator==(const T3DVector& b) const
339  {
340  return X == b.X && Y == b.Y && Z == b.Z;
341  }
342 
343  AkForceInline bool operator!=(const T3DVector& b) const
344  {
345  return X != b.X || Y != b.Y || Z != b.Z;
346  }
347 
348  AkForceInline bool operator<(const T3DVector& b) const
349  {
350  return X < b.X && Y < b.Y && Z < b.Z;
351  }
352 
353  AkForceInline bool operator<=(const T3DVector& b) const
354  {
355  return X <= b.X && Y <= b.Y && Z <= b.Z;
356  }
357 
358  AkForceInline bool operator>(const T3DVector b) const
359  {
360  return X > b.X && Y > b.Y && Z > b.Z;
361  }
362 
363  AkForceInline bool operator>=(const T3DVector& b) const
364  {
365  return X >= b.X && Y >= b.Y && Z >= b.Z;
366  }
367 
368  AkForceInline T3DVector& operator*=(const TDataType f)
369  {
370  X = X * f;
371  Y = Y * f;
372  Z = Z * f;
373 
374  return *this;
375  }
376 
377  AkForceInline T3DVector& operator/=(const TDataType f)
378  {
379  TDataType oneoverf = static_cast<TDataType>(1.0) / f;
380  X = X * oneoverf;
381  Y = Y * oneoverf;
382  Z = Z * oneoverf;
383 
384  return *this;
385  }
386 
388  {
389  T3DVector v;
390 
391  v.X = X * v2.X;
392  v.Y = Y * v2.Y;
393  v.Z = Z * v2.Z;
394 
395  return v;
396  }
397 
398  AkForceInline T3DVector operator*(const TDataType f) const
399  {
400  T3DVector v;
401 
402  v.X = X * f;
403  v.Y = Y * f;
404  v.Z = Z * f;
405 
406  return v;
407  }
408 
410  {
411  T3DVector v;
412 
413  v.X = X / in_rhs.X;
414  v.Y = Y / in_rhs.Y;
415  v.Z = Z / in_rhs.Z;
416 
417  return v;
418  }
419 
420  AkForceInline T3DVector operator/(const TDataType f) const
421  {
422  T3DVector v;
423 
424  TDataType oneoverf = static_cast<TDataType>(1.0) / f;
425 
426  v.X = X * oneoverf;
427  v.Y = Y * oneoverf;
428  v.Z = Z * oneoverf;
429 
430  return v;
431  }
432 
433  AkForceInline T3DVector operator+(const TDataType f) const
434  {
435  T3DVector v;
436 
437  v.X = X + f;
438  v.Y = Y + f;
439  v.Z = Z + f;
440 
441  return v;
442  }
443 
444  AkForceInline T3DVector operator-(const TDataType f) const
445  {
446  T3DVector v;
447 
448  v.X = X - f;
449  v.Y = Y - f;
450  v.Z = Z - f;
451 
452  return v;
453  }
454 
456  {
457  T3DVector v;
458 
459  v.X = X + b.X;
460  v.Y = Y + b.Y;
461  v.Z = Z + b.Z;
462 
463  return v;
464  }
465 
467  {
468  T3DVector v;
469 
470  v.X = X - b.X;
471  v.Y = Y - b.Y;
472  v.Z = Z - b.Z;
473 
474  return v;
475  }
476 
477  AkForceInline TDataType HorizontalMin() const
478  {
479  return AkMin(X, AkMin(Y, Z));
480  }
481 
482  AkForceInline TDataType HorizontalMax() const
483  {
484  return AkMax(X, AkMax(Y, Z));
485  }
486 
487  AkForceInline static T3DVector Min(const T3DVector& A, const T3DVector& B)
488  {
489  T3DVector min;
490 
491  min.X = AkMin(A.X, B.X);
492  min.Y = AkMin(A.Y, B.Y);
493  min.Z = AkMin(A.Z, B.Z);
494 
495  return min;
496  }
497 
498  AkForceInline static T3DVector Max(const T3DVector& A, const T3DVector& B)
499  {
500  T3DVector max;
501 
502  max.X = AkMax(A.X, B.X);
503  max.Y = AkMax(A.Y, B.Y);
504  max.Z = AkMax(A.Z, B.Z);
505 
506  return max;
507  }
508 
509  AkForceInline bool Equals(const T3DVector& b, const TDataType tolerance = static_cast<TDataType>(0.0)) const
510  {
511  return fabs(X - b.X) <= tolerance && fabs(Y - b.Y) <= tolerance && fabs(Z - b.Z) <= tolerance;
512  }
513 
514  //-----------------------------------------------------------
515  // Conversion functions
517  {
518  T3DVector v;
519 
520  v.X = -X;
521  v.Y = Z;
522  v.Z = -Y;
523 
524  return v;
525  }
526 
528  const TDataType azimuth,
529  const TDataType elevation)
530  {
531  TDataType cosElevation = RealPrecision<TDataType>::Cos(elevation);
532  X = RealPrecision<TDataType>::Cos(azimuth) * cosElevation;
533  Y = RealPrecision<TDataType>::Sin(azimuth) * cosElevation;
534  Z = RealPrecision<TDataType>::Sin(elevation);
535 
536  return *this;
537  }
538 
539  // Determinant of 3 column vectors.
540  static AkForceInline TDataType Determinant(
541  const T3DVector& a,
542  const T3DVector& b,
543  const T3DVector& c)
544  {
545  return (a.X*b.Y*c.Z + a.Y*b.Z*c.X + a.Z*b.X*c.Y) -
546  (a.Z*b.Y*c.X + a.Y*b.X*c.Z + a.X*b.Z*c.Y);
547  }
548 
549  // Convert a vector to a different base
551  const T3DVector& A,
552  const T3DVector& B,
553  const T3DVector& C) const
554  {
555  T3DVector v;
556 
557  TDataType d = Determinant(A, B, C);
558 
560  {
561  v.X = static_cast<TDataType>(0.0); v.Y = static_cast<TDataType>(0.0); v.Z = static_cast<TDataType>(0.0);
562  return v;
563  }
564 
565  // http://mathworld.wolfram.com/MatrixInverse.html
566  T3DVector invA = T3DVector(B.Y*C.Z - B.Z*C.Y, A.Z*C.Y - A.Y*C.Z, A.Y*B.Z - A.Z*B.Y);
567  T3DVector invB = T3DVector(B.Z*C.X - B.X*C.Z, A.X*C.Z - A.Z*C.X, A.Z*B.X - A.X*B.Z);
568  T3DVector invC = T3DVector(B.X*C.Y - B.Y*C.X, A.Y*C.X - A.X*C.Y, A.X*B.Y - A.Y*B.X);
569 
570  TDataType oneover_d = static_cast<TDataType>(1.0) / d;
571  invA *= oneover_d;
572  invB *= oneover_d;
573  invC *= oneover_d;
574 
575  // Project coordinates using a vector to matrix multiplication
576  v.X = X * invA.X + Y * invB.X + Z * invC.X;
577  v.Y = X * invA.Y + Y * invB.Y + Z * invC.Y;
578  v.Z = X * invA.Z + Y * invB.Z + Z * invC.Z;
579 
580  // v /= v.Length();
581 
582  return v;
583  }
584 
586  {
587  TDataType l = Length();
588  if (l != static_cast<TDataType>(0.0))
589  {
590  X /= l;
591  Y /= l;
592  Z /= l;
593  }
594  else
595  {
596  X = static_cast<TDataType>(0.0);
597  Y = static_cast<TDataType>(0.0);
598  Z = static_cast<TDataType>(0.0);
599  }
600  return *this;
601  }
602 
603  AkForceInline TDataType L2_Norm() const
604  {
605  return RealPrecision<TDataType>::Sqrt(X*X + Y*Y + Z*Z);
606  }
607 
608  AkForceInline TDataType DotProduct(const T3DVector& v2) const
609  {
610  return X*v2.X + Y*v2.Y + Z*v2.Z;
611  }
612 
613  AkForceInline TDataType Dot(const T3DVector& v2) const
614  {
615  return DotProduct(v2);
616  }
617 
619  {
620  T3DVector uxv;
621 
622  const T3DVector& u = *this;
623 
624  uxv.X = u.Y*v.Z - u.Z*v.Y;
625  uxv.Y = u.Z*v.X - u.X*v.Z;
626  uxv.Z = u.X*v.Y - u.Y*v.X;
627 
628  return uxv;
629  }
630 
631  AkForceInline TDataType Length() const
632  {
633  return RealPrecision<TDataType>::Sqrt(X*X + Y*Y + Z*Z);
634  }
635 
636  AkForceInline TDataType LengthSquared() const
637  {
638  return X*X + Y*Y + Z*Z;
639  }
640 
641  // Usefull in VBAP algorithm, only points that are a positive linear composition matters.
643  {
647  }
648 
650  {
651  T3DVector abs = *this;
652  abs.X = (TDataType)fabs(abs.X);
653  abs.Y = (TDataType)fabs(abs.Y);
654  abs.Z = (TDataType)fabs(abs.Z);
655  return abs;
656  }
657 
658  AkForceInline bool IsFinite() const
659  {
660  return
664  }
665 
666  TDataType X;
667  TDataType Y;
668  TDataType Z;
669 };
670 
671 template<typename TDataType>
673 {
674  return v * f;
675 }
676 
677 template<typename TDataType>
679 {
681  res.X = f / v.X;
682  res.Y = f / v.Y;
683  res.Z = f / v.Z;
684  return res;
685 }
686 
687 
688 // Ak3DVector typedefs
689 
690 // Ak3DVector32 - Can be implicitly converted to 64 but not the other way around.
693 
694 // Ak3DVector64 - It is necessary to call vec.Cast<Ak3DVector64>() to convert to 32 bit vector type.
696 
697 // Casting methods.
698 
699 // Generic cast between two T3DVector<> types.
700 template<typename TDataType>
701 template<typename TVectorType>
702 TVectorType T3DVector<TDataType>::Cast() const
703 {
704  TVectorType v;
705  v.X = static_cast<typename TVectorType::data_type>(X);
706  v.Y = static_cast<typename TVectorType::data_type>(Y);
707  v.Z = static_cast<typename TVectorType::data_type>(Z);
708  return v;
709 }
710 
711 
713 {
714 public:
715  //-----------------------------------------------------------
716  // Constructor/Destructor functions
717  Ak2DVector() = default;
718 
720  X(x),
721  Y(y)
722  {
723  }
724 
725  //-----------------------------------------------------------
726  // Basic vector operators
728  {
729  X = b.X;
730  Y = b.Y;
731 
732  return *this;
733  }
734 
736  {
737  X = b.theta;
738  Y = b.phi;
739 
740  return *this;
741  }
742 
744  {
745  Ak2DVector v;
746 
747  v.X = X - b.X;
748  v.Y = Y - b.Y;
749 
750  return v;
751  }
752 
754  {
755  X = X * f;
756  Y = Y * f;
757 
758  return *this;
759  }
760 
762  {
763  AkReal32 oneoverf = 1.f / f;
764  X = X * oneoverf;
765  Y = Y * oneoverf;
766 
767  return *this;
768  }
769 
770  AkForceInline bool operator==(const Ak2DVector& b) const
771  {
772  return b.X == X && b.Y == Y;
773  }
774 
775  AkForceInline bool operator!=(const Ak2DVector& b) const
776  {
777  return b.X != X && b.Y != Y;
778  }
779 
781  {
782  return sqrtf(X*X+Y*Y);
783  }
784 
785  //-----------------------------------------------------------
786  // Conversion functions
788  {
789  // (radial, azimuth, elevation)
790  AkReal32 r = sqrtf( in_Cartesian.X*in_Cartesian.X + in_Cartesian.Y*in_Cartesian.Y + in_Cartesian.Z*in_Cartesian.Z);
791  AKASSERT( r != 0);
792 
793  X = atan2f(in_Cartesian.Y, in_Cartesian.X);
794  Y = asinf(in_Cartesian.Z / r);
795 
797 
798  return *this;
799  }
800 
802  const Ak2DVector& A,
803  const Ak2DVector& B) const
804  {
805  Ak2DVector v;
806 
807  // Project coordinates using a vector to matrix multiplication
808  AkReal32 d = (A.X*B.Y - A.Y*B.X);
809 
810  if (d < AKVECTORS_EPSILON && d > -AKVECTORS_EPSILON)
811  {
812  v.X = 0.0f; v.Y = 0.0f;
813  return v;
814  }
815 
816  Ak2DVector invA = Ak2DVector( B.Y, -A.Y );
817  Ak2DVector invB = Ak2DVector( -B.X, A.X );
818 
819  AkReal32 oneover_d = 1.f / d;
820  invA *= oneover_d;
821  invB *= oneover_d;
822 
823  v.X = X * invA.X + Y * invB.X;
824  v.Y = X * invA.Y + Y * invB.Y;
825  // v /= v.Length();
826 
827  return v;
828  }
829 
831  {
832  /*
833  Normalise spherical coordinates.
834  X (azimuthal) -> [-PI, PI], circle lies on xy plan, 0 is on X axix
835  Y (elevation) -> [-PI/2, PI/2], half circle on Z axis, 0 on XY plan, PI/2 straigt up on Z axis.
836  */
837 
838  Ak2DVector v;
839 
840  v.X = X;
841  v.Y = Y;
842 
843  if (X > AKVECTORS_PI)
844  v.X = X - AKVECTORS_TWOPI;
845  else if (X < -AKVECTORS_PI)
846  v.X = X + AKVECTORS_TWOPI;
847 
848  if (Y > AKVECTORS_PIOVERTWO)
849  v.Y = Y - AKVECTORS_PI;
850  else if (Y < -AKVECTORS_PIOVERTWO)
851  v.Y = Y + AKVECTORS_PI;
852 
855 
856  return v;
857  }
858 
860  {
861  /*
862  Normalise spherical coordinates.
863  X (azimuthal) -> [-PI, PI], circle lies on xy plan, 0 is on X axix
864  Y (elevation) -> [-PI/2, PI/2], half circle on Z axis, 0 on XY plan, PI/2 straigt up on Z axis.
865  */
866 
867  if (X > AKVECTORS_PI)
868  X = X - AKVECTORS_TWOPI;
869  else if (X < -AKVECTORS_PI)
870  X = X + AKVECTORS_TWOPI;
871 
872  if (Y > AKVECTORS_PIOVERTWO)
873  Y = Y - AKVECTORS_PI;
874  else if (Y < -AKVECTORS_PIOVERTWO)
875  Y = Y + AKVECTORS_PI;
876  }
877 
878  // Useful in VBAP algorithm, only points that are a positive linear composition matters.
880  {
881  const AkReal32 POSITIVE_TEST_EPSILON = 0.00001f; //0.005f;
882  return X >= -POSITIVE_TEST_EPSILON &&
883  Y >= -POSITIVE_TEST_EPSILON;
884  }
885 
888 };
889 
890 
891 
893 {
894  static const int MAX_SIZE = 16;
895 
896 public:
897  //-----------------------------------------------------------
898  // Constructor/Destructor functions
899  AkMatrix4x4() = default;
900 
901  //-----------------------------------------------------------
902  // Basic vector operators
904  {
905  for (int i = 0; i < MAX_SIZE; i++)
906  m_Data[i] /= f;
907 
908  return *this;
909  }
910 
912  {
913  for (int i = 0; i < MAX_SIZE; i++)
914  {
915  m_Data[i] = in_Data[i];
916  }
917 
918  return *this;
919  }
920 
921  AkReal32 m_Data[MAX_SIZE];
922 };
923 
925 {
926 
927 public:
928  //-----------------------------------------------------------
929  // Constructor/Destructor functions
930  AkMatrix3x3() = default;
931 
932  static AkMatrix3x3 FromColumnVectors(const Ak3DVector& in_col0, const Ak3DVector& in_col1, const Ak3DVector& in_col2)
933  {
934  AkMatrix3x3 m;
935 
936  m(0, 0) = in_col0.X;
937  m(1, 0) = in_col0.Y;
938  m(2, 0) = in_col0.Z;
939 
940  m(0, 1) = in_col1.X;
941  m(1, 1) = in_col1.Y;
942  m(2, 1) = in_col1.Z;
943 
944  m(0, 2) = in_col2.X;
945  m(1, 2) = in_col2.Y;
946  m(2, 2) = in_col2.Z;
947 
948  return m;
949  }
950 
951  //-----------------------------------------------------------
952  // Basic vector operators
954  {
955  for (int i = 0; i < 3; i++)
956  {
957  for (int j = 0; j < 3; j++)
958  {
959  m_Data[i][j] /= f;
960  }
961  }
962  return *this;
963  }
964 
966  {
967  return m_Data[column][row];
968  }
969 
970  AkForceInline const AkReal32& operator()(const AkUInt32 row, const AkUInt32 column) const
971  {
972  return m_Data[column][row];
973  }
974 
976  {
977  Ak3DVector res;
978  res.X = in_rhs.X * m_Data[0][0] + in_rhs.Y * m_Data[1][0] + in_rhs.Z * m_Data[2][0];
979  res.Y = in_rhs.X * m_Data[0][1] + in_rhs.Y * m_Data[1][1] + in_rhs.Z * m_Data[2][1];
980  res.Z = in_rhs.X * m_Data[0][2] + in_rhs.Y * m_Data[1][2] + in_rhs.Z * m_Data[2][2];
981  return res;
982  }
983 
985  {
986  Add(*this, *this, in_rhs);
987  return *this;
988  }
989 
990  static AkForceInline void Add(AkMatrix3x3& out_res, const AkMatrix3x3& in_m0, const AkMatrix3x3& in_m1)
991  {
992 #define ADD(i,j) out_res(i,j) = in_m0(i,j) + in_m1(i,j)
993  ADD(0, 0); ADD(0, 1); ADD(0, 2);
994  ADD(1, 0); ADD(1, 1); ADD(1, 2);
995  ADD(2, 0); ADD(2, 1); ADD(2, 2);
996 #undef ADD
997  }
998 
1000  {
1001  m_Data[0][0] *= in_f; m_Data[0][1] *= in_f; m_Data[0][2] *= in_f;
1002  m_Data[1][0] *= in_f; m_Data[1][1] *= in_f; m_Data[1][2] *= in_f;
1003  m_Data[2][0] *= in_f; m_Data[2][1] *= in_f; m_Data[2][2] *= in_f;
1004  return *this;
1005  }
1006 
1007  static AkForceInline void Diagonal(AkMatrix3x3& out_mat, AkReal32 in_f)
1008  {
1009  out_mat(0, 0) = in_f; out_mat(0, 1) = 0.f; out_mat(0, 2) = 0.f;
1010  out_mat(1, 0) = 0.f; out_mat(1, 1) = in_f; out_mat(1, 2) = 0.f;
1011  out_mat(2, 0) = 0.f; out_mat(2, 1) = 0.f; out_mat(2, 2) = in_f;
1012  }
1013 
1014  // Creates the matrix Mu such that Mu*v = u X v
1015  static AkForceInline void CrossProductMatrix(AkMatrix3x3& out_mat, const Ak3DVector& in_u)
1016  {
1017  out_mat(0, 0) = 0.f; out_mat(0, 1) = -in_u.Z; out_mat(0, 2) = in_u.Y;
1018  out_mat(1, 0) = in_u.Z; out_mat(1, 1) = 0.f; out_mat(1, 2) = -in_u.X;
1019  out_mat(2, 0) = -in_u.Y; out_mat(2, 1) = in_u.X; out_mat(2, 2) = 0.f;
1020  }
1021 
1022  static AkForceInline void OuterProduct(AkMatrix3x3& out_mat, const Ak3DVector& in_v0, const Ak3DVector& in_v1)
1023  {
1024  out_mat(0, 0) = in_v0.X*in_v1.X; out_mat(0, 1) = in_v0.X*in_v1.Y; out_mat(0, 2) = in_v0.X*in_v1.Z;
1025  out_mat(1, 0) = in_v0.Y*in_v1.X; out_mat(1, 1) = in_v0.Y*in_v1.Y; out_mat(1, 2) = in_v0.Y*in_v1.Z;
1026  out_mat(2, 0) = in_v0.Z*in_v1.X; out_mat(2, 1) = in_v0.Z*in_v1.Y; out_mat(2, 2) = in_v0.Z*in_v1.Z;
1027  }
1028 
1029  static AkForceInline void Rotation(AkMatrix3x3& out_mat, AkReal32 in_angle, const Ak3DVector& in_axis)
1030  {
1031  Rotation(out_mat, sinf(in_angle), cosf(in_angle), in_axis);
1032  }
1033 
1034  static void Rotation(AkMatrix3x3& out_mat, AkReal32 in_sin, AkReal32 in_cos, const Ak3DVector& in_axis)
1035  {
1036  Diagonal(out_mat, in_cos);
1037 
1038  AkMatrix3x3 outer;
1039  OuterProduct(outer, in_axis, in_axis);
1040  outer *= (1.f - in_cos);
1041  out_mat += outer;
1042 
1043  AkMatrix3x3 cross;
1044  CrossProductMatrix(cross, in_axis*in_sin);
1045  out_mat += cross;
1046  }
1047 
1048  // [column][row]
1050 };
1051 
1053 {
1054 public:
1055  // Identity quaternion
1056  AkQuaternion(): W(1.f), X(0.f), Y(0.f), Z(0.f) {}
1057 
1058  AkQuaternion(AkReal32 in_W, AkReal32 in_X, AkReal32 in_Y, AkReal32 in_Z) :
1059  W(in_W),
1060  X(in_X),
1061  Y(in_Y),
1062  Z(in_Z)
1063  {}
1064 
1065  // Create a quaternion from a 3x3 rotation matrix
1067  {
1068  AkQuaternion q;
1069 
1070  AkReal32 trace = in_mat(0,0) + in_mat(1, 1) + in_mat(2, 2);
1071  if (trace > 0.0f)
1072  {
1073  AkReal32 srt = sqrtf(trace + 1.f);
1074  AkReal32 s = 0.5f / srt;
1075 
1076  q.W = 0.5f * srt;
1077  q.X = (in_mat(2, 1) - in_mat(1, 2)) * s;
1078  q.Y = (in_mat(0, 2) - in_mat(2, 0)) * s;
1079  q.Z = (in_mat(1, 0) - in_mat(0, 1)) * s;
1080 
1081  }
1082  else
1083  {
1084  // diagonal is negative
1085  AkUInt32 i = 0;
1086  if (in_mat(1, 1) > in_mat(0, 0))
1087  i = 1;
1088  if (in_mat(2, 2) > in_mat(i, i))
1089  i = 2;
1090 
1091  AkUInt32 j = (i + 1) % 3;
1092  AkUInt32 k = (i + 2) % 3;
1093 
1094  AkReal32 s = sqrtf( in_mat(i, i) - in_mat(j, j) - in_mat(k, k) + 1.0f );
1095  AkReal32 t = (s == 0.f) ? 0.f : (0.5f / s);
1096 
1097  AkReal32 qt[4];
1098 
1099  qt[i] = 0.5f * s;
1100  qt[j] = (in_mat(j, i) + in_mat(i, j)) * t;
1101  qt[k] = (in_mat(k, i) + in_mat(i, k)) * t;
1102  qt[3] = (in_mat(k, j) - in_mat(j, k)) * t;
1103 
1104  q.X = qt[0];
1105  q.Y = qt[1];
1106  q.Z = qt[2];
1107  q.W = qt[3];
1108  }
1109 
1110  return q;
1111  }
1112 
1113  // Create a rotation quaternion from euler angles.
1115  AkReal32 in_x, // Rotation around the X axis, in radians.
1116  AkReal32 in_y, // Rotation around the Y axis, in radians.
1117  AkReal32 in_z // Rotation around the Z axis, in radians.
1118  )
1119  {
1120  AkReal32 sy = sinf(in_z / 2.f);
1121  AkReal32 cy = cosf(in_z / 2.f);
1122  AkReal32 sp = sinf(in_y / 2.f);
1123  AkReal32 cp = cosf(in_y / 2.f);
1124  AkReal32 sr = sinf(in_x / 2.f);
1125  AkReal32 cr = cosf(in_x / 2.f);
1126 
1127  AkQuaternion q;
1128  q.W = cr * cp * cy + sr * sp * sy;
1129  q.X = sr * cp * cy - cr * sp * sy;
1130  q.Y = cr * sp * cy + sr * cp * sy;
1131  q.Z = cr * cp * sy - sr * sp * cy;
1132 
1133  return q;
1134  }
1135 
1136  static AkQuaternion FromAngleAndAxis(AkReal32 in_angle, const Ak3DVector& in_axis)
1137  {
1138  AkQuaternion q;
1139 
1140  AkReal32 sa = sinf(in_angle / 2.f);
1141  q.W = cosf(in_angle / 2.f);
1142  q.X = in_axis.X * sa;
1143  q.Y = in_axis.Y * sa;
1144  q.Z = in_axis.Z * sa;
1145 
1146  return q;
1147  }
1148 
1150  {
1151  return sqrtf( W*W + X*X + Y*Y + Z*Z );
1152  }
1153 
1155  {
1156  AkReal32 f = 1.0f / Length();
1157  W *= f;
1158  X *= f;
1159  Y *= f;
1160  Z *= f;
1161  return *this;
1162  }
1163 
1165  {
1166  AkReal32 norm = W*W + X*X + Y*Y + Z*Z;
1167  if (norm > 0.0)
1168  {
1169  AkReal32 invNorm = 1.0f / norm;
1170  return AkQuaternion(W*invNorm, -X*invNorm, -Y*invNorm, -Z*invNorm);
1171  }
1172  else
1173  {
1174  return AkQuaternion();
1175  }
1176  }
1177 
1178  // Create a quaternion representing the shortest arc rotation between (normalized) vectors v0, v1
1179  AkQuaternion(const Ak3DVector& in_v0, const Ak3DVector& in_v1)
1180  {
1181  AkReal32 dot = in_v0.Dot(in_v1);
1182  if (dot >= 1.0f - AKVECTORS_EPSILON)
1183  {
1184  // No rotation - return unity quaternion.
1185  AkQuaternion();
1186  }
1187  if (dot <= -1.f - AKVECTORS_EPSILON)
1188  {
1189  // 180 degree rotation - can use any non-zero length axis.
1190  Ak3DVector axis = Ak3DVector(0.f, 0.f, 1.f).Cross(in_v0);
1191  AkReal32 len = axis.Length();
1192  if (len < AKVECTORS_EPSILON)
1193  {
1194  axis = Ak3DVector(0.f, 1.f, 0.f).Cross(in_v0);
1195  len = axis.Length();
1196  }
1197  axis.Normalize();
1198  AkQuaternion(AKVECTORS_PI, axis);
1199  }
1200  else
1201  {
1202  AkReal32 sqrt = sqrtf((1.f + dot) * 2.f);
1203  AkReal32 invs = 1.f / sqrt;
1204 
1205  Ak3DVector cross = in_v0.Cross(in_v1);
1206 
1207  X = cross.X * invs;
1208  Y = cross.Y * invs;
1209  Z = cross.Z * invs;
1210  W = sqrt * 0.5f;
1211  Normalize();
1212  }
1213  }
1214 
1215  // Build quaternion from an axis and angle representation.
1216  AkQuaternion(AkReal32 in_angle, const Ak3DVector& in_axis)
1217  {
1218  AkReal32 cosHalfAngle = cosf(in_angle / 2.f);
1219  W = cosHalfAngle;
1220  X = cosHalfAngle*in_axis.X;
1221  Y = cosHalfAngle*in_axis.Y;
1222  Z = cosHalfAngle*in_axis.Z;
1223  }
1224 
1225  /// Quaternion multiplication.
1227  {
1228  return AkQuaternion(
1229  W*Q.W - X*Q.X - Y*Q.Y - Z*Q.Z,
1230  W*Q.X + X*Q.W + Y*Q.Z - Z*Q.Y,
1231  W*Q.Y - X*Q.Z + Y*Q.W + Z*Q.X,
1232  W*Q.Z + X*Q.Y - Y*Q.X + Z*Q.W);
1233  }
1234 
1236  {
1237  return RotateVector(in_v);
1238  }
1239 
1241  {
1242  /*
1243  // impl 1
1244  Ak3DVector uv, uuv;
1245  Ak3DVector qvec(X, Y, Z);
1246  uv = qvec.Cross(in_v);
1247  uuv = qvec.Cross(uv);
1248  uv *= (2.0f * W);
1249  uuv *= 2.0f;
1250  return in_v + uv + uuv;
1251  */
1252 
1253  // impl 2
1254  Ak3DVector32 u(X, Y, Z);
1255  Ak3DVector32 res =
1256  u * u.Dot(in_v) * 2.f
1257  + in_v * (W * W - u.Dot(u))
1258  + u.Cross(in_v) * W * 2.0f;
1259 
1260  return res;
1261  }
1262 
1264  {
1265  Ak3DVector32 u(-X, -Y, -Z);
1266  Ak3DVector32 t = 2.f * u.Cross(in_v);
1267  Ak3DVector32 res = in_v + (W * t) + u.Cross(t);
1268  return res;
1269  }
1270 
1275 };
1276 
1278 {
1281 };
1282 
1283 class AkLine
1284 {
1285 public:
1287  mint(1.175494351e-38F),
1288  maxt(3.402823466e+38F)
1289  {
1290  }
1291 
1293  L(in_L),
1294  P(in_P),
1295  mint(1.175494351e-38F),
1296  maxt(3.402823466e+38F)
1297  {
1298  }
1299 
1301  {
1302  return P + L*t;
1303  }
1304 
1306  {
1307  /*
1308  a (V1 X V2) = (P2 - P1) X V2
1309  If the lines intersect at a single point, then the resultant vectors
1310  on each side of this equation must be parallel, and the left side must
1311  not be the zero vector. We should check to make sure that this is
1312  true. Once we have checked this, we can solve for 'a' by taking the
1313  magnitude of each side and dividing. If the resultant vectors are
1314  parallel, but in opposite directions, then 'a' is the negative of the
1315  ratio of magnitudes. Once we have 'a' we can go back to the equation
1316  for L1 to find the intersection point.
1317  */
1318  Ak3DVector V1 = L;
1319  Ak3DVector V2 = B - A;
1320  Ak3DVector P1 = P;
1321  Ak3DVector P2 = A;
1322 
1323  // k(V1 X V2) = (A - P) X V2
1324 
1325  Ak3DVector v1CrossV2 = V1.Cross(V2);
1327  P2 - P1,
1328  V2,
1329  v1CrossV2
1330  );
1331  AkReal32 t = det / v1CrossV2.LengthSquared();
1332 
1334  P2 - P1,
1335  V1,
1336  v1CrossV2
1337  );
1338  AkReal32 s = det / v1CrossV2.LengthSquared();
1339 
1340  AkReal32 distsqrd = ((P2 + V2*s) - (P1 + V1*t)).LengthSquared();
1341 
1342  if ((AkReal32)fabs(v1CrossV2.L2_Norm()) >= AKVECTORS_EPSILON
1343  && distsqrd < 0.001
1344  && s <= 1.0f )
1345  {
1346 #ifdef AKPORTALS_DEBUG
1347  Ak3DVector minPoint = PointAt(t);
1348 
1349  char msg[256];
1350  sprintf(msg, "L1a=[%0.2f,%0.2f,%0.2f];\n", P.X, P.Y, P.Z); AKPLATFORM::OutputDebugMsg(msg);
1351  sprintf(msg, "L1b=[%0.2f,%0.2f,%0.2f];\n", V1.X + P.X, V1.Y + P.Y, V1.Z + P.Z); AKPLATFORM::OutputDebugMsg(msg);
1352  sprintf(msg, "L2a=[%0.2f,%0.2f,%0.2f];\n", A.X, A.Y, A.Z); AKPLATFORM::OutputDebugMsg(msg);
1353  sprintf(msg, "L2b=[%0.2f,%0.2f,%0.2f];\n", B.X, B.Y, B.Z); AKPLATFORM::OutputDebugMsg(msg);
1354  sprintf(msg, "%% t=%0.2f Min t=%0.2f, Max t=%0.2f\n", t, mint, maxt); AKPLATFORM::OutputDebugMsg(msg);
1355  sprintf(msg, "intrPoint=[%0.2f,%0.2f,%0.2f];\n", minPoint.X, minPoint.Y, minPoint.Z); AKPLATFORM::OutputDebugMsg(msg);
1356  sprintf(msg, "\n"); AKPLATFORM::OutputDebugMsg(msg);
1357 #endif
1358 
1359  mint = AkMin(mint, t);
1360  maxt = AkMax(maxt, t);
1361 
1362  return true;
1363  }
1364 
1365 #ifdef AKPORTALS_DEBUG
1366  // char msg[256];
1367  // sprintf(msg, "%% DISCARTED t=%0.2f Min t=%0.2f, Max t=%0.2f\n", t, mint, maxt); AKPLATFORM::OutputDebugMsg(msg);
1368 #endif
1369  return false;
1370  }
1371 
1374 
1377 };
1378 
1379 class AkPlane
1380 {
1381 public:
1382  AkPlane() = default;
1383 
1385  Ak3DVector in_p1,
1386  Ak3DVector in_p2,
1387  Ak3DVector in_p4)
1388  {
1389  SetPlane(
1390  in_p1,
1391  in_p2,
1392  in_p4);
1393  }
1394 
1395  void SetPlane(
1396  Ak3DVector in_p1,
1397  Ak3DVector in_p2,
1398  Ak3DVector in_p4)
1399  {
1400  // Reorder A-B-C to clockwwise if necessary
1401  AKASSERT(in_p1.X < 100000 && in_p1.X > -100000);
1402  AKASSERT(in_p1.Y < 100000 && in_p1.Y > -100000);
1403  AKASSERT(in_p1.Z < 100000 && in_p1.Z > -100000);
1404 
1405  AKASSERT(in_p2.X < 100000 && in_p2.X > -100000);
1406  AKASSERT(in_p2.Y < 100000 && in_p2.Y > -100000);
1407  AKASSERT(in_p2.Z < 100000 && in_p2.Z > -100000);
1408 
1409  AKASSERT(in_p4.X < 100000 && in_p4.X > -100000);
1410  AKASSERT(in_p4.Y < 100000 && in_p4.Y > -100000);
1411  AKASSERT(in_p4.Z < 100000 && in_p4.Z > -100000);
1412 
1413  p1 = in_p1;
1414  p2 = in_p2;
1415  p4 = in_p4;
1416 
1417  SetNormal();
1418 
1419  // Ax + By + Cz + D = 0
1420  // Find D using the normal and a point
1421  D = -(N.X*p1.X) - (N.Y*p1.Y) - (N.Z*p1.Z);
1422  }
1423 
1424 #define EPSILON 0.01f
1426  const Ak3DVector& in_Origin,
1427  const Ak3DVector& in_Destination,
1428  Ak3DVector& out_Intersection
1429  ) const
1430  {
1431  AkReal32 A = N.X;
1432  AkReal32 B = N.Y;
1433  AkReal32 C = N.Z;
1434 
1435  Ak3DVector ray = in_Destination - in_Origin;
1436  AkReal32 rayLength = ray.Length();
1437 
1438  Ak3DVector intersect;
1439 
1440  // If ray is < EPSILON, use on of the point directly for the test and skip the linear projection
1441  if (rayLength <= EPSILON)
1442  {
1443  Ak3DVector temp = in_Origin - p1;
1444  AkReal32 dot = temp.DotProduct(N);
1445  if (dot < EPSILON && dot > -EPSILON)
1446  {
1447  intersect = in_Origin;
1448  }
1449  else
1450  {
1451  // For debug only, to remove
1452  out_Intersection = p1;
1453  return false;
1454  }
1455 
1456  }
1457  else
1458  {
1459  // Normalize ray
1460  ray.Normalize();
1461 
1462  // 1) if ray len ~= 0, only check if one of the point is on target, ie: assign the intersect point
1463 
1464  // Is ray parallel to the plane?
1465  if ((A*ray.X + B*ray.Y + C*ray.Z) == 0.0f)
1466  {
1467  // For debug only, to remove
1468  AkReal32 t = -(A*in_Origin.X + B*in_Origin.Y + C*in_Origin.Z + D) / (A*ray.X + B*ray.Y + C*ray.Z);
1469  intersect = Ak3DVector(in_Origin.X + ray.X*t, in_Origin.Y + ray.Y*t, in_Origin.Z + ray.Z*t);
1470  out_Intersection = intersect; // For debugging
1471  return false;
1472  }
1473 
1474 
1475  // Distance along the ray where reflector is hit
1476  AkReal32 t = -(A*in_Origin.X + B*in_Origin.Y + C*in_Origin.Z + D) / (A*ray.X + B*ray.Y + C*ray.Z);
1477 
1478  // Is the ray going towards the plane? Is it long enough?
1479  if (t < -EPSILON || t >(rayLength + EPSILON))
1480  {
1481  // For debug only, to remove
1482  intersect = Ak3DVector(in_Origin.X + ray.X*t, in_Origin.Y + ray.Y*t, in_Origin.Z + ray.Z*t);
1483  out_Intersection = intersect; // For debugging
1484  return false; // The ray doesn't intersect
1485  }
1486 
1487  // Find the coordinate of intersection on the plane
1488  intersect = Ak3DVector(in_Origin.X + ray.X*t, in_Origin.Y + ray.Y*t, in_Origin.Z + ray.Z*t);
1489  }
1490  ///////////////////////////////////////
1491  //
1492  // p2____v3____p3
1493  // | . |
1494  // ^ inter v4
1495  // v1 v
1496  // | |
1497  // p1__ v2>___p4
1498 
1499  Ak3DVector v1 = p2 - p1;
1500  Ak3DVector v2 = p4 - p1;
1501  Ak3DVector vInter1 = intersect - p1;
1502 
1503  Ak3DVector p3 = p4 + v1;
1504  Ak3DVector v3 = p2 - p3;
1505  Ak3DVector v4 = p4 - p3;
1506  Ak3DVector vInter2 = intersect - p3;
1507 
1508  v1.Normalize(); v2.Normalize(); v3.Normalize(); v4.Normalize(); vInter1.Normalize(); vInter2.Normalize();
1509 
1510  // Since it's a square, the angle between the point of intersection and any segment of the pannel should be < 90 degree,
1511  // therefore the dot product of the two normalized vectors should be > 0
1512  AkReal32 dot1 = v1.DotProduct(vInter1);
1513  AkReal32 dot2 = v2.DotProduct(vInter1);
1514  AkReal32 dot3 = v3.DotProduct(vInter2);
1515  AkReal32 dot4 = v4.DotProduct(vInter2);
1516 
1517  out_Intersection = intersect;
1518 
1519  return dot1 >= -EPSILON && dot2 >= -EPSILON && dot3 >= -EPSILON && dot4 >= -EPSILON;
1520  }
1521 
1523  Ak3DVector in_P,
1524  Ak3DVector& out_B) const
1525  {
1526  AkReal32 distance = (AkReal32)(AkReal32)fabs(N.X * in_P.X + N.Y * in_P.Y + N.Z * in_P.Z + D);
1527 
1528  Ak3DVector pointToPlane = N;
1529  pointToPlane *= distance;
1530 
1531  out_B = in_P + pointToPlane;
1532 
1533  return (AkReal32)fabs(distance);
1534  }
1535 
1537  AkReal32* out_mat) const
1538  {
1539  // http://ami.ektf.hu/uploads/papers/finalpdf/AMI_40_from175to186.pd
1540  /* m_pReflectionMatrix
1541  reflection on z axis
1542 
1543  P0 (x0, y0, z0), P1 (x1, y1, z1) and P2 (x2, y2, z2),
1544  normal = (cx, cy, cz)
1545  d = -CxX0 - CyY0 - CzZ0
1546 
1547  Reflect = 1-2Cx^2 -2CxCy -2CxCz -2Cxd
1548  -2CxCy 1-2Cy^2 -2CyCz -2Cyd
1549  -2CxCz -2CyCz 1-2Cz^2 -2Czd
1550  0 0 0 1
1551  */
1552 
1553  AkReal32 d = -(N.X*p1.X) - (N.Y*p1.Y) - (N.Z*p1.Z);
1554 
1555  out_mat[0] = 1 - 2 * N.X*N.X; out_mat[1] = -2 * N.X*N.Y; out_mat[2] = -2 * N.X*N.Z; out_mat[3] = -2 * N.X*d;
1556  out_mat[0 + 4] = -2 * N.X*N.Y; out_mat[1 + 4] = 1 - 2 * N.Y*N.Y; out_mat[2 + 4] = -2 * N.Y*N.Z; out_mat[3 + 4] = -2 * N.Y*d;
1557  out_mat[0 + 8] = -2 * N.X*N.Z; out_mat[1 + 8] = -2 * N.Y*N.Z; out_mat[2 + 8] = 1 - 2 * N.Z*N.Z; out_mat[3 + 8] = -2 * N.Z*d;
1558  out_mat[0 + 12] = 0; out_mat[1 + 12] = 0; out_mat[2 + 12] = 0; out_mat[3 + 12] = 1;
1559  }
1560 
1561  Ak3DVector GetN() const { return N; }
1562  AkReal32 GetD() const { return D; }
1563 
1565  const AkPlane& in_PlaneB,
1566  AkIntersectionPoints& out_Intrs) const
1567  {
1568  out_Intrs.count = 0;
1569 
1570  // Use vector to solve A
1571 
1572  Ak3DVector point;
1573 
1574  Ak3DVector N1 = N;
1575  Ak3DVector N2 = in_PlaneB.GetN();
1576  AkReal32 D1 = D;
1577  AkReal32 D2 = in_PlaneB.GetD();
1578 
1579  Ak3DVector L = N1.Cross(N2);
1580  if (L.Length() < 0.001f)
1581  {
1582  return false; // The two planes are parallel
1583  }
1584 
1585  AkUInt8 pivotAxis = 0;
1586 
1587  if ((AkReal32)fabs(L.Y) > (AkReal32)fabs(L.X))
1588  {
1589  pivotAxis = 1;
1590  if ((AkReal32)fabs(L.Z) > (AkReal32)fabs(L.Y))
1591  {
1592  pivotAxis = 2;
1593  }
1594  }
1595  else if ((AkReal32)fabs(L.Z) > (AkReal32)fabs(L.X))
1596  {
1597  pivotAxis = 2;
1598  }
1599 
1600  /*
1601  Pu = ( N1v*D2 - N2v*D1 ) / Lw
1602  Pv = ( N2u*D1 - N1u*D2 ) / Lw
1603  Pz = 0
1604  */
1605 
1606  switch (pivotAxis)
1607  {
1608  case 0:
1609  AKASSERT((AkReal32)fabs(L.X) > AKVECTORS_EPSILON);
1610  point.X = 0.f;
1611  point.Y = (N1.Z*D2 - N2.Z*D1) / L.X;
1612  point.Z = (N2.Y*D1 - N1.Y*D2) / L.X;
1613  break;
1614  case 1:
1615  AKASSERT((AkReal32)fabs(L.Y) > AKVECTORS_EPSILON);
1616  point.X = (N1.Z*D2 - N2.Z*D1) / L.Y;
1617  point.Y = 0.f;
1618  point.Z = (N2.X*D1 - N1.X*D2) / L.Y;
1619  break;
1620  case 2:
1621  AKASSERT((AkReal32)fabs(L.Z) > AKVECTORS_EPSILON);
1622  point.X = (N1.Y*D2 - N2.Y*D1) / L.Z;
1623  point.Y = (N2.X*D1 - N1.X*D2) / L.Z;
1624  point.Z = 0.f;
1625  break;
1626  };
1627 
1628 
1629 
1630  L.Normalize();
1631 
1632  AkLine intrLine = AkLine(L, point);
1633  AkLine intrLine2 = AkLine(L, point);
1634 
1635  //in_PlaneB.GetP1()
1636 
1637  // find min max
1638  AkUInt32 cpt = 0;
1639  AkUInt32 cpt2 = 0;
1640  Ak3DVector p3 = GetP2() + (GetP4() - GetP1());
1641 
1642 #ifdef AKPORTALS_DEBUG
1643  char msg[256];
1644  sprintf(msg, "P1a=[%0.2f,%0.2f,%0.2f];\n", GetP1().X, GetP1().Y, GetP1().Z); AKPLATFORM::OutputDebugMsg(msg);
1645  sprintf(msg, "P2a=[%0.2f,%0.2f,%0.2f];\n", GetP2().X, GetP2().Y, GetP2().Z); AKPLATFORM::OutputDebugMsg(msg);
1646  sprintf(msg, "P4a=[%0.2f,%0.2f,%0.2f];\n", GetP4().X, GetP4().Y, GetP4().Z); AKPLATFORM::OutputDebugMsg(msg);
1647 
1648  sprintf(msg, "P1b=[%0.2f,%0.2f,%0.2f];\n", in_PlaneB.GetP1().X, in_PlaneB.GetP1().Y, in_PlaneB.GetP1().Z); AKPLATFORM::OutputDebugMsg(msg);
1649  sprintf(msg, "P2b=[%0.2f,%0.2f,%0.2f];\n", in_PlaneB.GetP2().X, in_PlaneB.GetP2().Y, in_PlaneB.GetP2().Z); AKPLATFORM::OutputDebugMsg(msg);
1650  sprintf(msg, "P4b=[%0.2f,%0.2f,%0.2f];\n", in_PlaneB.GetP4().X, in_PlaneB.GetP4().Y, in_PlaneB.GetP4().Z); AKPLATFORM::OutputDebugMsg(msg);
1651 
1652  sprintf(msg, "line1=[%0.2f,%0.2f,%0.2f];\n", point.X + L.X*1000.f, point.Y + L.Y*1000.f, point.Z + L.Z*1000.f); AKPLATFORM::OutputDebugMsg(msg);
1653  sprintf(msg, "line2=[%0.2f,%0.2f,%0.2f];\n", point.X - L.X*1000.f, point.Y - L.Y*500.f, point.Z - L.Z*500.f); AKPLATFORM::OutputDebugMsg(msg);
1654 
1655 
1656  sprintf(msg, "%% Plane intersec\n"); AKPLATFORM::OutputDebugMsg(msg);
1657 #endif
1658  // for the four lines in rectangle
1659  // Find where the line is crossing with plane A
1660  if (intrLine.Intersect(GetP1(), GetP2())) cpt++;
1661  if (intrLine.Intersect(GetP1(), GetP4())) cpt++;
1662  if (intrLine.Intersect(GetP2(), p3)) cpt++;
1663  if (intrLine.Intersect(p3, GetP4())) cpt++;
1664  //AKASSERT(cpt == 2);
1665 
1666 #ifdef AKPORTALS_DEBUG
1667  sprintf(msg, "%% Portal intersec\n"); AKPLATFORM::OutputDebugMsg(msg);
1668 #endif
1669 
1670  // Find where the line is crossing with plane B
1671  p3 = in_PlaneB.GetP2() + (in_PlaneB.GetP4() - in_PlaneB.GetP1());
1672  if (intrLine2.Intersect(in_PlaneB.GetP1(), in_PlaneB.GetP2())) cpt2++;
1673  if (intrLine2.Intersect(in_PlaneB.GetP1(), in_PlaneB.GetP4())) cpt2++;
1674  if (intrLine2.Intersect(in_PlaneB.GetP2(), p3)) cpt2++;
1675  if (intrLine2.Intersect(p3, in_PlaneB.GetP4())) cpt2++;
1676  // **AKASSERT(cpt2 == 2 || cpt == 2);
1677 
1678  if (cpt < 2 || cpt2 < 2)
1679  {
1680 #ifdef AKPORTALS_DEBUG
1681  sprintf(msg, "%% NON \n"); AKPLATFORM::OutputDebugMsg(msg);
1682  sprintf(msg, "%% _______________________\n"); AKPLATFORM::OutputDebugMsg(msg);
1683 #endif
1684  return false;
1685  }
1686 
1687  AkReal32 start = AkMax(intrLine.mint, intrLine2.mint);
1688  AkReal32 end = AkMin(intrLine.maxt, intrLine2.maxt);
1689 
1690  Ak3DVector minPoint = intrLine.PointAt(start);
1691  Ak3DVector maxPoint = intrLine.PointAt(end);
1692 #ifdef AKPORTALS_DEBUG
1693  sprintf(msg, "P1a=[%0.2f,%0.2f,%0.2f];\n", GetP1().X, GetP1().Y, GetP1().Z); AKPLATFORM::OutputDebugMsg(msg);
1694  sprintf(msg, "P2a=[%0.2f,%0.2f,%0.2f];\n", GetP2().X, GetP2().Y, GetP2().Z); AKPLATFORM::OutputDebugMsg(msg);
1695  sprintf(msg, "P4a=[%0.2f,%0.2f,%0.2f];\n", GetP4().X, GetP4().Y, GetP4().Z); AKPLATFORM::OutputDebugMsg(msg);
1696 
1697  sprintf(msg, "P1b=[%0.2f,%0.2f,%0.2f];\n", in_PlaneB.GetP1().X, in_PlaneB.GetP1().Y, in_PlaneB.GetP1().Z); AKPLATFORM::OutputDebugMsg(msg);
1698  sprintf(msg, "P2b=[%0.2f,%0.2f,%0.2f];\n", in_PlaneB.GetP2().X, in_PlaneB.GetP2().Y, in_PlaneB.GetP2().Z); AKPLATFORM::OutputDebugMsg(msg);
1699  sprintf(msg, "P4b=[%0.2f,%0.2f,%0.2f];\n", in_PlaneB.GetP4().X, in_PlaneB.GetP4().Y, in_PlaneB.GetP4().Z); AKPLATFORM::OutputDebugMsg(msg);
1700 
1701  sprintf(msg, "line1=[%0.2f,%0.2f,%0.2f];\n", point.X + L.X*1000.f, point.Y + L.Y*1000.f, point.Z + L.Z*1000.f); AKPLATFORM::OutputDebugMsg(msg);
1702  sprintf(msg, "line2=[%0.2f,%0.2f,%0.2f];\n", point.X - L.X*1000.f, point.Y - L.Y*500.f, point.Z - L.Z*500.f); AKPLATFORM::OutputDebugMsg(msg);
1703 
1704  sprintf(msg, "intr1=[%0.2f,%0.2f,%0.2f];\n", minPoint.X, minPoint.Y, minPoint.Z); AKPLATFORM::OutputDebugMsg(msg);
1705  sprintf(msg, "intr2=[%0.2f,%0.2f,%0.2f];\n", maxPoint.X, maxPoint.Y, maxPoint.Z); AKPLATFORM::OutputDebugMsg(msg);
1706 
1707  sprintf(msg, "%% _______________________\n"); AKPLATFORM::OutputDebugMsg(msg);
1708 #endif
1709  out_Intrs.points[0] = minPoint;
1710  out_Intrs.points[1] = maxPoint;
1711  out_Intrs.count = 2;
1712 
1713  return true;
1714  }
1715 
1716  Ak3DVector GetP1() const { return p1; }
1717  Ak3DVector GetP2() const { return p2; }
1718  Ak3DVector GetP4() const { return p4; }
1719 
1720 private:
1721  bool SetNormal()
1722  {
1723  //m_pNormal = (B-A) cross (C-A); normalize
1724  Ak3DVector a = p2 - p1;
1725  Ak3DVector b = p4 - p1;
1726 
1727  N = Ak3DVector(a.Y*b.Z - a.Z*b.Y, -(a.X*b.Z - a.Z*b.X), a.X*b.Y - a.Y*b.X);
1728 
1729  AkReal32 len = N.Length();
1730  AKASSERT(len > 0.f);
1731 
1732  if (len > 0)
1733  {
1734  N /= len;
1735  }
1736  else
1737  {
1738  return false;
1739  }
1740 
1741  return true;
1742  };
1743 
1744  /*
1745  p2__________p3
1746  | . |
1747  ^ inter v3
1748  v1 v
1749  | |
1750  p1__ v2>___p4
1751  */
1752 
1753  Ak3DVector p1; // Bottom left
1754  Ak3DVector p2; // Top left
1755  Ak3DVector p4; // Tottom right
1756  Ak3DVector N; // Normal vector
1757  AkReal32 D; // Plane equation: Ax + By + Cz = D => N.Xx + N.Yy + N.Zz = D
1758 };
1759 
1760 template<typename TReal>
1762 {
1764 
1765  TBoundingBox(const TVectorType& in_min, const TVectorType& in_max) :
1766  m_Min(in_min),
1767  m_Max(in_max)
1768  {}
1769 
1771  m_Min(TVectorType(RealPrecision<TReal>::MAX_VALUE, RealPrecision<TReal>::MAX_VALUE, RealPrecision<TReal>::MAX_VALUE)),
1772  m_Max(TVectorType(-RealPrecision<TReal>::MAX_VALUE, -RealPrecision<TReal>::MAX_VALUE, -RealPrecision<TReal>::MAX_VALUE))
1773  {}
1774 
1775  void Update(const TVectorType& in_point)
1776  {
1777  if (m_Min.X > in_point.X)
1778  m_Min.X = in_point.X;
1779 
1780  if (m_Min.Y > in_point.Y)
1781  m_Min.Y = in_point.Y;
1782 
1783  if (m_Min.Z > in_point.Z)
1784  m_Min.Z = in_point.Z;
1785 
1786  if (m_Max.X < in_point.X)
1787  m_Max.X = in_point.X;
1788 
1789  if (m_Max.Y < in_point.Y)
1790  m_Max.Y = in_point.Y;
1791 
1792  if (m_Max.Z < in_point.Z)
1793  m_Max.Z = in_point.Z;
1794  }
1795 
1796  AkForceInline bool IsWithin(const TVectorType& in_Point) const
1797  {
1798  return in_Point >= m_Min && in_Point <= m_Max;
1799  }
1800 
1801  AkForceInline bool IsWithin(const TBoundingBox& in_BB) const
1802  {
1803  return (m_Min.X <= in_BB.m_Max.X && m_Max.X >= in_BB.m_Min.X) &&
1804  (m_Min.Y <= in_BB.m_Max.Y && m_Max.Y >= in_BB.m_Min.Y) &&
1805  (m_Min.Z <= in_BB.m_Max.Z && m_Max.Z >= in_BB.m_Min.Z);
1806  }
1807 
1809  {
1810  TBoundingBox result;
1811 
1812  result.m_Max.X = AkMin(m_Max.X, in_BB.m_Max.X);
1813  result.m_Max.Y = AkMin(m_Max.Y, in_BB.m_Max.Y);
1814  result.m_Max.Z = AkMin(m_Max.Z, in_BB.m_Max.Z);
1815 
1816  result.m_Min.X = AkMax(m_Min.X, in_BB.m_Min.X);
1817  result.m_Min.Y = AkMax(m_Min.Y, in_BB.m_Min.Y);
1818  result.m_Min.Z = AkMax(m_Min.Z, in_BB.m_Min.Z);
1819 
1820  return result;
1821  }
1822 
1823  AkForceInline bool IsEmpty() const
1824  {
1825  return (m_Min.X >= m_Max.X) || (m_Min.Y >= m_Max.Y) || (m_Min.Z >= m_Max.Z);
1826  }
1827 
1828  AkForceInline bool IsValid() const
1829  {
1830  return (m_Min.X <= m_Max.X) && (m_Min.Y <= m_Max.Y) && (m_Min.Z <= m_Max.Z);
1831  }
1832 
1835 };
1836 
1839 
1840 class AkBox
1841 {
1842 public:
1843  AkBox() = default;
1844 
1845  void Init(
1846  const Ak3DVector& in_center,
1847  const Ak3DVector& in_extent,
1848  const Ak3DVector& in_Front,
1849  const Ak3DVector& in_Up)
1850  {
1851  AKASSERT(fabs(in_Front.Length() - 1.f) < 0.001 && fabs(in_Up.Length() - 1.f) < 0.001);//Must be unit vectors.
1852  AKASSERT(fabs(in_Front.Dot(in_Up) - 0.f) < 0.001); //Must be orthogonal.
1853 
1854  m_Center = in_center;
1855  m_Extent = in_extent;
1856 
1857  m_Z = in_Front;
1858  m_Y = in_Up;
1859  m_X = m_Z.Cross(m_Y);
1860  }
1861 
1862  bool IsPointInBox(const Ak3DVector& in_Point) const
1863  {
1864  Ak3DVector pt = in_Point - m_Center;
1865  return fabs(pt.Dot(m_X)) <= m_Extent.X && fabs(pt.Dot(m_Y)) <= m_Extent.Y && fabs(pt.Dot(m_Z)) <= m_Extent.Z;
1866  }
1867 
1868  Ak3DVector GetSize() const { return m_Extent*2.f; }
1869  Ak3DVector GetCenter() const { return m_Center; }
1870 
1871  Ak3DVector GetUx() const { return m_X; }
1872  Ak3DVector GetUy() const { return m_Y; }
1873  Ak3DVector GetUz() const { return m_Z; }
1874 
1875  Ak3DVector GetFront() const { return m_Z; }
1876  Ak3DVector GetUp() const { return m_Y; }
1877  Ak3DVector GetSide() const { return m_X; }
1878 
1880  {
1881  Ak3DVector size = GetSize();
1882  return size.X * size.Y * size.Z;
1883  }
1884 
1886  const Ak3DVector& L,
1887  const AkBox& B) const
1888  {
1889  // Separating Axis Theorem for Oriented Bounding Boxes by Johnny Huynh
1890  const AkBox& A = *this;
1891  Ak3DVector T = B.GetCenter() - A.GetCenter();
1892 
1893  AkReal32 WA = A.m_Extent.X;
1894  AkReal32 HA = A.m_Extent.Y;
1895  AkReal32 DA = A.m_Extent.Z;
1896 
1897  AkReal32 WB = B.m_Extent.X;
1898  AkReal32 HB = B.m_Extent.Y;
1899  AkReal32 DB = B.m_Extent.Z;
1900 
1901  Ak3DVector Ax = A.GetUx();
1902  Ak3DVector Ay = A.GetUy();
1903  Ak3DVector Az = A.GetUz();
1904 
1905  Ak3DVector Bx = B.GetUx();
1906  Ak3DVector By = B.GetUy();
1907  Ak3DVector Bz = B.GetUz();
1908 
1909  /*
1910  | T • L | > | (WA*Ax) • L | + | (HA*Ay) • L | + |(DA*Az) • L | +
1911  | (WB*Bx) • L | +| (HB*By) • L | +| (DB*Bz) • L |*/
1912 
1913  AkReal32 left = (AkReal32)fabs(T.DotProduct(L));
1914  AkReal32 dpax = (AkReal32)fabs((Ax*WA).DotProduct(L));
1915  AkReal32 dpay = (AkReal32)fabs((Ay*HA).DotProduct(L));
1916  AkReal32 dpaz = (AkReal32)fabs((Az*DA).DotProduct(L));
1917  AkReal32 dpbx = (AkReal32)fabs((Bx*WB).DotProduct(L));
1918  AkReal32 dpby = (AkReal32)fabs((By*HB).DotProduct(L));
1919  AkReal32 dpbz = (AkReal32)fabs((Bz*DB).DotProduct(L));
1920 
1921  AkReal32 right = dpax + dpay + dpaz + dpbx + dpby + dpbz;
1922 
1923  return left > right;
1924  }
1925 
1926  void UpdateBoundingBox(AkBoundingBox& out_aabb) const
1927  {
1928  Ak3DVector x = m_X * m_Extent.X;
1929  out_aabb.Update(m_Center + x);
1930  out_aabb.Update(m_Center - x);
1931  Ak3DVector y = m_Y * m_Extent.Y;
1932  out_aabb.Update(m_Center + y);
1933  out_aabb.Update(m_Center - y);
1934  Ak3DVector Z = m_Z * m_Extent.Z;
1935  out_aabb.Update(m_Center + Z);
1936  out_aabb.Update(m_Center - Z);
1937  }
1938 
1939 private:
1940 
1941  Ak3DVector m_Center;
1942  Ak3DVector m_Extent;
1943 
1944  //Orthonormal Axes
1945  Ak3DVector m_X;
1946  Ak3DVector m_Y;
1947  Ak3DVector m_Z;
1948 };
AkMatrix3x3 & operator/=(const AkReal32 f)
Definition: AkVectors.h:953
AkForceInline T3DVector & operator*=(const TDataType f)
Definition: AkVectors.h:368
AkForceInline AkQuaternion & Normalize()
Definition: AkVectors.h:1154
#define AkMin(x1, x2)
T3DVector< AkReal32 > Ak3DVector
Definition: AkVectors.h:691
TDataType X
Definition: AkVectors.h:666
bool FindIntersectionPoints(const AkPlane &in_PlaneB, AkIntersectionPoints &out_Intrs) const
Definition: AkVectors.h:1564
T3DVector(const AkVector &in_vector)
Definition: AkVectors.h:250
AkReal32 DistPoint_to_Plane(Ak3DVector in_P, Ak3DVector &out_B) const
Definition: AkVectors.h:1522
#define AKVECTORS_TWOPI
Definition: AkVectors.h:47
Ak3DVector GetUz() const
Definition: AkVectors.h:1873
T3DVector(TDataType in_x, TDataType in_y, TDataType in_z)
Definition: AkVectors.h:231
AkForceInline T3DVector Abs() const
Definition: AkVectors.h:649
AkInt32 Y
Y Position.
Definition: AkVectors.h:122
static AkReal64 ACos(AkReal64 in_value)
Definition: AkVectors.h:163
Ak3DVector points[2]
Definition: AkVectors.h:1279
AkForceInline bool operator==(const T3DVector &b) const
Definition: AkVectors.h:338
AkForceInline bool IsWithin(const TBoundingBox &in_BB) const
Definition: AkVectors.h:1801
AkPlane()=default
AkForceInline Ak2DVector operator=(const Ak2DVector &b)
Definition: AkVectors.h:727
TBoundingBox< AkReal32 > AkBoundingBox
Definition: AkVectors.h:1837
T3DVector< AkReal64 > Ak3DVector64
Definition: AkVectors.h:695
#define AKVECTORS_PI
Definition: AkVectors.h:46
#define AkMax(x1, x2)
Ak3DVector GetN() const
Definition: AkVectors.h:1561
Ak3DVector PointAt(AkReal32 t) const
Definition: AkVectors.h:1300
bool Intersect(Ak3DVector A, Ak3DVector B)
Definition: AkVectors.h:1305
AkReal32 phi
Elevation.
Definition: AkTypes.h:729
AkReal32 X
Definition: AkVectors.h:1272
Ak4DVector operator-(const Ak4DVector &b) const
Definition: AkVectors.h:94
bool SeparatingAxisExists(const Ak3DVector &L, const AkBox &B) const
Definition: AkVectors.h:1885
AkSafeConversion TTypeConverter
Definition: AkVectors.h:218
bool IsPointInBox(const Ak3DVector &in_Point) const
Definition: AkVectors.h:1862
TDataType Y
Definition: AkVectors.h:667
static AkReal64 Cos(AkReal64 in_value)
Definition: AkVectors.h:160
static bool IsFinite(AkReal64 in_val)
Definition: AkVectors.h:164
AkForceInline AkQuaternion Inverse() const
Definition: AkVectors.h:1164
AkForceInline AkQuaternion operator*(const AkQuaternion &Q) const
Quaternion multiplication.
Definition: AkVectors.h:1226
Ak4DVector & operator/=(const AkReal32 f)
Definition: AkVectors.h:84
Ak3DIntVector(AkInt32 x, AkInt32 y, AkInt32 z)
Definition: AkVectors.h:114
static AkQuaternion FromRotationMatrix(const AkMatrix3x3 &in_mat)
Definition: AkVectors.h:1066
void SetPlane(Ak3DVector in_p1, Ak3DVector in_p2, Ak3DVector in_p4)
Definition: AkVectors.h:1395
void OutputDebugMsg(const char *in_pszMsg)
Output a debug message on the console (Ansi string)
AkMatrix4x4()=default
static AkForceInline void Diagonal(AkMatrix3x3 &out_mat, AkReal32 in_f)
Definition: AkVectors.h:1007
T3DVector(TDataType in_scalar)
Definition: AkVectors.h:295
AkForceInline bool IsEmpty() const
Definition: AkVectors.h:1823
T3DVector< AkReal32 > Ak3DVector32
Definition: AkVectors.h:692
static void Rotation(AkMatrix3x3 &out_mat, AkReal32 in_sin, AkReal32 in_cos, const Ak3DVector &in_axis)
Definition: AkVectors.h:1034
float32x4_t AKSIMD_V4F32
Vector of 4 32-bit floats.
Definition: AkSimdTypes.h:62
AkForceInline bool operator==(const Ak2DVector &b) const
Definition: AkVectors.h:770
Ak3DVector GetUx() const
Definition: AkVectors.h:1871
uint8_t AkUInt8
Unsigned 8-bit integer.
void UpdateBoundingBox(AkBoundingBox &out_aabb) const
Definition: AkVectors.h:1926
static AkReal64 Sqrt(AkReal64 in_value)
Definition: AkVectors.h:162
Ak3DVector GetCenter() const
Definition: AkVectors.h:1869
static AkForceInline TDataType Determinant(const T3DVector &a, const T3DVector &b, const T3DVector &c)
Definition: AkVectors.h:540
float AkReal32
32-bit floating point
Ak2DVector & operator/=(const AkReal32 f)
Definition: AkVectors.h:761
AkForceInline T3DVector LinearCombination(const T3DVector &A, const T3DVector &B, const T3DVector &C) const
Definition: AkVectors.h:550
static AkReal32 Sqrt(AkReal32 in_value)
Definition: AkVectors.h:142
AkReal32 X
Definition: AkVectors.h:886
int32_t AkInt32
Signed 32-bit integer.
AkReal32 maxt
Definition: AkVectors.h:1376
static AkMatrix3x3 FromColumnVectors(const Ak3DVector &in_col0, const Ak3DVector &in_col1, const Ak3DVector &in_col2)
Definition: AkVectors.h:932
TBoundingBox Intersect(const TBoundingBox &in_BB) const
Definition: AkVectors.h:1808
Ak2DVector()=default
AkForceInline TDataType DotProduct(const T3DVector &v2) const
Definition: AkVectors.h:608
AkForceInline T3DVector operator-(const T3DVector &b) const
Definition: AkVectors.h:466
AkForceInline T3DVector & operator/=(const TDataType f)
Definition: AkVectors.h:377
AkForceInline T3DVector operator*(const T3DVector v2) const
Definition: AkVectors.h:387
#define AKVECTORS_PIOVERTWO
Definition: AkVectors.h:48
AkForceInline bool IsFinite() const
Definition: AkVectors.h:658
Ak4DVector & operator=(const Ak4DVector &b)
Definition: AkVectors.h:74
AkForceInline bool operator!=(const Ak2DVector &b) const
Definition: AkVectors.h:775
AkForceInline void Convert(AkReal64 &out_to, AkReal32 in_from)
Definition: AkVectors.h:195
AkForceInline bool IsAllPositive() const
Definition: AkVectors.h:879
AkForceInline AkReal32 Length() const
Definition: AkVectors.h:780
Ak4DVector()
Definition: AkVectors.h:56
Ak3DVector GetSide() const
Definition: AkVectors.h:1877
AkLine()
Definition: AkVectors.h:1286
AkReal32 Y
Y Position.
Definition: AkTypes.h:405
Ak2DVector(AkReal32 x, AkReal32 y)
Definition: AkVectors.h:719
static AkReal64 Sin(AkReal64 in_value)
Definition: AkVectors.h:161
AkForceInline AkMatrix3x3 & operator*=(const AkReal32 &in_f)
Definition: AkVectors.h:999
AkMatrix4x4 & operator=(AkReal32 *in_Data)
Definition: AkVectors.h:911
void Update(const TVectorType &in_point)
Definition: AkVectors.h:1775
static AkQuaternion FromAngleAndAxis(AkReal32 in_angle, const Ak3DVector &in_axis)
Definition: AkVectors.h:1136
AkForceInline TDataType LengthSquared() const
Definition: AkVectors.h:636
AkReal32 GetVolume() const
Definition: AkVectors.h:1879
AkReal32 GetD() const
Definition: AkVectors.h:1562
AkForceInline TDataType Dot(const T3DVector &v2) const
Definition: AkVectors.h:613
AkReal32 X
X Position.
Definition: AkTypes.h:404
TDataType data_type
Definition: AkVectors.h:215
AkForceInline bool operator!=(const T3DVector &b) const
Definition: AkVectors.h:343
Ak2DVector operator-(const Ak2DVector &b) const
Definition: AkVectors.h:743
#define AKSIMD_GETELEMENT_V4F32(__vName, __num__)
Get the element at index num in vector __vName.
Definition: AkSimd.h:37
AkReal32 m_Data[MAX_SIZE]
Definition: AkVectors.h:921
AkForceInline T3DVector operator+(const TDataType f) const
Definition: AkVectors.h:433
AkForceInline T3DVector< TDataType > operator*(const TDataType f, const T3DVector< TDataType > &v)
Definition: AkVectors.h:672
#define AKASSERT(Condition)
Definition: AkAssert.h:67
AkForceInline T3DVector operator-(const TDataType f) const
Definition: AkVectors.h:444
AkReal32 v[4]
Definition: AkVectors.h:106
Spherical coordinates.
Definition: AkTypes.h:728
static AkForceInline T3DVector Min(const T3DVector &A, const T3DVector &B)
Definition: AkVectors.h:487
AkForceInline T3DVector SphericalToCartesian(const TDataType azimuth, const TDataType elevation)
Definition: AkVectors.h:527
AkReal32 mint
Definition: AkVectors.h:1375
AkForceInline AKSIMD_V4F32 PointV4F32() const
Definition: AkVectors.h:309
AkMatrix3x3()=default
AkReal32 Z
Z Position.
Definition: AkTypes.h:406
static AkForceInline void OuterProduct(AkMatrix3x3 &out_mat, const Ak3DVector &in_v0, const Ak3DVector &in_v1)
Definition: AkVectors.h:1022
AkForceInline void Convert(TReal &out_to, TReal in_from)
Definition: AkVectors.h:200
Ak3DVector GetFront() const
Definition: AkVectors.h:1875
Ak3DVector GetUy() const
Definition: AkVectors.h:1872
AkForceInline T3DVector operator+(const T3DVector &b) const
Definition: AkVectors.h:455
AkReal32 Y
Definition: AkVectors.h:887
static AkForceInline void Add(AkMatrix3x3 &out_res, const AkMatrix3x3 &in_m0, const AkMatrix3x3 &in_m1)
Definition: AkVectors.h:990
TVectorType Cast() const
Definition: AkVectors.h:702
AkMatrix4x4 & operator/=(const AkReal32 f)
Definition: AkVectors.h:903
TBoundingBox< AkReal64 > AkBoundingBox64
Definition: AkVectors.h:1838
Ak3DIntVector()=default
AkForceInline Ak3DVector UnrotateVector(const Ak3DVector32 &in_v) const
Definition: AkVectors.h:1263
AkForceInline AkReal32 & operator()(const AkUInt32 row, const AkUInt32 column)
Definition: AkVectors.h:965
AkReal32 W
Definition: AkVectors.h:1271
AkQuaternion(AkReal32 in_angle, const Ak3DVector &in_axis)
Definition: AkVectors.h:1216
AkForceInline T3DVector< TDataType > operator/(const TDataType f, const T3DVector< TDataType > &v)
Definition: AkVectors.h:678
AkLine(Ak3DVector in_L, Ak3DVector in_P)
Definition: AkVectors.h:1292
static AkQuaternion FromEulers(AkReal32 in_x, AkReal32 in_y, AkReal32 in_z)
Definition: AkVectors.h:1114
double AkReal64
64-bit floating point
static AkForceInline void CrossProductMatrix(AkMatrix3x3 &out_mat, const Ak3DVector &in_u)
Definition: AkVectors.h:1015
bool DoesRayIntersect(const Ak3DVector &in_Origin, const Ak3DVector &in_Destination, Ak3DVector &out_Intersection) const
Definition: AkVectors.h:1425
Ak3DVector P
Definition: AkVectors.h:1373
AkReal32 Z
Definition: AkVectors.h:1274
AkForceInline Ak3DVector32 operator*(const Ak3DVector32 &in_v) const
Definition: AkVectors.h:1235
AkBox()=default
AkForceInline bool operator<(const T3DVector &b) const
Definition: AkVectors.h:348
static AkReal32 Cos(AkReal32 in_value)
Definition: AkVectors.h:140
AkForceInline Ak2DVector NormalizeSpherical() const
Definition: AkVectors.h:830
AkForceInline bool IsWithin(const TVectorType &in_Point) const
Definition: AkVectors.h:1796
uint64_t AkUInt64
Unsigned 64-bit integer.
AkReal64 Y
Y Position.
Definition: AkTypes.h:356
#define ADD(i, j)
void Zero()
Definition: AkVectors.h:329
AkForceInline void NormalizeSpherical()
Definition: AkVectors.h:859
static AkForceInline void Rotation(AkMatrix3x3 &out_mat, AkReal32 in_angle, const Ak3DVector &in_axis)
Definition: AkVectors.h:1029
Ak3DVector GetUp() const
Definition: AkVectors.h:1876
#define AKVECTORS_EPSILON
Definition: AkVectors.h:49
TVectorType m_Max
Definition: AkVectors.h:1834
AkForceInline T3DVector Rotate180X_90Y() const
Definition: AkVectors.h:516
static AkReal32 Sin(AkReal32 in_value)
Definition: AkVectors.h:141
void Init(const Ak3DVector &in_center, const Ak3DVector &in_extent, const Ak3DVector &in_Front, const Ak3DVector &in_Up)
Definition: AkVectors.h:1845
AkReal32 theta
Azimuth.
Definition: AkTypes.h:723
AkForceInline AkMatrix3x3 & operator+=(const AkMatrix3x3 &in_rhs)
Definition: AkVectors.h:984
AkReal32 Y
Definition: AkVectors.h:1273
AkForceInline bool IsValid() const
Definition: AkVectors.h:1828
Ak3DVector GetP2() const
Definition: AkVectors.h:1717
AkForceInline const AkReal32 & operator()(const AkUInt32 row, const AkUInt32 column) const
Definition: AkVectors.h:970
AkForceInline bool operator>=(const T3DVector &b) const
Definition: AkVectors.h:363
AkForceInline T3DVector operator/(const TDataType f) const
Definition: AkVectors.h:420
3D 64-bit vector. Intended as storage for world positions of sounds and objects, benefiting from 64-b...
Definition: AkTypes.h:327
AkForceInline Ak2DVector & CartesianToSpherical(const Ak3DVector &in_Cartesian)
Definition: AkVectors.h:787
AkPlane(Ak3DVector in_p1, Ak3DVector in_p2, Ak3DVector in_p4)
Definition: AkVectors.h:1384
uint32_t AkUInt32
Unsigned 32-bit integer.
AkQuaternion(const Ak3DVector &in_v0, const Ak3DVector &in_v1)
Definition: AkVectors.h:1179
static AkReal32 ACos(AkReal32 in_value)
Definition: AkVectors.h:143
AkInt32 X
X Position.
Definition: AkVectors.h:121
AkForceInline T3DVector operator/(const T3DVector in_rhs) const
Definition: AkVectors.h:409
#define EPSILON
Definition: AkVectors.h:1424
TDataType Z
Definition: AkVectors.h:668
3D vector for some operations in 3D space. Typically intended only for localized calculations due to ...
Definition: AkTypes.h:362
Ak3DVector GetSize() const
Definition: AkVectors.h:1868
Ak3DVector GetP1() const
Definition: AkVectors.h:1716
T3DVector(const AKSIMD_V4F32 &in_v4f32)
Definition: AkVectors.h:302
AkForceInline bool IsAllPositive() const
Definition: AkVectors.h:642
AkForceInline TDataType HorizontalMax() const
Definition: AkVectors.h:482
Ak3DVector GetP4() const
Definition: AkVectors.h:1718
AkForceInline void Convert(TToReal &out_to, TFromReal in_from)
Definition: AkVectors.h:183
AkForceInline TDataType L2_Norm() const
Definition: AkVectors.h:603
AkForceInline AkReal32 Length() const
Definition: AkVectors.h:1149
AkForceInline bool Equals(const T3DVector &b, const TDataType tolerance=static_cast< TDataType >(0.0)) const
Definition: AkVectors.h:509
AkReal64 Z
Z Position.
Definition: AkTypes.h:357
AkInt32 Z
Z Position.
Definition: AkVectors.h:123
AkForceInline T3DVector operator*(const TDataType f) const
Definition: AkVectors.h:398
#define AkForceInline
Definition: AkTypes.h:63
static AkForceInline T3DVector Max(const T3DVector &A, const T3DVector &B)
Definition: AkVectors.h:498
void SetReflection(AkReal32 *out_mat) const
Definition: AkVectors.h:1536
AkForceInline bool operator<=(const T3DVector &b) const
Definition: AkVectors.h:353
AkForceInline Ak3DVector operator*(const Ak3DVector &in_rhs) const
Definition: AkVectors.h:975
Ak4DVector(const AkVector &b)
Definition: AkVectors.h:64
AkForceInline T3DVector & Normalize()
Definition: AkVectors.h:585
Ak3DVector L
Definition: AkVectors.h:1372
Ak2DVector & operator*=(const AkReal32 f)
Definition: AkVectors.h:753
AkForceInline Ak3DVector RotateVector(const Ak3DVector32 &in_v) const
Definition: AkVectors.h:1240
T3DVector(const T3DVector< TFromDataType > &in_vector)
Definition: AkVectors.h:240
AkForceInline T3DVector Cross(const T3DVector &v) const
Definition: AkVectors.h:618
AkForceInline Ak2DVector operator=(const AkSphericalCoord &b)
Definition: AkVectors.h:735
AkForceInline bool operator>(const T3DVector b) const
Definition: AkVectors.h:358
AkForceInline TDataType HorizontalMin() const
Definition: AkVectors.h:477
AkForceInline Ak2DVector LinearCombination(const Ak2DVector &A, const Ak2DVector &B) const
Definition: AkVectors.h:801
static bool IsFinite(AkReal32 in_val)
Definition: AkVectors.h:144
AkReal64 X
X Position.
Definition: AkTypes.h:355
AkQuaternion(AkReal32 in_W, AkReal32 in_X, AkReal32 in_Y, AkReal32 in_Z)
Definition: AkVectors.h:1058
TVectorType m_Min
Definition: AkVectors.h:1833
AkReal32 m_Data[3][3]
Definition: AkVectors.h:1049
AkForceInline TDataType Length() const
Definition: AkVectors.h:631
T3DVector(const AkVector64 &in_vector)
Definition: AkVectors.h:260
AkForceInline AKSIMD_V4F32 VectorV4F32() const
Definition: AkVectors.h:319
TBoundingBox(const TVectorType &in_min, const TVectorType &in_max)
Definition: AkVectors.h:1765

Was this page helpful?

Need Support?

Questions? Problems? Need more info? Contact us, and we can help!

Visit our Support page

Tell us about your project. We're here to help.

Register your project and we'll help you get started with no strings attached!

Get started with Wwise