Version
menu_open
link
Wwise SDK 2019.2.15
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  /*
1018  a (V1 X V2) = (P2 - P1) X V2
1019  If the lines intersect at a single point, then the resultant vectors
1020  on each side of this equation must be parallel, and the left side must
1021  not be the zero vector. We should check to make sure that this is
1022  true. Once we have checked this, we can solve for 'a' by taking the
1023  magnitude of each side and dividing. If the resultant vectors are
1024  parallel, but in opposite directions, then 'a' is the negative of the
1025  ratio of magnitudes. Once we have 'a' we can go back to the equation
1026  for L1 to find the intersection point.
1027  */
1028  Ak3DVector V1 = L;
1029  Ak3DVector V2 = B - A;
1030  Ak3DVector P1 = P;
1031  Ak3DVector P2 = A;
1032 
1033  // k(V1 X V2) = (A - P) X V2
1034 
1035  Ak3DVector v1CrossV2 = V1.Cross(V2);
1037  P2 - P1,
1038  V2,
1039  v1CrossV2
1040  );
1041  AkReal32 t = det / v1CrossV2.LengthSquared();
1042 
1044  P2 - P1,
1045  V1,
1046  v1CrossV2
1047  );
1048  AkReal32 s = det / v1CrossV2.LengthSquared();
1049 
1050  AkReal32 distsqrd = ((P2 + V2*s) - (P1 + V1*t)).LengthSquared();
1051 
1052  if ((AkReal32)fabs(v1CrossV2.L2_Norm()) >= AKVECTORS_EPSILON
1053  && distsqrd < 0.001
1054  && s <= 1.0f )
1055  {
1056 #ifdef AKPORTALS_DEBUG
1057  Ak3DVector minPoint = PointAt(t);
1058 
1059  char msg[256];
1060  sprintf(msg, "L1a=[%0.2f,%0.2f,%0.2f];\n", P.X, P.Y, P.Z); AKPLATFORM::OutputDebugMsg(msg);
1061  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);
1062  sprintf(msg, "L2a=[%0.2f,%0.2f,%0.2f];\n", A.X, A.Y, A.Z); AKPLATFORM::OutputDebugMsg(msg);
1063  sprintf(msg, "L2b=[%0.2f,%0.2f,%0.2f];\n", B.X, B.Y, B.Z); AKPLATFORM::OutputDebugMsg(msg);
1064  sprintf(msg, "%% t=%0.2f Min t=%0.2f, Max t=%0.2f\n", t, mint, maxt); AKPLATFORM::OutputDebugMsg(msg);
1065  sprintf(msg, "intrPoint=[%0.2f,%0.2f,%0.2f];\n", minPoint.X, minPoint.Y, minPoint.Z); AKPLATFORM::OutputDebugMsg(msg);
1066  sprintf(msg, "\n"); AKPLATFORM::OutputDebugMsg(msg);
1067 #endif
1068 
1069  mint = AkMin(mint, t);
1070  maxt = AkMax(maxt, t);
1071 
1072  return true;
1073  }
1074 
1075 #ifdef AKPORTALS_DEBUG
1076  // char msg[256];
1077  // sprintf(msg, "%% DISCARTED t=%0.2f Min t=%0.2f, Max t=%0.2f\n", t, mint, maxt); AKPLATFORM::OutputDebugMsg(msg);
1078 #endif
1079  return false;
1080  }
1081 
1084 
1087 };
1088 
1089 class AkPlane
1090 {
1091 public:
1093  {
1094  }
1095 
1097  Ak3DVector in_p1,
1098  Ak3DVector in_p2,
1099  Ak3DVector in_p4
1100  )
1101  {
1102  SetPlane(
1103  in_p1,
1104  in_p2,
1105  in_p4);
1106  }
1107 
1109  {
1110  }
1111 
1112  void SetPlane(
1113  Ak3DVector in_p1,
1114  Ak3DVector in_p2,
1115  Ak3DVector in_p4
1116  )
1117  {
1118  // Reorder A-B-C to clockwwise if necessary
1119  AKASSERT(in_p1.X < 100000 && in_p1.X > -100000);
1120  AKASSERT(in_p1.Y < 100000 && in_p1.Y > -100000);
1121  AKASSERT(in_p1.Z < 100000 && in_p1.Z > -100000);
1122 
1123  AKASSERT(in_p2.X < 100000 && in_p2.X > -100000);
1124  AKASSERT(in_p2.Y < 100000 && in_p2.Y > -100000);
1125  AKASSERT(in_p2.Z < 100000 && in_p2.Z > -100000);
1126 
1127  AKASSERT(in_p4.X < 100000 && in_p4.X > -100000);
1128  AKASSERT(in_p4.Y < 100000 && in_p4.Y > -100000);
1129  AKASSERT(in_p4.Z < 100000 && in_p4.Z > -100000);
1130 
1131  p1 = in_p1;
1132  p2 = in_p2;
1133  p4 = in_p4;
1134 
1135  SetNormal();
1136 
1137  // Ax + By + Cz + D = 0
1138  // Find D using the normal and a point
1139  D = -(N.X*p1.X) - (N.Y*p1.Y) - (N.Z*p1.Z);
1140  }
1141 
1142 #define EPSILON 0.01f
1144  const Ak3DVector& in_Origin,
1145  const Ak3DVector& in_Destination,
1146  Ak3DVector& out_Intersection
1147  ) const
1148  {
1149  AkReal32 A = N.X;
1150  AkReal32 B = N.Y;
1151  AkReal32 C = N.Z;
1152 
1153  Ak3DVector ray = in_Destination - in_Origin;
1154  AkReal32 rayLength = ray.Length();
1155 
1156  Ak3DVector intersect;
1157 
1158  // If ray is < EPSILON, use on of the point directly for the test and skip the linear projection
1159  if (rayLength <= EPSILON)
1160  {
1161  Ak3DVector temp = in_Origin - p1;
1162  AkReal32 dot = temp.DotProduct(N);
1163  if (dot < EPSILON && dot > -EPSILON)
1164  {
1165  intersect = in_Origin;
1166  }
1167  else
1168  {
1169  // For debug only, to remove
1170  out_Intersection = p1;
1171  return false;
1172  }
1173 
1174  }
1175  else
1176  {
1177  // Normalize ray
1178  ray.Normalize();
1179 
1180  // TODO: possible fix for all edge cases
1181  // 1) if ray len ~= 0, only check if one of the point is on target, ie: assign the intersect point
1182 
1183  // Is ray parallel to the plane?
1184  if ((A*ray.X + B*ray.Y + C*ray.Z) == 0.0f)
1185  {
1186  // For debug only, to remove
1187  AkReal32 t = -(A*in_Origin.X + B*in_Origin.Y + C*in_Origin.Z + D) / (A*ray.X + B*ray.Y + C*ray.Z);
1188  intersect = Ak3DVector(in_Origin.X + ray.X*t, in_Origin.Y + ray.Y*t, in_Origin.Z + ray.Z*t);
1189  out_Intersection = intersect; // For debugging
1190  return false;
1191  }
1192 
1193 
1194  // Distance along the ray where reflector is hit
1195  AkReal32 t = -(A*in_Origin.X + B*in_Origin.Y + C*in_Origin.Z + D) / (A*ray.X + B*ray.Y + C*ray.Z);
1196 
1197  // Is the ray going towards the plane? Is it long enough?
1198  if (t < -EPSILON || t >(rayLength + EPSILON))
1199  {
1200  // For debug only, to remove
1201  intersect = Ak3DVector(in_Origin.X + ray.X*t, in_Origin.Y + ray.Y*t, in_Origin.Z + ray.Z*t);
1202  out_Intersection = intersect; // For debugging
1203  return false; // The ray doesn't intersect
1204  }
1205 
1206  // Find the coordinate of intersection on the plane
1207  intersect = Ak3DVector(in_Origin.X + ray.X*t, in_Origin.Y + ray.Y*t, in_Origin.Z + ray.Z*t);
1208  }
1209  ///////////////////////////////////////
1210  //
1211  // p2____v3____p3
1212  // | . |
1213  // ^ inter v4
1214  // v1 v
1215  // | |
1216  // p1__ v2>___p4
1217 
1218  Ak3DVector v1 = p2 - p1;
1219  Ak3DVector v2 = p4 - p1;
1220  Ak3DVector vInter1 = intersect - p1;
1221 
1222  Ak3DVector p3 = p4 + v1;
1223  Ak3DVector v3 = p2 - p3;
1224  Ak3DVector v4 = p4 - p3;
1225  Ak3DVector vInter2 = intersect - p3;
1226 
1227  v1.Normalize(); v2.Normalize(); v3.Normalize(); v4.Normalize(); vInter1.Normalize(); vInter2.Normalize();
1228 
1229  // Since it's a square, the angle between the point of intersection and any segment of the pannel should be < 90 degree,
1230  // therefore the dot product of the two normalized vectors should be > 0
1231  AkReal32 dot1 = v1.DotProduct(vInter1);
1232  AkReal32 dot2 = v2.DotProduct(vInter1);
1233  AkReal32 dot3 = v3.DotProduct(vInter2);
1234  AkReal32 dot4 = v4.DotProduct(vInter2);
1235 
1236  out_Intersection = intersect;
1237 
1238  return dot1 >= -EPSILON && dot2 >= -EPSILON && dot3 >= -EPSILON && dot4 >= -EPSILON;
1239  }
1240 
1242  Ak3DVector in_P,
1243  Ak3DVector& out_B) const
1244  {
1245  AkReal32 distance = (AkReal32)(AkReal32)fabs(N.X * in_P.X + N.Y * in_P.Y + N.Z * in_P.Z + D);
1246 
1247  Ak3DVector pointToPlane = N;
1248  pointToPlane *= distance;
1249 
1250  out_B = in_P + pointToPlane;
1251 
1252  return (AkReal32)fabs(distance);
1253  }
1254 
1256  AkReal32* out_mat) const
1257  {
1258  // http://ami.ektf.hu/uploads/papers/finalpdf/AMI_40_from175to186.pd
1259  /* m_pReflectionMatrix
1260  reflection on z axis
1261 
1262  P0 (x0, y0, z0), P1 (x1, y1, z1) and P2 (x2, y2, z2),
1263  normal = (cx, cy, cz)
1264  d = -CxX0 - CyY0 - CzZ0
1265 
1266  Reflect = 1-2Cx^2 -2CxCy -2CxCz -2Cxd
1267  -2CxCy 1-2Cy^2 -2CyCz -2Cyd
1268  -2CxCz -2CyCz 1-2Cz^2 -2Czd
1269  0 0 0 1
1270  */
1271 
1272  AkReal32 d = -(N.X*p1.X) - (N.Y*p1.Y) - (N.Z*p1.Z);
1273 
1274  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;
1275  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;
1276  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;
1277  out_mat[0 + 12] = 0; out_mat[1 + 12] = 0; out_mat[2 + 12] = 0; out_mat[3 + 12] = 1;
1278  }
1279 
1280  Ak3DVector GetN() const { return N; }
1281  AkReal32 GetD() const { return D; }
1282 
1284  const AkPlane& in_PlaneB,
1285  AkIntersectionPoints& out_Intrs) const
1286  {
1287  out_Intrs.count = 0;
1288 
1289  // Use vector to solve A
1290 
1291  Ak3DVector point;
1292 
1293  Ak3DVector N1 = N;
1294  Ak3DVector N2 = in_PlaneB.GetN();
1295  AkReal32 D1 = D;
1296  AkReal32 D2 = in_PlaneB.GetD();
1297 
1298  Ak3DVector L = N1.Cross(N2);
1299  if (L.Length() < 0.001f)
1300  {
1301  return false; // The two planes are parallel
1302  }
1303 
1304  AkUInt8 pivotAxis = 0;
1305 
1306  if ((AkReal32)fabs(L.Y) > (AkReal32)fabs(L.X))
1307  {
1308  pivotAxis = 1;
1309  if ((AkReal32)fabs(L.Z) > (AkReal32)fabs(L.Y))
1310  {
1311  pivotAxis = 2;
1312  }
1313  }
1314  else if ((AkReal32)fabs(L.Z) > (AkReal32)fabs(L.X))
1315  {
1316  pivotAxis = 2;
1317  }
1318 
1319  /*
1320  Pu = ( N1v*D2 - N2v*D1 ) / Lw
1321  Pv = ( N2u*D1 - N1u*D2 ) / Lw
1322  Pz = 0
1323  */
1324 
1325  switch (pivotAxis)
1326  {
1327  case 0:
1328  AKASSERT((AkReal32)fabs(L.X) > AKVECTORS_EPSILON);
1329  point.X = 0.f;
1330  point.Y = (N1.Z*D2 - N2.Z*D1) / L.X;
1331  point.Z = (N2.Y*D1 - N1.Y*D2) / L.X;
1332  break;
1333  case 1:
1334  AKASSERT((AkReal32)fabs(L.Y) > AKVECTORS_EPSILON);
1335  point.X = (N1.Z*D2 - N2.Z*D1) / L.Y;
1336  point.Y = 0.f;
1337  point.Z = (N2.X*D1 - N1.X*D2) / L.Y;
1338  break;
1339  case 2:
1340  AKASSERT((AkReal32)fabs(L.Z) > AKVECTORS_EPSILON);
1341  point.X = (N1.Y*D2 - N2.Y*D1) / L.Z;
1342  point.Y = (N2.X*D1 - N1.X*D2) / L.Z;
1343  point.Z = 0.f;
1344  break;
1345  };
1346 
1347 
1348 
1349  L.Normalize();
1350 
1351  AkLine intrLine = AkLine(L, point);
1352  AkLine intrLine2 = AkLine(L, point);
1353 
1354  //in_PlaneB.GetP1()
1355 
1356  // find min max
1357  AkUInt32 cpt = 0;
1358  AkUInt32 cpt2 = 0;
1359  Ak3DVector p3 = GetP2() + (GetP4() - GetP1());
1360 
1361 #ifdef AKPORTALS_DEBUG
1362  char msg[256];
1363  sprintf(msg, "P1a=[%0.2f,%0.2f,%0.2f];\n", GetP1().X, GetP1().Y, GetP1().Z); AKPLATFORM::OutputDebugMsg(msg);
1364  sprintf(msg, "P2a=[%0.2f,%0.2f,%0.2f];\n", GetP2().X, GetP2().Y, GetP2().Z); AKPLATFORM::OutputDebugMsg(msg);
1365  sprintf(msg, "P4a=[%0.2f,%0.2f,%0.2f];\n", GetP4().X, GetP4().Y, GetP4().Z); AKPLATFORM::OutputDebugMsg(msg);
1366 
1367  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);
1368  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);
1369  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);
1370 
1371  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);
1372  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);
1373 
1374 
1375  sprintf(msg, "%% Plane intersec\n"); AKPLATFORM::OutputDebugMsg(msg);
1376 #endif
1377  // for the four lines in rectangle
1378  // Find where the line is crossing with plane A
1379  if (intrLine.Intersect(GetP1(), GetP2())) cpt++;
1380  if (intrLine.Intersect(GetP1(), GetP4())) cpt++;
1381  if (intrLine.Intersect(GetP2(), p3)) cpt++;
1382  if (intrLine.Intersect(p3, GetP4())) cpt++;
1383  //AKASSERT(cpt == 2);
1384 
1385 #ifdef AKPORTALS_DEBUG
1386  sprintf(msg, "%% Portal intersec\n"); AKPLATFORM::OutputDebugMsg(msg);
1387 #endif
1388 
1389  // Find where the line is crossing with plane B
1390  p3 = in_PlaneB.GetP2() + (in_PlaneB.GetP4() - in_PlaneB.GetP1());
1391  if (intrLine2.Intersect(in_PlaneB.GetP1(), in_PlaneB.GetP2())) cpt2++;
1392  if (intrLine2.Intersect(in_PlaneB.GetP1(), in_PlaneB.GetP4())) cpt2++;
1393  if (intrLine2.Intersect(in_PlaneB.GetP2(), p3)) cpt2++;
1394  if (intrLine2.Intersect(p3, in_PlaneB.GetP4())) cpt2++;
1395  // **AKASSERT(cpt2 == 2 || cpt == 2);
1396 
1397  if (cpt < 2 || cpt2 < 2)
1398  {
1399 #ifdef AKPORTALS_DEBUG
1400  sprintf(msg, "%% NON \n"); AKPLATFORM::OutputDebugMsg(msg);
1401  sprintf(msg, "%% _______________________\n"); AKPLATFORM::OutputDebugMsg(msg);
1402 #endif
1403  return false;
1404  }
1405 
1406  AkReal32 start = AkMax(intrLine.mint, intrLine2.mint);
1407  AkReal32 end = AkMin(intrLine.maxt, intrLine2.maxt);
1408 
1409  Ak3DVector minPoint = intrLine.PointAt(start);
1410  Ak3DVector maxPoint = intrLine.PointAt(end);
1411 #ifdef AKPORTALS_DEBUG
1412  sprintf(msg, "P1a=[%0.2f,%0.2f,%0.2f];\n", GetP1().X, GetP1().Y, GetP1().Z); AKPLATFORM::OutputDebugMsg(msg);
1413  sprintf(msg, "P2a=[%0.2f,%0.2f,%0.2f];\n", GetP2().X, GetP2().Y, GetP2().Z); AKPLATFORM::OutputDebugMsg(msg);
1414  sprintf(msg, "P4a=[%0.2f,%0.2f,%0.2f];\n", GetP4().X, GetP4().Y, GetP4().Z); AKPLATFORM::OutputDebugMsg(msg);
1415 
1416  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);
1417  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);
1418  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);
1419 
1420  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);
1421  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);
1422 
1423  sprintf(msg, "intr1=[%0.2f,%0.2f,%0.2f];\n", minPoint.X, minPoint.Y, minPoint.Z); AKPLATFORM::OutputDebugMsg(msg);
1424  sprintf(msg, "intr2=[%0.2f,%0.2f,%0.2f];\n", maxPoint.X, maxPoint.Y, maxPoint.Z); AKPLATFORM::OutputDebugMsg(msg);
1425 
1426  sprintf(msg, "%% _______________________\n"); AKPLATFORM::OutputDebugMsg(msg);
1427 #endif
1428  out_Intrs.points[0] = minPoint;
1429  out_Intrs.points[1] = maxPoint;
1430  out_Intrs.count = 2;
1431 
1432  return true;
1433  }
1434 
1435  Ak3DVector GetP1() const { return p1; }
1436  Ak3DVector GetP2() const { return p2; }
1437  Ak3DVector GetP4() const { return p4; }
1438 
1439 private:
1440  bool SetNormal()
1441  {
1442  //m_pNormal = (B-A) cross (C-A); normalize
1443  Ak3DVector a = p2 - p1;
1444  Ak3DVector b = p4 - p1;
1445 
1446  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);
1447 
1448  AkReal32 len = N.Length();
1449  AKASSERT(len > 0.f);
1450 
1451  if (len > 0)
1452  {
1453  N /= len;
1454  }
1455  else
1456  {
1457  // TODO handle invalid reflectors
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:1283
AkReal32 DistPoint_to_Plane(Ak3DVector in_P, Ak3DVector &out_B) const
Definition: AkVectors.h:1241
#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
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:1280
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:473
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:1112
void OutputDebugMsg(const char *in_pszMsg)
Output a debug message on the console (Ansi string)
Definition: AkPlatformFuncs.h:70
~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:1092
AkMatrix4x4()
Definition: AkVectors.h:711
AkReal32 X
Definition: AkVectors.h:698
AkReal32 maxt
Definition: AkVectors.h:1086
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:319
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:1281
AkReal32 X
X Position.
Definition: AkTypes.h:318
~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:472
AkReal32 mint
Definition: AkVectors.h:1085
~AkPlane()
Definition: AkVectors.h:1108
Ak3DVector(AkReal32 x, AkReal32 y, AkReal32 z)
Definition: AkVectors.h:141
AkReal32 Z
Z Position.
Definition: AkTypes.h:320
int32_t AkInt32
Signed 32-bit integer.
Definition: AkTypes.h:98
uint8_t AkUInt8
Unsigned 8-bit integer.
Definition: AkTypes.h:83
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:1143
~Ak4DVector()
Definition: AkVectors.h:73
Ak3DVector P
Definition: AkVectors.h:1083
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:467
AkForceInline AkMatrix3x3 & operator+=(const AkMatrix3x3 &in_rhs)
Definition: AkVectors.h:779
AkReal32 Y
Definition: AkVectors.h:978
Ak3DVector GetP2() const
Definition: AkVectors.h:1436
float AkReal32
32-bit floating point
Definition: AkTypes.h:103
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:1096
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:1142
3D vector.
Definition: AkTypes.h:301
Ak3DVector GetSize() const
Definition: AkVectors.h:1597
AkForceInline AkReal32 Dot(const Ak3DVector &v2) const
Definition: AkVectors.h:467
Ak3DVector GetP1() const
Definition: AkVectors.h:1435
~Ak3DIntVector()
Definition: AkVectors.h:123
Ak3DVector GetP4() const
Definition: AkVectors.h:1437
uint32_t AkUInt32
Unsigned 32-bit integer.
Definition: AkTypes.h:85
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
#define AkForceInline
Definition: AkTypes.h:62
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:1255
Ak4DVector(const AkVector &b)
Definition: AkVectors.h:65
Ak3DVector L
Definition: AkVectors.h:1082
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

Was this page helpful?

Need Support?

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

Visit our Support page

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

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

Get started with Wwise