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