Table of Contents

Wwise SDK 2021.1.1
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: v2021.1.1 Build: 7601
25  Copyright (c) 2006-2021 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  // 1) if ray len ~= 0, only check if one of the point is on target, ie: assign the intersect point
1183 
1184  // Is ray parallel to the plane?
1185  if ((A*ray.X + B*ray.Y + C*ray.Z) == 0.0f)
1186  {
1187  // For debug only, to remove
1188  AkReal32 t = -(A*in_Origin.X + B*in_Origin.Y + C*in_Origin.Z + D) / (A*ray.X + B*ray.Y + C*ray.Z);
1189  intersect = Ak3DVector(in_Origin.X + ray.X*t, in_Origin.Y + ray.Y*t, in_Origin.Z + ray.Z*t);
1190  out_Intersection = intersect; // For debugging
1191  return false;
1192  }
1193 
1194 
1195  // Distance along the ray where reflector is hit
1196  AkReal32 t = -(A*in_Origin.X + B*in_Origin.Y + C*in_Origin.Z + D) / (A*ray.X + B*ray.Y + C*ray.Z);
1197 
1198  // Is the ray going towards the plane? Is it long enough?
1199  if (t < -EPSILON || t >(rayLength + EPSILON))
1200  {
1201  // For debug only, to remove
1202  intersect = Ak3DVector(in_Origin.X + ray.X*t, in_Origin.Y + ray.Y*t, in_Origin.Z + ray.Z*t);
1203  out_Intersection = intersect; // For debugging
1204  return false; // The ray doesn't intersect
1205  }
1206 
1207  // Find the coordinate of intersection on the plane
1208  intersect = Ak3DVector(in_Origin.X + ray.X*t, in_Origin.Y + ray.Y*t, in_Origin.Z + ray.Z*t);
1209  }
1210  ///////////////////////////////////////
1211  //
1212  // p2____v3____p3
1213  // | . |
1214  // ^ inter v4
1215  // v1 v
1216  // | |
1217  // p1__ v2>___p4
1218 
1219  Ak3DVector v1 = p2 - p1;
1220  Ak3DVector v2 = p4 - p1;
1221  Ak3DVector vInter1 = intersect - p1;
1222 
1223  Ak3DVector p3 = p4 + v1;
1224  Ak3DVector v3 = p2 - p3;
1225  Ak3DVector v4 = p4 - p3;
1226  Ak3DVector vInter2 = intersect - p3;
1227 
1228  v1.Normalize(); v2.Normalize(); v3.Normalize(); v4.Normalize(); vInter1.Normalize(); vInter2.Normalize();
1229 
1230  // Since it's a square, the angle between the point of intersection and any segment of the pannel should be < 90 degree,
1231  // therefore the dot product of the two normalized vectors should be > 0
1232  AkReal32 dot1 = v1.DotProduct(vInter1);
1233  AkReal32 dot2 = v2.DotProduct(vInter1);
1234  AkReal32 dot3 = v3.DotProduct(vInter2);
1235  AkReal32 dot4 = v4.DotProduct(vInter2);
1236 
1237  out_Intersection = intersect;
1238 
1239  return dot1 >= -EPSILON && dot2 >= -EPSILON && dot3 >= -EPSILON && dot4 >= -EPSILON;
1240  }
1241 
1243  Ak3DVector in_P,
1244  Ak3DVector& out_B) const
1245  {
1246  AkReal32 distance = (AkReal32)(AkReal32)fabs(N.X * in_P.X + N.Y * in_P.Y + N.Z * in_P.Z + D);
1247 
1248  Ak3DVector pointToPlane = N;
1249  pointToPlane *= distance;
1250 
1251  out_B = in_P + pointToPlane;
1252 
1253  return (AkReal32)fabs(distance);
1254  }
1255 
1257  AkReal32* out_mat) const
1258  {
1259  // http://ami.ektf.hu/uploads/papers/finalpdf/AMI_40_from175to186.pd
1260  /* m_pReflectionMatrix
1261  reflection on z axis
1262 
1263  P0 (x0, y0, z0), P1 (x1, y1, z1) and P2 (x2, y2, z2),
1264  normal = (cx, cy, cz)
1265  d = -CxX0 - CyY0 - CzZ0
1266 
1267  Reflect = 1-2Cx^2 -2CxCy -2CxCz -2Cxd
1268  -2CxCy 1-2Cy^2 -2CyCz -2Cyd
1269  -2CxCz -2CyCz 1-2Cz^2 -2Czd
1270  0 0 0 1
1271  */
1272 
1273  AkReal32 d = -(N.X*p1.X) - (N.Y*p1.Y) - (N.Z*p1.Z);
1274 
1275  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;
1276  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;
1277  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;
1278  out_mat[0 + 12] = 0; out_mat[1 + 12] = 0; out_mat[2 + 12] = 0; out_mat[3 + 12] = 1;
1279  }
1280 
1281  Ak3DVector GetN() const { return N; }
1282  AkReal32 GetD() const { return D; }
1283 
1285  const AkPlane& in_PlaneB,
1286  AkIntersectionPoints& out_Intrs) const
1287  {
1288  out_Intrs.count = 0;
1289 
1290  // Use vector to solve A
1291 
1292  Ak3DVector point;
1293 
1294  Ak3DVector N1 = N;
1295  Ak3DVector N2 = in_PlaneB.GetN();
1296  AkReal32 D1 = D;
1297  AkReal32 D2 = in_PlaneB.GetD();
1298 
1299  Ak3DVector L = N1.Cross(N2);
1300  if (L.Length() < 0.001f)
1301  {
1302  return false; // The two planes are parallel
1303  }
1304 
1305  AkUInt8 pivotAxis = 0;
1306 
1307  if ((AkReal32)fabs(L.Y) > (AkReal32)fabs(L.X))
1308  {
1309  pivotAxis = 1;
1310  if ((AkReal32)fabs(L.Z) > (AkReal32)fabs(L.Y))
1311  {
1312  pivotAxis = 2;
1313  }
1314  }
1315  else if ((AkReal32)fabs(L.Z) > (AkReal32)fabs(L.X))
1316  {
1317  pivotAxis = 2;
1318  }
1319 
1320  /*
1321  Pu = ( N1v*D2 - N2v*D1 ) / Lw
1322  Pv = ( N2u*D1 - N1u*D2 ) / Lw
1323  Pz = 0
1324  */
1325 
1326  switch (pivotAxis)
1327  {
1328  case 0:
1329  AKASSERT((AkReal32)fabs(L.X) > AKVECTORS_EPSILON);
1330  point.X = 0.f;
1331  point.Y = (N1.Z*D2 - N2.Z*D1) / L.X;
1332  point.Z = (N2.Y*D1 - N1.Y*D2) / L.X;
1333  break;
1334  case 1:
1335  AKASSERT((AkReal32)fabs(L.Y) > AKVECTORS_EPSILON);
1336  point.X = (N1.Z*D2 - N2.Z*D1) / L.Y;
1337  point.Y = 0.f;
1338  point.Z = (N2.X*D1 - N1.X*D2) / L.Y;
1339  break;
1340  case 2:
1341  AKASSERT((AkReal32)fabs(L.Z) > AKVECTORS_EPSILON);
1342  point.X = (N1.Y*D2 - N2.Y*D1) / L.Z;
1343  point.Y = (N2.X*D1 - N1.X*D2) / L.Z;
1344  point.Z = 0.f;
1345  break;
1346  };
1347 
1348 
1349 
1350  L.Normalize();
1351 
1352  AkLine intrLine = AkLine(L, point);
1353  AkLine intrLine2 = AkLine(L, point);
1354 
1355  //in_PlaneB.GetP1()
1356 
1357  // find min max
1358  AkUInt32 cpt = 0;
1359  AkUInt32 cpt2 = 0;
1360  Ak3DVector p3 = GetP2() + (GetP4() - GetP1());
1361 
1362 #ifdef AKPORTALS_DEBUG
1363  char msg[256];
1364  sprintf(msg, "P1a=[%0.2f,%0.2f,%0.2f];\n", GetP1().X, GetP1().Y, GetP1().Z); AKPLATFORM::OutputDebugMsg(msg);
1365  sprintf(msg, "P2a=[%0.2f,%0.2f,%0.2f];\n", GetP2().X, GetP2().Y, GetP2().Z); AKPLATFORM::OutputDebugMsg(msg);
1366  sprintf(msg, "P4a=[%0.2f,%0.2f,%0.2f];\n", GetP4().X, GetP4().Y, GetP4().Z); AKPLATFORM::OutputDebugMsg(msg);
1367 
1368  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);
1369  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);
1370  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);
1371 
1372  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);
1373  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);
1374 
1375 
1376  sprintf(msg, "%% Plane intersec\n"); AKPLATFORM::OutputDebugMsg(msg);
1377 #endif
1378  // for the four lines in rectangle
1379  // Find where the line is crossing with plane A
1380  if (intrLine.Intersect(GetP1(), GetP2())) cpt++;
1381  if (intrLine.Intersect(GetP1(), GetP4())) cpt++;
1382  if (intrLine.Intersect(GetP2(), p3)) cpt++;
1383  if (intrLine.Intersect(p3, GetP4())) cpt++;
1384  //AKASSERT(cpt == 2);
1385 
1386 #ifdef AKPORTALS_DEBUG
1387  sprintf(msg, "%% Portal intersec\n"); AKPLATFORM::OutputDebugMsg(msg);
1388 #endif
1389 
1390  // Find where the line is crossing with plane B
1391  p3 = in_PlaneB.GetP2() + (in_PlaneB.GetP4() - in_PlaneB.GetP1());
1392  if (intrLine2.Intersect(in_PlaneB.GetP1(), in_PlaneB.GetP2())) cpt2++;
1393  if (intrLine2.Intersect(in_PlaneB.GetP1(), in_PlaneB.GetP4())) cpt2++;
1394  if (intrLine2.Intersect(in_PlaneB.GetP2(), p3)) cpt2++;
1395  if (intrLine2.Intersect(p3, in_PlaneB.GetP4())) cpt2++;
1396  // **AKASSERT(cpt2 == 2 || cpt == 2);
1397 
1398  if (cpt < 2 || cpt2 < 2)
1399  {
1400 #ifdef AKPORTALS_DEBUG
1401  sprintf(msg, "%% NON \n"); AKPLATFORM::OutputDebugMsg(msg);
1402  sprintf(msg, "%% _______________________\n"); AKPLATFORM::OutputDebugMsg(msg);
1403 #endif
1404  return false;
1405  }
1406 
1407  AkReal32 start = AkMax(intrLine.mint, intrLine2.mint);
1408  AkReal32 end = AkMin(intrLine.maxt, intrLine2.maxt);
1409 
1410  Ak3DVector minPoint = intrLine.PointAt(start);
1411  Ak3DVector maxPoint = intrLine.PointAt(end);
1412 #ifdef AKPORTALS_DEBUG
1413  sprintf(msg, "P1a=[%0.2f,%0.2f,%0.2f];\n", GetP1().X, GetP1().Y, GetP1().Z); AKPLATFORM::OutputDebugMsg(msg);
1414  sprintf(msg, "P2a=[%0.2f,%0.2f,%0.2f];\n", GetP2().X, GetP2().Y, GetP2().Z); AKPLATFORM::OutputDebugMsg(msg);
1415  sprintf(msg, "P4a=[%0.2f,%0.2f,%0.2f];\n", GetP4().X, GetP4().Y, GetP4().Z); AKPLATFORM::OutputDebugMsg(msg);
1416 
1417  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);
1418  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);
1419  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);
1420 
1421  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);
1422  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);
1423 
1424  sprintf(msg, "intr1=[%0.2f,%0.2f,%0.2f];\n", minPoint.X, minPoint.Y, minPoint.Z); AKPLATFORM::OutputDebugMsg(msg);
1425  sprintf(msg, "intr2=[%0.2f,%0.2f,%0.2f];\n", maxPoint.X, maxPoint.Y, maxPoint.Z); AKPLATFORM::OutputDebugMsg(msg);
1426 
1427  sprintf(msg, "%% _______________________\n"); AKPLATFORM::OutputDebugMsg(msg);
1428 #endif
1429  out_Intrs.points[0] = minPoint;
1430  out_Intrs.points[1] = maxPoint;
1431  out_Intrs.count = 2;
1432 
1433  return true;
1434  }
1435 
1436  Ak3DVector GetP1() const { return p1; }
1437  Ak3DVector GetP2() const { return p2; }
1438  Ak3DVector GetP4() const { return p4; }
1439 
1440 private:
1441  bool SetNormal()
1442  {
1443  //m_pNormal = (B-A) cross (C-A); normalize
1444  Ak3DVector a = p2 - p1;
1445  Ak3DVector b = p4 - p1;
1446 
1447  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);
1448 
1449  AkReal32 len = N.Length();
1450  AKASSERT(len > 0.f);
1451 
1452  if (len > 0)
1453  {
1454  N /= len;
1455  }
1456  else
1457  {
1458  return false;
1459  }
1460 
1461  return true;
1462  };
1463 
1464  /*
1465  p2__________p3
1466  | . |
1467  ^ inter v3
1468  v1 v
1469  | |
1470  p1__ v2>___p4
1471  */
1472 
1473  Ak3DVector p1; // Bottom left
1474  Ak3DVector p2; // Top left
1475  Ak3DVector p4; // Tottom right
1476  Ak3DVector N; // Normal vector
1477  AkReal32 D; // Plane equation: Ax + By + Cz = D => N.Xx + N.Yy + N.Zz = D
1478 };
1479 
1481 {
1483  m_Min(Ak3DVector(FLT_MAX, FLT_MAX, FLT_MAX)),
1484  m_Max(Ak3DVector(-FLT_MAX, -FLT_MAX, -FLT_MAX))
1485  {}
1486 
1487  void Update(
1488  const Ak3DVector & in_point
1489  )
1490  {
1491  if (m_Min.X > in_point.X)
1492  m_Min.X = in_point.X;
1493 
1494  if (m_Min.Y > in_point.Y)
1495  m_Min.Y = in_point.Y;
1496 
1497  if (m_Min.Z > in_point.Z)
1498  m_Min.Z = in_point.Z;
1499 
1500  if (m_Max.X < in_point.X)
1501  m_Max.X = in_point.X;
1502 
1503  if (m_Max.Y < in_point.Y)
1504  m_Max.Y = in_point.Y;
1505 
1506  if (m_Max.Z < in_point.Z)
1507  m_Max.Z = in_point.Z;
1508  }
1509 
1511  const Ak3DVector & in_Point
1512  ) const
1513  {
1514  return in_Point >= m_Min && in_Point <= m_Max;
1515  }
1516 
1518  const AkBoundingBox & in_BB
1519  ) const
1520  {
1521  return (m_Min.X <= in_BB.m_Max.X && m_Max.X >= in_BB.m_Min.X) &&
1522  (m_Min.Y <= in_BB.m_Max.Y && m_Max.Y >= in_BB.m_Min.Y) &&
1523  (m_Min.Z <= in_BB.m_Max.Z && m_Max.Z >= in_BB.m_Min.Z);
1524  }
1525 
1527  const AkBoundingBox & in_BB
1528  ) const
1529  {
1530  AkBoundingBox result;
1531 
1532  result.m_Max.X = AkMin(m_Max.X, in_BB.m_Max.X);
1533  result.m_Max.Y = AkMin(m_Max.Y, in_BB.m_Max.Y);
1534  result.m_Max.Z = AkMin(m_Max.Z, in_BB.m_Max.Z);
1535 
1536  result.m_Min.X = AkMax(m_Min.X, in_BB.m_Min.X);
1537  result.m_Min.Y = AkMax(m_Min.Y, in_BB.m_Min.Y);
1538  result.m_Min.Z = AkMax(m_Min.Z, in_BB.m_Min.Z);
1539 
1540  return result;
1541  }
1542 
1543  // returns acos(in_fAngle)
1545  AkReal32 in_fAngle
1546  ) const
1547  {
1548  AKASSERT((in_fAngle <= 1.0f) && (in_fAngle >= -1.0f));
1549  return acosf(in_fAngle);
1550  }
1551 
1552  AkForceInline bool IsEmpty() const
1553  {
1554  return (m_Min.X >= m_Max.X) || (m_Min.Y >= m_Max.Y) || (m_Min.Z >= m_Max.Z);
1555  }
1556 
1559 };
1560 
1561 class AkBox
1562 {
1563 public:
1565  {
1566  }
1567 
1569  {
1570  }
1571 
1572  void Init(
1573  const Ak3DVector & in_center,
1574  const Ak3DVector & in_extent,
1575  const Ak3DVector & in_Front,
1576  const Ak3DVector & in_Up)
1577  {
1578  AKASSERT(fabs(in_Front.Length() - 1.f) < 0.001 && fabs(in_Up.Length() - 1.f) < 0.001);//Must be unit vectors.
1579  AKASSERT(fabs(in_Front.Dot(in_Up) - 0.f) < 0.001); //Must be orthogonal.
1580 
1581  m_Center = in_center;
1582  m_Extent = in_extent;
1583 
1584  m_Z = in_Front;
1585  m_Y = in_Up;
1586  m_X = m_Z.Cross(m_Y);
1587  }
1588 
1590  const Ak3DVector & in_Point
1591  ) const
1592  {
1593  Ak3DVector pt = in_Point - m_Center;
1594  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;
1595  }
1596 
1597  Ak3DVector GetSize() const { return m_Extent*2.f; }
1598  Ak3DVector GetCenter() const { return m_Center; }
1599 
1600  Ak3DVector GetUx() const { return m_X; }
1601  Ak3DVector GetUy() const { return m_Y; }
1602  Ak3DVector GetUz() const { return m_Z; }
1603 
1604  Ak3DVector GetFront() const { return m_Z; }
1605  Ak3DVector GetUp() const { return m_Y; }
1606  Ak3DVector GetSide() const { return m_X; }
1607 
1609  {
1610  Ak3DVector size = GetSize();
1611  return size.X * size.Y * size.Z;
1612  }
1613 
1615  const Ak3DVector& L,
1616  const AkBox& B
1617  ) const
1618  {
1619  // Separating Axis Theorem for Oriented Bounding Boxes by Johnny Huynh
1620  const AkBox& A = *this;
1621  Ak3DVector T = B.GetCenter() - A.GetCenter();
1622 
1623  AkReal32 WA = A.m_Extent.X;
1624  AkReal32 HA = A.m_Extent.Y;
1625  AkReal32 DA = A.m_Extent.Z;
1626 
1627  AkReal32 WB = B.m_Extent.X;
1628  AkReal32 HB = B.m_Extent.Y;
1629  AkReal32 DB = B.m_Extent.Z;
1630 
1631  Ak3DVector Ax = A.GetUx();
1632  Ak3DVector Ay = A.GetUy();
1633  Ak3DVector Az = A.GetUz();
1634 
1635  Ak3DVector Bx = B.GetUx();
1636  Ak3DVector By = B.GetUy();
1637  Ak3DVector Bz = B.GetUz();
1638 
1639  /*
1640  | T • L | > | (WA*Ax) • L | + | (HA*Ay) • L | + |(DA*Az) • L | +
1641  | (WB*Bx) • L | +| (HB*By) • L | +| (DB*Bz) • L |*/
1642 
1643  AkReal32 left = (AkReal32)fabs(T.DotProduct(L));
1644  AkReal32 dpax = (AkReal32)fabs((Ax*WA).DotProduct(L));
1645  AkReal32 dpay = (AkReal32)fabs((Ay*HA).DotProduct(L));
1646  AkReal32 dpaz = (AkReal32)fabs((Az*DA).DotProduct(L));
1647  AkReal32 dpbx = (AkReal32)fabs((Bx*WB).DotProduct(L));
1648  AkReal32 dpby = (AkReal32)fabs((By*HB).DotProduct(L));
1649  AkReal32 dpbz = (AkReal32)fabs((Bz*DB).DotProduct(L));
1650 
1651  AkReal32 right = dpax + dpay + dpaz + dpbx + dpby + dpbz;
1652 
1653  return left > right;
1654  }
1655 
1656  void UpdateBoundingBox(AkBoundingBox& out_aabb) const
1657  {
1658  Ak3DVector x = m_X * m_Extent.X;
1659  out_aabb.Update(m_Center + x);
1660  out_aabb.Update(m_Center - x);
1661  Ak3DVector y = m_Y * m_Extent.Y;
1662  out_aabb.Update(m_Center + y);
1663  out_aabb.Update(m_Center - y);
1664  Ak3DVector Z = m_Z * m_Extent.Z;
1665  out_aabb.Update(m_Center + Z);
1666  out_aabb.Update(m_Center - Z);
1667  }
1668 
1669 
1670 private:
1671 
1672  Ak3DVector m_Center;
1673  Ak3DVector m_Extent;
1674 
1675  //Orthonormal Axes
1676  Ak3DVector m_X;
1677  Ak3DVector m_Y;
1678  Ak3DVector m_Z;
1679 };
#define AkMin(x1, x2)
Definition: AkPlatformFuncs.h:94
bool FindIntersectionPoints(const AkPlane &in_PlaneB, AkIntersectionPoints &out_Intrs) const
Definition: AkVectors.h:1284
AkReal32 DistPoint_to_Plane(Ak3DVector in_P, Ak3DVector &out_B) const
Definition: AkVectors.h:1242
#define AKVECTORS_TWOPI
Definition: AkVectors.h:48
Ak3DVector GetUz() const
Definition: AkVectors.h:1602
Ak3DIntVector()
Definition: AkVectors.h:115
AkForceInline bool operator<(const Ak3DVector &b) const
Definition: AkVectors.h:220
AkForceInline Ak3DVector Cross(const Ak3DVector &v) const
Definition: AkVectors.h:472
AkInt32 Y
Y Position.
Definition: AkVectors.h:126
Ak3DVector points[2]
Definition: AkVectors.h:984
#define AkForceInline
Force inlining.
Definition: AkTypes.h:61
AkForceInline Ak2DVector CartesianToSpherical(const Ak3DVector &in_Cartesian)
Definition: AkVectors.h:595
Ak2DVector operator*=(const AkReal32 f)
Definition: AkVectors.h:561
AkForceInline Ak3DVector operator-(const Ak3DVector &b) const
Definition: AkVectors.h:326
AkReal32 X
Definition: AkVectors.h:512
AkForceInline Ak3DVector operator*=(const AkReal32 f)
Definition: AkVectors.h:240
AkForceInline Ak2DVector operator=(const Ak2DVector &b)
Definition: AkVectors.h:535
AkReal32 Z
Definition: AkVectors.h:514
AkForceInline AKSIMD_V4F32 VectorV4F32() const
Definition: AkVectors.h:171
#define AKVECTORS_PI
Definition: AkVectors.h:47
#define AkMax(x1, x2)
Definition: AkPlatformFuncs.h:93
Ak3DVector GetN() const
Definition: AkVectors.h:1281
Ak3DVector PointAt(AkReal32 t) const
Definition: AkVectors.h:1008
Ak3DVector(const AKSIMD_V4F32 &in_v4f32)
Definition: AkVectors.h:156
bool Intersect(Ak3DVector A, Ak3DVector B)
Definition: AkVectors.h:1013
AkReal32 phi
Elevation.
Definition: AkTypes.h:477
AkReal32 X
Definition: AkVectors.h:977
Ak4DVector operator-(const Ak4DVector &b) const
Definition: AkVectors.h:97
bool SeparatingAxisExists(const Ak3DVector &L, const AkBox &B) const
Definition: AkVectors.h:1614
bool IsPointInBox(const Ak3DVector &in_Point) const
Definition: AkVectors.h:1589
Ak4DVector operator/=(const AkReal32 f)
Definition: AkVectors.h:87
AkForceInline bool operator==(const Ak3DVector &b) const
Definition: AkVectors.h:192
AkForceInline Ak3DVector Rotate180X_90Y() const
Definition: AkVectors.h:370
AkForceInline AkQuaternion Inverse() const
Definition: AkVectors.h:882
AkForceInline AkQuaternion operator*(const AkQuaternion &Q) const
Quaternion multiplication.
Definition: AkVectors.h:944
Ak3DIntVector(AkInt32 x, AkInt32 y, AkInt32 z)
Definition: AkVectors.h:116
void SetPlane(Ak3DVector in_p1, Ak3DVector in_p2, Ak3DVector in_p4)
Definition: AkVectors.h:1114
void OutputDebugMsg(const char *in_pszMsg)
Output a debug message on the console (Ansi string)
Definition: AkPlatformFuncs.h:121
~Ak2DVector()
Definition: AkVectors.h:523
AkForceInline AkReal32 DotProduct(const Ak3DVector &v2) const
Definition: AkVectors.h:462
AkForceInline AkReal32 Length() const
Definition: AkVectors.h:484
static AkForceInline void Diagonal(AkMatrix3x3 &out_mat, AkReal32 in_f)
Definition: AkVectors.h:802
void Zero()
Definition: AkVectors.h:182
AkForceInline AkReal32 Length()
Definition: AkVectors.h:867
AkMatrix4x4 operator=(AkReal32 *in_Data)
Definition: AkVectors.h:724
AkForceInline Ak3DVector operator=(const AkVector &b)
Definition: AkVectors.h:211
static void Rotation(AkMatrix3x3 &out_mat, AkReal32 in_sin, AkReal32 in_cos, const Ak3DVector &in_axis)
Definition: AkVectors.h:829
AkForceInline bool operator==(const Ak2DVector &b) const
Definition: AkVectors.h:578
AkForceInline Ak3DVector operator*(const Ak3DVector &in_rhs)
Definition: AkVectors.h:770
AkForceInline Ak3DVector operator-(const AkReal32 f) const
Definition: AkVectors.h:304
AkForceInline Ak3DVector operator+(const Ak3DVector &b) const
Definition: AkVectors.h:315
Ak3DVector GetUx() const
Definition: AkVectors.h:1600
void UpdateBoundingBox(AkBoundingBox &out_aabb) const
Definition: AkVectors.h:1656
AkUInt32 count
Definition: AkVectors.h:985
Ak3DVector GetCenter() const
Definition: AkVectors.h:1598
AkPlane()
Definition: AkVectors.h:1094
AkMatrix4x4()
Definition: AkVectors.h:711
AkReal32 X
Definition: AkVectors.h:698
AkReal32 maxt
Definition: AkVectors.h:1088
AkForceInline bool operator>=(const Ak3DVector &b) const
Definition: AkVectors.h:235
~Ak3DVector()
Definition: AkVectors.h:180
Ak3DVector()
Definition: AkVectors.h:135
#define AKVECTORS_PIOVERTWO
Definition: AkVectors.h:49
AkForceInline bool operator!=(const Ak2DVector &b) const
Definition: AkVectors.h:583
AkForceInline bool IsAllPositive() const
Definition: AkVectors.h:691
AkForceInline AkReal32 LengthSquared() const
Definition: AkVectors.h:489
AkForceInline AkReal32 Length() const
Definition: AkVectors.h:588
Ak4DVector()
Definition: AkVectors.h:57
Ak3DVector GetSide() const
Definition: AkVectors.h:1606
AkLine()
Definition: AkVectors.h:991
AkReal32 Y
Y Position.
Definition: AkTypes.h:323
Ak2DVector(AkReal32 x, AkReal32 y)
Definition: AkVectors.h:525
AkForceInline AkMatrix3x3 & operator*=(const AkReal32 &in_f)
Definition: AkVectors.h:794
AkReal32 GetVolume() const
Definition: AkVectors.h:1608
AkReal32 GetD() const
Definition: AkVectors.h:1282
AkReal32 X
X Position.
Definition: AkTypes.h:322
~AkBox()
Definition: AkVectors.h:1568
AkForceInline Ak3DVector operator*(const AkReal32 f) const
Definition: AkVectors.h:270
AkForceInline bool operator>(const Ak3DVector b) const
Definition: AkVectors.h:230
Ak2DVector operator-(const Ak2DVector &b) const
Definition: AkVectors.h:551
AkReal32 m_Data[MAX_SIZE]
Definition: AkVectors.h:734
AkForceInline AkReal32 ACos(AkReal32 in_fAngle) const
Definition: AkVectors.h:1544
AkBoundingBox Intersect(const AkBoundingBox &in_BB) const
Definition: AkVectors.h:1526
AkMatrix3x3()
Definition: AkVectors.h:743
Ak2DVector()
Definition: AkVectors.h:522
#define AKASSERT(Condition)
Definition: AkAssert.h:76
AkReal32 v[4]
Definition: AkVectors.h:109
Spherical coordinates.
Definition: AkTypes.h:476
AkReal32 mint
Definition: AkVectors.h:1087
~AkPlane()
Definition: AkVectors.h:1110
Ak3DVector(AkReal32 x, AkReal32 y, AkReal32 z)
Definition: AkVectors.h:141
AkReal32 Z
Z Position.
Definition: AkTypes.h:324
int32_t AkInt32
Signed 32-bit integer.
Definition: AkTypes.h:90
uint8_t AkUInt8
Unsigned 8-bit integer.
Definition: AkTypes.h:75
AkQuaternion()
Definition: AkVectors.h:851
static AkForceInline void OuterProduct(AkMatrix3x3 &out_mat, const Ak3DVector &in_v0, const Ak3DVector &in_v1)
Definition: AkVectors.h:817
Ak3DVector(const AkVector &b)
Definition: AkVectors.h:150
Ak3DVector GetFront() const
Definition: AkVectors.h:1604
Ak3DVector GetUy() const
Definition: AkVectors.h:1601
Ak4DVector operator=(const Ak4DVector &b)
Definition: AkVectors.h:77
AkForceInline bool IsWithin(const AkBoundingBox &in_BB) const
Definition: AkVectors.h:1517
AkReal32 Y
Definition: AkVectors.h:699
AkMatrix4x4 operator/=(const AkReal32 f)
Definition: AkVectors.h:716
AkForceInline bool operator!=(const Ak3DVector &b) const
Definition: AkVectors.h:197
static AkForceInline void Add(AkMatrix3x3 &out_res, const AkMatrix3x3 &in_m0, const AkMatrix3x3 &in_m1)
Definition: AkVectors.h:785
AkForceInline bool IsEmpty() const
Definition: AkVectors.h:1552
AkMatrix3x3 operator/=(const AkReal32 f)
Definition: AkVectors.h:748
AkForceInline Ak3DVector SphericalToCartesian(const AkReal32 azimuth, const AkReal32 elevation)
Definition: AkVectors.h:381
AkForceInline AkReal32 & operator()(const AkUInt32 row, const AkUInt32 column)
Definition: AkVectors.h:760
AkReal32 W
Definition: AkVectors.h:976
void Update(const Ak3DVector &in_point)
Definition: AkVectors.h:1487
Definition: AkVectors.h:1562
AkQuaternion(AkReal32 in_angle, const Ak3DVector &in_axis)
Definition: AkVectors.h:934
AkLine(Ak3DVector in_L, Ak3DVector in_P)
Definition: AkVectors.h:997
static AkReal32 Determinant(const Ak3DVector &a, const Ak3DVector &b, const Ak3DVector &c)
Definition: AkVectors.h:394
~AkMatrix4x4()
Definition: AkVectors.h:712
static AkForceInline void CrossProductMatrix(AkMatrix3x3 &out_mat, const Ak3DVector &in_u)
Definition: AkVectors.h:810
bool DoesRayIntersect(const Ak3DVector &in_Origin, const Ak3DVector &in_Destination, Ak3DVector &out_Intersection) const
Definition: AkVectors.h:1145
~Ak4DVector()
Definition: AkVectors.h:73
Ak3DVector P
Definition: AkVectors.h:1085
AkForceInline bool IsAllPositive() const
Definition: AkVectors.h:495
AkForceInline AkReal32 L2_Norm() const
Definition: AkVectors.h:457
AkReal32 Z
Definition: AkVectors.h:979
AkForceInline AKSIMD_V4F32 PointV4F32() const
Definition: AkVectors.h:162
AkForceInline const AkQuaternion & Normalize()
Definition: AkVectors.h:872
AkForceInline Ak2DVector NormalizeSpherical() const
Definition: AkVectors.h:638
Ak3DVector m_Min
Definition: AkVectors.h:1557
AkForceInline Ak3DVector operator/(const AkReal32 f) const
Definition: AkVectors.h:281
AkQuaternion(const Ak3DVector &in_fromVector)
Definition: AkVectors.h:860
#define ADD(i, j)
AkForceInline void NormalizeSpherical()
Definition: AkVectors.h:669
AkReal32 Y
Definition: AkVectors.h:513
static AkForceInline void Rotation(AkMatrix3x3 &out_mat, AkReal32 in_angle, const Ak3DVector &in_axis)
Definition: AkVectors.h:824
Ak3DVector GetUp() const
Definition: AkVectors.h:1605
AkBoundingBox()
Definition: AkVectors.h:1482
#define AKVECTORS_EPSILON
Definition: AkVectors.h:50
static AkForceInline Ak3DVector Max(const Ak3DVector &A, const Ak3DVector &B)
Definition: AkVectors.h:357
void Init(const Ak3DVector &in_center, const Ak3DVector &in_extent, const Ak3DVector &in_Front, const Ak3DVector &in_Up)
Definition: AkVectors.h:1572
AkReal32 theta
Azimuth.
Definition: AkTypes.h:471
AkForceInline AkMatrix3x3 & operator+=(const AkMatrix3x3 &in_rhs)
Definition: AkVectors.h:779
AkReal32 Y
Definition: AkVectors.h:978
Ak3DVector GetP2() const
Definition: AkVectors.h:1437
float AkReal32
32-bit floating point
Definition: AkTypes.h:95
AkForceInline const AkReal32 & operator()(const AkUInt32 row, const AkUInt32 column) const
Definition: AkVectors.h:765
~AkMatrix3x3()
Definition: AkVectors.h:744
#define AKSIMD_GETELEMENT_V4F32(__vName, __num__)
Retrieve scalar element from vector.
Definition: AkSimd.h:38
AkForceInline Ak3DVector operator/=(const AkReal32 f)
Definition: AkVectors.h:249
AkForceInline bool operator<=(const Ak3DVector &b) const
Definition: AkVectors.h:225
AkPlane(Ak3DVector in_p1, Ak3DVector in_p2, Ak3DVector in_p4)
Definition: AkVectors.h:1098
AkQuaternion(const Ak3DVector &in_v0, const Ak3DVector &in_v1)
Definition: AkVectors.h:897
AkInt32 X
X Position.
Definition: AkVectors.h:125
AkForceInline Ak3DVector operator+(const AkReal32 f) const
Definition: AkVectors.h:293
#define EPSILON
Definition: AkVectors.h:1144
3D vector.
Definition: AkTypes.h:305
Ak3DVector GetSize() const
Definition: AkVectors.h:1597
AkForceInline AkReal32 Dot(const Ak3DVector &v2) const
Definition: AkVectors.h:467
Ak3DVector GetP1() const
Definition: AkVectors.h:1436
~Ak3DIntVector()
Definition: AkVectors.h:123
Ak3DVector GetP4() const
Definition: AkVectors.h:1438
uint32_t AkUInt32
Unsigned 32-bit integer.
Definition: AkTypes.h:77
AkInt32 Z
Z Position.
Definition: AkVectors.h:127
AkForceInline const Ak3DVector & Normalize()
Definition: AkVectors.h:439
AkForceInline Ak3DVector operator=(const Ak3DVector &b)
Definition: AkVectors.h:202
Ak3DVector m_Max
Definition: AkVectors.h:1558
static AkForceInline Ak3DVector Min(const Ak3DVector &A, const Ak3DVector &B)
Definition: AkVectors.h:346
void SetReflection(AkReal32 *out_mat) const
Definition: AkVectors.h:1256
Ak4DVector(const AkVector &b)
Definition: AkVectors.h:65
Ak3DVector L
Definition: AkVectors.h:1084
AkForceInline bool IsWithin(const Ak3DVector &in_Point) const
Definition: AkVectors.h:1510
AkForceInline Ak2DVector operator=(const AkSphericalCoord &b)
Definition: AkVectors.h:543
Ak2DVector operator/=(const AkReal32 f)
Definition: AkVectors.h:569
AkForceInline Ak2DVector LinearCombination(const Ak2DVector &A, const Ak2DVector &B) const
Definition: AkVectors.h:609
AkQuaternion(AkReal32 in_W, AkReal32 in_X, AkReal32 in_Y, AkReal32 in_Z)
Definition: AkVectors.h:853
AkBox()
Definition: AkVectors.h:1564
AkForceInline Ak3DVector Abs() const
Definition: AkVectors.h:503
AkReal32 m_Data[3][3]
Definition: AkVectors.h:844
Definition: AkVectors.h:989
AkForceInline Ak3DVector operator*(const Ak3DVector v2) const
Definition: AkVectors.h:259
AkForceInline Ak3DVector LinearCombination(const Ak3DVector &A, const Ak3DVector &B, const Ak3DVector &C) const
Definition: AkVectors.h:404