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