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