Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

Capsule.h

Go to the documentation of this file.
00001 //------------------------------------------------------------------------------
00002 // Lamp : Open source game middleware
00003 // Copyright (C) 2004  Junpei Ohtani ( Email : junpee@users.sourceforge.jp )
00004 //
00005 // This library is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 //
00010 // This library is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with this library; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 //------------------------------------------------------------------------------
00019 
00020 /** @file
00021  * カプセルヘッダ
00022  * @author Junpee
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      * @param origin 原点の初期値
00072      * @param direction 方向の初期値
00073      * @param radius 半径の初期値
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      * @param originX 原点Xの初期値
00083      * @param originY 原点Yの初期値
00084      * @param originZ 原点Zの初期値
00085      * @param directionX 方向Xの初期値
00086      * @param directionY 方向Yの初期値
00087      * @param directionZ 方向Zの初期値
00088      * @param radius 半径の初期値
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      * @param source 初期値配列
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      * @param origin 設定する原点
00111      * @param direction 設定する方向
00112      * @param radius 設定する半径
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      * @param originX 設定する原点X
00124      * @param originY 設定する原点Y
00125      * @param originZ 設定する原点Z
00126      * @param directionX 設定する方向X
00127      * @param directionY 設定する方向Y
00128      * @param directionZ 設定する方向Z
00129      * @param radius 設定する半径
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      * @param source 設定値配列
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      * @param origin 設定する原点
00152      */
00153     inline void setOrigin(const Vector3& origin){ origin_ = origin; }
00154 
00155     /**
00156      * 方向の設定
00157      * @param direction 設定する方向
00158      */
00159     inline void setDirection(const Vector3& direction){
00160         direction_ = direction;
00161     }
00162 
00163     /**
00164      * 半径の設定
00165      * @param radius 設定する半径
00166      */
00167     inline void setRadius(float radius){ radius_ = radius; }
00168 
00169     //--------------------------------------------------------------------------
00170     /**
00171      * 位置の設定
00172      * @param source ソース位置
00173      * @param target ターゲット位置
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      * @return 原点
00186      */
00187     inline const Vector3& getOrigin() const{ return origin_; }
00188 
00189     /**
00190      * 方向の取得
00191      * @return 方向
00192      */
00193     inline const Vector3& getDirection() const{ return direction_; }
00194 
00195     /**
00196      * 半径の取得
00197      * @return 半径
00198      */
00199     inline float getRadius() const{ return radius_; }
00200 
00201     //--------------------------------------------------------------------------
00202     /**
00203      * ソース位置の取得
00204      * @return ソース位置
00205      */
00206     inline const Vector3& getSourcePosition() const{ return origin_; }
00207 
00208     /**
00209      * ターゲット位置の取得
00210      * @return ターゲット位置
00211      */
00212     inline Vector3 getTargetPosition() const{ return (origin_ + direction_); }
00213 
00214     //--------------------------------------------------------------------------
00215     // カプセル演算
00216     //--------------------------------------------------------------------------
00217     /**
00218      * ゼロカプセルかどうか
00219      * @return ゼロカプセルならtrue
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      * @param matrix 乗算する行列
00232      * @return 変換後のカプセル
00233      */
00234     inline Capsule transform(const Matrix33& matrix) const{
00235         return Capsule(matrix * origin_, matrix * direction_, radius_);
00236     }
00237 
00238     /**
00239      * トランスフォーム
00240      * @param matrix 乗算する行列
00241      * @return 変換後のカプセル
00242      */
00243     inline Capsule transform(const Matrix34& matrix) const{
00244         return Capsule(matrix * origin_,
00245             matrix.multiply33(direction_), radius_);
00246     }
00247 
00248     /**
00249      * トランスフォーム
00250      * @param matrix 乗算する行列
00251      * @return 変換後のカプセル
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      * @param matrix 乗算する行列
00264      * @return 変換後のカプセル
00265      */
00266     inline Capsule scaledTransform(const Matrix33& matrix) const{
00267         // ベクトル(1,0,0),(0,1,0),(0,0,1)を変換して最長の長さを半径に乗算
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      * @param matrix 乗算する行列
00287      * @return 変換後のカプセル
00288      */
00289     inline Capsule scaledTransform(const Matrix34& matrix) const{
00290         // ベクトル(1,0,0),(0,1,0),(0,0,1)を変換して最長の長さを半径に乗算
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      * @param matrix 乗算する行列
00310      * @return 変換後のカプセル
00311      */
00312     inline Capsule scaledTransform(const Matrix44& matrix) const{
00313         // ベクトル(1,0,0),(0,1,0),(0,0,1)を変換して最長の長さを半径に乗算
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      * @param point 距離判定する点
00334      * @return 距離
00335      */
00336     float getDistance(const Vector3& point) const{
00337         return Math::sqrt(getSquaredDistance(point));
00338     }
00339 
00340     /**
00341      * 点距離の二乗
00342      * @param point 距離判定する点
00343      * @return 距離の二乗
00344      */
00345     float getSquaredDistance(const Vector3& point) const;
00346 
00347     //--------------------------------------------------------------------------
00348     /**
00349      * 軸沿いボックス距離
00350      * @param axisAlignedBox 距離判定する軸沿いボックス
00351      * @return 距離
00352      */
00353     float getDistance(const AxisAlignedBox& axisAlignedBox) const{
00354         return Math::sqrt(getSquaredDistance(axisAlignedBox));
00355     }
00356 
00357     /**
00358      * 軸沿いボックス距離の二乗
00359      * @param axisAlignedBox 距離判定する軸沿いボックス
00360      * @return 距離の二乗
00361      */
00362     float getSquaredDistance(const AxisAlignedBox& axisAlignedBox) const;
00363 
00364     //--------------------------------------------------------------------------
00365     /**
00366      * カプセル距離
00367      * @param capsule 距離判定するカプセル
00368      * @return 距離
00369      */
00370     float getDistance(const Capsule& capsule) const{
00371         return Math::sqrt(getSquaredDistance(capsule));
00372     }
00373 
00374     /**
00375      * カプセル距離の二乗
00376      * @param capsule 距離判定するカプセル
00377      * @return 距離の二乗
00378      */
00379     float getSquaredDistance(const Capsule& capsule) const;
00380 
00381     //--------------------------------------------------------------------------
00382     /**
00383      * コーン距離
00384      * @param cone 距離判定するコーン
00385      * @return 距離
00386      */
00387     float getDistance(const Cone& cone) const{
00388         return Math::sqrt(getSquaredDistance(cone));
00389     }
00390 
00391     /**
00392      * コーン距離の二乗
00393      * @param cone 距離判定するコーン
00394      * @return 距離の二乗
00395      */
00396     float getSquaredDistance(const Cone& cone) const;
00397 
00398     //--------------------------------------------------------------------------
00399     /**
00400      * ライン距離
00401      * @param line 距離判定するライン
00402      * @return 距離
00403      */
00404     float getDistance(const Line& line) const{
00405         return Math::sqrt(getSquaredDistance(line));
00406     }
00407 
00408     /**
00409      * ライン距離の二乗
00410      * @param line 距離判定するライン
00411      * @return 距離の二乗
00412      */
00413     float getSquaredDistance(const Line& line) const;
00414 
00415     //--------------------------------------------------------------------------
00416     /**
00417      * 指向性ボックス距離
00418      * @param orientedBox 距離判定する指向性ボックス
00419      * @return 距離
00420      */
00421     float getDistance(const OrientedBox& orientedBox) const{
00422         return Math::sqrt(getSquaredDistance(orientedBox));
00423     }
00424 
00425     /**
00426      * 指向性ボックス距離の二乗
00427      * @param orientedBox 距離判定する指向性ボックス
00428      * @return 距離の二乗
00429      */
00430     float getSquaredDistance(const OrientedBox& orientedBox) const;
00431 
00432     //--------------------------------------------------------------------------
00433     /**
00434      * 平面距離
00435      * @param plane 距離判定する平面
00436      * @return 距離
00437      */
00438     float getDistance(const Plane& plane) const;
00439 
00440     /**
00441      * 平面距離の二乗
00442      * @param plane 距離判定する平面
00443      * @return 距離の二乗
00444      */
00445     float getSquaredDistance(const Plane& plane) const{
00446         float distance = getDistance(plane);
00447         return (distance * distance);
00448     }
00449 
00450     //--------------------------------------------------------------------------
00451     /**
00452      * レイ距離
00453      * @param ray 距離判定するレイ
00454      * @return 距離
00455      */
00456     float getDistance(const Ray& ray) const{
00457         return Math::sqrt(getSquaredDistance(ray));
00458     }
00459 
00460     /**
00461      * レイ距離の二乗
00462      * @param ray 距離判定するレイ
00463      * @return 距離の二乗
00464      */
00465     float getSquaredDistance(const Ray& ray) const;
00466 
00467     //--------------------------------------------------------------------------
00468     /**
00469      * セグメント距離
00470      * @param segment 距離判定するセグメント
00471      * @return 距離
00472      */
00473     float getDistance(const Segment& segment) const{
00474         return Math::sqrt(getSquaredDistance(segment));
00475     }
00476 
00477     /**
00478      * セグメント距離の二乗
00479      * @param segment 距離判定するセグメント
00480      * @return 距離の二乗
00481      */
00482     float getSquaredDistance(const Segment& segment) const;
00483 
00484     //--------------------------------------------------------------------------
00485     /**
00486      * 球距離
00487      * @param sphere 距離判定する球
00488      * @return 距離
00489      */
00490     float getDistance(const Sphere& sphere) const{
00491         return Math::sqrt(getSquaredDistance(sphere));
00492     }
00493 
00494     /**
00495      * 球距離の二乗
00496      * @param sphere 距離判定する球
00497      * @return 距離の二乗
00498      */
00499     float getSquaredDistance(const Sphere& sphere) const;
00500 
00501     //--------------------------------------------------------------------------
00502     /**
00503      * 三角距離
00504      * @param triangle 距離判定する三角
00505      * @return 距離
00506      */
00507     float getDistance(const Triangle& triangle) const{
00508         return Math::sqrt(getSquaredDistance(triangle));
00509     }
00510 
00511     /**
00512      * 三角距離の二乗
00513      * @param triangle 距離判定する三角
00514      * @return 距離の二乗
00515      */
00516     float getSquaredDistance(const Triangle& triangle) const;
00517 
00518     //--------------------------------------------------------------------------
00519     // 交差
00520     //--------------------------------------------------------------------------
00521     /**
00522      * 点交差
00523      * @param point 交差判定する点
00524      * @return 交差していればtrue
00525      */
00526     bool intersect(const Vector3& point) const;
00527 
00528     //--------------------------------------------------------------------------
00529     /**
00530      * 軸沿いボックス交差
00531      * @param axisAlignedBox 交差判定する軸沿いボックス
00532      * @return 交差していればtrue
00533      */
00534     bool intersect(const AxisAlignedBox& axisAlignedBox) const;
00535 
00536     //--------------------------------------------------------------------------
00537     /**
00538      * カプセル交差
00539      * @param capsule 交差判定するカプセル
00540      * @return 交差していればtrue
00541      */
00542     bool intersect(const Capsule& capsule) const;
00543 
00544     //--------------------------------------------------------------------------
00545     /**
00546      * コーン交差
00547      * @param cone 交差判定するコーン
00548      * @return 交差していればtrue
00549      */
00550     bool intersect(const Cone& cone) const;
00551 
00552     //--------------------------------------------------------------------------
00553     /**
00554      * ライン交差
00555      * @param line 交差判定するライン
00556      * @return 交差していればtrue
00557      */
00558     bool intersect(const Line& line) const;
00559 
00560     //--------------------------------------------------------------------------
00561     /**
00562      * 指向性ボックス交差
00563      * @param orientedBox 交差判定する指向性ボックス
00564      * @return 交差していればtrue
00565      */
00566     bool intersect(const OrientedBox& orientedBox) const;
00567 
00568     //--------------------------------------------------------------------------
00569     /**
00570      * 平面交差
00571      * @param plane 交差判定する平面
00572      * @return 交差していればtrue
00573      */
00574     bool intersect(const Plane& plane) const;
00575 
00576     //--------------------------------------------------------------------------
00577     /**
00578      * レイ交差
00579      * @param ray 交差判定するレイ
00580      * @return 交差していればtrue
00581      */
00582     bool intersect(const Ray& ray) const;
00583 
00584     //--------------------------------------------------------------------------
00585     /**
00586      * セグメント交差
00587      * @param segment 交差判定するセグメント
00588      * @return 交差していればtrue
00589      */
00590     bool intersect(const Segment& segment) const;
00591 
00592     //--------------------------------------------------------------------------
00593     /**
00594      * 球交差
00595      * @param sphere 交差判定する球
00596      * @return 交差していればtrue
00597      */
00598     bool intersect(const Sphere& sphere) const;
00599 
00600     //--------------------------------------------------------------------------
00601     /**
00602      * 三角交差
00603      * @param triangle 交差判定する三角
00604      * @return 交差していればtrue
00605      */
00606     bool intersect(const Triangle& triangle) const;
00607 
00608     //--------------------------------------------------------------------------
00609     // 論理演算
00610     //--------------------------------------------------------------------------
00611     /**
00612      * カプセルが同じかどうか
00613      * @param target 比較するカプセル
00614      * @return 同じ値であればtrueを返す
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      * @param target 比較するカプセル
00625      * @param epsilon 誤差
00626      * @return 誤差の範囲内で同じ値であればtrueを返す
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      * @param target 比較するカプセル
00639      * @return 同じでない値であればtrueを返す
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      * @param target 比較するカプセル
00649      * @param epsilon 誤差
00650      * @return 誤差の範囲内で同じでない値であればtrueを返す
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      * @return カプセルの文字列表記
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 } // End of namespace Lamp
00691 #endif // End of CAPSULE_H_
00692 //------------------------------------------------------------------------------

Generated on Wed Mar 16 10:29:28 2005 for Lamp by doxygen 1.3.2