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 #ifndef AXIS_ALIGNED_BOX_H_
00026 #define AXIS_ALIGNED_BOX_H_
00027
00028 #include <Core/Primitive/Vector3.h>
00029 #include <Core/Primitive/Matrix33.h>
00030 #include <Core/Primitive/Matrix34.h>
00031 #include <Core/Primitive/Matrix44.h>
00032
00033 namespace Lamp{
00034
00035 class Capsule;
00036 class Cone;
00037 class Line;
00038 class OrientedBox;
00039 class Plane;
00040 class Ray;
00041 class Segment;
00042 class Sphere;
00043 class Triangle;
00044
00045
00046
00047
00048
00049
00050
00051 class AxisAlignedBox{
00052 public:
00053
00054
00055
00056
00057 static const AxisAlignedBox zero;
00058
00059
00060 static const AxisAlignedBox unit;
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 inline AxisAlignedBox(){}
00071
00072
00073
00074
00075
00076
00077 inline AxisAlignedBox(const Vector3& minimum, const Vector3& maximum) :
00078 minimum_(minimum), maximum_(maximum){
00079 Assert(minimum_.x <= maximum_.x);
00080 Assert(minimum_.y <= maximum_.y);
00081 Assert(minimum_.z <= maximum_.z);
00082 }
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 inline AxisAlignedBox(
00094 float minimumX, float minimumY, float minimumZ,
00095 float maximumX, float maximumY, float maximumZ) :
00096 minimum_(minimumX, minimumY, minimumZ),
00097 maximum_(maximumX, maximumY, maximumZ){
00098 Assert(minimum_.x <= maximum_.x);
00099 Assert(minimum_.y <= maximum_.y);
00100 Assert(minimum_.z <= maximum_.z);
00101 }
00102
00103
00104
00105
00106
00107 inline explicit AxisAlignedBox(const float* const source) :
00108 minimum_(source[0], source[1], source[2]),
00109 maximum_(source[3], source[4], source[5]){
00110 Assert(minimum_.x <= maximum_.x);
00111 Assert(minimum_.y <= maximum_.y);
00112 Assert(minimum_.z <= maximum_.z);
00113 }
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 inline void set(const Vector3& minimum, const Vector3& maximum){
00124 minimum_ = minimum;
00125 maximum_ = maximum;
00126 Assert(minimum_.x <= maximum_.x);
00127 Assert(minimum_.y <= maximum_.y);
00128 Assert(minimum_.z <= maximum_.z);
00129 }
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 inline void set(
00141 float minimumX, float minimumY, float minimumZ,
00142 float maximumX, float maximumY, float maximumZ){
00143 minimum_.set(minimumX, minimumY, minimumZ);
00144 maximum_.set(maximumX, maximumY, maximumZ);
00145 Assert(minimum_.x <= maximum_.x);
00146 Assert(minimum_.y <= maximum_.y);
00147 Assert(minimum_.z <= maximum_.z);
00148 }
00149
00150
00151
00152
00153
00154 inline void set(const float* const source){
00155 minimum_.set(source[0], source[1], source[2]);
00156 maximum_.set(source[3], source[4], source[5]);
00157 Assert(minimum_.x <= maximum_.x);
00158 Assert(minimum_.y <= maximum_.y);
00159 Assert(minimum_.z <= maximum_.z);
00160 }
00161
00162
00163
00164
00165
00166
00167
00168
00169 inline const Vector3& getMinimum() const{ return minimum_; }
00170
00171
00172
00173
00174
00175 inline const Vector3& getMaximum() const{ return maximum_; }
00176
00177
00178
00179
00180
00181 inline Vector3 getSize() const{ return (maximum_ - minimum_); }
00182
00183
00184
00185
00186
00187 inline Vector3 getCenter() const{ return (maximum_ + minimum_) * 0.5f; }
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 inline Vector3 getCorner(int index) const{
00210 if(index == 0){
00211 return minimum_;
00212 }else if(index == 1){
00213 return Vector3(minimum_.x, maximum_.y, minimum_.z);
00214 }else if(index == 2){
00215 return Vector3(maximum_.x, maximum_.y, minimum_.z);
00216 }else if(index == 3){
00217 return Vector3(maximum_.x, minimum_.y, minimum_.z);
00218 }else if(index == 4){
00219 return maximum_;
00220 }else if(index == 5){
00221 return Vector3(minimum_.x, maximum_.y, maximum_.z);
00222 }else if(index == 6){
00223 return Vector3(minimum_.x, minimum_.y, maximum_.z);
00224 }else if(index == 7){
00225 return Vector3(maximum_.x, minimum_.y, maximum_.z);
00226 }
00227 ErrorOut("AxisAlignedBox::getCorner() Out of index");
00228 return Vector3(0.f, 0.f, 0.f);
00229 }
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 inline void getCornerArray(Vector3 corner[8]) const{
00251 corner[0] = minimum_;
00252 corner[1].set(minimum_.x, maximum_.y, minimum_.z);
00253 corner[2].set(maximum_.x, maximum_.y, minimum_.z);
00254 corner[3].set(maximum_.x, minimum_.y, minimum_.z);
00255 corner[4] = maximum_;
00256 corner[5].set(minimum_.x, maximum_.y, maximum_.z);
00257 corner[6].set(minimum_.x, minimum_.y, maximum_.z);
00258 corner[7].set(maximum_.x, minimum_.y, maximum_.z);
00259 }
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269 inline const AxisAlignedBox& merge(const AxisAlignedBox& box){
00270 if(minimum_.x > box.minimum_.x){ minimum_.x = box.minimum_.x; }
00271 if(maximum_.x < box.maximum_.x){ maximum_.x = box.maximum_.x; }
00272 if(minimum_.y > box.minimum_.y){ minimum_.y = box.minimum_.y; }
00273 if(maximum_.y < box.maximum_.y){ maximum_.y = box.maximum_.y; }
00274 if(minimum_.z > box.minimum_.z){ minimum_.z = box.minimum_.z; }
00275 if(maximum_.z < box.maximum_.z){ maximum_.z = box.maximum_.z; }
00276 return *this;
00277 }
00278
00279
00280
00281
00282
00283
00284 inline const AxisAlignedBox& merge(const Vector3& vector){
00285 if(minimum_.x > vector.x){ minimum_.x = vector.x; }
00286 else if(maximum_.x < vector.x){ maximum_.x = vector.x; }
00287 if(minimum_.y > vector.y){ minimum_.y = vector.y; }
00288 else if(maximum_.y < vector.y){ maximum_.y = vector.y; }
00289 if(minimum_.z > vector.z){ minimum_.z = vector.z; }
00290 else if(maximum_.z < vector.z){ maximum_.z = vector.z; }
00291 return *this;
00292 }
00293
00294
00295
00296
00297
00298
00299 inline bool isZero() const{
00300 return epsilonEquals(zero, Math::epsilon);
00301 }
00302
00303
00304
00305
00306
00307 inline bool isUnit() const{
00308 return epsilonEquals(unit, Math::epsilon);
00309 }
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 inline AxisAlignedBox transform(const Matrix33& matrix) const{
00320 AxisAlignedBox result;
00321 Vector3 corner[8];
00322 getCornerArray(corner);
00323 result.maximum_ = result.minimum_ = matrix * corner[7];
00324 for(int i = 0; i < 7; i++){ result.merge(matrix * corner[i]); }
00325 return result;
00326 }
00327
00328
00329
00330
00331
00332
00333 inline AxisAlignedBox transform(const Matrix34& matrix) const{
00334 AxisAlignedBox result;
00335 Vector3 corner[8];
00336 getCornerArray(corner);
00337 result.maximum_ = result.minimum_ = matrix * corner[7];
00338 for(int i = 0; i < 7; i++){ result.merge(matrix * corner[i]); }
00339 return result;
00340 }
00341
00342
00343
00344
00345
00346
00347 inline AxisAlignedBox transform(const Matrix44& matrix) const{
00348 AxisAlignedBox result;
00349 Vector3 corner[8];
00350 getCornerArray(corner);
00351 result.maximum_ = result.minimum_ = matrix * corner[7];
00352 for(int i = 0; i < 7; i++){ result.merge(matrix * corner[i]); }
00353 return result;
00354 }
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364 float getDistance(const Vector3& point) const{
00365 return Math::sqrt(getSquaredDistance(point));
00366 }
00367
00368
00369
00370
00371
00372
00373 float getSquaredDistance(const Vector3& point) const;
00374
00375
00376
00377
00378
00379
00380
00381 float getDistance(const AxisAlignedBox& axisAlignedBox) const{
00382 return Math::sqrt(getSquaredDistance(axisAlignedBox));
00383 }
00384
00385
00386
00387
00388
00389
00390 float getSquaredDistance(const AxisAlignedBox& axisAlignedBox) const;
00391
00392
00393
00394
00395
00396
00397
00398 float getDistance(const Capsule& capsule) const{
00399 return Math::sqrt(getSquaredDistance(capsule));
00400 }
00401
00402
00403
00404
00405
00406
00407 float getSquaredDistance(const Capsule& capsule) const;
00408
00409
00410
00411
00412
00413
00414
00415 float getDistance(const Cone& cone) const{
00416 return Math::sqrt(getSquaredDistance(cone));
00417 }
00418
00419
00420
00421
00422
00423
00424 float getSquaredDistance(const Cone& cone) const;
00425
00426
00427
00428
00429
00430
00431
00432 float getDistance(const Line& line) const{
00433 return Math::sqrt(getSquaredDistance(line));
00434 }
00435
00436
00437
00438
00439
00440
00441 float getSquaredDistance(const Line& line) const;
00442
00443
00444
00445
00446
00447
00448
00449 float getDistance(const OrientedBox& orientedBox) const{
00450 return Math::sqrt(getSquaredDistance(orientedBox));
00451 }
00452
00453
00454
00455
00456
00457
00458 float getSquaredDistance(const OrientedBox& orientedBox) const;
00459
00460
00461
00462
00463
00464
00465
00466 float getDistance(const Plane& plane) const;
00467
00468
00469
00470
00471
00472
00473 float getSquaredDistance(const Plane& plane) const{
00474 float distance = getDistance(plane);
00475 return (distance * distance);
00476 }
00477
00478
00479
00480
00481
00482
00483
00484 float getDistance(const Ray& ray) const{
00485 return Math::sqrt(getSquaredDistance(ray));
00486 }
00487
00488
00489
00490
00491
00492
00493 float getSquaredDistance(const Ray& ray) const;
00494
00495
00496
00497
00498
00499
00500
00501 float getDistance(const Segment& segment) const{
00502 return Math::sqrt(getSquaredDistance(segment));
00503 }
00504
00505
00506
00507
00508
00509
00510 float getSquaredDistance(const Segment& segment) const;
00511
00512
00513
00514
00515
00516
00517
00518 float getDistance(const Sphere& sphere) const{
00519 return Math::sqrt(getSquaredDistance(sphere));
00520 }
00521
00522
00523
00524
00525
00526
00527 float getSquaredDistance(const Sphere& sphere) const;
00528
00529
00530
00531
00532
00533
00534
00535 float getDistance(const Triangle& triangle) const{
00536 return Math::sqrt(getSquaredDistance(triangle));
00537 }
00538
00539
00540
00541
00542
00543
00544 float getSquaredDistance(const Triangle& triangle) const;
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554 bool intersect(const Vector3& point) const;
00555
00556
00557
00558
00559
00560
00561
00562 bool intersect(const AxisAlignedBox& axisAlignedBox) const;
00563
00564
00565
00566
00567
00568
00569
00570 bool intersect(const Capsule& capsule) const;
00571
00572
00573
00574
00575
00576
00577
00578 bool intersect(const Cone& cone) const;
00579
00580
00581
00582
00583
00584
00585
00586 bool intersect(const Line& line) const;
00587
00588
00589
00590
00591
00592
00593
00594 bool intersect(const OrientedBox& orientedBox) const;
00595
00596
00597
00598
00599
00600
00601
00602 bool intersect(const Plane& plane) const;
00603
00604
00605
00606
00607
00608
00609
00610 bool intersect(const Ray& ray) const;
00611
00612
00613
00614
00615
00616
00617
00618 bool intersect(const Segment& segment) const;
00619
00620
00621
00622
00623
00624
00625
00626 bool intersect(const Sphere& sphere) const;
00627
00628
00629
00630
00631
00632
00633
00634 bool intersect(const Triangle& triangle) const;
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644 inline bool operator ==(const AxisAlignedBox& target) const{
00645 return ((minimum_ == target.minimum_) && (maximum_ == target.maximum_));
00646 }
00647
00648
00649
00650
00651
00652
00653
00654 inline bool epsilonEquals(
00655 const AxisAlignedBox& target, float epsilon) const{
00656 Assert(epsilon >= 0.f);
00657 return (minimum_.epsilonEquals(target.minimum_, epsilon) &&
00658 maximum_.epsilonEquals(target.maximum_, epsilon));
00659 }
00660
00661
00662
00663
00664
00665
00666 inline bool operator !=(const AxisAlignedBox& target) const{
00667 return ((minimum_ != target.minimum_) || (maximum_ != target.maximum_));
00668 }
00669
00670
00671
00672
00673
00674
00675
00676 inline bool notEpsilonEquals(
00677 const AxisAlignedBox& target, float epsilon) const{
00678 Assert(epsilon >= 0.f);
00679 return (minimum_.notEpsilonEquals(target.minimum_, epsilon) ||
00680 maximum_.notEpsilonEquals(target.maximum_, epsilon));
00681 }
00682
00683
00684
00685
00686
00687
00688
00689
00690 inline String toString() const{
00691 String returnString;
00692 returnString.format("{ ( %.8f, %.8f, %.8f ) ( %.8f, %.8f, %.8f ) }",
00693 minimum_.x, minimum_.y, minimum_.z,
00694 maximum_.x, maximum_.y, maximum_.z);
00695 return returnString;
00696 }
00697
00698 private:
00699
00700
00701
00702
00703 Vector3 minimum_;
00704
00705 Vector3 maximum_;
00706
00707 };
00708
00709
00710 }
00711 #endif // End of AXIS_ALIGNED_BOX_H_
00712