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