00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #pragma once
00032
00033 #include <AK/SoundEngine/Common/AkTypes.h>
00034 #include <AK/SoundEngine/Common/AkSimd.h>
00035 #include <AK/SoundEngine/Common/AkSpeakerVolumes.h>
00036 #include <AK/SoundEngine/Common/IAkPluginMemAlloc.h>
00037 #include <AK/Tools/Common/AkArray.h>
00038 #include <AK/Tools/Common/AkObject.h>
00039
00040 #include <math.h>
00041 #include <stdio.h>
00042 #include <float.h>
00043
00044
00045
00046
00047 #define AKVECTORS_PI (3.1415926535897932384626433832795f)
00048 #define AKVECTORS_TWOPI (6.283185307179586476925286766559f)
00049 #define AKVECTORS_PIOVERTWO (1.5707963267948966192313216916398f)
00050 #define AKVECTORS_EPSILON (1.0e-38f) // epsilon value for fast log(0)
00051
00052 class Ak4DVector
00053 {
00054 public:
00055
00056
00057 Ak4DVector()
00058 {
00059 v[0] = 0.0f;
00060 v[1] = 0.0f;
00061 v[2] = 0.0f;
00062 v[3] = 0.0f;
00063 }
00064
00065 Ak4DVector(const AkVector& b)
00066 {
00067 v[0] = b.X;
00068 v[1] = b.Y;
00069 v[2] = b.Z;
00070 v[3] = 1;
00071 }
00072
00073 ~Ak4DVector(){}
00074
00075
00076
00077 Ak4DVector operator=(const Ak4DVector& b)
00078 {
00079 v[0] = b.v[0];
00080 v[1] = b.v[1];
00081 v[2] = b.v[2];
00082 v[3] = b.v[3];
00083
00084 return *this;
00085 }
00086
00087 Ak4DVector operator/=(const AkReal32 f)
00088 {
00089 v[0] = v[0] / f;
00090 v[1] = v[1] / f;
00091 v[2] = v[2] / f;
00092 v[3] = v[3] / f;
00093
00094 return *this;
00095 }
00096
00097 Ak4DVector operator-(const Ak4DVector& b) const
00098 {
00099 Ak4DVector p;
00100
00101 p.v[0] = v[0] - b.v[0];
00102 p.v[1] = v[1] - b.v[1];
00103 p.v[2] = v[2] - b.v[2];
00104 p.v[3] = v[3] - b.v[3];
00105
00106 return p;
00107 }
00108
00109 AkReal32 v[4];
00110 };
00111
00112 struct Ak3DIntVector
00113 {
00114 public:
00115 Ak3DIntVector(){}
00116 Ak3DIntVector(AkInt32 x, AkInt32 y, AkInt32 z)
00117 {
00118 X = x;
00119 Y = y;
00120 Z = z;
00121 }
00122
00123 ~Ak3DIntVector(){}
00124
00125 AkInt32 X;
00126 AkInt32 Y;
00127 AkInt32 Z;
00128 };
00129
00130 class Ak3DVector
00131 {
00132 public:
00133
00134
00135 Ak3DVector() :
00136 X(0.f),
00137 Y(0.f),
00138 Z(0.f)
00139 {}
00140
00141 Ak3DVector(
00142 AkReal32 x,
00143 AkReal32 y,
00144 AkReal32 z)
00145 {
00146 X = x;
00147 Y = y;
00148 Z = z;
00149 }
00150 Ak3DVector(const AkVector& b)
00151 {
00152 X = b.X;
00153 Y = b.Y;
00154 Z = b.Z;
00155 }
00156 explicit Ak3DVector(const AKSIMD_V4F32& in_v4f32)
00157 {
00158 X = AKSIMD_GETELEMENT_V4F32(in_v4f32, 0);
00159 Y = AKSIMD_GETELEMENT_V4F32(in_v4f32, 1);
00160 Z = AKSIMD_GETELEMENT_V4F32(in_v4f32, 2);
00161 }
00162 AkForceInline AKSIMD_V4F32 PointV4F32() const
00163 {
00164 AKSIMD_V4F32 v4f32;
00165 AKSIMD_GETELEMENT_V4F32(v4f32, 0) = X;
00166 AKSIMD_GETELEMENT_V4F32(v4f32, 1) = Y;
00167 AKSIMD_GETELEMENT_V4F32(v4f32, 2) = Z;
00168 AKSIMD_GETELEMENT_V4F32(v4f32, 3) = 1.f;
00169 return v4f32;
00170 }
00171 AkForceInline AKSIMD_V4F32 VectorV4F32() const
00172 {
00173 AKSIMD_V4F32 v4f32;
00174 AKSIMD_GETELEMENT_V4F32(v4f32, 0) = X;
00175 AKSIMD_GETELEMENT_V4F32(v4f32, 1) = Y;
00176 AKSIMD_GETELEMENT_V4F32(v4f32, 2) = Z;
00177 AKSIMD_GETELEMENT_V4F32(v4f32, 3) = 0.f;
00178 return v4f32;
00179 }
00180 ~Ak3DVector() {}
00181
00182 void Zero()
00183 {
00184 X = 0.f;
00185 Y = 0.f;
00186 Z = 0.f;
00187 }
00188
00189
00190
00191
00192 AkForceInline bool operator==(const Ak3DVector& b) const
00193 {
00194 return X == b.X && Y == b.Y && Z == b.Z;
00195 }
00196
00197 AkForceInline bool operator!=(const Ak3DVector& b) const
00198 {
00199 return X != b.X || Y != b.Y || Z != b.Z;
00200 }
00201
00202 AkForceInline Ak3DVector operator=(const Ak3DVector& b)
00203 {
00204 X = b.X;
00205 Y = b.Y;
00206 Z = b.Z;
00207
00208 return *this;
00209 }
00210
00211 AkForceInline Ak3DVector operator=(const AkVector& b)
00212 {
00213 X = b.X;
00214 Y = b.Y;
00215 Z = b.Z;
00216
00217 return *this;
00218 }
00219
00220 AkForceInline bool operator<(const Ak3DVector& b) const
00221 {
00222 return X < b.X && Y < b.Y && Z < b.Z;
00223 }
00224
00225 AkForceInline bool operator<=(const Ak3DVector& b) const
00226 {
00227 return X <= b.X && Y <= b.Y && Z <= b.Z;
00228 }
00229
00230 AkForceInline bool operator>(const Ak3DVector b) const
00231 {
00232 return X > b.X && Y > b.Y && Z > b.Z;
00233 }
00234
00235 AkForceInline bool operator>=(const Ak3DVector& b) const
00236 {
00237 return X >= b.X && Y >= b.Y && Z >= b.Z;
00238 }
00239
00240 AkForceInline Ak3DVector operator*=(const AkReal32 f)
00241 {
00242 X = X * f;
00243 Y = Y * f;
00244 Z = Z * f;
00245
00246 return *this;
00247 }
00248
00249 AkForceInline Ak3DVector operator/=(const AkReal32 f)
00250 {
00251 AkReal32 oneoverf = 1.f / f;
00252 X = X * oneoverf;
00253 Y = Y * oneoverf;
00254 Z = Z * oneoverf;
00255
00256 return *this;
00257 }
00258
00259 AkForceInline Ak3DVector operator*(const Ak3DVector v2) const
00260 {
00261 Ak3DVector v;
00262
00263 v.X = X * v2.X;
00264 v.Y = Y * v2.Y;
00265 v.Z = Z * v2.Z;
00266
00267 return v;
00268 }
00269
00270 AkForceInline Ak3DVector operator*(const AkReal32 f) const
00271 {
00272 Ak3DVector v;
00273
00274 v.X = X * f;
00275 v.Y = Y * f;
00276 v.Z = Z * f;
00277
00278 return v;
00279 }
00280
00281 AkForceInline Ak3DVector operator/(const AkReal32 f) const
00282 {
00283 Ak3DVector v;
00284 AkReal32 oneoverf = 1.f / f;
00285
00286 v.X = X * oneoverf;
00287 v.Y = Y * oneoverf;
00288 v.Z = Z * oneoverf;
00289
00290 return v;
00291 }
00292
00293 AkForceInline Ak3DVector operator+(const AkReal32 f) const
00294 {
00295 Ak3DVector v;
00296
00297 v.X = X + f;
00298 v.Y = Y + f;
00299 v.Z = Z + f;
00300
00301 return v;
00302 }
00303
00304 AkForceInline Ak3DVector operator-(const AkReal32 f) const
00305 {
00306 Ak3DVector v;
00307
00308 v.X = X - f;
00309 v.Y = Y - f;
00310 v.Z = Z - f;
00311
00312 return v;
00313 }
00314
00315 AkForceInline Ak3DVector operator+(const Ak3DVector& b) const
00316 {
00317 Ak3DVector v;
00318
00319 v.X = X + b.X;
00320 v.Y = Y + b.Y;
00321 v.Z = Z + b.Z;
00322
00323 return v;
00324 }
00325
00326 AkForceInline Ak3DVector operator-(const Ak3DVector& b) const
00327 {
00328 Ak3DVector v;
00329
00330 v.X = X - b.X;
00331 v.Y = Y - b.Y;
00332 v.Z = Z - b.Z;
00333
00334 return v;
00335 }
00336
00337 AkForceInline operator AkVector()
00338 {
00339 AkVector v;
00340 v.X = X; v.Y = Y; v.Z = Z;
00341
00342 return v;
00343 }
00344
00345
00346 AkForceInline static Ak3DVector Min(const Ak3DVector& A, const Ak3DVector& B)
00347 {
00348 Ak3DVector min;
00349
00350 min.X = AkMin(A.X, B.X);
00351 min.Y = AkMin(A.Y, B.Y);
00352 min.Z = AkMin(A.Z, B.Z);
00353
00354 return min;
00355 }
00356
00357 AkForceInline static Ak3DVector Max(const Ak3DVector& A, const Ak3DVector& B)
00358 {
00359 Ak3DVector max;
00360
00361 max.X = AkMax(A.X, B.X);
00362 max.Y = AkMax(A.Y, B.Y);
00363 max.Z = AkMax(A.Z, B.Z);
00364
00365 return max;
00366 }
00367
00368
00369
00370 AkForceInline Ak3DVector Rotate180X_90Y() const
00371 {
00372 Ak3DVector v;
00373
00374 v.X = -X;
00375 v.Y = Z;
00376 v.Z = -Y;
00377
00378 return v;
00379 }
00380
00381 AkForceInline Ak3DVector SphericalToCartesian(
00382 const AkReal32 azimuth,
00383 const AkReal32 elevation)
00384 {
00385 AkReal32 cosElevation = cosf(elevation);
00386 X = cosf(azimuth) * cosElevation;
00387 Y = sinf(azimuth) * cosElevation;
00388 Z = sinf(elevation);
00389
00390 return *this;
00391 }
00392
00393
00394 static AkReal32 Determinant(
00395 const Ak3DVector & a,
00396 const Ak3DVector & b,
00397 const Ak3DVector & c)
00398 {
00399 return (a.X*b.Y*c.Z + a.Y*b.Z*c.X + a.Z*b.X*c.Y) -
00400 (a.Z*b.Y*c.X + a.Y*b.X*c.Z + a.X*b.Z*c.Y);
00401 }
00402
00403
00404 AkForceInline Ak3DVector LinearCombination(
00405 const Ak3DVector& A,
00406 const Ak3DVector& B,
00407 const Ak3DVector& C) const
00408 {
00409 Ak3DVector v;
00410
00411 AkReal32 d = Determinant(A, B, C);
00412
00413 if (d < AKVECTORS_EPSILON && d > -AKVECTORS_EPSILON)
00414 {
00415 v.X = 0.0f; v.Y = 0.0f; v.Z = 0.0f;
00416 return v;
00417 }
00418
00419
00420 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);
00421 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);
00422 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);
00423
00424 AkReal32 oneover_d = 1.f / d;
00425 invA *= oneover_d;
00426 invB *= oneover_d;
00427 invC *= oneover_d;
00428
00429
00430 v.X = X * invA.X + Y * invB.X + Z * invC.X;
00431 v.Y = X * invA.Y + Y * invB.Y + Z * invC.Y;
00432 v.Z = X * invA.Z + Y * invB.Z + Z * invC.Z;
00433
00434
00435
00436 return v;
00437 }
00438
00439 AkForceInline const Ak3DVector& Normalize()
00440 {
00441 AkReal32 l = Length();
00442 if (l != 0.f)
00443 {
00444 X /= l;
00445 Y /= l;
00446 Z /= l;
00447 }
00448 else
00449 {
00450 X = 0.f;
00451 Y = 0.f;
00452 Z = 0.f;
00453 }
00454 return *this;
00455 }
00456
00457 AkForceInline AkReal32 L2_Norm() const
00458 {
00459 return sqrtf(X*X + Y*Y + Z*Z);
00460 }
00461
00462 AkForceInline AkReal32 DotProduct(const Ak3DVector& v2) const
00463 {
00464 return X*v2.X + Y*v2.Y + Z*v2.Z;
00465 }
00466
00467 AkForceInline AkReal32 Dot(const Ak3DVector& v2) const
00468 {
00469 return DotProduct(v2);
00470 }
00471
00472 AkForceInline Ak3DVector Cross(const Ak3DVector& v) const
00473 {
00474 Ak3DVector uxv;
00475 const Ak3DVector& u = *this;
00476
00477 uxv.X = u.Y*v.Z - u.Z*v.Y;
00478 uxv.Y = u.Z*v.X - u.X*v.Z;
00479 uxv.Z = u.X*v.Y - u.Y*v.X;
00480
00481 return uxv;
00482 }
00483
00484 AkForceInline AkReal32 Length() const
00485 {
00486 return sqrtf(X*X + Y*Y + Z*Z);
00487 }
00488
00489 AkForceInline AkReal32 LengthSquared() const
00490 {
00491 return X*X + Y*Y + Z*Z;
00492 }
00493
00494
00495 AkForceInline bool IsAllPositive() const
00496 {
00497 const AkReal32 POSITIVE_TEST_EPSILON = 0.00001f;
00498 return X >= -POSITIVE_TEST_EPSILON &&
00499 Y >= -POSITIVE_TEST_EPSILON &&
00500 Z >= -POSITIVE_TEST_EPSILON;
00501 }
00502
00503 AkForceInline Ak3DVector Abs() const
00504 {
00505 Ak3DVector abs = *this;
00506 abs.X = (AkReal32)fabs(abs.X);
00507 abs.Y = (AkReal32)fabs(abs.Y);
00508 abs.Z = (AkReal32)fabs(abs.Z);
00509 return abs;
00510 }
00511
00512 AkReal32 X;
00513 AkReal32 Y;
00514 AkReal32 Z;
00515 };
00516
00517 class Ak2DVector
00518 {
00519 public:
00520
00521
00522 Ak2DVector(){}
00523 ~Ak2DVector(){}
00524
00525 Ak2DVector(
00526 AkReal32 x,
00527 AkReal32 y)
00528 {
00529 X = x;
00530 Y = y;
00531 }
00532
00533
00534
00535 AkForceInline Ak2DVector operator=(const Ak2DVector& b)
00536 {
00537 X = b.X;
00538 Y = b.Y;
00539
00540 return *this;
00541 }
00542
00543 AkForceInline Ak2DVector operator=(const AkSphericalCoord& b)
00544 {
00545 X = b.theta;
00546 Y = b.phi;
00547
00548 return *this;
00549 }
00550
00551 Ak2DVector operator-(const Ak2DVector& b) const
00552 {
00553 Ak2DVector v;
00554
00555 v.X = X - b.X;
00556 v.Y = Y - b.Y;
00557
00558 return v;
00559 }
00560
00561 Ak2DVector operator*=(const AkReal32 f)
00562 {
00563 X = X * f;
00564 Y = Y * f;
00565
00566 return *this;
00567 }
00568
00569 Ak2DVector operator/=(const AkReal32 f)
00570 {
00571 AkReal32 oneoverf = 1.f / f;
00572 X = X * oneoverf;
00573 Y = Y * oneoverf;
00574
00575 return *this;
00576 }
00577
00578 AkForceInline bool operator==(const Ak2DVector& b) const
00579 {
00580 return b.X == X && b.Y == Y;
00581 }
00582
00583 AkForceInline bool operator!=(const Ak2DVector& b) const
00584 {
00585 return b.X != X && b.Y != Y;
00586 }
00587
00588 AkForceInline AkReal32 Length() const
00589 {
00590 return sqrtf(X*X+Y*Y);
00591 }
00592
00593
00594
00595 AkForceInline Ak2DVector CartesianToSpherical( const Ak3DVector& in_Cartesian )
00596 {
00597
00598 AkReal32 r = sqrtf( in_Cartesian.X*in_Cartesian.X + in_Cartesian.Y*in_Cartesian.Y + in_Cartesian.Z*in_Cartesian.Z);
00599 AKASSERT( r != 0);
00600
00601 X = atan2f(in_Cartesian.Y, in_Cartesian.X);
00602 Y = asinf(in_Cartesian.Z / r);
00603
00604 NormalizeSpherical();
00605
00606 return *this;
00607 }
00608
00609 AkForceInline Ak2DVector LinearCombination(
00610 const Ak2DVector& A,
00611 const Ak2DVector& B) const
00612 {
00613 Ak2DVector v;
00614
00615
00616 AkReal32 d = (A.X*B.Y - A.Y*B.X);
00617
00618 if (d < AKVECTORS_EPSILON && d > -AKVECTORS_EPSILON)
00619 {
00620 v.X = 0.0f; v.Y = 0.0f;
00621 return v;
00622 }
00623
00624 Ak2DVector invA = Ak2DVector( B.Y, -A.Y );
00625 Ak2DVector invB = Ak2DVector( -B.X, A.X );
00626
00627 AkReal32 oneover_d = 1.f / d;
00628 invA *= oneover_d;
00629 invB *= oneover_d;
00630
00631 v.X = X * invA.X + Y * invB.X;
00632 v.Y = X * invA.Y + Y * invB.Y;
00633
00634
00635 return v;
00636 }
00637
00638 AkForceInline Ak2DVector NormalizeSpherical() const
00639 {
00640
00641
00642
00643
00644
00645
00646 Ak2DVector v;
00647
00648 v.X = X;
00649 v.Y = Y;
00650
00651 if (X > AKVECTORS_PI)
00652 v.X = X - AKVECTORS_TWOPI;
00653
00654 if (X < -AKVECTORS_PI)
00655 v.X = X + AKVECTORS_TWOPI;
00656
00657 if (Y > AKVECTORS_PIOVERTWO)
00658 v.Y = Y - AKVECTORS_PI;
00659
00660 if (Y < -AKVECTORS_PIOVERTWO)
00661 v.Y = Y + AKVECTORS_PI;
00662
00663 AKASSERT(X<AKVECTORS_PI);
00664 AKASSERT(Y<AKVECTORS_PIOVERTWO);
00665
00666 return v;
00667 }
00668
00669 AkForceInline void NormalizeSpherical()
00670 {
00671
00672
00673
00674
00675
00676
00677 if (X > AKVECTORS_PI)
00678 X = X - AKVECTORS_TWOPI;
00679
00680 if (X < -AKVECTORS_PI)
00681 X = X + AKVECTORS_TWOPI;
00682
00683 if (Y > AKVECTORS_PIOVERTWO)
00684 Y = Y - AKVECTORS_PI;
00685
00686 if (Y < -AKVECTORS_PIOVERTWO)
00687 Y = Y + AKVECTORS_PI;
00688 }
00689
00690
00691 AkForceInline bool IsAllPositive() const
00692 {
00693 const AkReal32 POSITIVE_TEST_EPSILON = 0.00001f;
00694 return X >= -POSITIVE_TEST_EPSILON &&
00695 Y >= -POSITIVE_TEST_EPSILON;
00696 }
00697
00698 AkReal32 X;
00699 AkReal32 Y;
00700 };
00701
00702
00703
00704 class AkMatrix4x4
00705 {
00706 static const int MAX_SIZE = 16;
00707
00708 public:
00709
00710
00711 AkMatrix4x4() {}
00712 ~AkMatrix4x4() {}
00713
00714
00715
00716 AkMatrix4x4 operator/=(const AkReal32 f)
00717 {
00718 for (int i = 0; i < MAX_SIZE; i++)
00719 m_Data[i] /= f;
00720
00721 return *this;
00722 }
00723
00724 AkMatrix4x4 operator=(AkReal32 * in_Data)
00725 {
00726 for (int i = 0; i < MAX_SIZE; i++)
00727 {
00728 m_Data[i] = in_Data[i];
00729 }
00730
00731 return *this;
00732 }
00733
00734 AkReal32 m_Data[MAX_SIZE];
00735 };
00736
00737 class AkMatrix3x3
00738 {
00739
00740 public:
00741
00742
00743 AkMatrix3x3() {}
00744 ~AkMatrix3x3() {}
00745
00746
00747
00748 AkMatrix3x3 operator/=(const AkReal32 f)
00749 {
00750 for (int i = 0; i < 3; i++)
00751 {
00752 for (int j = 0; j < 3; j++)
00753 {
00754 m_Data[i][j] /= f;
00755 }
00756 }
00757 return *this;
00758 }
00759
00760 AkForceInline AkReal32& operator()(const AkUInt32 row, const AkUInt32 column)
00761 {
00762 return m_Data[column][row];
00763 }
00764
00765 AkForceInline const AkReal32& operator()(const AkUInt32 row, const AkUInt32 column) const
00766 {
00767 return m_Data[column][row];
00768 }
00769
00770 AkForceInline Ak3DVector operator*(const Ak3DVector& in_rhs)
00771 {
00772 Ak3DVector res;
00773 res.X = in_rhs.X * m_Data[0][0] + in_rhs.Y * m_Data[1][0] + in_rhs.Z * m_Data[2][0];
00774 res.Y = in_rhs.X * m_Data[0][1] + in_rhs.Y * m_Data[1][1] + in_rhs.Z * m_Data[2][1];
00775 res.Z = in_rhs.X * m_Data[0][2] + in_rhs.Y * m_Data[1][2] + in_rhs.Z * m_Data[2][2];
00776 return res;
00777 }
00778
00779 AkForceInline AkMatrix3x3& operator+=(const AkMatrix3x3& in_rhs)
00780 {
00781 Add(*this, *this, in_rhs);
00782 return *this;
00783 }
00784
00785 static AkForceInline void Add(AkMatrix3x3& out_res, const AkMatrix3x3& in_m0, const AkMatrix3x3& in_m1)
00786 {
00787 #define ADD(i,j) out_res(i,j) = in_m0(i,j) + in_m1(i,j)
00788 ADD(0, 0); ADD(0, 1); ADD(0, 2);
00789 ADD(1, 0); ADD(1, 1); ADD(1, 2);
00790 ADD(2, 0); ADD(2, 1); ADD(2, 2);
00791 #undef ADD
00792 }
00793
00794 AkForceInline AkMatrix3x3& operator*=(const AkReal32& in_f)
00795 {
00796 m_Data[0][0] *= in_f; m_Data[0][1] *= in_f; m_Data[0][2] *= in_f;
00797 m_Data[1][0] *= in_f; m_Data[1][1] *= in_f; m_Data[1][2] *= in_f;
00798 m_Data[2][0] *= in_f; m_Data[2][1] *= in_f; m_Data[2][2] *= in_f;
00799 return *this;
00800 }
00801
00802 static AkForceInline void Diagonal(AkMatrix3x3& out_mat, AkReal32 in_f)
00803 {
00804 out_mat(0, 0) = in_f; out_mat(0, 1) = 0.f; out_mat(0, 2) = 0.f;
00805 out_mat(1, 0) = 0.f; out_mat(1, 1) = in_f; out_mat(1, 2) = 0.f;
00806 out_mat(2, 0) = 0.f; out_mat(2, 1) = 0.f; out_mat(2, 2) = in_f;
00807 }
00808
00809
00810 static AkForceInline void CrossProductMatrix(AkMatrix3x3& out_mat, const Ak3DVector& in_u)
00811 {
00812 out_mat(0, 0) = 0.f; out_mat(0, 1) = -in_u.Z; out_mat(0, 2) = in_u.Y;
00813 out_mat(1, 0) = in_u.Z; out_mat(1, 1) = 0.f; out_mat(1, 2) = -in_u.X;
00814 out_mat(2, 0) = -in_u.Y; out_mat(2, 1) = in_u.X; out_mat(2, 2) = 0.f;
00815 }
00816
00817 static AkForceInline void OuterProduct(AkMatrix3x3& out_mat, const Ak3DVector& in_v0, const Ak3DVector& in_v1)
00818 {
00819 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;
00820 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;
00821 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;
00822 }
00823
00824 static AkForceInline void Rotation(AkMatrix3x3& out_mat, AkReal32 in_angle, const Ak3DVector& in_axis)
00825 {
00826 Rotation(out_mat, sinf(in_angle), cosf(in_angle), in_axis);
00827 }
00828
00829 static void Rotation(AkMatrix3x3& out_mat, AkReal32 in_sin, AkReal32 in_cos, const Ak3DVector& in_axis)
00830 {
00831 Diagonal(out_mat, in_cos);
00832
00833 AkMatrix3x3 outer;
00834 OuterProduct(outer, in_axis, in_axis);
00835 outer *= (1.f - in_cos);
00836 out_mat += outer;
00837
00838 AkMatrix3x3 cross;
00839 CrossProductMatrix(cross, in_axis*in_sin);
00840 out_mat += cross;
00841 }
00842
00843
00844 AkReal32 m_Data[3][3];
00845 };
00846
00847 class AkQuaternion
00848 {
00849 public:
00850
00851 AkQuaternion(): W(1.f), X(0.f), Y(0.f), Z(0.f) {}
00852
00853 AkQuaternion(AkReal32 in_W, AkReal32 in_X, AkReal32 in_Y, AkReal32 in_Z) :
00854 W(in_W),
00855 X(in_X),
00856 Y(in_Y),
00857 Z(in_Z)
00858 {}
00859
00860 AkQuaternion(const Ak3DVector& in_fromVector):
00861 W(0.f),
00862 X(in_fromVector.X),
00863 Y(in_fromVector.Y),
00864 Z(in_fromVector.Z)
00865 {}
00866
00867 AkForceInline AkReal32 Length()
00868 {
00869 return sqrtf( W*W + X*X + Y*Y + Z*Z );
00870 }
00871
00872 AkForceInline const AkQuaternion& Normalize()
00873 {
00874 AkReal32 f = 1.0f / Length();
00875 W *= f;
00876 X *= f;
00877 Y *= f;
00878 Z *= f;
00879 return *this;
00880 }
00881
00882 AkForceInline AkQuaternion Inverse() const
00883 {
00884 AkReal32 norm = W*W + X*X + Y*Y + Z*Z;
00885 if (norm > 0.0)
00886 {
00887 AkReal32 invNorm = 1.0f / norm;
00888 return AkQuaternion(W*invNorm, -X*invNorm, -Y*invNorm, -Z*invNorm);
00889 }
00890 else
00891 {
00892 return AkQuaternion();
00893 }
00894 }
00895
00896
00897 AkQuaternion(const Ak3DVector& in_v0, const Ak3DVector& in_v1)
00898 {
00899 AkReal32 dot = in_v0.Dot(in_v1);
00900 if (dot >= 1.0f - AKVECTORS_EPSILON)
00901 {
00902
00903 AkQuaternion();
00904 }
00905 if (dot <= -1.f - AKVECTORS_EPSILON)
00906 {
00907
00908 Ak3DVector axis = Ak3DVector(0.f, 0.f, 1.f).Cross(in_v0);
00909 AkReal32 len = axis.Length();
00910 if (len < AKVECTORS_EPSILON)
00911 {
00912 axis = Ak3DVector(0.f, 1.f, 0.f).Cross(in_v0);
00913 len = axis.Length();
00914 }
00915 axis.Normalize();
00916 AkQuaternion(AKVECTORS_PI, axis);
00917 }
00918 else
00919 {
00920 AkReal32 sqrt = sqrtf((1.f + dot) * 2.f);
00921 AkReal32 invs = 1.f / sqrt;
00922
00923 Ak3DVector cross = in_v0.Cross(in_v1);
00924
00925 X = cross.X * invs;
00926 Y = cross.Y * invs;
00927 Z = cross.Z * invs;
00928 W = sqrt * 0.5f;
00929 Normalize();
00930 }
00931 }
00932
00933
00934 AkQuaternion(AkReal32 in_angle, const Ak3DVector& in_axis)
00935 {
00936 AkReal32 sinHalfAngle = sinf(in_angle / 2.f);
00937 AkReal32 cosHalfAngle = cosf(in_angle / 2.f);
00938 W = cosHalfAngle;
00939 X = cosHalfAngle*in_axis.X;
00940 Y = cosHalfAngle*in_axis.Y;
00941 Z = cosHalfAngle*in_axis.Z;
00942 }
00943
00944
00945 AkForceInline AkQuaternion operator*(const AkQuaternion& Q) const
00946 {
00947 return AkQuaternion(
00948 W*Q.W - X*Q.X - Y*Q.Y - Z*Q.Z,
00949 W*Q.X + X*Q.W + Y*Q.Z - Z*Q.Y,
00950 W*Q.Y - X*Q.Z + Y*Q.W + Z*Q.X,
00951 W*Q.Z + X*Q.Y - Y*Q.X + Z*Q.W);
00952 }
00953
00954 AkForceInline Ak3DVector operator* (const Ak3DVector& in_v) const
00955 {
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968 Ak3DVector u(X, Y, Z);
00969 Ak3DVector res =
00970 u * u.Dot(in_v) * 2.f
00971 + in_v * (W*W - u.Dot(u))
00972 + u.Cross(in_v) * W * 2.0f;
00973
00974 return res;
00975 }
00976
00977 AkReal32 W;
00978 AkReal32 X;
00979 AkReal32 Y;
00980 AkReal32 Z;
00981 };
00982
00983 struct AkIntersectionPoints
00984 {
00985 Ak3DVector points[2];
00986 AkUInt32 count;
00987 };
00988
00989 class AkLine
00990 {
00991 public:
00992 AkLine()
00993 {
00994 mint = 1.175494351e-38F;
00995 maxt = 3.402823466e+38F;
00996 }
00997
00998 AkLine(
00999 Ak3DVector in_L,
01000 Ak3DVector in_P
01001 )
01002 {
01003 L = in_L;
01004 P = in_P;
01005 mint = 1.175494351e-38F;
01006 maxt = 3.402823466e+38F;
01007 }
01008
01009 Ak3DVector PointAt(AkReal32 t) const
01010 {
01011 return P + L*t;
01012 }
01013
01014 bool Intersect(
01015 Ak3DVector A,
01016 Ak3DVector B)
01017 {
01018 Ak3DVector L2 = B - A;
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031 Ak3DVector V1 = L;
01032 Ak3DVector V2 = B - A;
01033 Ak3DVector P1 = P;
01034 Ak3DVector P2 = A;
01035
01036
01037
01038 Ak3DVector v1CrossV2 = V1.Cross(V2);
01039 AkReal32 det = Ak3DVector::Determinant(
01040 P2 - P1,
01041 V2,
01042 v1CrossV2
01043 );
01044 AkReal32 t = det / v1CrossV2.LengthSquared();
01045
01046 det = Ak3DVector::Determinant(
01047 P2 - P1,
01048 V1,
01049 v1CrossV2
01050 );
01051 AkReal32 s = det / v1CrossV2.LengthSquared();
01052
01053 AkReal32 distsqrd = ((P2 + V2*s) - (P1 + V1*t)).LengthSquared();
01054
01055 if ((AkReal32)fabs(v1CrossV2.L2_Norm()) >= AKVECTORS_EPSILON
01056 && distsqrd < 0.001
01057 && s <= 1.0f )
01058 {
01059 #ifdef AKPORTALS_DEBUG
01060 Ak3DVector minPoint = PointAt(t);
01061
01062 char msg[256];
01063 sprintf(msg, "L1a=[%0.2f,%0.2f,%0.2f];\n", P.X, P.Y, P.Z); AKPLATFORM::OutputDebugMsg(msg);
01064 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);
01065 sprintf(msg, "L2a=[%0.2f,%0.2f,%0.2f];\n", A.X, A.Y, A.Z); AKPLATFORM::OutputDebugMsg(msg);
01066 sprintf(msg, "L2b=[%0.2f,%0.2f,%0.2f];\n", B.X, B.Y, B.Z); AKPLATFORM::OutputDebugMsg(msg);
01067 sprintf(msg, "%% t=%0.2f Min t=%0.2f, Max t=%0.2f\n", t, mint, maxt); AKPLATFORM::OutputDebugMsg(msg);
01068 sprintf(msg, "intrPoint=[%0.2f,%0.2f,%0.2f];\n", minPoint.X, minPoint.Y, minPoint.Z); AKPLATFORM::OutputDebugMsg(msg);
01069 sprintf(msg, "\n"); AKPLATFORM::OutputDebugMsg(msg);
01070 #endif
01071
01072 mint = AkMin(mint, t);
01073 maxt = AkMax(maxt, t);
01074
01075 return true;
01076 }
01077
01078 #ifdef AKPORTALS_DEBUG
01079
01080
01081 #endif
01082 return false;
01083 }
01084
01085 Ak3DVector L;
01086 Ak3DVector P;
01087
01088 AkReal32 mint;
01089 AkReal32 maxt;
01090 };
01091
01092 class AkPlane
01093 {
01094 public:
01095 AkPlane()
01096 {
01097 }
01098
01099 AkPlane(
01100 Ak3DVector in_p1,
01101 Ak3DVector in_p2,
01102 Ak3DVector in_p4
01103 )
01104 {
01105 SetPlane(
01106 in_p1,
01107 in_p2,
01108 in_p4);
01109 }
01110
01111 ~AkPlane()
01112 {
01113 }
01114
01115 void SetPlane(
01116 Ak3DVector in_p1,
01117 Ak3DVector in_p2,
01118 Ak3DVector in_p4
01119 )
01120 {
01121
01122 AKASSERT(in_p1.X < 100000 && in_p1.X > -100000);
01123 AKASSERT(in_p1.Y < 100000 && in_p1.Y > -100000);
01124 AKASSERT(in_p1.Z < 100000 && in_p1.Z > -100000);
01125
01126 AKASSERT(in_p2.X < 100000 && in_p2.X > -100000);
01127 AKASSERT(in_p2.Y < 100000 && in_p2.Y > -100000);
01128 AKASSERT(in_p2.Z < 100000 && in_p2.Z > -100000);
01129
01130 AKASSERT(in_p4.X < 100000 && in_p4.X > -100000);
01131 AKASSERT(in_p4.Y < 100000 && in_p4.Y > -100000);
01132 AKASSERT(in_p4.Z < 100000 && in_p4.Z > -100000);
01133
01134 p1 = in_p1;
01135 p2 = in_p2;
01136 p4 = in_p4;
01137
01138 SetNormal();
01139
01140
01141
01142 D = -(N.X*p1.X) - (N.Y*p1.Y) - (N.Z*p1.Z);
01143 }
01144
01145 #define EPSILON 0.01f
01146 bool DoesRayIntersect(
01147 const Ak3DVector& in_Origin,
01148 const Ak3DVector& in_Destination,
01149 Ak3DVector& out_Intersection
01150 ) const
01151 {
01152 AkReal32 A = N.X;
01153 AkReal32 B = N.Y;
01154 AkReal32 C = N.Z;
01155
01156 Ak3DVector ray = in_Destination - in_Origin;
01157 AkReal32 rayLength = ray.Length();
01158
01159 Ak3DVector intersect;
01160
01161
01162 if (rayLength <= EPSILON)
01163 {
01164 Ak3DVector temp = in_Origin - p1;
01165 AkReal32 dot = temp.DotProduct(N);
01166 if (dot < EPSILON && dot > -EPSILON)
01167 {
01168 intersect = in_Origin;
01169 }
01170 else
01171 {
01172
01173 out_Intersection = p1;
01174 return false;
01175 }
01176
01177 }
01178 else
01179 {
01180
01181 ray.Normalize();
01182
01183
01184
01185
01186
01187 if ((A*ray.X + B*ray.Y + C*ray.Z) == 0.0f)
01188 {
01189
01190 AkReal32 t = -(A*in_Origin.X + B*in_Origin.Y + C*in_Origin.Z + D) / (A*ray.X + B*ray.Y + C*ray.Z);
01191 intersect = Ak3DVector(in_Origin.X + ray.X*t, in_Origin.Y + ray.Y*t, in_Origin.Z + ray.Z*t);
01192 out_Intersection = intersect;
01193 return false;
01194 }
01195
01196
01197
01198 AkReal32 t = -(A*in_Origin.X + B*in_Origin.Y + C*in_Origin.Z + D) / (A*ray.X + B*ray.Y + C*ray.Z);
01199
01200
01201 if (t < -EPSILON || t >(rayLength + EPSILON))
01202 {
01203
01204 intersect = Ak3DVector(in_Origin.X + ray.X*t, in_Origin.Y + ray.Y*t, in_Origin.Z + ray.Z*t);
01205 out_Intersection = intersect;
01206 return false;
01207 }
01208
01209
01210 intersect = Ak3DVector(in_Origin.X + ray.X*t, in_Origin.Y + ray.Y*t, in_Origin.Z + ray.Z*t);
01211 }
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221 Ak3DVector v1 = p2 - p1;
01222 Ak3DVector v2 = p4 - p1;
01223 Ak3DVector vInter1 = intersect - p1;
01224
01225 Ak3DVector p3 = p4 + v1;
01226 Ak3DVector v3 = p2 - p3;
01227 Ak3DVector v4 = p4 - p3;
01228 Ak3DVector vInter2 = intersect - p3;
01229
01230 v1.Normalize(); v2.Normalize(); v3.Normalize(); v4.Normalize(); vInter1.Normalize(); vInter2.Normalize();
01231
01232
01233
01234 AkReal32 dot1 = v1.DotProduct(vInter1);
01235 AkReal32 dot2 = v2.DotProduct(vInter1);
01236 AkReal32 dot3 = v3.DotProduct(vInter2);
01237 AkReal32 dot4 = v4.DotProduct(vInter2);
01238
01239 out_Intersection = intersect;
01240
01241 return dot1 >= -EPSILON && dot2 >= -EPSILON && dot3 >= -EPSILON && dot4 >= -EPSILON;
01242 }
01243
01244 AkReal32 DistPoint_to_Plane(
01245 Ak3DVector in_P,
01246 Ak3DVector& out_B) const
01247 {
01248 AkReal32 distance = (AkReal32)(AkReal32)fabs(N.X * in_P.X + N.Y * in_P.Y + N.Z * in_P.Z + D);
01249
01250 Ak3DVector pointToPlane = N;
01251 pointToPlane *= distance;
01252
01253 out_B = in_P + pointToPlane;
01254
01255 return (AkReal32)fabs(distance);
01256 }
01257
01258 void SetReflection(
01259 AkReal32* out_mat) const
01260 {
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275 AkReal32 d = -(N.X*p1.X) - (N.Y*p1.Y) - (N.Z*p1.Z);
01276
01277 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;
01278 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;
01279 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;
01280 out_mat[0 + 12] = 0; out_mat[1 + 12] = 0; out_mat[2 + 12] = 0; out_mat[3 + 12] = 1;
01281 }
01282
01283 Ak3DVector GetN() const { return N; }
01284 AkReal32 GetD() const { return D; }
01285
01286 bool FindIntersectionPoints(
01287 const AkPlane& in_PlaneB,
01288 AkIntersectionPoints& out_Intrs) const
01289 {
01290 out_Intrs.count = 0;
01291
01292
01293
01294 Ak3DVector point;
01295
01296 Ak3DVector N1 = N;
01297 Ak3DVector N2 = in_PlaneB.GetN();
01298 AkReal32 D1 = D;
01299 AkReal32 D2 = in_PlaneB.GetD();
01300
01301 Ak3DVector L = N1.Cross(N2);
01302 if (L.Length() < 0.001f)
01303 {
01304 return false;
01305 }
01306
01307 AkUInt8 pivotAxis = 0;
01308
01309 if ((AkReal32)fabs(L.Y) > (AkReal32)fabs(L.X))
01310 {
01311 pivotAxis = 1;
01312 if ((AkReal32)fabs(L.Z) > (AkReal32)fabs(L.Y))
01313 {
01314 pivotAxis = 2;
01315 }
01316 }
01317 else if ((AkReal32)fabs(L.Z) > (AkReal32)fabs(L.X))
01318 {
01319 pivotAxis = 2;
01320 }
01321
01322
01323
01324
01325
01326
01327
01328 switch (pivotAxis)
01329 {
01330 case 0:
01331 AKASSERT((AkReal32)fabs(L.X) > AKVECTORS_EPSILON);
01332 point.X = 0.f;
01333 point.Y = (N1.Z*D2 - N2.Z*D1) / L.X;
01334 point.Z = (N2.Y*D1 - N1.Y*D2) / L.X;
01335 break;
01336 case 1:
01337 AKASSERT((AkReal32)fabs(L.Y) > AKVECTORS_EPSILON);
01338 point.X = (N1.Z*D2 - N2.Z*D1) / L.Y;
01339 point.Y = 0.f;
01340 point.Z = (N2.X*D1 - N1.X*D2) / L.Y;
01341 break;
01342 case 2:
01343 AKASSERT((AkReal32)fabs(L.Z) > AKVECTORS_EPSILON);
01344 point.X = (N1.Y*D2 - N2.Y*D1) / L.Z;
01345 point.Y = (N2.X*D1 - N1.X*D2) / L.Z;
01346 point.Z = 0.f;
01347 break;
01348 };
01349
01350
01351
01352 L.Normalize();
01353
01354 AkLine intrLine = AkLine(L, point);
01355 AkLine intrLine2 = AkLine(L, point);
01356
01357
01358
01359
01360 AkUInt32 cpt = 0;
01361 AkUInt32 cpt2 = 0;
01362 Ak3DVector p3 = GetP2() + (GetP4() - GetP1());
01363
01364 #ifdef AKPORTALS_DEBUG
01365 char msg[256];
01366 sprintf(msg, "P1a=[%0.2f,%0.2f,%0.2f];\n", GetP1().X, GetP1().Y, GetP1().Z); AKPLATFORM::OutputDebugMsg(msg);
01367 sprintf(msg, "P2a=[%0.2f,%0.2f,%0.2f];\n", GetP2().X, GetP2().Y, GetP2().Z); AKPLATFORM::OutputDebugMsg(msg);
01368 sprintf(msg, "P4a=[%0.2f,%0.2f,%0.2f];\n", GetP4().X, GetP4().Y, GetP4().Z); AKPLATFORM::OutputDebugMsg(msg);
01369
01370 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);
01371 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);
01372 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);
01373
01374 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);
01375 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);
01376
01377
01378 sprintf(msg, "%% Plane intersec\n"); AKPLATFORM::OutputDebugMsg(msg);
01379 #endif
01380
01381
01382 if (intrLine.Intersect(GetP1(), GetP2())) cpt++;
01383 if (intrLine.Intersect(GetP1(), GetP4())) cpt++;
01384 if (intrLine.Intersect(GetP2(), p3)) cpt++;
01385 if (intrLine.Intersect(p3, GetP4())) cpt++;
01386
01387
01388 #ifdef AKPORTALS_DEBUG
01389 sprintf(msg, "%% Portal intersec\n"); AKPLATFORM::OutputDebugMsg(msg);
01390 #endif
01391
01392
01393 p3 = in_PlaneB.GetP2() + (in_PlaneB.GetP4() - in_PlaneB.GetP1());
01394 if (intrLine2.Intersect(in_PlaneB.GetP1(), in_PlaneB.GetP2())) cpt2++;
01395 if (intrLine2.Intersect(in_PlaneB.GetP1(), in_PlaneB.GetP4())) cpt2++;
01396 if (intrLine2.Intersect(in_PlaneB.GetP2(), p3)) cpt2++;
01397 if (intrLine2.Intersect(p3, in_PlaneB.GetP4())) cpt2++;
01398
01399
01400 if (cpt < 2 || cpt2 < 2)
01401 {
01402 #ifdef AKPORTALS_DEBUG
01403 sprintf(msg, "%% NON \n"); AKPLATFORM::OutputDebugMsg(msg);
01404 sprintf(msg, "%% _______________________\n"); AKPLATFORM::OutputDebugMsg(msg);
01405 #endif
01406 return false;
01407 }
01408
01409 AkReal32 start = AkMax(intrLine.mint, intrLine2.mint);
01410 AkReal32 end = AkMin(intrLine.maxt, intrLine2.maxt);
01411
01412 Ak3DVector minPoint = intrLine.PointAt(start);
01413 Ak3DVector maxPoint = intrLine.PointAt(end);
01414 #ifdef AKPORTALS_DEBUG
01415 sprintf(msg, "P1a=[%0.2f,%0.2f,%0.2f];\n", GetP1().X, GetP1().Y, GetP1().Z); AKPLATFORM::OutputDebugMsg(msg);
01416 sprintf(msg, "P2a=[%0.2f,%0.2f,%0.2f];\n", GetP2().X, GetP2().Y, GetP2().Z); AKPLATFORM::OutputDebugMsg(msg);
01417 sprintf(msg, "P4a=[%0.2f,%0.2f,%0.2f];\n", GetP4().X, GetP4().Y, GetP4().Z); AKPLATFORM::OutputDebugMsg(msg);
01418
01419 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);
01420 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);
01421 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);
01422
01423 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);
01424 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);
01425
01426 sprintf(msg, "intr1=[%0.2f,%0.2f,%0.2f];\n", minPoint.X, minPoint.Y, minPoint.Z); AKPLATFORM::OutputDebugMsg(msg);
01427 sprintf(msg, "intr2=[%0.2f,%0.2f,%0.2f];\n", maxPoint.X, maxPoint.Y, maxPoint.Z); AKPLATFORM::OutputDebugMsg(msg);
01428
01429 sprintf(msg, "%% _______________________\n"); AKPLATFORM::OutputDebugMsg(msg);
01430 #endif
01431 out_Intrs.points[0] = minPoint;
01432 out_Intrs.points[1] = maxPoint;
01433 out_Intrs.count = 2;
01434
01435 return true;
01436 }
01437
01438 Ak3DVector GetP1() const { return p1; }
01439 Ak3DVector GetP2() const { return p2; }
01440 Ak3DVector GetP4() const { return p4; }
01441
01442 private:
01443 bool SetNormal()
01444 {
01445
01446 Ak3DVector a = p2 - p1;
01447 Ak3DVector b = p4 - p1;
01448
01449 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);
01450
01451 AkReal32 len = N.Length();
01452 AKASSERT(len > 0.f);
01453
01454 if (len > 0)
01455 {
01456 N /= len;
01457 }
01458 else
01459 {
01460
01461 return false;
01462 }
01463
01464 return true;
01465 };
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476 Ak3DVector p1;
01477 Ak3DVector p2;
01478 Ak3DVector p4;
01479 Ak3DVector N;
01480 AkReal32 D;
01481 };
01482
01483 struct AkBoundingBox
01484 {
01485 AkBoundingBox() :
01486 m_Min(Ak3DVector(FLT_MAX, FLT_MAX, FLT_MAX)),
01487 m_Max(Ak3DVector(-FLT_MAX, -FLT_MAX, -FLT_MAX))
01488 {}
01489
01490 void Update(
01491 const Ak3DVector & in_point
01492 )
01493 {
01494 if (m_Min.X > in_point.X)
01495 m_Min.X = in_point.X;
01496
01497 if (m_Min.Y > in_point.Y)
01498 m_Min.Y = in_point.Y;
01499
01500 if (m_Min.Z > in_point.Z)
01501 m_Min.Z = in_point.Z;
01502
01503 if (m_Max.X < in_point.X)
01504 m_Max.X = in_point.X;
01505
01506 if (m_Max.Y < in_point.Y)
01507 m_Max.Y = in_point.Y;
01508
01509 if (m_Max.Z < in_point.Z)
01510 m_Max.Z = in_point.Z;
01511 }
01512
01513 AkForceInline bool IsWithin(
01514 const Ak3DVector & in_Point
01515 ) const
01516 {
01517 return in_Point >= m_Min && in_Point <= m_Max;
01518 }
01519
01520 AkForceInline bool IsWithin(
01521 const AkBoundingBox & in_BB
01522 ) const
01523 {
01524 return (m_Min.X <= in_BB.m_Max.X && m_Max.X >= in_BB.m_Min.X) &&
01525 (m_Min.Y <= in_BB.m_Max.Y && m_Max.Y >= in_BB.m_Min.Y) &&
01526 (m_Min.Z <= in_BB.m_Max.Z && m_Max.Z >= in_BB.m_Min.Z);
01527 }
01528
01529 AkBoundingBox Intersect(
01530 const AkBoundingBox & in_BB
01531 ) const
01532 {
01533 AkBoundingBox result;
01534
01535 result.m_Max.X = AkMin(m_Max.X, in_BB.m_Max.X);
01536 result.m_Max.Y = AkMin(m_Max.Y, in_BB.m_Max.Y);
01537 result.m_Max.Z = AkMin(m_Max.Z, in_BB.m_Max.Z);
01538
01539 result.m_Min.X = AkMax(m_Min.X, in_BB.m_Min.X);
01540 result.m_Min.Y = AkMax(m_Min.Y, in_BB.m_Min.Y);
01541 result.m_Min.Z = AkMax(m_Min.Z, in_BB.m_Min.Z);
01542
01543 return result;
01544 }
01545
01546
01547 AkForceInline AkReal32 ACos(
01548 AkReal32 in_fAngle
01549 ) const
01550 {
01551 AKASSERT((in_fAngle <= 1.0f) && (in_fAngle >= -1.0f));
01552 return acosf(in_fAngle);
01553 }
01554
01555 AkForceInline bool IsEmpty() const
01556 {
01557 return (m_Min.X >= m_Max.X) || (m_Min.Y >= m_Max.Y) || (m_Min.Z >= m_Max.Z);
01558 }
01559
01560 Ak3DVector m_Min;
01561 Ak3DVector m_Max;
01562 };
01563
01564 class AkBox
01565 {
01566 public:
01567 AkBox()
01568 {
01569 }
01570
01571 ~AkBox()
01572 {
01573 }
01574
01575 void Init(
01576 const Ak3DVector & in_center,
01577 const Ak3DVector & in_extent,
01578 const Ak3DVector & in_Front,
01579 const Ak3DVector & in_Up)
01580 {
01581 AKASSERT(fabs(in_Front.Length() - 1.f) < 0.001 && fabs(in_Up.Length() - 1.f) < 0.001);
01582 AKASSERT(fabs(in_Front.Dot(in_Up) - 0.f) < 0.001);
01583
01584 m_Center = in_center;
01585 m_Extent = in_extent;
01586
01587 m_Z = in_Front,
01588 m_Y = in_Up;
01589 m_X = m_Z.Cross(m_Y);
01590 }
01591
01592 bool IsPointInBox(
01593 const Ak3DVector & in_Point
01594 ) const
01595 {
01596 Ak3DVector pt = in_Point - m_Center;
01597 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;
01598 }
01599
01600 Ak3DVector GetSize() const { return m_Extent*2.f; }
01601 Ak3DVector GetCenter() const { return m_Center; }
01602
01603 Ak3DVector GetUx() const { return m_X; }
01604 Ak3DVector GetUy() const { return m_Y; }
01605 Ak3DVector GetUz() const { return m_Z; }
01606
01607 Ak3DVector GetFront() const { return m_Z; }
01608 Ak3DVector GetUp() const { return m_Y; }
01609 Ak3DVector GetSide() const { return m_X; }
01610
01611 AkReal32 GetVolume() const
01612 {
01613 Ak3DVector size = GetSize();
01614 return size.X * size.Y * size.Z;
01615 }
01616
01617 bool SeparatingAxisExists(
01618 const Ak3DVector& L,
01619 const AkBox& B
01620 ) const
01621 {
01622
01623 const AkBox& A = *this;
01624 Ak3DVector T = B.GetCenter() - A.GetCenter();
01625
01626 AkReal32 WA = A.m_Extent.X;
01627 AkReal32 HA = A.m_Extent.Y;
01628 AkReal32 DA = A.m_Extent.Z;
01629
01630 AkReal32 WB = B.m_Extent.X;
01631 AkReal32 HB = B.m_Extent.Y;
01632 AkReal32 DB = B.m_Extent.Z;
01633
01634 Ak3DVector Ax = A.GetUx();
01635 Ak3DVector Ay = A.GetUy();
01636 Ak3DVector Az = A.GetUz();
01637
01638 Ak3DVector Bx = B.GetUx();
01639 Ak3DVector By = B.GetUy();
01640 Ak3DVector Bz = B.GetUz();
01641
01642
01643
01644
01645
01646 AkReal32 left = (AkReal32)fabs(T.DotProduct(L));
01647 AkReal32 dpax = (AkReal32)fabs((Ax*WA).DotProduct(L));
01648 AkReal32 dpay = (AkReal32)fabs((Ay*HA).DotProduct(L));
01649 AkReal32 dpaz = (AkReal32)fabs((Az*DA).DotProduct(L));
01650 AkReal32 dpbx = (AkReal32)fabs((Bx*WB).DotProduct(L));
01651 AkReal32 dpby = (AkReal32)fabs((By*HB).DotProduct(L));
01652 AkReal32 dpbz = (AkReal32)fabs((Bz*DB).DotProduct(L));
01653
01654 AkReal32 right = dpax + dpay + dpaz + dpbx + dpby + dpbz;
01655
01656 return left > right;
01657 }
01658
01659 void UpdateBoundingBox(AkBoundingBox& out_aabb) const
01660 {
01661 Ak3DVector x = m_X * m_Extent.X;
01662 out_aabb.Update(m_Center + x);
01663 out_aabb.Update(m_Center - x);
01664 Ak3DVector y = m_Y * m_Extent.Y;
01665 out_aabb.Update(m_Center + y);
01666 out_aabb.Update(m_Center - y);
01667 Ak3DVector Z = m_Z * m_Extent.Z;
01668 out_aabb.Update(m_Center + Z);
01669 out_aabb.Update(m_Center - Z);
01670 }
01671
01672
01673 private:
01674
01675 Ak3DVector m_Center;
01676 Ak3DVector m_Extent;
01677
01678
01679 Ak3DVector m_X;
01680 Ak3DVector m_Y;
01681 Ak3DVector m_Z;
01682 };