Version
menu_open
link
Wwise SDK 2022.1.11
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  //-----------------------------------------------------------
510  // Conversion functions
512  {
513  T3DVector v;
514 
515  v.X = -X;
516  v.Y = Z;
517  v.Z = -Y;
518 
519  return v;
520  }
521 
523  const TDataType azimuth,
524  const TDataType elevation)
525  {
526  TDataType cosElevation = RealPrecision<TDataType>::Cos(elevation);
527  X = RealPrecision<TDataType>::Cos(azimuth) * cosElevation;
528  Y = RealPrecision<TDataType>::Sin(azimuth) * cosElevation;
529  Z = RealPrecision<TDataType>::Sin(elevation);
530 
531  return *this;
532  }
533 
534  // Determinant of 3 column vectors.
535  static AkForceInline TDataType Determinant(
536  const T3DVector& a,
537  const T3DVector& b,
538  const T3DVector& c)
539  {
540  return (a.X*b.Y*c.Z + a.Y*b.Z*c.X + a.Z*b.X*c.Y) -
541  (a.Z*b.Y*c.X + a.Y*b.X*c.Z + a.X*b.Z*c.Y);
542  }
543 
544  // Convert a vector to a different base
546  const T3DVector& A,
547  const T3DVector& B,
548  const T3DVector& C) const
549  {
550  T3DVector v;
551 
552  TDataType d = Determinant(A, B, C);
553 
555  {
556  v.X = static_cast<TDataType>(0.0); v.Y = static_cast<TDataType>(0.0); v.Z = static_cast<TDataType>(0.0);
557  return v;
558  }
559 
560  // http://mathworld.wolfram.com/MatrixInverse.html
561  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);
562  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);
563  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);
564 
565  TDataType oneover_d = static_cast<TDataType>(1.0) / d;
566  invA *= oneover_d;
567  invB *= oneover_d;
568  invC *= oneover_d;
569 
570  // Project coordinates using a vector to matrix multiplication
571  v.X = X * invA.X + Y * invB.X + Z * invC.X;
572  v.Y = X * invA.Y + Y * invB.Y + Z * invC.Y;
573  v.Z = X * invA.Z + Y * invB.Z + Z * invC.Z;
574 
575  // v /= v.Length();
576 
577  return v;
578  }
579 
581  {
582  TDataType l = Length();
583  if (l != static_cast<TDataType>(0.0))
584  {
585  X /= l;
586  Y /= l;
587  Z /= l;
588  }
589  else
590  {
591  X = static_cast<TDataType>(0.0);
592  Y = static_cast<TDataType>(0.0);
593  Z = static_cast<TDataType>(0.0);
594  }
595  return *this;
596  }
597 
598  AkForceInline TDataType L2_Norm() const
599  {
600  return RealPrecision<TDataType>::Sqrt(X*X + Y*Y + Z*Z);
601  }
602 
603  AkForceInline TDataType DotProduct(const T3DVector& v2) const
604  {
605  return X*v2.X + Y*v2.Y + Z*v2.Z;
606  }
607 
608  AkForceInline TDataType Dot(const T3DVector& v2) const
609  {
610  return DotProduct(v2);
611  }
612 
614  {
615  T3DVector uxv;
616 
617  const T3DVector& u = *this;
618 
619  uxv.X = u.Y*v.Z - u.Z*v.Y;
620  uxv.Y = u.Z*v.X - u.X*v.Z;
621  uxv.Z = u.X*v.Y - u.Y*v.X;
622 
623  return uxv;
624  }
625 
626  AkForceInline TDataType Length() const
627  {
628  return RealPrecision<TDataType>::Sqrt(X*X + Y*Y + Z*Z);
629  }
630 
631  AkForceInline TDataType LengthSquared() const
632  {
633  return X*X + Y*Y + Z*Z;
634  }
635 
636  // Usefull in VBAP algorithm, only points that are a positive linear composition matters.
638  {
642  }
643 
645  {
646  T3DVector abs = *this;
647  abs.X = (TDataType)fabs(abs.X);
648  abs.Y = (TDataType)fabs(abs.Y);
649  abs.Z = (TDataType)fabs(abs.Z);
650  return abs;
651  }
652 
653  AkForceInline bool IsFinite() const
654  {
655  return
659  }
660 
661  TDataType X;
662  TDataType Y;
663  TDataType Z;
664 };
665 
666 template<typename TDataType>
668 {
669  return v * f;
670 }
671 
672 template<typename TDataType>
674 {
676  res.X = f / v.X;
677  res.Y = f / v.Y;
678  res.Z = f / v.Z;
679  return res;
680 }
681 
682 
683 // Ak3DVector typedefs
684 
685 // Ak3DVector32 - Can be implicitly converted to 64 but not the other way around.
688 
689 // Ak3DVector64 - It is necessary to call vec.Cast<Ak3DVector64>() to convert to 32 bit vector type.
691 
692 // Casting methods.
693 
694 // Generic cast between two T3DVector<> types.
695 template<typename TDataType>
696 template<typename TVectorType>
697 TVectorType T3DVector<TDataType>::Cast() const
698 {
699  TVectorType v;
700  v.X = static_cast<typename TVectorType::data_type>(X);
701  v.Y = static_cast<typename TVectorType::data_type>(Y);
702  v.Z = static_cast<typename TVectorType::data_type>(Z);
703  return v;
704 }
705 
706 
708 {
709 public:
710  //-----------------------------------------------------------
711  // Constructor/Destructor functions
712  Ak2DVector() = default;
713 
715  X(x),
716  Y(y)
717  {
718  }
719 
720  //-----------------------------------------------------------
721  // Basic vector operators
723  {
724  X = b.X;
725  Y = b.Y;
726 
727  return *this;
728  }
729 
731  {
732  X = b.theta;
733  Y = b.phi;
734 
735  return *this;
736  }
737 
739  {
740  Ak2DVector v;
741 
742  v.X = X - b.X;
743  v.Y = Y - b.Y;
744 
745  return v;
746  }
747 
749  {
750  X = X * f;
751  Y = Y * f;
752 
753  return *this;
754  }
755 
757  {
758  AkReal32 oneoverf = 1.f / f;
759  X = X * oneoverf;
760  Y = Y * oneoverf;
761 
762  return *this;
763  }
764 
765  AkForceInline bool operator==(const Ak2DVector& b) const
766  {
767  return b.X == X && b.Y == Y;
768  }
769 
770  AkForceInline bool operator!=(const Ak2DVector& b) const
771  {
772  return b.X != X && b.Y != Y;
773  }
774 
776  {
777  return sqrtf(X*X+Y*Y);
778  }
779 
780  //-----------------------------------------------------------
781  // Conversion functions
783  {
784  // (radial, azimuth, elevation)
785  AkReal32 r = sqrtf( in_Cartesian.X*in_Cartesian.X + in_Cartesian.Y*in_Cartesian.Y + in_Cartesian.Z*in_Cartesian.Z);
786  AKASSERT( r != 0);
787 
788  X = atan2f(in_Cartesian.Y, in_Cartesian.X);
789  Y = asinf(in_Cartesian.Z / r);
790 
792 
793  return *this;
794  }
795 
797  const Ak2DVector& A,
798  const Ak2DVector& B) const
799  {
800  Ak2DVector v;
801 
802  // Project coordinates using a vector to matrix multiplication
803  AkReal32 d = (A.X*B.Y - A.Y*B.X);
804 
805  if (d < AKVECTORS_EPSILON && d > -AKVECTORS_EPSILON)
806  {
807  v.X = 0.0f; v.Y = 0.0f;
808  return v;
809  }
810 
811  Ak2DVector invA = Ak2DVector( B.Y, -A.Y );
812  Ak2DVector invB = Ak2DVector( -B.X, A.X );
813 
814  AkReal32 oneover_d = 1.f / d;
815  invA *= oneover_d;
816  invB *= oneover_d;
817 
818  v.X = X * invA.X + Y * invB.X;
819  v.Y = X * invA.Y + Y * invB.Y;
820  // v /= v.Length();
821 
822  return v;
823  }
824 
826  {
827  /*
828  Normalise spherical coordinates.
829  X (azimuthal) -> [-PI, PI], circle lies on xy plan, 0 is on X axix
830  Y (elevation) -> [-PI/2, PI/2], half circle on Z axis, 0 on XY plan, PI/2 straigt up on Z axis.
831  */
832 
833  Ak2DVector v;
834 
835  v.X = X;
836  v.Y = Y;
837 
838  if (X > AKVECTORS_PI)
839  v.X = X - AKVECTORS_TWOPI;
840  else if (X < -AKVECTORS_PI)
841  v.X = X + AKVECTORS_TWOPI;
842 
843  if (Y > AKVECTORS_PIOVERTWO)
844  v.Y = Y - AKVECTORS_PI;
845  else if (Y < -AKVECTORS_PIOVERTWO)
846  v.Y = Y + AKVECTORS_PI;
847 
850 
851  return v;
852  }
853 
855  {
856  /*
857  Normalise spherical coordinates.
858  X (azimuthal) -> [-PI, PI], circle lies on xy plan, 0 is on X axix
859  Y (elevation) -> [-PI/2, PI/2], half circle on Z axis, 0 on XY plan, PI/2 straigt up on Z axis.
860  */
861 
862  if (X > AKVECTORS_PI)
863  X = X - AKVECTORS_TWOPI;
864  else if (X < -AKVECTORS_PI)
865  X = X + AKVECTORS_TWOPI;
866 
867  if (Y > AKVECTORS_PIOVERTWO)
868  Y = Y - AKVECTORS_PI;
869  else if (Y < -AKVECTORS_PIOVERTWO)
870  Y = Y + AKVECTORS_PI;
871  }
872 
873  // Useful in VBAP algorithm, only points that are a positive linear composition matters.
875  {
876  const AkReal32 POSITIVE_TEST_EPSILON = 0.00001f; //0.005f;
877  return X >= -POSITIVE_TEST_EPSILON &&
878  Y >= -POSITIVE_TEST_EPSILON;
879  }
880 
883 };
884 
885 
886 
888 {
889  static const int MAX_SIZE = 16;
890 
891 public:
892  //-----------------------------------------------------------
893  // Constructor/Destructor functions
894  AkMatrix4x4() = default;
895 
896  //-----------------------------------------------------------
897  // Basic vector operators
899  {
900  for (int i = 0; i < MAX_SIZE; i++)
901  m_Data[i] /= f;
902 
903  return *this;
904  }
905 
907  {
908  for (int i = 0; i < MAX_SIZE; i++)
909  {
910  m_Data[i] = in_Data[i];
911  }
912 
913  return *this;
914  }
915 
916  AkReal32 m_Data[MAX_SIZE];
917 };
918 
920 {
921 
922 public:
923  //-----------------------------------------------------------
924  // Constructor/Destructor functions
925  AkMatrix3x3() = default;
926 
927  static AkMatrix3x3 FromColumnVectors(const Ak3DVector& in_col0, const Ak3DVector& in_col1, const Ak3DVector& in_col2)
928  {
929  AkMatrix3x3 m;
930 
931  m(0, 0) = in_col0.X;
932  m(1, 0) = in_col0.Y;
933  m(2, 0) = in_col0.Z;
934 
935  m(0, 1) = in_col1.X;
936  m(1, 1) = in_col1.Y;
937  m(2, 1) = in_col1.Z;
938 
939  m(0, 2) = in_col2.X;
940  m(1, 2) = in_col2.Y;
941  m(2, 2) = in_col2.Z;
942 
943  return m;
944  }
945 
946  //-----------------------------------------------------------
947  // Basic vector operators
949  {
950  for (int i = 0; i < 3; i++)
951  {
952  for (int j = 0; j < 3; j++)
953  {
954  m_Data[i][j] /= f;
955  }
956  }
957  return *this;
958  }
959 
961  {
962  return m_Data[column][row];
963  }
964 
965  AkForceInline const AkReal32& operator()(const AkUInt32 row, const AkUInt32 column) const
966  {
967  return m_Data[column][row];
968  }
969 
971  {
972  Ak3DVector res;
973  res.X = in_rhs.X * m_Data[0][0] + in_rhs.Y * m_Data[1][0] + in_rhs.Z * m_Data[2][0];
974  res.Y = in_rhs.X * m_Data[0][1] + in_rhs.Y * m_Data[1][1] + in_rhs.Z * m_Data[2][1];
975  res.Z = in_rhs.X * m_Data[0][2] + in_rhs.Y * m_Data[1][2] + in_rhs.Z * m_Data[2][2];
976  return res;
977  }
978 
980  {
981  Add(*this, *this, in_rhs);
982  return *this;
983  }
984 
985  static AkForceInline void Add(AkMatrix3x3& out_res, const AkMatrix3x3& in_m0, const AkMatrix3x3& in_m1)
986  {
987 #define ADD(i,j) out_res(i,j) = in_m0(i,j) + in_m1(i,j)
988  ADD(0, 0); ADD(0, 1); ADD(0, 2);
989  ADD(1, 0); ADD(1, 1); ADD(1, 2);
990  ADD(2, 0); ADD(2, 1); ADD(2, 2);
991 #undef ADD
992  }
993 
995  {
996  m_Data[0][0] *= in_f; m_Data[0][1] *= in_f; m_Data[0][2] *= in_f;
997  m_Data[1][0] *= in_f; m_Data[1][1] *= in_f; m_Data[1][2] *= in_f;
998  m_Data[2][0] *= in_f; m_Data[2][1] *= in_f; m_Data[2][2] *= in_f;
999  return *this;
1000  }
1001 
1002  static AkForceInline void Diagonal(AkMatrix3x3& out_mat, AkReal32 in_f)
1003  {
1004  out_mat(0, 0) = in_f; out_mat(0, 1) = 0.f; out_mat(0, 2) = 0.f;
1005  out_mat(1, 0) = 0.f; out_mat(1, 1) = in_f; out_mat(1, 2) = 0.f;
1006  out_mat(2, 0) = 0.f; out_mat(2, 1) = 0.f; out_mat(2, 2) = in_f;
1007  }
1008 
1009  // Creates the matrix Mu such that Mu*v = u X v
1010  static AkForceInline void CrossProductMatrix(AkMatrix3x3& out_mat, const Ak3DVector& in_u)
1011  {
1012  out_mat(0, 0) = 0.f; out_mat(0, 1) = -in_u.Z; out_mat(0, 2) = in_u.Y;
1013  out_mat(1, 0) = in_u.Z; out_mat(1, 1) = 0.f; out_mat(1, 2) = -in_u.X;
1014  out_mat(2, 0) = -in_u.Y; out_mat(2, 1) = in_u.X; out_mat(2, 2) = 0.f;
1015  }
1016 
1017  static AkForceInline void OuterProduct(AkMatrix3x3& out_mat, const Ak3DVector& in_v0, const Ak3DVector& in_v1)
1018  {
1019  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;
1020  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;
1021  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;
1022  }
1023 
1024  static AkForceInline void Rotation(AkMatrix3x3& out_mat, AkReal32 in_angle, const Ak3DVector& in_axis)
1025  {
1026  Rotation(out_mat, sinf(in_angle), cosf(in_angle), in_axis);
1027  }
1028 
1029  static void Rotation(AkMatrix3x3& out_mat, AkReal32 in_sin, AkReal32 in_cos, const Ak3DVector& in_axis)
1030  {
1031  Diagonal(out_mat, in_cos);
1032 
1033  AkMatrix3x3 outer;
1034  OuterProduct(outer, in_axis, in_axis);
1035  outer *= (1.f - in_cos);
1036  out_mat += outer;
1037 
1038  AkMatrix3x3 cross;
1039  CrossProductMatrix(cross, in_axis*in_sin);
1040  out_mat += cross;
1041  }
1042 
1043  // [column][row]
1045 };
1046 
1048 {
1049 public:
1050  // Identity quaternion
1051  AkQuaternion(): W(1.f), X(0.f), Y(0.f), Z(0.f) {}
1052 
1053  AkQuaternion(AkReal32 in_W, AkReal32 in_X, AkReal32 in_Y, AkReal32 in_Z) :
1054  W(in_W),
1055  X(in_X),
1056  Y(in_Y),
1057  Z(in_Z)
1058  {}
1059 
1060  // Create a quaternion from a 3x3 rotation matrix
1062  {
1063  AkQuaternion q;
1064 
1065  AkReal32 trace = in_mat(0,0) + in_mat(1, 1) + in_mat(2, 2);
1066  if (trace > 0.0f)
1067  {
1068  AkReal32 srt = sqrtf(trace + 1.f);
1069  AkReal32 s = 0.5f / srt;
1070 
1071  q.W = 0.5f * srt;
1072  q.X = (in_mat(2, 1) - in_mat(1, 2)) * s;
1073  q.Y = (in_mat(0, 2) - in_mat(2, 0)) * s;
1074  q.Z = (in_mat(1, 0) - in_mat(0, 1)) * s;
1075 
1076  }
1077  else
1078  {
1079  // diagonal is negative
1080  AkUInt32 i = 0;
1081  if (in_mat(1, 1) > in_mat(0, 0))
1082  i = 1;
1083  if (in_mat(2, 2) > in_mat(i, i))
1084  i = 2;
1085 
1086  AkUInt32 j = (i + 1) % 3;
1087  AkUInt32 k = (i + 2) % 3;
1088 
1089  AkReal32 s = sqrtf( in_mat(i, i) - in_mat(j, j) - in_mat(k, k) + 1.0f );
1090  AkReal32 t = (s == 0.f) ? 0.f : (0.5f / s);
1091 
1092  AkReal32 qt[4];
1093 
1094  qt[i] = 0.5f * s;
1095  qt[j] = (in_mat(j, i) + in_mat(i, j)) * t;
1096  qt[k] = (in_mat(k, i) + in_mat(i, k)) * t;
1097  qt[3] = (in_mat(k, j) - in_mat(j, k)) * t;
1098 
1099  q.X = qt[0];
1100  q.Y = qt[1];
1101  q.Z = qt[2];
1102  q.W = qt[3];
1103  }
1104 
1105  return q;
1106  }
1107 
1108  // Create a rotation quaternion from euler angles.
1110  AkReal32 in_x, // Rotation around the X axis, in radians.
1111  AkReal32 in_y, // Rotation around the Y axis, in radians.
1112  AkReal32 in_z // Rotation around the Z axis, in radians.
1113  )
1114  {
1115  AkReal32 sy = sinf(in_z / 2.f);
1116  AkReal32 cy = cosf(in_z / 2.f);
1117  AkReal32 sp = sinf(in_y / 2.f);
1118  AkReal32 cp = cosf(in_y / 2.f);
1119  AkReal32 sr = sinf(in_x / 2.f);
1120  AkReal32 cr = cosf(in_x / 2.f);
1121 
1122  AkQuaternion q;
1123  q.W = cr * cp * cy + sr * sp * sy;
1124  q.X = sr * cp * cy - cr * sp * sy;
1125  q.Y = cr * sp * cy + sr * cp * sy;
1126  q.Z = cr * cp * sy - sr * sp * cy;
1127 
1128  return q;
1129  }
1130 
1131  static AkQuaternion FromAngleAndAxis(AkReal32 in_angle, const Ak3DVector& in_axis)
1132  {
1133  AkQuaternion q;
1134 
1135  AkReal32 sa = sinf(in_angle / 2.f);
1136  q.W = cosf(in_angle / 2.f);
1137  q.X = in_axis.X * sa;
1138  q.Y = in_axis.Y * sa;
1139  q.Z = in_axis.Z * sa;
1140 
1141  return q;
1142  }
1143 
1145  {
1146  return sqrtf( W*W + X*X + Y*Y + Z*Z );
1147  }
1148 
1150  {
1151  AkReal32 f = 1.0f / Length();
1152  W *= f;
1153  X *= f;
1154  Y *= f;
1155  Z *= f;
1156  return *this;
1157  }
1158 
1160  {
1161  AkReal32 norm = W*W + X*X + Y*Y + Z*Z;
1162  if (norm > 0.0)
1163  {
1164  AkReal32 invNorm = 1.0f / norm;
1165  return AkQuaternion(W*invNorm, -X*invNorm, -Y*invNorm, -Z*invNorm);
1166  }
1167  else
1168  {
1169  return AkQuaternion();
1170  }
1171  }
1172 
1173  // Create a quaternion representing the shortest arc rotation between (normalized) vectors v0, v1
1174  AkQuaternion(const Ak3DVector& in_v0, const Ak3DVector& in_v1)
1175  {
1176  AkReal32 dot = in_v0.Dot(in_v1);
1177  if (dot >= 1.0f - AKVECTORS_EPSILON)
1178  {
1179  // No rotation - return unity quaternion.
1180  AkQuaternion();
1181  }
1182  if (dot <= -1.f - AKVECTORS_EPSILON)
1183  {
1184  // 180 degree rotation - can use any non-zero length axis.
1185  Ak3DVector axis = Ak3DVector(0.f, 0.f, 1.f).Cross(in_v0);
1186  AkReal32 len = axis.Length();
1187  if (len < AKVECTORS_EPSILON)
1188  {
1189  axis = Ak3DVector(0.f, 1.f, 0.f).Cross(in_v0);
1190  len = axis.Length();
1191  }
1192  axis.Normalize();
1193  AkQuaternion(AKVECTORS_PI, axis);
1194  }
1195  else
1196  {
1197  AkReal32 sqrt = sqrtf((1.f + dot) * 2.f);
1198  AkReal32 invs = 1.f / sqrt;
1199 
1200  Ak3DVector cross = in_v0.Cross(in_v1);
1201 
1202  X = cross.X * invs;
1203  Y = cross.Y * invs;
1204  Z = cross.Z * invs;
1205  W = sqrt * 0.5f;
1206  Normalize();
1207  }
1208  }
1209 
1210  // Build quaternion from an axis and angle representation.
1211  AkQuaternion(AkReal32 in_angle, const Ak3DVector& in_axis)
1212  {
1213  AkReal32 cosHalfAngle = cosf(in_angle / 2.f);
1214  W = cosHalfAngle;
1215  X = cosHalfAngle*in_axis.X;
1216  Y = cosHalfAngle*in_axis.Y;
1217  Z = cosHalfAngle*in_axis.Z;
1218  }
1219 
1220  /// Quaternion multiplication.
1222  {
1223  return AkQuaternion(
1224  W*Q.W - X*Q.X - Y*Q.Y - Z*Q.Z,
1225  W*Q.X + X*Q.W + Y*Q.Z - Z*Q.Y,
1226  W*Q.Y - X*Q.Z + Y*Q.W + Z*Q.X,
1227  W*Q.Z + X*Q.Y - Y*Q.X + Z*Q.W);
1228  }
1229 
1231  {
1232  return RotateVector(in_v);
1233  }
1234 
1236  {
1237  /*
1238  // impl 1
1239  Ak3DVector uv, uuv;
1240  Ak3DVector qvec(X, Y, Z);
1241  uv = qvec.Cross(in_v);
1242  uuv = qvec.Cross(uv);
1243  uv *= (2.0f * W);
1244  uuv *= 2.0f;
1245  return in_v + uv + uuv;
1246  */
1247 
1248  // impl 2
1249  Ak3DVector32 u(X, Y, Z);
1250  Ak3DVector32 res =
1251  u * u.Dot(in_v) * 2.f
1252  + in_v * (W * W - u.Dot(u))
1253  + u.Cross(in_v) * W * 2.0f;
1254 
1255  return res;
1256  }
1257 
1259  {
1260  Ak3DVector32 u(-X, -Y, -Z);
1261  Ak3DVector32 t = 2.f * u.Cross(in_v);
1262  Ak3DVector32 res = in_v + (W * t) + u.Cross(t);
1263  return res;
1264  }
1265 
1270 };
1271 
1273 {
1276 };
1277 
1278 class AkLine
1279 {
1280 public:
1282  mint(1.175494351e-38F),
1283  maxt(3.402823466e+38F)
1284  {
1285  }
1286 
1288  L(in_L),
1289  P(in_P),
1290  mint(1.175494351e-38F),
1291  maxt(3.402823466e+38F)
1292  {
1293  }
1294 
1296  {
1297  return P + L*t;
1298  }
1299 
1301  {
1302  /*
1303  a (V1 X V2) = (P2 - P1) X V2
1304  If the lines intersect at a single point, then the resultant vectors
1305  on each side of this equation must be parallel, and the left side must
1306  not be the zero vector. We should check to make sure that this is
1307  true. Once we have checked this, we can solve for 'a' by taking the
1308  magnitude of each side and dividing. If the resultant vectors are
1309  parallel, but in opposite directions, then 'a' is the negative of the
1310  ratio of magnitudes. Once we have 'a' we can go back to the equation
1311  for L1 to find the intersection point.
1312  */
1313  Ak3DVector V1 = L;
1314  Ak3DVector V2 = B - A;
1315  Ak3DVector P1 = P;
1316  Ak3DVector P2 = A;
1317 
1318  // k(V1 X V2) = (A - P) X V2
1319 
1320  Ak3DVector v1CrossV2 = V1.Cross(V2);
1322  P2 - P1,
1323  V2,
1324  v1CrossV2
1325  );
1326  AkReal32 t = det / v1CrossV2.LengthSquared();
1327 
1329  P2 - P1,
1330  V1,
1331  v1CrossV2
1332  );
1333  AkReal32 s = det / v1CrossV2.LengthSquared();
1334 
1335  AkReal32 distsqrd = ((P2 + V2*s) - (P1 + V1*t)).LengthSquared();
1336 
1337  if ((AkReal32)fabs(v1CrossV2.L2_Norm()) >= AKVECTORS_EPSILON
1338  && distsqrd < 0.001
1339  && s <= 1.0f )
1340  {
1341 #ifdef AKPORTALS_DEBUG
1342  Ak3DVector minPoint = PointAt(t);
1343 
1344  char msg[256];
1345  sprintf(msg, "L1a=[%0.2f,%0.2f,%0.2f];\n", P.X, P.Y, P.Z); AKPLATFORM::OutputDebugMsg(msg);
1346  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);
1347  sprintf(msg, "L2a=[%0.2f,%0.2f,%0.2f];\n", A.X, A.Y, A.Z); AKPLATFORM::OutputDebugMsg(msg);
1348  sprintf(msg, "L2b=[%0.2f,%0.2f,%0.2f];\n", B.X, B.Y, B.Z); AKPLATFORM::OutputDebugMsg(msg);
1349  sprintf(msg, "%% t=%0.2f Min t=%0.2f, Max t=%0.2f\n", t, mint, maxt); AKPLATFORM::OutputDebugMsg(msg);
1350  sprintf(msg, "intrPoint=[%0.2f,%0.2f,%0.2f];\n", minPoint.X, minPoint.Y, minPoint.Z); AKPLATFORM::OutputDebugMsg(msg);
1351  sprintf(msg, "\n"); AKPLATFORM::OutputDebugMsg(msg);
1352 #endif
1353 
1354  mint = AkMin(mint, t);
1355  maxt = AkMax(maxt, t);
1356 
1357  return true;
1358  }
1359 
1360 #ifdef AKPORTALS_DEBUG
1361  // char msg[256];
1362  // sprintf(msg, "%% DISCARTED t=%0.2f Min t=%0.2f, Max t=%0.2f\n", t, mint, maxt); AKPLATFORM::OutputDebugMsg(msg);
1363 #endif
1364  return false;
1365  }
1366 
1369 
1372 };
1373 
1374 class AkPlane
1375 {
1376 public:
1377  AkPlane() = default;
1378 
1380  Ak3DVector in_p1,
1381  Ak3DVector in_p2,
1382  Ak3DVector in_p4)
1383  {
1384  SetPlane(
1385  in_p1,
1386  in_p2,
1387  in_p4);
1388  }
1389 
1390  void SetPlane(
1391  Ak3DVector in_p1,
1392  Ak3DVector in_p2,
1393  Ak3DVector in_p4)
1394  {
1395  // Reorder A-B-C to clockwwise if necessary
1396  AKASSERT(in_p1.X < 100000 && in_p1.X > -100000);
1397  AKASSERT(in_p1.Y < 100000 && in_p1.Y > -100000);
1398  AKASSERT(in_p1.Z < 100000 && in_p1.Z > -100000);
1399 
1400  AKASSERT(in_p2.X < 100000 && in_p2.X > -100000);
1401  AKASSERT(in_p2.Y < 100000 && in_p2.Y > -100000);
1402  AKASSERT(in_p2.Z < 100000 && in_p2.Z > -100000);
1403 
1404  AKASSERT(in_p4.X < 100000 && in_p4.X > -100000);
1405  AKASSERT(in_p4.Y < 100000 && in_p4.Y > -100000);
1406  AKASSERT(in_p4.Z < 100000 && in_p4.Z > -100000);
1407 
1408  p1 = in_p1;
1409  p2 = in_p2;
1410  p4 = in_p4;
1411 
1412  SetNormal();
1413 
1414  // Ax + By + Cz + D = 0
1415  // Find D using the normal and a point
1416  D = -(N.X*p1.X) - (N.Y*p1.Y) - (N.Z*p1.Z);
1417  }
1418 
1419 #define EPSILON 0.01f
1421  const Ak3DVector& in_Origin,
1422  const Ak3DVector& in_Destination,
1423  Ak3DVector& out_Intersection
1424  ) const
1425  {
1426  AkReal32 A = N.X;
1427  AkReal32 B = N.Y;
1428  AkReal32 C = N.Z;
1429 
1430  Ak3DVector ray = in_Destination - in_Origin;
1431  AkReal32 rayLength = ray.Length();
1432 
1433  Ak3DVector intersect;
1434 
1435  // If ray is < EPSILON, use on of the point directly for the test and skip the linear projection
1436  if (rayLength <= EPSILON)
1437  {
1438  Ak3DVector temp = in_Origin - p1;
1439  AkReal32 dot = temp.DotProduct(N);
1440  if (dot < EPSILON && dot > -EPSILON)
1441  {
1442  intersect = in_Origin;
1443  }
1444  else
1445  {
1446  // For debug only, to remove
1447  out_Intersection = p1;
1448  return false;
1449  }
1450 
1451  }
1452  else
1453  {
1454  // Normalize ray
1455  ray.Normalize();
1456 
1457  // 1) if ray len ~= 0, only check if one of the point is on target, ie: assign the intersect point
1458 
1459  // Is ray parallel to the plane?
1460  if ((A*ray.X + B*ray.Y + C*ray.Z) == 0.0f)
1461  {
1462  // For debug only, to remove
1463  AkReal32 t = -(A*in_Origin.X + B*in_Origin.Y + C*in_Origin.Z + D) / (A*ray.X + B*ray.Y + C*ray.Z);
1464  intersect = Ak3DVector(in_Origin.X + ray.X*t, in_Origin.Y + ray.Y*t, in_Origin.Z + ray.Z*t);
1465  out_Intersection = intersect; // For debugging
1466  return false;
1467  }
1468 
1469 
1470  // Distance along the ray where reflector is hit
1471  AkReal32 t = -(A*in_Origin.X + B*in_Origin.Y + C*in_Origin.Z + D) / (A*ray.X + B*ray.Y + C*ray.Z);
1472 
1473  // Is the ray going towards the plane? Is it long enough?
1474  if (t < -EPSILON || t >(rayLength + EPSILON))
1475  {
1476  // For debug only, to remove
1477  intersect = Ak3DVector(in_Origin.X + ray.X*t, in_Origin.Y + ray.Y*t, in_Origin.Z + ray.Z*t);
1478  out_Intersection = intersect; // For debugging
1479  return false; // The ray doesn't intersect
1480  }
1481 
1482  // Find the coordinate of intersection on the plane
1483  intersect = Ak3DVector(in_Origin.X + ray.X*t, in_Origin.Y + ray.Y*t, in_Origin.Z + ray.Z*t);
1484  }
1485  ///////////////////////////////////////
1486  //
1487  // p2____v3____p3
1488  // | . |
1489  // ^ inter v4
1490  // v1 v
1491  // | |
1492  // p1__ v2>___p4
1493 
1494  Ak3DVector v1 = p2 - p1;
1495  Ak3DVector v2 = p4 - p1;
1496  Ak3DVector vInter1 = intersect - p1;
1497 
1498  Ak3DVector p3 = p4 + v1;
1499  Ak3DVector v3 = p2 - p3;
1500  Ak3DVector v4 = p4 - p3;
1501  Ak3DVector vInter2 = intersect - p3;
1502 
1503  v1.Normalize(); v2.Normalize(); v3.Normalize(); v4.Normalize(); vInter1.Normalize(); vInter2.Normalize();
1504 
1505  // Since it's a square, the angle between the point of intersection and any segment of the pannel should be < 90 degree,
1506  // therefore the dot product of the two normalized vectors should be > 0
1507  AkReal32 dot1 = v1.DotProduct(vInter1);
1508  AkReal32 dot2 = v2.DotProduct(vInter1);
1509  AkReal32 dot3 = v3.DotProduct(vInter2);
1510  AkReal32 dot4 = v4.DotProduct(vInter2);
1511 
1512  out_Intersection = intersect;
1513 
1514  return dot1 >= -EPSILON && dot2 >= -EPSILON && dot3 >= -EPSILON && dot4 >= -EPSILON;
1515  }
1516 
1518  Ak3DVector in_P,
1519  Ak3DVector& out_B) const
1520  {
1521  AkReal32 distance = (AkReal32)(AkReal32)fabs(N.X * in_P.X + N.Y * in_P.Y + N.Z * in_P.Z + D);
1522 
1523  Ak3DVector pointToPlane = N;
1524  pointToPlane *= distance;
1525 
1526  out_B = in_P + pointToPlane;
1527 
1528  return (AkReal32)fabs(distance);
1529  }
1530 
1532  AkReal32* out_mat) const
1533  {
1534  // http://ami.ektf.hu/uploads/papers/finalpdf/AMI_40_from175to186.pd
1535  /* m_pReflectionMatrix
1536  reflection on z axis
1537 
1538  P0 (x0, y0, z0), P1 (x1, y1, z1) and P2 (x2, y2, z2),
1539  normal = (cx, cy, cz)
1540  d = -CxX0 - CyY0 - CzZ0
1541 
1542  Reflect = 1-2Cx^2 -2CxCy -2CxCz -2Cxd
1543  -2CxCy 1-2Cy^2 -2CyCz -2Cyd
1544  -2CxCz -2CyCz 1-2Cz^2 -2Czd
1545  0 0 0 1
1546  */
1547 
1548  AkReal32 d = -(N.X*p1.X) - (N.Y*p1.Y) - (N.Z*p1.Z);
1549 
1550  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;
1551  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;
1552  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;
1553  out_mat[0 + 12] = 0; out_mat[1 + 12] = 0; out_mat[2 + 12] = 0; out_mat[3 + 12] = 1;
1554  }
1555 
1556  Ak3DVector GetN() const { return N; }
1557  AkReal32 GetD() const { return D; }
1558 
1560  const AkPlane& in_PlaneB,
1561  AkIntersectionPoints& out_Intrs) const
1562  {
1563  out_Intrs.count = 0;
1564 
1565  // Use vector to solve A
1566 
1567  Ak3DVector point;
1568 
1569  Ak3DVector N1 = N;
1570  Ak3DVector N2 = in_PlaneB.GetN();
1571  AkReal32 D1 = D;
1572  AkReal32 D2 = in_PlaneB.GetD();
1573 
1574  Ak3DVector L = N1.Cross(N2);
1575  if (L.Length() < 0.001f)
1576  {
1577  return false; // The two planes are parallel
1578  }
1579 
1580  AkUInt8 pivotAxis = 0;
1581 
1582  if ((AkReal32)fabs(L.Y) > (AkReal32)fabs(L.X))
1583  {
1584  pivotAxis = 1;
1585  if ((AkReal32)fabs(L.Z) > (AkReal32)fabs(L.Y))
1586  {
1587  pivotAxis = 2;
1588  }
1589  }
1590  else if ((AkReal32)fabs(L.Z) > (AkReal32)fabs(L.X))
1591  {
1592  pivotAxis = 2;
1593  }
1594 
1595  /*
1596  Pu = ( N1v*D2 - N2v*D1 ) / Lw
1597  Pv = ( N2u*D1 - N1u*D2 ) / Lw
1598  Pz = 0
1599  */
1600 
1601  switch (pivotAxis)
1602  {
1603  case 0:
1604  AKASSERT((AkReal32)fabs(L.X) > AKVECTORS_EPSILON);
1605  point.X = 0.f;
1606  point.Y = (N1.Z*D2 - N2.Z*D1) / L.X;
1607  point.Z = (N2.Y*D1 - N1.Y*D2) / L.X;
1608  break;
1609  case 1:
1610  AKASSERT((AkReal32)fabs(L.Y) > AKVECTORS_EPSILON);
1611  point.X = (N1.Z*D2 - N2.Z*D1) / L.Y;
1612  point.Y = 0.f;
1613  point.Z = (N2.X*D1 - N1.X*D2) / L.Y;
1614  break;
1615  case 2:
1616  AKASSERT((AkReal32)fabs(L.Z) > AKVECTORS_EPSILON);
1617  point.X = (N1.Y*D2 - N2.Y*D1) / L.Z;
1618  point.Y = (N2.X*D1 - N1.X*D2) / L.Z;
1619  point.Z = 0.f;
1620  break;
1621  };
1622 
1623 
1624 
1625  L.Normalize();
1626 
1627  AkLine intrLine = AkLine(L, point);
1628  AkLine intrLine2 = AkLine(L, point);
1629 
1630  //in_PlaneB.GetP1()
1631 
1632  // find min max
1633  AkUInt32 cpt = 0;
1634  AkUInt32 cpt2 = 0;
1635  Ak3DVector p3 = GetP2() + (GetP4() - GetP1());
1636 
1637 #ifdef AKPORTALS_DEBUG
1638  char msg[256];
1639  sprintf(msg, "P1a=[%0.2f,%0.2f,%0.2f];\n", GetP1().X, GetP1().Y, GetP1().Z); AKPLATFORM::OutputDebugMsg(msg);
1640  sprintf(msg, "P2a=[%0.2f,%0.2f,%0.2f];\n", GetP2().X, GetP2().Y, GetP2().Z); AKPLATFORM::OutputDebugMsg(msg);
1641  sprintf(msg, "P4a=[%0.2f,%0.2f,%0.2f];\n", GetP4().X, GetP4().Y, GetP4().Z); AKPLATFORM::OutputDebugMsg(msg);
1642 
1643  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);
1644  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);
1645  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);
1646 
1647  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);
1648  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);
1649 
1650 
1651  sprintf(msg, "%% Plane intersec\n"); AKPLATFORM::OutputDebugMsg(msg);
1652 #endif
1653  // for the four lines in rectangle
1654  // Find where the line is crossing with plane A
1655  if (intrLine.Intersect(GetP1(), GetP2())) cpt++;
1656  if (intrLine.Intersect(GetP1(), GetP4())) cpt++;
1657  if (intrLine.Intersect(GetP2(), p3)) cpt++;
1658  if (intrLine.Intersect(p3, GetP4())) cpt++;
1659  //AKASSERT(cpt == 2);
1660 
1661 #ifdef AKPORTALS_DEBUG
1662  sprintf(msg, "%% Portal intersec\n"); AKPLATFORM::OutputDebugMsg(msg);
1663 #endif
1664 
1665  // Find where the line is crossing with plane B
1666  p3 = in_PlaneB.GetP2() + (in_PlaneB.GetP4() - in_PlaneB.GetP1());
1667  if (intrLine2.Intersect(in_PlaneB.GetP1(), in_PlaneB.GetP2())) cpt2++;
1668  if (intrLine2.Intersect(in_PlaneB.GetP1(), in_PlaneB.GetP4())) cpt2++;
1669  if (intrLine2.Intersect(in_PlaneB.GetP2(), p3)) cpt2++;
1670  if (intrLine2.Intersect(p3, in_PlaneB.GetP4())) cpt2++;
1671  // **AKASSERT(cpt2 == 2 || cpt == 2);
1672 
1673  if (cpt < 2 || cpt2 < 2)
1674  {
1675 #ifdef AKPORTALS_DEBUG
1676  sprintf(msg, "%% NON \n"); AKPLATFORM::OutputDebugMsg(msg);
1677  sprintf(msg, "%% _______________________\n"); AKPLATFORM::OutputDebugMsg(msg);
1678 #endif
1679  return false;
1680  }
1681 
1682  AkReal32 start = AkMax(intrLine.mint, intrLine2.mint);
1683  AkReal32 end = AkMin(intrLine.maxt, intrLine2.maxt);
1684 
1685  Ak3DVector minPoint = intrLine.PointAt(start);
1686  Ak3DVector maxPoint = intrLine.PointAt(end);
1687 #ifdef AKPORTALS_DEBUG
1688  sprintf(msg, "P1a=[%0.2f,%0.2f,%0.2f];\n", GetP1().X, GetP1().Y, GetP1().Z); AKPLATFORM::OutputDebugMsg(msg);
1689  sprintf(msg, "P2a=[%0.2f,%0.2f,%0.2f];\n", GetP2().X, GetP2().Y, GetP2().Z); AKPLATFORM::OutputDebugMsg(msg);
1690  sprintf(msg, "P4a=[%0.2f,%0.2f,%0.2f];\n", GetP4().X, GetP4().Y, GetP4().Z); AKPLATFORM::OutputDebugMsg(msg);
1691 
1692  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);
1693  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);
1694  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);
1695 
1696  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);
1697  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);
1698 
1699  sprintf(msg, "intr1=[%0.2f,%0.2f,%0.2f];\n", minPoint.X, minPoint.Y, minPoint.Z); AKPLATFORM::OutputDebugMsg(msg);
1700  sprintf(msg, "intr2=[%0.2f,%0.2f,%0.2f];\n", maxPoint.X, maxPoint.Y, maxPoint.Z); AKPLATFORM::OutputDebugMsg(msg);
1701 
1702  sprintf(msg, "%% _______________________\n"); AKPLATFORM::OutputDebugMsg(msg);
1703 #endif
1704  out_Intrs.points[0] = minPoint;
1705  out_Intrs.points[1] = maxPoint;
1706  out_Intrs.count = 2;
1707 
1708  return true;
1709  }
1710 
1711  Ak3DVector GetP1() const { return p1; }
1712  Ak3DVector GetP2() const { return p2; }
1713  Ak3DVector GetP4() const { return p4; }
1714 
1715 private:
1716  bool SetNormal()
1717  {
1718  //m_pNormal = (B-A) cross (C-A); normalize
1719  Ak3DVector a = p2 - p1;
1720  Ak3DVector b = p4 - p1;
1721 
1722  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);
1723 
1724  AkReal32 len = N.Length();
1725  AKASSERT(len > 0.f);
1726 
1727  if (len > 0)
1728  {
1729  N /= len;
1730  }
1731  else
1732  {
1733  return false;
1734  }
1735 
1736  return true;
1737  };
1738 
1739  /*
1740  p2__________p3
1741  | . |
1742  ^ inter v3
1743  v1 v
1744  | |
1745  p1__ v2>___p4
1746  */
1747 
1748  Ak3DVector p1; // Bottom left
1749  Ak3DVector p2; // Top left
1750  Ak3DVector p4; // Tottom right
1751  Ak3DVector N; // Normal vector
1752  AkReal32 D; // Plane equation: Ax + By + Cz = D => N.Xx + N.Yy + N.Zz = D
1753 };
1754 
1755 template<typename TReal>
1757 {
1759 
1760  TBoundingBox(const TVectorType& in_min, const TVectorType& in_max) :
1761  m_Min(in_min),
1762  m_Max(in_max)
1763  {}
1764 
1766  m_Min(TVectorType(RealPrecision<TReal>::MAX_VALUE, RealPrecision<TReal>::MAX_VALUE, RealPrecision<TReal>::MAX_VALUE)),
1767  m_Max(TVectorType(-RealPrecision<TReal>::MAX_VALUE, -RealPrecision<TReal>::MAX_VALUE, -RealPrecision<TReal>::MAX_VALUE))
1768  {}
1769 
1770  void Update(const TVectorType& in_point)
1771  {
1772  if (m_Min.X > in_point.X)
1773  m_Min.X = in_point.X;
1774 
1775  if (m_Min.Y > in_point.Y)
1776  m_Min.Y = in_point.Y;
1777 
1778  if (m_Min.Z > in_point.Z)
1779  m_Min.Z = in_point.Z;
1780 
1781  if (m_Max.X < in_point.X)
1782  m_Max.X = in_point.X;
1783 
1784  if (m_Max.Y < in_point.Y)
1785  m_Max.Y = in_point.Y;
1786 
1787  if (m_Max.Z < in_point.Z)
1788  m_Max.Z = in_point.Z;
1789  }
1790 
1791  AkForceInline bool IsWithin(const TVectorType& in_Point) const
1792  {
1793  return in_Point >= m_Min && in_Point <= m_Max;
1794  }
1795 
1796  AkForceInline bool IsWithin(const TBoundingBox& in_BB) const
1797  {
1798  return (m_Min.X <= in_BB.m_Max.X && m_Max.X >= in_BB.m_Min.X) &&
1799  (m_Min.Y <= in_BB.m_Max.Y && m_Max.Y >= in_BB.m_Min.Y) &&
1800  (m_Min.Z <= in_BB.m_Max.Z && m_Max.Z >= in_BB.m_Min.Z);
1801  }
1802 
1804  {
1805  TBoundingBox result;
1806 
1807  result.m_Max.X = AkMin(m_Max.X, in_BB.m_Max.X);
1808  result.m_Max.Y = AkMin(m_Max.Y, in_BB.m_Max.Y);
1809  result.m_Max.Z = AkMin(m_Max.Z, in_BB.m_Max.Z);
1810 
1811  result.m_Min.X = AkMax(m_Min.X, in_BB.m_Min.X);
1812  result.m_Min.Y = AkMax(m_Min.Y, in_BB.m_Min.Y);
1813  result.m_Min.Z = AkMax(m_Min.Z, in_BB.m_Min.Z);
1814 
1815  return result;
1816  }
1817 
1818  AkForceInline bool IsEmpty() const
1819  {
1820  return (m_Min.X >= m_Max.X) || (m_Min.Y >= m_Max.Y) || (m_Min.Z >= m_Max.Z);
1821  }
1822 
1823  AkForceInline bool IsValid() const
1824  {
1825  return (m_Min.X <= m_Max.X) && (m_Min.Y <= m_Max.Y) && (m_Min.Z <= m_Max.Z);
1826  }
1827 
1830 };
1831 
1834 
1835 class AkBox
1836 {
1837 public:
1838  AkBox() = default;
1839 
1840  void Init(
1841  const Ak3DVector& in_center,
1842  const Ak3DVector& in_extent,
1843  const Ak3DVector& in_Front,
1844  const Ak3DVector& in_Up)
1845  {
1846  AKASSERT(fabs(in_Front.Length() - 1.f) < 0.001 && fabs(in_Up.Length() - 1.f) < 0.001);//Must be unit vectors.
1847  AKASSERT(fabs(in_Front.Dot(in_Up) - 0.f) < 0.001); //Must be orthogonal.
1848 
1849  m_Center = in_center;
1850  m_Extent = in_extent;
1851 
1852  m_Z = in_Front;
1853  m_Y = in_Up;
1854  m_X = m_Z.Cross(m_Y);
1855  }
1856 
1857  bool IsPointInBox(const Ak3DVector& in_Point) const
1858  {
1859  Ak3DVector pt = in_Point - m_Center;
1860  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;
1861  }
1862 
1863  Ak3DVector GetSize() const { return m_Extent*2.f; }
1864  Ak3DVector GetCenter() const { return m_Center; }
1865 
1866  Ak3DVector GetUx() const { return m_X; }
1867  Ak3DVector GetUy() const { return m_Y; }
1868  Ak3DVector GetUz() const { return m_Z; }
1869 
1870  Ak3DVector GetFront() const { return m_Z; }
1871  Ak3DVector GetUp() const { return m_Y; }
1872  Ak3DVector GetSide() const { return m_X; }
1873 
1875  {
1876  Ak3DVector size = GetSize();
1877  return size.X * size.Y * size.Z;
1878  }
1879 
1881  const Ak3DVector& L,
1882  const AkBox& B) const
1883  {
1884  // Separating Axis Theorem for Oriented Bounding Boxes by Johnny Huynh
1885  const AkBox& A = *this;
1886  Ak3DVector T = B.GetCenter() - A.GetCenter();
1887 
1888  AkReal32 WA = A.m_Extent.X;
1889  AkReal32 HA = A.m_Extent.Y;
1890  AkReal32 DA = A.m_Extent.Z;
1891 
1892  AkReal32 WB = B.m_Extent.X;
1893  AkReal32 HB = B.m_Extent.Y;
1894  AkReal32 DB = B.m_Extent.Z;
1895 
1896  Ak3DVector Ax = A.GetUx();
1897  Ak3DVector Ay = A.GetUy();
1898  Ak3DVector Az = A.GetUz();
1899 
1900  Ak3DVector Bx = B.GetUx();
1901  Ak3DVector By = B.GetUy();
1902  Ak3DVector Bz = B.GetUz();
1903 
1904  /*
1905  | T • L | > | (WA*Ax) • L | + | (HA*Ay) • L | + |(DA*Az) • L | +
1906  | (WB*Bx) • L | +| (HB*By) • L | +| (DB*Bz) • L |*/
1907 
1908  AkReal32 left = (AkReal32)fabs(T.DotProduct(L));
1909  AkReal32 dpax = (AkReal32)fabs((Ax*WA).DotProduct(L));
1910  AkReal32 dpay = (AkReal32)fabs((Ay*HA).DotProduct(L));
1911  AkReal32 dpaz = (AkReal32)fabs((Az*DA).DotProduct(L));
1912  AkReal32 dpbx = (AkReal32)fabs((Bx*WB).DotProduct(L));
1913  AkReal32 dpby = (AkReal32)fabs((By*HB).DotProduct(L));
1914  AkReal32 dpbz = (AkReal32)fabs((Bz*DB).DotProduct(L));
1915 
1916  AkReal32 right = dpax + dpay + dpaz + dpbx + dpby + dpbz;
1917 
1918  return left > right;
1919  }
1920 
1921  void UpdateBoundingBox(AkBoundingBox& out_aabb) const
1922  {
1923  Ak3DVector x = m_X * m_Extent.X;
1924  out_aabb.Update(m_Center + x);
1925  out_aabb.Update(m_Center - x);
1926  Ak3DVector y = m_Y * m_Extent.Y;
1927  out_aabb.Update(m_Center + y);
1928  out_aabb.Update(m_Center - y);
1929  Ak3DVector Z = m_Z * m_Extent.Z;
1930  out_aabb.Update(m_Center + Z);
1931  out_aabb.Update(m_Center - Z);
1932  }
1933 
1934 private:
1935 
1936  Ak3DVector m_Center;
1937  Ak3DVector m_Extent;
1938 
1939  //Orthonormal Axes
1940  Ak3DVector m_X;
1941  Ak3DVector m_Y;
1942  Ak3DVector m_Z;
1943 };
AkMatrix3x3 & operator/=(const AkReal32 f)
Definition: AkVectors.h:948
AkForceInline T3DVector & operator*=(const TDataType f)
Definition: AkVectors.h:368
AkForceInline AkQuaternion & Normalize()
Definition: AkVectors.h:1149
#define AkMin(x1, x2)
T3DVector< AkReal32 > Ak3DVector
Definition: AkVectors.h:686
TDataType X
Definition: AkVectors.h:661
bool FindIntersectionPoints(const AkPlane &in_PlaneB, AkIntersectionPoints &out_Intrs) const
Definition: AkVectors.h:1559
T3DVector(const AkVector &in_vector)
Definition: AkVectors.h:250
AkReal32 DistPoint_to_Plane(Ak3DVector in_P, Ak3DVector &out_B) const
Definition: AkVectors.h:1517
#define AKVECTORS_TWOPI
Definition: AkVectors.h:47
Ak3DVector GetUz() const
Definition: AkVectors.h:1868
T3DVector(TDataType in_x, TDataType in_y, TDataType in_z)
Definition: AkVectors.h:231
AkForceInline T3DVector Abs() const
Definition: AkVectors.h:644
AkInt32 Y
Y Position.
Definition: AkVectors.h:122
static AkReal64 ACos(AkReal64 in_value)
Definition: AkVectors.h:163
Ak3DVector points[2]
Definition: AkVectors.h:1274
float32x4_t AKSIMD_V4F32
Vector of 4 32-bit floats.
Definition: AkSimd.h:72
AkForceInline bool operator==(const T3DVector &b) const
Definition: AkVectors.h:338
AkForceInline bool IsWithin(const TBoundingBox &in_BB) const
Definition: AkVectors.h:1796
AkPlane()=default
AkForceInline Ak2DVector operator=(const Ak2DVector &b)
Definition: AkVectors.h:722
TBoundingBox< AkReal32 > AkBoundingBox
Definition: AkVectors.h:1832
T3DVector< AkReal64 > Ak3DVector64
Definition: AkVectors.h:690
#define AKVECTORS_PI
Definition: AkVectors.h:46
#define AkMax(x1, x2)
Ak3DVector GetN() const
Definition: AkVectors.h:1556
Ak3DVector PointAt(AkReal32 t) const
Definition: AkVectors.h:1295
bool Intersect(Ak3DVector A, Ak3DVector B)
Definition: AkVectors.h:1300
AkReal32 phi
Elevation.
Definition: AkTypes.h:792
AkReal32 X
Definition: AkVectors.h:1267
Ak4DVector operator-(const Ak4DVector &b) const
Definition: AkVectors.h:94
bool SeparatingAxisExists(const Ak3DVector &L, const AkBox &B) const
Definition: AkVectors.h:1880
AkSafeConversion TTypeConverter
Definition: AkVectors.h:218
bool IsPointInBox(const Ak3DVector &in_Point) const
Definition: AkVectors.h:1857
TDataType Y
Definition: AkVectors.h:662
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:1159
AkForceInline AkQuaternion operator*(const AkQuaternion &Q) const
Quaternion multiplication.
Definition: AkVectors.h:1221
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:1061
void SetPlane(Ak3DVector in_p1, Ak3DVector in_p2, Ak3DVector in_p4)
Definition: AkVectors.h:1390
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:1002
T3DVector(TDataType in_scalar)
Definition: AkVectors.h:295
AkForceInline bool IsEmpty() const
Definition: AkVectors.h:1818
T3DVector< AkReal32 > Ak3DVector32
Definition: AkVectors.h:687
static void Rotation(AkMatrix3x3 &out_mat, AkReal32 in_sin, AkReal32 in_cos, const Ak3DVector &in_axis)
Definition: AkVectors.h:1029
AkForceInline bool operator==(const Ak2DVector &b) const
Definition: AkVectors.h:765
Ak3DVector GetUx() const
Definition: AkVectors.h:1866
uint8_t AkUInt8
Unsigned 8-bit integer.
void UpdateBoundingBox(AkBoundingBox &out_aabb) const
Definition: AkVectors.h:1921
static AkReal64 Sqrt(AkReal64 in_value)
Definition: AkVectors.h:162
Ak3DVector GetCenter() const
Definition: AkVectors.h:1864
static AkForceInline TDataType Determinant(const T3DVector &a, const T3DVector &b, const T3DVector &c)
Definition: AkVectors.h:535
float AkReal32
32-bit floating point
Ak2DVector & operator/=(const AkReal32 f)
Definition: AkVectors.h:756
AkForceInline T3DVector LinearCombination(const T3DVector &A, const T3DVector &B, const T3DVector &C) const
Definition: AkVectors.h:545
static AkReal32 Sqrt(AkReal32 in_value)
Definition: AkVectors.h:142
AkReal32 X
Definition: AkVectors.h:881
int32_t AkInt32
Signed 32-bit integer.
AkReal32 maxt
Definition: AkVectors.h:1371
static AkMatrix3x3 FromColumnVectors(const Ak3DVector &in_col0, const Ak3DVector &in_col1, const Ak3DVector &in_col2)
Definition: AkVectors.h:927
TBoundingBox Intersect(const TBoundingBox &in_BB) const
Definition: AkVectors.h:1803
Ak2DVector()=default
AkForceInline TDataType DotProduct(const T3DVector &v2) const
Definition: AkVectors.h:603
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:653
Ak4DVector & operator=(const Ak4DVector &b)
Definition: AkVectors.h:74
AkForceInline bool operator!=(const Ak2DVector &b) const
Definition: AkVectors.h:770
AkForceInline void Convert(AkReal64 &out_to, AkReal32 in_from)
Definition: AkVectors.h:195
AkForceInline bool IsAllPositive() const
Definition: AkVectors.h:874
AkForceInline AkReal32 Length() const
Definition: AkVectors.h:775
Ak4DVector()
Definition: AkVectors.h:56
Ak3DVector GetSide() const
Definition: AkVectors.h:1872
AkLine()
Definition: AkVectors.h:1281
AkReal32 Y
Y Position.
Definition: AkTypes.h:468
Ak2DVector(AkReal32 x, AkReal32 y)
Definition: AkVectors.h:714
static AkReal64 Sin(AkReal64 in_value)
Definition: AkVectors.h:161
AkForceInline AkMatrix3x3 & operator*=(const AkReal32 &in_f)
Definition: AkVectors.h:994
AkMatrix4x4 & operator=(AkReal32 *in_Data)
Definition: AkVectors.h:906
void Update(const TVectorType &in_point)
Definition: AkVectors.h:1770
static AkQuaternion FromAngleAndAxis(AkReal32 in_angle, const Ak3DVector &in_axis)
Definition: AkVectors.h:1131
AkForceInline TDataType LengthSquared() const
Definition: AkVectors.h:631
AkReal32 GetVolume() const
Definition: AkVectors.h:1874
AkReal32 GetD() const
Definition: AkVectors.h:1557
AkForceInline TDataType Dot(const T3DVector &v2) const
Definition: AkVectors.h:608
AkReal32 X
X Position.
Definition: AkTypes.h:467
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:738
#define AKSIMD_GETELEMENT_V4F32(__vName, __num__)
Get the element at index num in vector __vName.
Definition: AkSimd.h:38
AkReal32 m_Data[MAX_SIZE]
Definition: AkVectors.h:916
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:667
#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:791
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:522
AkReal32 mint
Definition: AkVectors.h:1370
AkForceInline AKSIMD_V4F32 PointV4F32() const
Definition: AkVectors.h:309
AkMatrix3x3()=default
AkReal32 Z
Z Position.
Definition: AkTypes.h:469
static AkForceInline void OuterProduct(AkMatrix3x3 &out_mat, const Ak3DVector &in_v0, const Ak3DVector &in_v1)
Definition: AkVectors.h:1017
AkForceInline void Convert(TReal &out_to, TReal in_from)
Definition: AkVectors.h:200
Ak3DVector GetFront() const
Definition: AkVectors.h:1870
Ak3DVector GetUy() const
Definition: AkVectors.h:1867
AkForceInline T3DVector operator+(const T3DVector &b) const
Definition: AkVectors.h:455
AkReal32 Y
Definition: AkVectors.h:882
static AkForceInline void Add(AkMatrix3x3 &out_res, const AkMatrix3x3 &in_m0, const AkMatrix3x3 &in_m1)
Definition: AkVectors.h:985
TVectorType Cast() const
Definition: AkVectors.h:697
AkMatrix4x4 & operator/=(const AkReal32 f)
Definition: AkVectors.h:898
TBoundingBox< AkReal64 > AkBoundingBox64
Definition: AkVectors.h:1833
Ak3DIntVector()=default
AkForceInline Ak3DVector UnrotateVector(const Ak3DVector32 &in_v) const
Definition: AkVectors.h:1258
AkForceInline AkReal32 & operator()(const AkUInt32 row, const AkUInt32 column)
Definition: AkVectors.h:960
AkReal32 W
Definition: AkVectors.h:1266
AkQuaternion(AkReal32 in_angle, const Ak3DVector &in_axis)
Definition: AkVectors.h:1211
AkForceInline T3DVector< TDataType > operator/(const TDataType f, const T3DVector< TDataType > &v)
Definition: AkVectors.h:673
AkLine(Ak3DVector in_L, Ak3DVector in_P)
Definition: AkVectors.h:1287
static AkQuaternion FromEulers(AkReal32 in_x, AkReal32 in_y, AkReal32 in_z)
Definition: AkVectors.h:1109
double AkReal64
64-bit floating point
static AkForceInline void CrossProductMatrix(AkMatrix3x3 &out_mat, const Ak3DVector &in_u)
Definition: AkVectors.h:1010
bool DoesRayIntersect(const Ak3DVector &in_Origin, const Ak3DVector &in_Destination, Ak3DVector &out_Intersection) const
Definition: AkVectors.h:1420
Ak3DVector P
Definition: AkVectors.h:1368
AkReal32 Z
Definition: AkVectors.h:1269
AkForceInline Ak3DVector32 operator*(const Ak3DVector32 &in_v) const
Definition: AkVectors.h:1230
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:825
AkForceInline bool IsWithin(const TVectorType &in_Point) const
Definition: AkVectors.h:1791
uint64_t AkUInt64
Unsigned 64-bit integer.
AkReal64 Y
Y Position.
Definition: AkTypes.h:419
#define ADD(i, j)
void Zero()
Definition: AkVectors.h:329
AkForceInline void NormalizeSpherical()
Definition: AkVectors.h:854
static AkForceInline void Rotation(AkMatrix3x3 &out_mat, AkReal32 in_angle, const Ak3DVector &in_axis)
Definition: AkVectors.h:1024
Ak3DVector GetUp() const
Definition: AkVectors.h:1871
#define AKVECTORS_EPSILON
Definition: AkVectors.h:49
TVectorType m_Max
Definition: AkVectors.h:1829
AkForceInline T3DVector Rotate180X_90Y() const
Definition: AkVectors.h:511
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:1840
AkReal32 theta
Azimuth.
Definition: AkTypes.h:786
AkForceInline AkMatrix3x3 & operator+=(const AkMatrix3x3 &in_rhs)
Definition: AkVectors.h:979
AkReal32 Y
Definition: AkVectors.h:1268
AkForceInline bool IsValid() const
Definition: AkVectors.h:1823
Ak3DVector GetP2() const
Definition: AkVectors.h:1712
AkForceInline const AkReal32 & operator()(const AkUInt32 row, const AkUInt32 column) const
Definition: AkVectors.h:965
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:390
AkForceInline Ak2DVector & CartesianToSpherical(const Ak3DVector &in_Cartesian)
Definition: AkVectors.h:782
AkPlane(Ak3DVector in_p1, Ak3DVector in_p2, Ak3DVector in_p4)
Definition: AkVectors.h:1379
uint32_t AkUInt32
Unsigned 32-bit integer.
AkQuaternion(const Ak3DVector &in_v0, const Ak3DVector &in_v1)
Definition: AkVectors.h:1174
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:1419
TDataType Z
Definition: AkVectors.h:663
3D vector for some operations in 3D space. Typically intended only for localized calculations due to ...
Definition: AkTypes.h:425
Ak3DVector GetSize() const
Definition: AkVectors.h:1863
Ak3DVector GetP1() const
Definition: AkVectors.h:1711
T3DVector(const AKSIMD_V4F32 &in_v4f32)
Definition: AkVectors.h:302
AkForceInline bool IsAllPositive() const
Definition: AkVectors.h:637
AkForceInline TDataType HorizontalMax() const
Definition: AkVectors.h:482
Ak3DVector GetP4() const
Definition: AkVectors.h:1713
AkForceInline void Convert(TToReal &out_to, TFromReal in_from)
Definition: AkVectors.h:183
AkForceInline TDataType L2_Norm() const
Definition: AkVectors.h:598
AkForceInline AkReal32 Length() const
Definition: AkVectors.h:1144
AkReal64 Z
Z Position.
Definition: AkTypes.h:420
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:1531
AkForceInline bool operator<=(const T3DVector &b) const
Definition: AkVectors.h:353
AkForceInline Ak3DVector operator*(const Ak3DVector &in_rhs) const
Definition: AkVectors.h:970
Ak4DVector(const AkVector &b)
Definition: AkVectors.h:64
AkForceInline T3DVector & Normalize()
Definition: AkVectors.h:580
Ak3DVector L
Definition: AkVectors.h:1367
Ak2DVector & operator*=(const AkReal32 f)
Definition: AkVectors.h:748
AkForceInline Ak3DVector RotateVector(const Ak3DVector32 &in_v) const
Definition: AkVectors.h:1235
T3DVector(const T3DVector< TFromDataType > &in_vector)
Definition: AkVectors.h:240
AkForceInline T3DVector Cross(const T3DVector &v) const
Definition: AkVectors.h:613
AkForceInline Ak2DVector operator=(const AkSphericalCoord &b)
Definition: AkVectors.h:730
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:796
static bool IsFinite(AkReal32 in_val)
Definition: AkVectors.h:144
AkReal64 X
X Position.
Definition: AkTypes.h:418
AkQuaternion(AkReal32 in_W, AkReal32 in_X, AkReal32 in_Y, AkReal32 in_Z)
Definition: AkVectors.h:1053
TVectorType m_Min
Definition: AkVectors.h:1828
AkReal32 m_Data[3][3]
Definition: AkVectors.h:1044
AkForceInline TDataType Length() const
Definition: AkVectors.h:626
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:1760

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