Table of Contents

Wwise SDK 2019.1.5
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  Version: <VERSION> Build: <BUILDNUMBER>
25  Copyright (c) <COPYRIGHTYEAR> Audiokinetic Inc.
26 *******************************************************************************/
27 
28 // AkVectors.h
29 //
30 
31 #pragma once
32 
37 #include <AK/Tools/Common/AkArray.h>
39 
40 #include <math.h>
41 #include <stdio.h>
42 #include <float.h>
43 
44 //#define AKVBAP_DEBUG 1
45 //#define AKPORTALS_DEBUG
46 
47 #define AKVECTORS_PI (3.1415926535897932384626433832795f)
48 #define AKVECTORS_TWOPI (6.283185307179586476925286766559f)
49 #define AKVECTORS_PIOVERTWO (1.5707963267948966192313216916398f)
50 #define AKVECTORS_EPSILON (1.0e-38f) // epsilon value for fast log(0)
51 
52 class Ak4DVector
53 {
54 public:
55  //-----------------------------------------------------------
56  // Constructor/Destructor functions
58  {
59  v[0] = 0.0f;
60  v[1] = 0.0f;
61  v[2] = 0.0f;
62  v[3] = 0.0f;
63  }
64 
65  Ak4DVector(const AkVector& b)
66  {
67  v[0] = b.X;
68  v[1] = b.Y;
69  v[2] = b.Z;
70  v[3] = 1;
71  }
72 
74 
75  //-----------------------------------------------------------
76  // Basic vector operators
78  {
79  v[0] = b.v[0];
80  v[1] = b.v[1];
81  v[2] = b.v[2];
82  v[3] = b.v[3];
83 
84  return *this;
85  }
86 
88  {
89  v[0] = v[0] / f;
90  v[1] = v[1] / f;
91  v[2] = v[2] / f;
92  v[3] = v[3] / f;
93 
94  return *this;
95  }
96 
97  Ak4DVector operator-(const Ak4DVector& b) const
98  {
99  Ak4DVector p;
100 
101  p.v[0] = v[0] - b.v[0];
102  p.v[1] = v[1] - b.v[1];
103  p.v[2] = v[2] - b.v[2];
104  p.v[3] = v[3] - b.v[3];
105 
106  return p;
107  }
108 
110 };
111 
113 {
114 public:
117  {
118  X = x;
119  Y = y;
120  Z = z;
121  }
122 
124 
125  AkInt32 X; ///< X Position
126  AkInt32 Y; ///< Y Position
127  AkInt32 Z; ///< Z Position
128 };
129 
131 {
132 public:
133  //-----------------------------------------------------------
134  // Constructor/Destructor functions
136  X(0.f),
137  Y(0.f),
138  Z(0.f)
139  {}
140 
142  AkReal32 x,
143  AkReal32 y,
144  AkReal32 z)
145  {
146  X = x;
147  Y = y;
148  Z = z;
149  }
151  {
152  X = b.X;
153  Y = b.Y;
154  Z = b.Z;
155  }
156  explicit Ak3DVector(const AKSIMD_V4F32& in_v4f32)
157  {
158  X = AKSIMD_GETELEMENT_V4F32(in_v4f32, 0);
159  Y = AKSIMD_GETELEMENT_V4F32(in_v4f32, 1);
160  Z = AKSIMD_GETELEMENT_V4F32(in_v4f32, 2);
161  }
163  {
164  AKSIMD_V4F32 v4f32;
165  AKSIMD_GETELEMENT_V4F32(v4f32, 0) = X;
166  AKSIMD_GETELEMENT_V4F32(v4f32, 1) = Y;
167  AKSIMD_GETELEMENT_V4F32(v4f32, 2) = Z;
168  AKSIMD_GETELEMENT_V4F32(v4f32, 3) = 1.f;
169  return v4f32;
170  }
172  {
173  AKSIMD_V4F32 v4f32;
174  AKSIMD_GETELEMENT_V4F32(v4f32, 0) = X;
175  AKSIMD_GETELEMENT_V4F32(v4f32, 1) = Y;
176  AKSIMD_GETELEMENT_V4F32(v4f32, 2) = Z;
177  AKSIMD_GETELEMENT_V4F32(v4f32, 3) = 0.f;
178  return v4f32;
179  }
181 
182  void Zero()
183  {
184  X = 0.f;
185  Y = 0.f;
186  Z = 0.f;
187  }
188 
189 
190  //-----------------------------------------------------------
191  // Basic vector operators
192  AkForceInline bool operator==(const Ak3DVector& b) const
193  {
194  return X == b.X && Y == b.Y && Z == b.Z;
195  }
196 
197  AkForceInline bool operator!=(const Ak3DVector& b) const
198  {
199  return X != b.X || Y != b.Y || Z != b.Z;
200  }
201 
203  {
204  X = b.X;
205  Y = b.Y;
206  Z = b.Z;
207 
208  return *this;
209  }
210 
212  {
213  X = b.X;
214  Y = b.Y;
215  Z = b.Z;
216 
217  return *this;
218  }
219 
220  AkForceInline bool operator<(const Ak3DVector& b) const
221  {
222  return X < b.X && Y < b.Y && Z < b.Z;
223  }
224 
225  AkForceInline bool operator<=(const Ak3DVector& b) const
226  {
227  return X <= b.X && Y <= b.Y && Z <= b.Z;
228  }
229 
230  AkForceInline bool operator>(const Ak3DVector b) const
231  {
232  return X > b.X && Y > b.Y && Z > b.Z;
233  }
234 
235  AkForceInline bool operator>=(const Ak3DVector& b) const
236  {
237  return X >= b.X && Y >= b.Y && Z >= b.Z;
238  }
239 
241  {
242  X = X * f;
243  Y = Y * f;
244  Z = Z * f;
245 
246  return *this;
247  }
248 
250  {
251  AkReal32 oneoverf = 1.f / f;
252  X = X * oneoverf;
253  Y = Y * oneoverf;
254  Z = Z * oneoverf;
255 
256  return *this;
257  }
258 
260  {
261  Ak3DVector v;
262 
263  v.X = X * v2.X;
264  v.Y = Y * v2.Y;
265  v.Z = Z * v2.Z;
266 
267  return v;
268  }
269 
271  {
272  Ak3DVector v;
273 
274  v.X = X * f;
275  v.Y = Y * f;
276  v.Z = Z * f;
277 
278  return v;
279  }
280 
282  {
283  Ak3DVector v;
284  AkReal32 oneoverf = 1.f / f;
285 
286  v.X = X * oneoverf;
287  v.Y = Y * oneoverf;
288  v.Z = Z * oneoverf;
289 
290  return v;
291  }
292 
294  {
295  Ak3DVector v;
296 
297  v.X = X + f;
298  v.Y = Y + f;
299  v.Z = Z + f;
300 
301  return v;
302  }
303 
305  {
306  Ak3DVector v;
307 
308  v.X = X - f;
309  v.Y = Y - f;
310  v.Z = Z - f;
311 
312  return v;
313  }
314 
316  {
317  Ak3DVector v;
318 
319  v.X = X + b.X;
320  v.Y = Y + b.Y;
321  v.Z = Z + b.Z;
322 
323  return v;
324  }
325 
327  {
328  Ak3DVector v;
329 
330  v.X = X - b.X;
331  v.Y = Y - b.Y;
332  v.Z = Z - b.Z;
333 
334  return v;
335  }
336 
337  AkForceInline operator</span> AkVector()
338  {
339  AkVector v;
340  v.X = X; v.Y = Y; v.Z = Z;
341 
342  return v;
343  }
344 
345 
346  AkForceInline static Ak3DVector Min(const Ak3DVector& A, const Ak3DVector& B)
347  {
348  Ak3DVector min;
349 
350  min.X = AkMin(A.X, B.X);
351  min.Y = AkMin(A.Y, B.Y);
352  min.Z = AkMin(A.Z, B.Z);
353 
354  return min;
355  }
356 
357  AkForceInline static Ak3DVector Max(const Ak3DVector& A, const Ak3DVector& B)
358  {
359  Ak3DVector max;
360 
361  max.X = AkMax(A.X, B.X);
362  max.Y = AkMax(A.Y, B.Y);
363  max.Z = AkMax(A.Z, B.Z);
364 
365  return max;
366  }
367 
368  //-----------------------------------------------------------
369  // Conversion functions
371  {
372  Ak3DVector v;
373 
374  v.X = -X;
375  v.Y = Z;
376  v.Z = -Y;
377 
378  return v;
379  }
380 
382  const AkReal32 azimuth,
383  const AkReal32 elevation)
384  {
385  AkReal32 cosElevation = cosf(elevation);
386  X = cosf(azimuth) * cosElevation;
387  Y = sinf(azimuth) * cosElevation;
388  Z = sinf(elevation);
389 
390  return *this;
391  }
392 
393  // Determinant of 3 column vectors.
395  const Ak3DVector & a,
396  const Ak3DVector & b,
397  const Ak3DVector & c)
398  {
399  return (a.X*b.Y*c.Z + a.Y*b.Z*c.X + a.Z*b.X*c.Y) -
400  (a.Z*b.Y*c.X + a.Y*b.X*c.Z + a.X*b.Z*c.Y);
401  }
402 
403  // Convert a vector to a different base
405  const Ak3DVector& A,
406  const Ak3DVector& B,
407  const Ak3DVector& C) const
408  {
409  Ak3DVector v;
410 
411  AkReal32 d = Determinant(A, B, C);
412 
413  if (d < AKVECTORS_EPSILON && d > -AKVECTORS_EPSILON)
414  {
415  v.X = 0.0f; v.Y = 0.0f; v.Z = 0.0f;
416  return v;
417  }
418 
419  // http://mathworld.wolfram.com/MatrixInverse.html
420  Ak3DVector invA = Ak3DVector(B.Y*C.Z - B.Z*C.Y, A.Z*C.Y - A.Y*C.Z, A.Y*B.Z - A.Z*B.Y);
421  Ak3DVector invB = Ak3DVector(B.Z*C.X - B.X*C.Z, A.X*C.Z - A.Z*C.X, A.Z*B.X - A.X*B.Z);
422  Ak3DVector invC = Ak3DVector(B.X*C.Y - B.Y*C.X, A.Y*C.X - A.X*C.Y, A.X*B.Y - A.Y*B.X);
423 
424  AkReal32 oneover_d = 1.f / d;
425  invA *= oneover_d;
426  invB *= oneover_d;
427  invC *= oneover_d;
428 
429  // Project coordinates using a vector to matrix multiplication
430  v.X = X * invA.X + Y * invB.X + Z * invC.X;
431  v.Y = X * invA.Y + Y * invB.Y + Z * invC.Y;
432  v.Z = X * invA.Z + Y * invB.Z + Z * invC.Z;
433 
434  // v /= v.Length();
435 
436  return v;
437  }
438 
440  {
441  AkReal32 l = Length();
442  if (l != 0.f)
443  {
444  X /= l;
445  Y /= l;
446  Z /= l;
447  }
448  else
449  {
450  X = 0.f;
451  Y = 0.f;
452  Z = 0.f;
453  }
454  return *this;
455  }
456 
458  {
459  return sqrtf(X*X + Y*Y + Z*Z);
460  }
461 
463  {
464  return X*v2.X + Y*v2.Y + Z*v2.Z;
465  }
466 
468  {
469  return DotProduct(v2);
470  }
471 
473  {
474  Ak3DVector uxv;
475  const Ak3DVector& u = *this;
476 
477  uxv.X = u.Y*v.Z - u.Z*v.Y;
478  uxv.Y = u.Z*v.X - u.X*v.Z;
479  uxv.Z = u.X*v.Y - u.Y*v.X;
480 
481  return uxv;
482  }
483  //
485  {
486  return sqrtf(X*X + Y*Y + Z*Z);
487  }
488 
490  {
491  return X*X + Y*Y + Z*Z;
492  }
493 
494  // Usefull in VBAP algorithm, only points that are a positive linear composition matters.
496  {
497  const AkReal32 POSITIVE_TEST_EPSILON = 0.00001f;
498  return X >= -POSITIVE_TEST_EPSILON &&
499  Y >= -POSITIVE_TEST_EPSILON &&
500  Z >= -POSITIVE_TEST_EPSILON;
501  }
502 
504  {
505  Ak3DVector abs = *this;
506  abs.X = (AkReal32)fabs(abs.X);
507  abs.Y = (AkReal32)fabs(abs.Y);
508  abs.Z = (AkReal32)fabs(abs.Z);
509  return abs;
510  }
511 
515 };
516 
518 {
519 public:
520  //-----------------------------------------------------------
521  // Constructor/Destructor functions
524 
526  AkReal32 x,
527  AkReal32 y)
528  {
529  X = x;
530  Y = y;
531  }
532 
533  //-----------------------------------------------------------
534  // Basic vector operators
536  {
537  X = b.X;
538  Y = b.Y;
539 
540  return *this;
541  }
542 
544  {
545  X = b.theta;
546  Y = b.phi;
547 
548  return *this;
549  }
550 
551  Ak2DVector operator-(const Ak2DVector& b) const
552  {
553  Ak2DVector v;
554 
555  v.X = X - b.X;
556  v.Y = Y - b.Y;
557 
558  return v;
559  }
560 
562  {
563  X = X * f;
564  Y = Y * f;
565 
566  return *this;
567  }
568 
570  {
571  AkReal32 oneoverf = 1.f / f;
572  X = X * oneoverf;
573  Y = Y * oneoverf;
574 
575  return *this;
576  }
577 
578  AkForceInline bool operator==(const Ak2DVector& b) const
579  {
580  return b.X == X && b.Y == Y;
581  }
582 
583  AkForceInline bool operator!=(const Ak2DVector& b) const
584  {
585  return b.X != X && b.Y != Y;
586  }
587 
589  {
590  return sqrtf(X*X+Y*Y);
591  }
592 
593  //-----------------------------------------------------------
594  // Conversion functions
596  {
597  // (radial, azimuth, elevation)
598  AkReal32 r = sqrtf( in_Cartesian.X*in_Cartesian.X + in_Cartesian.Y*in_Cartesian.Y + in_Cartesian.Z*in_Cartesian.Z);
599  AKASSERT( r != 0);
600 
601  X = atan2f(in_Cartesian.Y, in_Cartesian.X);
602  Y = asinf(in_Cartesian.Z / r);
603 
605 
606  return *this;
607  }
608 
610  const Ak2DVector& A,
611  const Ak2DVector& B) const
612  {
613  Ak2DVector v;
614 
615  // Project coordinates using a vector to matrix multiplication
616  AkReal32 d = (A.X*B.Y - A.Y*B.X);
617 
618  if (d < AKVECTORS_EPSILON && d > -AKVECTORS_EPSILON)
619  {
620  v.X = 0.0f; v.Y = 0.0f;
621  return v;
622  }
623 
624  Ak2DVector invA = Ak2DVector( B.Y, -A.Y );
625  Ak2DVector invB = Ak2DVector( -B.X, A.X );
626 
627  AkReal32 oneover_d = 1.f / d;
628  invA *= oneover_d;
629  invB *= oneover_d;
630 
631  v.X = X * invA.X + Y * invB.X;
632  v.Y = X * invA.Y + Y * invB.Y;
633  // v /= v.Length();
634 
635  return v;
636  }
637 
639  {
640  /*
641  Normalise spherical coordinates.
642  X (azimuthal) -> [-PI, PI], circle lies on xy plan, 0 is on X axix
643  Y (elevation) -> [-PI/2, PI/2], half circle on Z axis, 0 on XY plan, PI/2 straigt up on Z axis.
644  */
645 
646  Ak2DVector v;
647 
648  v.X = X;
649  v.Y = Y;
650 
651  if (X > AKVECTORS_PI)
652  v.X = X - AKVECTORS_TWOPI;
653 
654  if (X < -AKVECTORS_PI)
655  v.X = X + AKVECTORS_TWOPI;
656 
657  if (Y > AKVECTORS_PIOVERTWO)
658  v.Y = Y - AKVECTORS_PI;
659 
660  if (Y < -AKVECTORS_PIOVERTWO)
661  v.Y = Y + AKVECTORS_PI;
662 
665 
666  return v;
667  }
668 
670  {
671  /*
672  Normalise spherical coordinates.
673  X (azimuthal) -> [-PI, PI], circle lies on xy plan, 0 is on X axix
674  Y (elevation) -> [-PI/2, PI/2], half circle on Z axis, 0 on XY plan, PI/2 straigt up on Z axis.
675  */
676 
677  if (X > AKVECTORS_PI)
678  X = X - AKVECTORS_TWOPI;
679 
680  if (X < -AKVECTORS_PI)
681  X = X + AKVECTORS_TWOPI;
682 
683  if (Y > AKVECTORS_PIOVERTWO)
684  Y = Y - AKVECTORS_PI;
685 
686  if (Y < -AKVECTORS_PIOVERTWO)
687  Y = Y + AKVECTORS_PI;
688  }
689 
690  // Useful in VBAP algorithm, only points that are a positive linear composition matters.
692  {
693  const AkReal32 POSITIVE_TEST_EPSILON = 0.00001f; //0.005f;
694  return X >= -POSITIVE_TEST_EPSILON &&
695  Y >= -POSITIVE_TEST_EPSILON;
696  }
697 
700 };
701 
702 
703 
705 {
706  static const int MAX_SIZE = 16;
707 
708 public:
709  //-----------------------------------------------------------
710  // Constructor/Destructor functions
713 
714  //-----------------------------------------------------------
715  // Basic vector operators
717  {
718  for (int i = 0; i < MAX_SIZE; i++)
719  m_Data[i] /= f;
720 
721  return *this;
722  }
723 
725  {
726  for (int i = 0; i < MAX_SIZE; i++)
727  {
728  m_Data[i] = in_Data[i];
729  }
730 
731  return *this;
732  }
733 
734  AkReal32 m_Data[MAX_SIZE];
735 };
736 
738 {
739 
740 public:
741  //-----------------------------------------------------------
742  // Constructor/Destructor functions
745 
746  //-----------------------------------------------------------
747  // Basic vector operators
749  {
750  for (int i = 0; i < 3; i++)
751  {
752  for (int j = 0; j < 3; j++)
753  {
754  m_Data[i][j] /= f;
755  }
756  }
757  return *this;
758  }
759 
761  {
762  return m_Data[column][row];
763  }
764 
765  AkForceInline const AkReal32& operator()(const AkUInt32 row, const AkUInt32 column) const
766  {
767  return m_Data[column][row];
768  }
769 
771  {
772  Ak3DVector res;
773  res.X = in_rhs.X * m_Data[0][0] + in_rhs.Y * m_Data[1][0] + in_rhs.Z * m_Data[2][0];
774  res.Y = in_rhs.X * m_Data[0][1] + in_rhs.Y * m_Data[1][1] + in_rhs.Z * m_Data[2][1];
775  res.Z = in_rhs.X * m_Data[0][2] + in_rhs.Y * m_Data[1][2] + in_rhs.Z * m_Data[2][2];
776  return res;
777  }
778 
780  {
781  Add(*this, *this, in_rhs);
782  return *this;
783  }
784 
785  static AkForceInline void Add(AkMatrix3x3& out_res, const AkMatrix3x3& in_m0, const AkMatrix3x3& in_m1)
786  {
787 #define ADD(i,j) out_res(i,j) = in_m0(i,j) + in_m1(i,j)
788  ADD(0, 0); ADD(0, 1); ADD(0, 2);
789  ADD(1, 0); ADD(1, 1); ADD(1, 2);
790  ADD(2, 0); ADD(2, 1); ADD(2, 2);
791 #undef ADD
792  }
793 
795  {
796  m_Data[0][0] *= in_f; m_Data[0][1] *= in_f; m_Data[0][2] *= in_f;
797  m_Data[1][0] *= in_f; m_Data[1][1] *= in_f; m_Data[1][2] *= in_f;
798  m_Data[2][0] *= in_f; m_Data[2][1] *= in_f; m_Data[2][2] *= in_f;
799  return *this;
800  }
801 
802  static AkForceInline void Diagonal(AkMatrix3x3& out_mat, AkReal32 in_f)
803  {
804  out_mat(0, 0) = in_f; out_mat(0, 1) = 0.f; out_mat(0, 2) = 0.f;
805  out_mat(1, 0) = 0.f; out_mat(1, 1) = in_f; out_mat(1, 2) = 0.f;
806  out_mat(2, 0) = 0.f; out_mat(2, 1) = 0.f; out_mat(2, 2) = in_f;
807  }
808 
809  // Creates the matrix Mu such that Mu*v = u X v
810  static AkForceInline void CrossProductMatrix(AkMatrix3x3& out_mat, const Ak3DVector& in_u)
811  {
812  out_mat(0, 0) = 0.f; out_mat(0, 1) = -in_u.Z; out_mat(0, 2) = in_u.Y;
813  out_mat(1, 0) = in_u.Z; out_mat(1, 1) = 0.f; out_mat(1, 2) = -in_u.X;
814  out_mat(2, 0) = -in_u.Y; out_mat(2, 1) = in_u.X; out_mat(2, 2) = 0.f;
815  }
816 
817  static AkForceInline void OuterProduct(AkMatrix3x3& out_mat, const Ak3DVector& in_v0, const Ak3DVector& in_v1)
818  {
819  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;
820  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;
821  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;
822  }
823 
824  static AkForceInline void Rotation(AkMatrix3x3& out_mat, AkReal32 in_angle, const Ak3DVector& in_axis)
825  {
826  Rotation(out_mat, sinf(in_angle), cosf(in_angle), in_axis);
827  }
828 
829  static void Rotation(AkMatrix3x3& out_mat, AkReal32 in_sin, AkReal32 in_cos, const Ak3DVector& in_axis)
830  {
831  Diagonal(out_mat, in_cos);
832 
833  AkMatrix3x3 outer;
834  OuterProduct(outer, in_axis, in_axis);
835  outer *= (1.f - in_cos);
836  out_mat += outer;
837 
838  AkMatrix3x3 cross;
839  CrossProductMatrix(cross, in_axis*in_sin);
840  out_mat += cross;
841  }
842 
843  // [column][row]
845 };
846 
848 {
849 public:
850  // Identity quaternion
851  AkQuaternion(): W(1.f), X(0.f), Y(0.f), Z(0.f) {}
852 
853  AkQuaternion(AkReal32 in_W, AkReal32 in_X, AkReal32 in_Y, AkReal32 in_Z) :
854  W(in_W),
855  X(in_X),
856  Y(in_Y),
857  Z(in_Z)
858  {}
859 
860  AkQuaternion(const Ak3DVector& in_fromVector):
861  W(0.f),
862  X(in_fromVector.X),
863  Y(in_fromVector.Y),
864  Z(in_fromVector.Z)
865  {}
866 
868  {
869  return sqrtf( W*W + X*X + Y*Y + Z*Z );
870  }
871 
873  {
874  AkReal32 f = 1.0f / Length();
875  W *= f;
876  X *= f;
877  Y *= f;
878  Z *= f;
879  return *this;
880  }
881 
883  {
884  AkReal32 norm = W*W + X*X + Y*Y + Z*Z;
885  if (norm > 0.0)
886  {
887  AkReal32 invNorm = 1.0f / norm;
888  return AkQuaternion(W*invNorm, -X*invNorm, -Y*invNorm, -Z*invNorm);
889  }
890  else
891  {
892  return AkQuaternion();
893  }
894  }
895 
896  // Create a quaternion representing the shortest arc rotation between (normalized) vectors v0, v1
897  AkQuaternion(const Ak3DVector& in_v0, const Ak3DVector& in_v1)
898  {
899  AkReal32 dot = in_v0.Dot(in_v1);
900  if (dot >= 1.0f - AKVECTORS_EPSILON)
901  {
902  // No rotation - return unity quaternion.
903  AkQuaternion();
904  }
905  if (dot <= -1.f - AKVECTORS_EPSILON)
906  {
907  // 180 degree rotation - can use any non-zero length axis.
908  Ak3DVector axis = Ak3DVector(0.f, 0.f, 1.f).Cross(in_v0);
909  AkReal32 len = axis.Length();
910  if (len < AKVECTORS_EPSILON)
911  {
912  axis = Ak3DVector(0.f, 1.f, 0.f).Cross(in_v0);
913  len = axis.Length();
914  }
915  axis.Normalize();
916  AkQuaternion(AKVECTORS_PI, axis);
917  }
918  else
919  {
920  AkReal32 sqrt = sqrtf((1.f + dot) * 2.f);
921  AkReal32 invs = 1.f / sqrt;
922 
923  Ak3DVector cross = in_v0.Cross(in_v1);
924 
925  X = cross.X * invs;
926  Y = cross.Y * invs;
927  Z = cross.Z * invs;
928  W = sqrt * 0.5f;
929  Normalize();
930  }
931  }
932 
933  // Build quaternion from an axis and angle representation.
934  AkQuaternion(AkReal32 in_angle, const Ak3DVector& in_axis)
935  {
936  AkReal32 cosHalfAngle = cosf(in_angle / 2.f);
937  W = cosHalfAngle;
938  X = cosHalfAngle*in_axis.X;
939  Y = cosHalfAngle*in_axis.Y;
940  Z = cosHalfAngle*in_axis.Z;
941  }
942 
943  /// Quaternion multiplication.
945  {
946  return AkQuaternion(
947  W*Q.W - X*Q.X - Y*Q.Y - Z*Q.Z,
948  W*Q.X + X*Q.W + Y*Q.Z - Z*Q.Y,
949  W*Q.Y - X*Q.Z + Y*Q.W + Z*Q.X,
950  W*Q.Z + X*Q.Y - Y*Q.X + Z*Q.W);
951  }
952 
954  {
955  /*
956  // impl 1
957  Ak3DVector uv, uuv;
958  Ak3DVector qvec(X, Y, Z);
959  uv = qvec.Cross(in_v);
960  uuv = qvec.Cross(uv);
961  uv *= (2.0f * W);
962  uuv *= 2.0f;
963  return in_v + uv + uuv;
964  */
965 
966  // impl 2
967  Ak3DVector u(X, Y, Z);
968  Ak3DVector res =
969  u * u.Dot(in_v) * 2.f
970  + in_v * (W*W - u.Dot(u))
971  + u.Cross(in_v) * W * 2.0f;
972 
973  return res;
974  }
975 
980 };
981 
983 {
986 };
987 
988 class AkLine
989 {
990 public:
992  {
993  mint = 1.175494351e-38F;
994  maxt = 3.402823466e+38F;
995  }
996 
998  Ak3DVector in_L,
999  Ak3DVector in_P
1000  )
1001  {
1002  L = in_L;
1003  P = in_P;
1004  mint = 1.175494351e-38F;
1005  maxt = 3.402823466e+38F;
1006  }
1007 
1009  {
1010  return P + L*t;
1011  }
1012 
1014  Ak3DVector A,
1015  Ak3DVector B)
1016  {
1017  Ak3DVector L2 = B - A;
1018 
1019  /*
1020  a (V1 X V2) = (P2 - P1) X V2
1021  If the lines intersect at a single point, then the resultant vectors
1022  on each side of this equation must be parallel, and the left side must
1023  not be the zero vector. We should check to make sure that this is
1024  true. Once we have checked this, we can solve for 'a' by taking the
1025  magnitude of each side and dividing. If the resultant vectors are
1026  parallel, but in opposite directions, then 'a' is the negative of the
1027  ratio of magnitudes. Once we have 'a' we can go back to the equation
1028  for L1 to find the intersection point.
1029  */
1030  Ak3DVector V1 = L;
1031  Ak3DVector V2 = B - A;
1032  Ak3DVector P1 = P;
1033  Ak3DVector P2 = A;
1034 
1035  // k(V1 X V2) = (A - P) X V2
1036 
1037  Ak3DVector v1CrossV2 = V1.Cross(V2);
1039  P2 - P1,
1040  V2,
1041  v1CrossV2
1042  );
1043  AkReal32 t = det / v1CrossV2.LengthSquared();
1044 
1046  P2 - P1,
1047  V1,
1048  v1CrossV2
1049  );
1050  AkReal32 s = det / v1CrossV2.LengthSquared();
1051 
1052  AkReal32 distsqrd = ((P2 + V2*s) - (P1 + V1*t)).LengthSquared();
1053 
1054  if ((AkReal32)fabs(v1CrossV2.L2_Norm()) >= AKVECTORS_EPSILON
1055  && distsqrd < 0.001
1056  && s <= 1.0f )
1057  {
1058 #ifdef AKPORTALS_DEBUG
1059  Ak3DVector minPoint = PointAt(t);
1060 
1061  char msg[256];
1062  sprintf(msg, "L1a=[%0.2f,%0.2f,%0.2f];\n", P.X, P.Y, P.Z); AKPLATFORM::OutputDebugMsg(msg);
1063  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);
1064  sprintf(msg, "L2a=[%0.2f,%0.2f,%0.2f];\n", A.X, A.Y, A.Z); AKPLATFORM::OutputDebugMsg(msg);
1065  sprintf(msg, "L2b=[%0.2f,%0.2f,%0.2f];\n", B.X, B.Y, B.Z); AKPLATFORM::OutputDebugMsg(msg);
1066  sprintf(msg, "%% t=%0.2f Min t=%0.2f, Max t=%0.2f\n", t, mint, maxt); AKPLATFORM::OutputDebugMsg(msg);
1067  sprintf(msg, "intrPoint=[%0.2f,%0.2f,%0.2f];\n", minPoint.X, minPoint.Y, minPoint.Z); AKPLATFORM::OutputDebugMsg(msg);
1068  sprintf(msg, "\n"); AKPLATFORM::OutputDebugMsg(msg);
1069 #endif
1070 
1071  mint = AkMin(mint, t);
1072  maxt = AkMax(maxt, t);
1073 
1074  return true;
1075  }
1076 
1077 #ifdef AKPORTALS_DEBUG
1078  // char msg[256];
1079  // sprintf(msg, "%% DISCARTED t=%0.2f Min t=%0.2f, Max t=%0.2f\n", t, mint, maxt); AKPLATFORM::OutputDebugMsg(msg);
1080 #endif
1081  return false;
1082  }
1083 
1086 
1089 };
1090 
1091 class AkPlane
1092 {
1093 public:
1095  {
1096  }
1097 
1099  Ak3DVector in_p1,
1100  Ak3DVector in_p2,
1101  Ak3DVector in_p4
1102  )
1103  {
1104  SetPlane(
1105  in_p1,
1106  in_p2,
1107  in_p4);
1108  }
1109 
1111  {
1112  }
1113 
1114  void SetPlane(
1115  Ak3DVector in_p1,
1116  Ak3DVector in_p2,
1117  Ak3DVector in_p4
1118  )
1119  {
1120  // Reorder A-B-C to clockwwise if necessary
1121  AKASSERT(in_p1.X < 100000 && in_p1.X > -100000);
1122  AKASSERT(in_p1.Y < 100000 && in_p1.Y > -100000);
1123  AKASSERT(in_p1.Z < 100000 && in_p1.Z > -100000);
1124 
1125  AKASSERT(in_p2.X < 100000 && in_p2.X > -100000);
1126  AKASSERT(in_p2.Y < 100000 && in_p2.Y > -100000);
1127  AKASSERT(in_p2.Z < 100000 && in_p2.Z > -100000);
1128 
1129  AKASSERT(in_p4.X < 100000 && in_p4.X > -100000);
1130  AKASSERT(in_p4.Y < 100000 && in_p4.Y > -100000);
1131  AKASSERT(in_p4.Z < 100000 && in_p4.Z > -100000);
1132 
1133  p1 = in_p1;
1134  p2 = in_p2;
1135  p4 = in_p4;
1136 
1137  SetNormal();
1138 
1139  // Ax + By + Cz + D = 0
1140  // Find D using the normal and a point
1141  D = -(N.X*p1.X) - (N.Y*p1.Y) - (N.Z*p1.Z);
1142  }
1143 
1144 #define EPSILON 0.01f
1146  const Ak3DVector& in_Origin,
1147  const Ak3DVector& in_Destination,
1148  Ak3DVector& out_Intersection
1149  ) const
1150  {
1151  AkReal32 A = N.X;
1152  AkReal32 B = N.Y;
1153  AkReal32 C = N.Z;
1154 
1155  Ak3DVector ray = in_Destination - in_Origin;
1156  AkReal32 rayLength = ray.Length();
1157 
1158  Ak3DVector intersect;
1159 
1160  // If ray is < EPSILON, use on of the point directly for the test and skip the linear projection
1161  if (rayLength <= EPSILON)
1162  {
1163  Ak3DVector temp = in_Origin - p1;
1164  AkReal32 dot = temp.DotProduct(N);
1165  if (dot < EPSILON && dot > -EPSILON)
1166  {
1167  intersect = in_Origin;
1168  }
1169  else
1170  {
1171  // For debug only, to remove
1172  out_Intersection = p1;
1173  return false;
1174  }
1175 
1176  }
1177  else
1178  {
1179  // Normalize ray
1180  ray.Normalize();
1181 
1182  // TODO: possible fix for all edge cases
1183  // 1) if ray len ~= 0, only check if one of the point is on target, ie: assign the intersect point
1184 
1185  // Is ray parallel to the plane?
1186  if ((A*ray.X + B*ray.Y + C*ray.Z) == 0.0f)
1187  {
1188  // For debug only, to remove
1189  AkReal32 t = -(A*in_Origin.X + B*in_Origin.Y + C*in_Origin.Z + D) / (A*ray.X + B*ray.Y + C*ray.Z);
1190  intersect = Ak3DVector(in_Origin.X + ray.X*t, in_Origin.Y + ray.Y*t, in_Origin.Z + ray.Z*t);
1191  out_Intersection = intersect; // For debugging
1192  return false;
1193  }
1194 
1195 
1196  // Distance along the ray where reflector is hit
1197  AkReal32 t = -(A*in_Origin.X + B*in_Origin.Y + C*in_Origin.Z + D) / (A*ray.X + B*ray.Y + C*ray.Z);
1198 
1199  // Is the ray going towards the plane? Is it long enough?
1200  if (t < -EPSILON || t >(rayLength + EPSILON))
1201  {
1202  // For debug only, to remove
1203  intersect = Ak3DVector(in_Origin.X + ray.X*t, in_Origin.Y + ray.Y*t, in_Origin.Z + ray.Z*t);
1204  out_Intersection = intersect; // For debugging
1205  return false; // The ray doesn't intersect
1206  }
1207 
1208  // Find the coordinate of intersection on the plane
1209  intersect = Ak3DVector(in_Origin.X + ray.X*t, in_Origin.Y + ray.Y*t, in_Origin.Z + ray.Z*t);
1210  }
1211  ///////////////////////////////////////
1212  //
1213  // p2____v3____p3
1214  // | . |
1215  // ^ inter v4
1216  // v1 v
1217  // | |
1218  // p1__ v2>___p4
1219 
1220  Ak3DVector v1 = p2 - p1;
1221  Ak3DVector v2 = p4 - p1;
1222  Ak3DVector vInter1 = intersect - p1;
1223 
1224  Ak3DVector p3 = p4 + v1;
1225  Ak3DVector v3 = p2 - p3;
1226  Ak3DVector v4 = p4 - p3;
1227  Ak3DVector vInter2 = intersect - p3;
1228 
1229  v1.Normalize(); v2.Normalize(); v3.Normalize(); v4.Normalize(); vInter1.Normalize(); vInter2.Normalize();
1230 
1231  // Since it's a square, the angle between the point of intersection and any segment of the pannel should be < 90 degree,
1232  // therefore the dot product of the two normalized vectors should be > 0
1233  AkReal32 dot1 = v1.DotProduct(vInter1);
1234  AkReal32 dot2 = v2.DotProduct(vInter1);
1235  AkReal32 dot3 = v3.DotProduct(vInter2);
1236  AkReal32 dot4 = v4.DotProduct(vInter2);
1237 
1238  out_Intersection = intersect;
1239 
1240  return dot1 >= -EPSILON && dot2 >= -EPSILON && dot3 >= -EPSILON && dot4 >= -EPSILON;
1241  }
1242 
1244  Ak3DVector in_P,
1245  Ak3DVector& out_B) const
1246  {
1247  AkReal32 distance = (AkReal32)(AkReal32)fabs(N.X * in_P.X + N.Y * in_P.Y + N.Z * in_P.Z + D);
1248 
1249  Ak3DVector pointToPlane = N;
1250  pointToPlane *= distance;
1251 
1252  out_B = in_P + pointToPlane;
1253 
1254  return (AkReal32)fabs(distance);
1255  }
1256 
1258  AkReal32* out_mat) const
1259  {
1260  // http://ami.ektf.hu/uploads/papers/finalpdf/AMI_40_from175to186.pd
1261  /* m_pReflectionMatrix
1262  reflection on z axis
1263 
1264  P0 (x0, y0, z0), P1 (x1, y1, z1) and P2 (x2, y2, z2),
1265  normal = (cx, cy, cz)
1266  d = -CxX0 - CyY0 - CzZ0
1267 
1268  Reflect = 1-2Cx^2 -2CxCy -2CxCz -2Cxd
1269  -2CxCy 1-2Cy^2 -2CyCz -2Cyd
1270  -2CxCz -2CyCz 1-2Cz^2 -2Czd
1271  0 0 0 1
1272  */
1273 
1274  AkReal32 d = -(N.X*p1.X) - (N.Y*p1.Y) - (N.Z*p1.Z);
1275 
1276  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;
1277  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;
1278  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;
1279  out_mat[0 + 12] = 0; out_mat[1 + 12] = 0; out_mat[2 + 12] = 0; out_mat[3 + 12] = 1;
1280  }
1281 
1282  Ak3DVector GetN() const { return N; }
1283  AkReal32 GetD() const { return D; }
1284 
1286  const AkPlane& in_PlaneB,
1287  AkIntersectionPoints& out_Intrs) const
1288  {
1289  out_Intrs.count = 0;
1290 
1291  // Use vector to solve A
1292 
1293  Ak3DVector point;
1294 
1295  Ak3DVector N1 = N;
1296  Ak3DVector N2 = in_PlaneB.GetN();
1297  AkReal32 D1 = D;
1298  AkReal32 D2 = in_PlaneB.GetD();
1299 
1300  Ak3DVector L = N1.Cross(N2);
1301  if (L.Length() < 0.001f)
1302  {
1303  return false; // The two planes are parallel
1304  }
1305 
1306  AkUInt8 pivotAxis = 0;
1307 
1308  if ((AkReal32)fabs(L.Y) > (AkReal32)fabs(L.X))
1309  {
1310  pivotAxis = 1;
1311  if ((AkReal32)fabs(L.Z) > (AkReal32)fabs(L.Y))
1312  {
1313  pivotAxis = 2;
1314  }
1315  }
1316  else if ((AkReal32)fabs(L.Z) > (AkReal32)fabs(L.X))
1317  {
1318  pivotAxis = 2;
1319  }
1320 
1321  /*
1322  Pu = ( N1v*D2 - N2v*D1 ) / Lw
1323  Pv = ( N2u*D1 - N1u*D2 ) / Lw
1324  Pz = 0
1325  */
1326 
1327  switch (pivotAxis)
1328  {
1329  case 0:
1330  AKASSERT((AkReal32)fabs(L.X) > AKVECTORS_EPSILON);
1331  point.X = 0.f;
1332  point.Y = (N1.Z*D2 - N2.Z*D1) / L.X;
1333  point.Z = (N2.Y*D1 - N1.Y*D2) / L.X;
1334  break;
1335  case 1:
1336  AKASSERT((AkReal32)fabs(L.Y) > AKVECTORS_EPSILON);
1337  point.X = (N1.Z*D2 - N2.Z*D1) / L.Y;
1338  point.Y = 0.f;
1339  point.Z = (N2.X*D1 - N1.X*D2) / L.Y;
1340  break;
1341  case 2:
1342  AKASSERT((AkReal32)fabs(L.Z) > AKVECTORS_EPSILON);
1343  point.X = (N1.Y*D2 - N2.Y*D1) / L.Z;
1344  point.Y = (N2.X*D1 - N1.X*D2) / L.Z;
1345  point.Z = 0.f;
1346  break;
1347  };
1348 
1349 
1350 
1351  L.Normalize();
1352 
1353  AkLine intrLine = AkLine(L, point);
1354  AkLine intrLine2 = AkLine(L, point);
1355 
1356  //in_PlaneB.GetP1()
1357 
1358  // find min max
1359  AkUInt32 cpt = 0;
1360  AkUInt32 cpt2 = 0;
1361  Ak3DVector p3 = GetP2() + (GetP4() - GetP1());
1362 
1363 #ifdef AKPORTALS_DEBUG
1364  char msg[256];
1365  sprintf(msg, "P1a=[%0.2f,%0.2f,%0.2f];\n", GetP1().X, GetP1().Y, GetP1().Z); AKPLATFORM::OutputDebugMsg(msg);
1366  sprintf(msg, "P2a=[%0.2f,%0.2f,%0.2f];\n", GetP2().X, GetP2().Y, GetP2().Z); AKPLATFORM::OutputDebugMsg(msg);
1367  sprintf(msg, "P4a=[%0.2f,%0.2f,%0.2f];\n", GetP4().X, GetP4().Y, GetP4().Z); AKPLATFORM::OutputDebugMsg(msg);
1368 
1369  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);
1370  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);
1371  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);
1372 
1373  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);
1374  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);
1375 
1376 
1377  sprintf(msg, "%% Plane intersec\n"); AKPLATFORM::OutputDebugMsg(msg);
1378 #endif
1379  // for the four lines in rectangle
1380  // Find where the line is crossing with plane A
1381  if (intrLine.Intersect(GetP1(), GetP2())) cpt++;
1382  if (intrLine.Intersect(GetP1(), GetP4())) cpt++;
1383  if (intrLine.Intersect(GetP2(), p3)) cpt++;
1384  if (intrLine.Intersect(p3, GetP4())) cpt++;
1385  //AKASSERT(cpt == 2);
1386 
1387 #ifdef AKPORTALS_DEBUG
1388  sprintf(msg, "%% Portal intersec\n"); AKPLATFORM::OutputDebugMsg(msg);
1389 #endif
1390 
1391  // Find where the line is crossing with plane B
1392  p3 = in_PlaneB.GetP2() + (in_PlaneB.GetP4() - in_PlaneB.GetP1());
1393  if (intrLine2.Intersect(in_PlaneB.GetP1(), in_PlaneB.GetP2())) cpt2++;
1394  if (intrLine2.Intersect(in_PlaneB.GetP1(), in_PlaneB.GetP4())) cpt2++;
1395  if (intrLine2.Intersect(in_PlaneB.GetP2(), p3)) cpt2++;
1396  if (intrLine2.Intersect(p3, in_PlaneB.GetP4())) cpt2++;
1397  // **AKASSERT(cpt2 == 2 || cpt == 2);
1398 
1399  if (cpt < 2 || cpt2 < 2)
1400  {
1401 #ifdef AKPORTALS_DEBUG
1402  sprintf(msg, "%% NON \n"); AKPLATFORM::OutputDebugMsg(msg);
1403  sprintf(msg, "%% _______________________\n"); AKPLATFORM::OutputDebugMsg(msg);
1404 #endif
1405  return false;
1406  }
1407 
1408  AkReal32 start = AkMax(intrLine.mint, intrLine2.mint);
1409  AkReal32 end = AkMin(intrLine.maxt, intrLine2.maxt);
1410 
1411  Ak3DVector minPoint = intrLine.PointAt(start);
1412  Ak3DVector maxPoint = intrLine.PointAt(end);
1413 #ifdef AKPORTALS_DEBUG
1414  sprintf(msg, "P1a=[%0.2f,%0.2f,%0.2f];\n", GetP1().X, GetP1().Y, GetP1().Z); AKPLATFORM::OutputDebugMsg(msg);
1415  sprintf(msg, "P2a=[%0.2f,%0.2f,%0.2f];\n", GetP2().X, GetP2().Y, GetP2().Z); AKPLATFORM::OutputDebugMsg(msg);
1416  sprintf(msg, "P4a=[%0.2f,%0.2f,%0.2f];\n", GetP4().X, GetP4().Y, GetP4().Z); AKPLATFORM::OutputDebugMsg(msg);
1417 
1418  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);
1419  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);
1420  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);
1421 
1422  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);
1423  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);
1424 
1425  sprintf(msg, "intr1=[%0.2f,%0.2f,%0.2f];\n", minPoint.X, minPoint.Y, minPoint.Z); AKPLATFORM::OutputDebugMsg(msg);
1426  sprintf(msg, "intr2=[%0.2f,%0.2f,%0.2f];\n", maxPoint.X, maxPoint.Y, maxPoint.Z); AKPLATFORM::OutputDebugMsg(msg);
1427 
1428  sprintf(msg, "%% _______________________\n"); AKPLATFORM::OutputDebugMsg(msg);
1429 #endif
1430  out_Intrs.points[0] = minPoint;
1431  out_Intrs.points[1] = maxPoint;
1432  out_Intrs.count = 2;
1433 
1434  return true;
1435  }
1436 
1437  Ak3DVector GetP1() const { return p1; }
1438  Ak3DVector GetP2() const { return p2; }
1439  Ak3DVector GetP4() const { return p4; }
1440 
1441 private:
1442  bool SetNormal()
1443  {
1444  //m_pNormal = (B-A) cross (C-A); normalize
1445  Ak3DVector a = p2 - p1;
1446  Ak3DVector b = p4 - p1;
1447 
1448  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);
1449 
1450  AkReal32 len = N.Length();
1451  AKASSERT(len > 0.f);
1452 
1453  if (len > 0)
1454  {
1455  N /= len;
1456  }
1457  else
1458  {
1459  // TODO handle invalid reflectors
1460  return false;
1461  }
1462 
1463  return true;
1464  };
1465 
1466  /*
1467  p2__________p3
1468  | . |
1469  ^ inter v3
1470  v1 v
1471  | |
1472  p1__ v2>___p4
1473  */
1474 
1475  Ak3DVector p1; // Bottom left
1476  Ak3DVector p2; // Top left
1477  Ak3DVector p4; // Tottom right
1478  Ak3DVector N; // Normal vector
1479  AkReal32 D; // Plane equation: Ax + By + Cz = D => N.Xx + N.Yy + N.Zz = D
1480 };
1481 
1483 {
1485  m_Min(Ak3DVector(FLT_MAX, FLT_MAX, FLT_MAX)),
1486  m_Max(Ak3DVector(-FLT_MAX, -FLT_MAX, -FLT_MAX))
1487  {}
1488 
1489  void Update(
1490  const Ak3DVector & in_point
1491  )
1492  {
1493  if (m_Min.X > in_point.X)
1494  m_Min.X = in_point.X;
1495 
1496  if (m_Min.Y > in_point.Y)
1497  m_Min.Y = in_point.Y;
1498 
1499  if (m_Min.Z > in_point.Z)
1500  m_Min.Z = in_point.Z;
1501 
1502  if (m_Max.X < in_point.X)
1503  m_Max.X = in_point.X;
1504 
1505  if (m_Max.Y < in_point.Y)
1506  m_Max.Y = in_point.Y;
1507 
1508  if (m_Max.Z < in_point.Z)
1509  m_Max.Z = in_point.Z;
1510  }
1511 
1513  const Ak3DVector & in_Point
1514  ) const
1515  {
1516  return in_Point >= m_Min && in_Point <= m_Max;
1517  }
1518 
1520  const AkBoundingBox & in_BB
1521  ) const
1522  {
1523  return (m_Min.X <= in_BB.m_Max.X && m_Max.X >= in_BB.m_Min.X) &&
1524  (m_Min.Y <= in_BB.m_Max.Y && m_Max.Y >= in_BB.m_Min.Y) &&
1525  (m_Min.Z <= in_BB.m_Max.Z && m_Max.Z >= in_BB.m_Min.Z);
1526  }
1527 
1529  const AkBoundingBox & in_BB
1530  ) const
1531  {
1532  AkBoundingBox result;
1533 
1534  result.m_Max.X = AkMin(m_Max.X, in_BB.m_Max.X);
1535  result.m_Max.Y = AkMin(m_Max.Y, in_BB.m_Max.Y);
1536  result.m_Max.Z = AkMin(m_Max.Z, in_BB.m_Max.Z);
1537 
1538  result.m_Min.X = AkMax(m_Min.X, in_BB.m_Min.X);
1539  result.m_Min.Y = AkMax(m_Min.Y, in_BB.m_Min.Y);
1540  result.m_Min.Z = AkMax(m_Min.Z, in_BB.m_Min.Z);
1541 
1542  return result;
1543  }
1544 
1545  // returns acos(in_fAngle)
1547  AkReal32 in_fAngle
1548  ) const
1549  {
1550  AKASSERT((in_fAngle <= 1.0f) && (in_fAngle >= -1.0f));
1551  return acosf(in_fAngle);
1552  }
1553 
1554  AkForceInline bool IsEmpty() const
1555  {
1556  return (m_Min.X >= m_Max.X) || (m_Min.Y >= m_Max.Y) || (m_Min.Z >= m_Max.Z);
1557  }
1558 
1561 };
1562 
1563 class AkBox
1564 {
1565 public:
1567  {
1568  }
1569 
1571  {
1572  }
1573 
1574  void Init(
1575  const Ak3DVector & in_center,
1576  const Ak3DVector & in_extent,
1577  const Ak3DVector & in_Front,
1578  const Ak3DVector & in_Up)
1579  {
1580  AKASSERT(fabs(in_Front.Length() - 1.f) < 0.001 && fabs(in_Up.Length() - 1.f) < 0.001);//Must be unit vectors.
1581  AKASSERT(fabs(in_Front.Dot(in_Up) - 0.f) < 0.001); //Must be orthogonal.
1582 
1583  m_Center = in_center;
1584  m_Extent = in_extent;
1585 
1586  m_Z = in_Front;
1587  m_Y = in_Up;
1588  m_X = m_Z.Cross(m_Y);
1589  }
1590 
1592  const Ak3DVector & in_Point
1593  ) const
1594  {
1595  Ak3DVector pt = in_Point - m_Center;
1596  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;
1597  }
1598 
1599  Ak3DVector GetSize() const { return m_Extent*2.f; }
1600  Ak3DVector GetCenter() const { return m_Center; }
1601 
1602  Ak3DVector GetUx() const { return m_X; }
1603  Ak3DVector GetUy() const { return m_Y; }
1604  Ak3DVector GetUz() const { return m_Z; }
1605 
1606  Ak3DVector GetFront() const { return m_Z; }
1607  Ak3DVector GetUp() const { return m_Y; }
1608  Ak3DVector GetSide() const { return m_X; }
1609 
1611  {
1612  Ak3DVector size = GetSize();
1613  return size.X * size.Y * size.Z;
1614  }
1615 
1617  const Ak3DVector& L,
1618  const AkBox& B
1619  ) const
1620  {
1621  // Separating Axis Theorem for Oriented Bounding Boxes by Johnny Huynh
1622  const AkBox& A = *this;
1623  Ak3DVector T = B.GetCenter() - A.GetCenter();
1624 
1625  AkReal32 WA = A.m_Extent.X;
1626  AkReal32 HA = A.m_Extent.Y;
1627  AkReal32 DA = A.m_Extent.Z;
1628 
1629  AkReal32 WB = B.m_Extent.X;
1630  AkReal32 HB = B.m_Extent.Y;
1631  AkReal32 DB = B.m_Extent.Z;
1632 
1633  Ak3DVector Ax = A.GetUx();
1634  Ak3DVector Ay = A.GetUy();
1635  Ak3DVector Az = A.GetUz();
1636 
1637  Ak3DVector Bx = B.GetUx();
1638  Ak3DVector By = B.GetUy();
1639  Ak3DVector Bz = B.GetUz();
1640 
1641  /*
1642  | T • L | > | (WA*Ax) • L | + | (HA*Ay) • L | + |(DA*Az) • L | +
1643  | (WB*Bx) • L | +| (HB*By) • L | +| (DB*Bz) • L |*/
1644 
1645  AkReal32 left = (AkReal32)fabs(T.DotProduct(L));
1646  AkReal32 dpax = (AkReal32)fabs((Ax*WA).DotProduct(L));
1647  AkReal32 dpay = (AkReal32)fabs((Ay*HA).DotProduct(L));
1648  AkReal32 dpaz = (AkReal32)fabs((Az*DA).DotProduct(L));
1649  AkReal32 dpbx = (AkReal32)fabs((Bx*WB).DotProduct(L));
1650  AkReal32 dpby = (AkReal32)fabs((By*HB).DotProduct(L));
1651  AkReal32 dpbz = (AkReal32)fabs((Bz*DB).DotProduct(L));
1652 
1653  AkReal32 right = dpax + dpay + dpaz + dpbx + dpby + dpbz;
1654 
1655  return left > right;
1656  }
1657 
1658  void UpdateBoundingBox(AkBoundingBox& out_aabb) const
1659  {
1660  Ak3DVector x = m_X * m_Extent.X;
1661  out_aabb.Update(m_Center + x);
1662  out_aabb.Update(m_Center - x);
1663  Ak3DVector y = m_Y * m_Extent.Y;
1664  out_aabb.Update(m_Center + y);
1665  out_aabb.Update(m_Center - y);
1666  Ak3DVector Z = m_Z * m_Extent.Z;
1667  out_aabb.Update(m_Center + Z);
1668  out_aabb.Update(m_Center - Z);
1669  }
1670 
1671 
1672 private:
1673 
1674  Ak3DVector m_Center;
1675  Ak3DVector m_Extent;
1676 
1677  //Orthonormal Axes
1678  Ak3DVector m_X;
1679  Ak3DVector m_Y;
1680  Ak3DVector m_Z;
1681 };
AkForceInline Ak2DVector LinearCombination(const Ak2DVector &A, const Ak2DVector &B) const
Definition: AkVectors.h:609
AkQuaternion(const Ak3DVector &in_v0, const Ak3DVector &in_v1)
Definition: AkVectors.h:897
AkForceInline Ak3DVector Rotate180X_90Y() const
Definition: AkVectors.h:370
Ak3DVector GetP2() const
Definition: AkVectors.h:1438
AkReal32 theta
Azimuth.
Definition: AkTypes.h:447
Ak3DVector(const AKSIMD_V4F32 &in_v4f32)
Definition: AkVectors.h:156
#define EPSILON
Definition: AkVectors.h:1144
AkInt32 X
X Position.
Definition: AkVectors.h:125
Ak3DVector L
Definition: AkVectors.h:1084
AkQuaternion()
Definition: AkVectors.h:851
AkForceInline bool operator<(const Ak3DVector &b) const
Definition: AkVectors.h:220
bool SeparatingAxisExists(const Ak3DVector &L, const AkBox &B) const
Definition: AkVectors.h:1616
void Zero()
Definition: AkVectors.h:182
AkMatrix4x4 operator=(AkReal32 *in_Data)
Definition: AkVectors.h:724
Ak3DVector P
Definition: AkVectors.h:1085
AkBoundingBox Intersect(const AkBoundingBox &in_BB) const
Definition: AkVectors.h:1528
AkForceInline Ak2DVector operator=(const AkSphericalCoord &b)
Definition: AkVectors.h:543
bool DoesRayIntersect(const Ak3DVector &in_Origin, const Ak3DVector &in_Destination, Ak3DVector &out_Intersection) const
Definition: AkVectors.h:1145
Ak4DVector operator-(const Ak4DVector &b) const
Definition: AkVectors.h:97
static void Rotation(AkMatrix3x3 &out_mat, AkReal32 in_sin, AkReal32 in_cos, const Ak3DVector &in_axis)
Definition: AkVectors.h:829
AkForceInline Ak3DVector operator-(const Ak3DVector &b) const
Definition: AkVectors.h:326
AkForceInline Ak3DVector operator+(const Ak3DVector &b) const
Definition: AkVectors.h:315
AkForceInline Ak2DVector CartesianToSpherical(const Ak3DVector &in_Cartesian)
Definition: AkVectors.h:595
AkReal32 m_Data[3][3]
Definition: AkVectors.h:844
AkForceInline bool operator==(const Ak3DVector &b) const
Definition: AkVectors.h:192
AkUInt32 count
Definition: AkVectors.h:985
AkReal32 X
Definition: AkVectors.h:512
Definition: AkVectors.h:1563
AkForceInline Ak3DVector LinearCombination(const Ak3DVector &A, const Ak3DVector &B, const Ak3DVector &C) const
Definition: AkVectors.h:404
#define AKSIMD_GETELEMENT_V4F32(__vName, __num__)
Retrieve scalar element from vector.
Definition: AkSimd.h:38
AkReal32 GetD() const
Definition: AkVectors.h:1283
AkForceInline AkReal32 Length()
Definition: AkVectors.h:867
AkMatrix4x4()
Definition: AkVectors.h:711
AkForceInline AKSIMD_V4F32 VectorV4F32() const
Definition: AkVectors.h:171
Ak3DVector GetUx() const
Definition: AkVectors.h:1602
static AkForceInline void Diagonal(AkMatrix3x3 &out_mat, AkReal32 in_f)
Definition: AkVectors.h:802
Ak3DIntVector(AkInt32 x, AkInt32 y, AkInt32 z)
Definition: AkVectors.h:116
AkPlane()
Definition: AkVectors.h:1094
~Ak3DIntVector()
Definition: AkVectors.h:123
Ak3DVector PointAt(AkReal32 t) const
Definition: AkVectors.h:1008
AkForceInline AkReal32 Length() const
Definition: AkVectors.h:484
uint8_t AkUInt8
Unsigned 8-bit integer.
Definition: AkTypes.h:76
AkQuaternion(AkReal32 in_angle, const Ak3DVector &in_axis)
Definition: AkVectors.h:934
AkLine()
Definition: AkVectors.h:991
~AkPlane()
Definition: AkVectors.h:1110
Ak2DVector operator *=(const AkReal32 f)
Definition: AkVectors.h:561
~Ak3DVector()
Definition: AkVectors.h:180
bool IsPointInBox(const Ak3DVector &in_Point) const
Definition: AkVectors.h:1591
Ak3DVector GetN() const
Definition: AkVectors.h:1282
void OutputDebugMsg(const char *in_pszMsg)
Output a debug message on the console (Ansi string)
Definition: AkPlatformFuncs.h:57
AkReal32 Z
Definition: AkVectors.h:514
AkForceInline bool IsEmpty() const
Definition: AkVectors.h:1554
AkPlane(Ak3DVector in_p1, Ak3DVector in_p2, Ak3DVector in_p4)
Definition: AkVectors.h:1098
~Ak2DVector()
Definition: AkVectors.h:523
AkReal32 X
X Position.
Definition: AkTypes.h:298
void SetReflection(AkReal32 *out_mat) const
Definition: AkVectors.h:1257
AkForceInline AkReal32 DotProduct(const Ak3DVector &v2) const
Definition: AkVectors.h:462
AkForceInline Ak3DVector operator=(const AkVector &b)
Definition: AkVectors.h:211
AkForceInline bool operator>(const Ak3DVector b) const
Definition: AkVectors.h:230
Ak3DVector GetSide() const
Definition: AkVectors.h:1608
Ak2DVector operator-(const Ak2DVector &b) const
Definition: AkVectors.h:551
AkReal32 v[4]
Definition: AkVectors.h:109
AkForceInline Ak3DVector operator-(const AkReal32 f) const
Definition: AkVectors.h:304
#define AKASSERT(Condition)
Definition: AkAssert.h:69
Ak4DVector operator/=(const AkReal32 f)
Definition: AkVectors.h:87
AkReal32 mint
Definition: AkVectors.h:1087
Ak4DVector()
Definition: AkVectors.h:57
void UpdateBoundingBox(AkBoundingBox &out_aabb) const
Definition: AkVectors.h:1658
AkForceInline Ak3DVector operator *(const Ak3DVector &in_rhs)
Definition: AkVectors.h:770
AkReal32 X
Definition: AkVectors.h:698
static AkForceInline void OuterProduct(AkMatrix3x3 &out_mat, const Ak3DVector &in_v0, const Ak3DVector &in_v1)
Definition: AkVectors.h:817
Ak3DVector GetCenter() const
Definition: AkVectors.h:1600
Ak3DVector points[2]
Definition: AkVectors.h:984
AkForceInline bool operator>=(const Ak3DVector &b) const
Definition: AkVectors.h:235
AkForceInline bool operator==(const Ak2DVector &b) const
Definition: AkVectors.h:578
#define AkForceInline
Force inlining.
Definition: AkTypes.h:62
AkForceInline bool IsAllPositive() const
Definition: AkVectors.h:691
AkForceInline bool operator!=(const Ak2DVector &b) const
Definition: AkVectors.h:583
AkReal32 W
Definition: AkVectors.h:976
#define AKVECTORS_EPSILON
Definition: AkVectors.h:50
int32_t AkInt32
Signed 32-bit integer.
Definition: AkTypes.h:91
AkForceInline AkReal32 Length() const
Definition: AkVectors.h:588
AkLine(Ak3DVector in_L, Ak3DVector in_P)
Definition: AkVectors.h:997
Ak2DVector(AkReal32 x, AkReal32 y)
Definition: AkVectors.h:525
Ak3DVector(AkReal32 x, AkReal32 y, AkReal32 z)
Definition: AkVectors.h:141
static AkForceInline void CrossProductMatrix(AkMatrix3x3 &out_mat, const Ak3DVector &in_u)
Definition: AkVectors.h:810
~AkMatrix4x4()
Definition: AkVectors.h:712
AkReal32 maxt
Definition: AkVectors.h:1088
AkForceInline AkQuaternion operator *(const AkQuaternion &Q) const
Quaternion multiplication.
Definition: AkVectors.h:944
#define AKVECTORS_PIOVERTWO
Definition: AkVectors.h:49
~AkBox()
Definition: AkVectors.h:1570
Ak2DVector()
Definition: AkVectors.h:522
AkMatrix4x4 operator/=(const AkReal32 f)
Definition: AkVectors.h:716
AkForceInline Ak3DVector operator *(const Ak3DVector v2) const
Definition: AkVectors.h:259
AkReal32 GetVolume() const
Definition: AkVectors.h:1610
AkReal32 phi
Elevation.
Definition: AkTypes.h:453
Ak3DVector m_Min
Definition: AkVectors.h:1559
Definition: AkVectors.h:988
Ak3DVector()
Definition: AkVectors.h:135
AkMatrix3x3()
Definition: AkVectors.h:743
AkForceInline AkQuaternion Inverse() const
Definition: AkVectors.h:882
static AkForceInline void Rotation(AkMatrix3x3 &out_mat, AkReal32 in_angle, const Ak3DVector &in_axis)
Definition: AkVectors.h:824
#define AkMin(x1, x2)
Definition: AkPlatformFuncs.h:94
AkForceInline const AkQuaternion & Normalize()
Definition: AkVectors.h:872
AkForceInline AkReal32 LengthSquared() const
Definition: AkVectors.h:489
AkForceInline AkReal32 & operator()(const AkUInt32 row, const AkUInt32 column)
Definition: AkVectors.h:760
AkForceInline AkMatrix3x3 & operator *=(const AkReal32 &in_f)
Definition: AkVectors.h:794
AkQuaternion(AkReal32 in_W, AkReal32 in_X, AkReal32 in_Y, AkReal32 in_Z)
Definition: AkVectors.h:853
AkReal32 X
Definition: AkVectors.h:977
AkBoundingBox()
Definition: AkVectors.h:1484
AkForceInline Ak3DVector operator *=(const AkReal32 f)
Definition: AkVectors.h:240
AkReal32 m_Data[MAX_SIZE]
Definition: AkVectors.h:734
Ak3DVector GetUp() const
Definition: AkVectors.h:1607
Ak3DVector GetP1() const
Definition: AkVectors.h:1437
AkMatrix3x3 operator/=(const AkReal32 f)
Definition: AkVectors.h:748
AkForceInline AkReal32 Dot(const Ak3DVector &v2) const
Definition: AkVectors.h:467
Ak3DVector GetUy() const
Definition: AkVectors.h:1603
#define AKVECTORS_TWOPI
Definition: AkVectors.h:48
AkInt32 Y
Y Position.
Definition: AkVectors.h:126
AkForceInline AkMatrix3x3 & operator+=(const AkMatrix3x3 &in_rhs)
Definition: AkVectors.h:779
Ak3DVector(const AkVector &b)
Definition: AkVectors.h:150
AkForceInline const AkReal32 & operator()(const AkUInt32 row, const AkUInt32 column) const
Definition: AkVectors.h:765
AkInt32 Z
Z Position.
Definition: AkVectors.h:127
Ak4DVector operator=(const Ak4DVector &b)
Definition: AkVectors.h:77
Ak3DVector GetFront() const
Definition: AkVectors.h:1606
bool FindIntersectionPoints(const AkPlane &in_PlaneB, AkIntersectionPoints &out_Intrs) const
Definition: AkVectors.h:1285
void SetPlane(Ak3DVector in_p1, Ak3DVector in_p2, Ak3DVector in_p4)
Definition: AkVectors.h:1114
AkForceInline Ak3DVector operator=(const Ak3DVector &b)
Definition: AkVectors.h:202
AkForceInline bool operator<=(const Ak3DVector &b) const
Definition: AkVectors.h:225
AkForceInline AKSIMD_V4F32 PointV4F32() const
Definition: AkVectors.h:162
AkForceInline Ak2DVector NormalizeSpherical() const
Definition: AkVectors.h:638
static AkForceInline void Add(AkMatrix3x3 &out_res, const AkMatrix3x3 &in_m0, const AkMatrix3x3 &in_m1)
Definition: AkVectors.h:785
AkForceInline bool operator!=(const Ak3DVector &b) const
Definition: AkVectors.h:197
AkReal32 Y
Definition: AkVectors.h:699
Ak3DVector GetP4() const
Definition: AkVectors.h:1439
AkForceInline void NormalizeSpherical()
Definition: AkVectors.h:669
AkForceInline Ak3DVector operator+(const AkReal32 f) const
Definition: AkVectors.h:293
Spherical coordinates.
Definition: AkTypes.h:451
AkReal32 Z
Z Position.
Definition: AkTypes.h:300
AkReal32 Y
Definition: AkVectors.h:513
3D vector.
Definition: AkTypes.h:280
AkForceInline Ak3DVector SphericalToCartesian(const AkReal32 azimuth, const AkReal32 elevation)
Definition: AkVectors.h:381
static AkReal32 Determinant(const Ak3DVector &a, const Ak3DVector &b, const Ak3DVector &c)
Definition: AkVectors.h:394
static AkForceInline Ak3DVector Max(const Ak3DVector &A, const Ak3DVector &B)
Definition: AkVectors.h:357
Ak2DVector operator/=(const AkReal32 f)
Definition: AkVectors.h:569
#define AkMax(x1, x2)
Definition: AkPlatformFuncs.h:93
void Update(const Ak3DVector &in_point)
Definition: AkVectors.h:1489
AkForceInline bool IsAllPositive() const
Definition: AkVectors.h:495
uint32_t AkUInt32
Unsigned 32-bit integer.
Definition: AkTypes.h:78
AkForceInline Ak3DVector Abs() const
Definition: AkVectors.h:503
AkForceInline AkReal32 L2_Norm() const
Definition: AkVectors.h:457
~Ak4DVector()
Definition: AkVectors.h:73
#define ADD(i, j)
AkForceInline const Ak3DVector & Normalize()
Definition: AkVectors.h:439
bool Intersect(Ak3DVector A, Ak3DVector B)
Definition: AkVectors.h:1013
static AkForceInline Ak3DVector Min(const Ak3DVector &A, const Ak3DVector &B)
Definition: AkVectors.h:346
AkBox()
Definition: AkVectors.h:1566
AkForceInline Ak3DVector operator/(const AkReal32 f) const
Definition: AkVectors.h:281
void Init(const Ak3DVector &in_center, const Ak3DVector &in_extent, const Ak3DVector &in_Front, const Ak3DVector &in_Up)
Definition: AkVectors.h:1574
Ak4DVector(const AkVector &b)
Definition: AkVectors.h:65
Ak3DIntVector()
Definition: AkVectors.h:115
AkForceInline Ak3DVector Cross(const Ak3DVector &v) const
Definition: AkVectors.h:472
float AkReal32
32-bit floating point
Definition: AkTypes.h:96
AkReal32 Z
Definition: AkVectors.h:979
AkForceInline bool IsWithin(const Ak3DVector &in_Point) const
Definition: AkVectors.h:1512
~AkMatrix3x3()
Definition: AkVectors.h:744
AkForceInline Ak3DVector operator/=(const AkReal32 f)
Definition: AkVectors.h:249
AkReal32 DistPoint_to_Plane(Ak3DVector in_P, Ak3DVector &out_B) const
Definition: AkVectors.h:1243
AkForceInline Ak2DVector operator=(const Ak2DVector &b)
Definition: AkVectors.h:535
Ak3DVector GetUz() const
Definition: AkVectors.h:1604
Ak3DVector GetSize() const
Definition: AkVectors.h:1599
Ak3DVector m_Max
Definition: AkVectors.h:1560
AkForceInline AkReal32 ACos(AkReal32 in_fAngle) const
Definition: AkVectors.h:1546
AkReal32 Y
Y Position.
Definition: AkTypes.h:299
AkQuaternion(const Ak3DVector &in_fromVector)
Definition: AkVectors.h:860
#define AKVECTORS_PI
Definition: AkVectors.h:47
AkReal32 Y
Definition: AkVectors.h:978
AkForceInline bool IsWithin(const AkBoundingBox &in_BB) const
Definition: AkVectors.h:1519