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

# AxisAlignedBoxIntersection.cpp

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 #include "LampBasic.h"
    00026 #include "Geometry/Intersection/AxisAlignedBoxIntersection.h"
    00027
    00028 namespace Lamp{
    00029
    00030 //------------------------------------------------------------------------------
    00031 // 点
    00032 //------------------------------------------------------------------------------
    00033 // 点交差
    00034 bool AxisAlignedBoxIntersection::intersect(
    00035     const AxisAlignedBox& aab, const Vector3& point){
    00036     const Vector3& max = aab.getMaximum();
    00037     const Vector3& min = aab.getMinimum();
    00038     if(point.x < min.x){ return false; }
    00039     if(point.y < min.y){ return false; }
    00040     if(point.z < min.z){ return false; }
    00041     if(point.x > max.x){ return false; }
    00042     if(point.y > max.y){ return false; }
    00043     if(point.z > max.z){ return false; }
    00044     return true;
    00045 }
    00046 //------------------------------------------------------------------------------
    00047 // 軸沿いボックス
    00048 //------------------------------------------------------------------------------
    00049 // 軸沿いボックス交差
    00050 bool AxisAlignedBoxIntersection::intersect(
    00051     const AxisAlignedBox& aab0, const AxisAlignedBox& aab1){
    00052     const Vector3& max0 = aab0.getMaximum();
    00053     const Vector3& min0 = aab0.getMinimum();
    00054     const Vector3& max1 = aab1.getMaximum();
    00055     const Vector3& min1 = aab1.getMinimum();
    00056     // 軸の最大、最小で比較して範囲が被っていなければ交差しない
    00057     if(max0.x < min1.x){ return false; }
    00058     if(max0.y < min1.y){ return false; }
    00059     if(max0.z < min1.z){ return false; }
    00060     if(min0.x > max1.x){ return false; }
    00061     if(min0.y > max1.y){ return false; }
    00062     if(min0.z > max1.z){ return false; }
    00063     return true;
    00064 }
    00065 //------------------------------------------------------------------------------
    00066 // カプセル
    00067 //------------------------------------------------------------------------------
    00068 // カプセル交差
    00069 bool AxisAlignedBoxIntersection::intersect(
    00070     const AxisAlignedBox& aab, const Capsule& capsule){
    00071     Assert(false);
    00072     return false;
    00073 }
    00074 //------------------------------------------------------------------------------
    00075 // コーン
    00076 //------------------------------------------------------------------------------
    00077 // コーン交差
    00078 bool AxisAlignedBoxIntersection::intersect(
    00079     const AxisAlignedBox& aab, const Cone& cone){
    00080     Assert(false);
    00081     return false;
    00082 }
    00083 //------------------------------------------------------------------------------
    00084 // ライン
    00085 //------------------------------------------------------------------------------
    00086 // ライン交差
    00087 bool AxisAlignedBoxIntersection::intersect(
    00088     const AxisAlignedBox& aab, const Line& line){
    00089     const Vector3& max = aab.getMaximum();
    00090     const Vector3& min = aab.getMinimum();
    00091     const Vector3& direction = line.getDirection();
    00092     const Vector3& origin = line.getOrigin();
    00093     float totalMinT = -Limit::floatMax;
    00094     float totalMaxT = Limit::floatMax;
    00095     // 各軸に関して調べる
    00096     for(int i = 0; i < 3; i++){
    00097         // ラインの方向が軸に垂直か調べる
    00098         float axisDirection = direction.array[i];
    00099         if(Math::abs(axisDirection) <= Math::epsilon){
    00100             // 軸の値が変化しないのでラインの原点がその軸の範囲内に無いと交差しない
    00101             if((origin.array[i] < min.array[i]) ||
    00102                 (origin.array[i] > max.array[i])){ return false; }
    00103             continue;
    00104         }
    00105         // 最小値と最大値を投影する
    00106         float minT = (min.array[i] - origin.array[i]) / axisDirection;
    00107         float maxT = (max.array[i] - origin.array[i]) / axisDirection;
    00108         if(minT > maxT){ Math::swap(minT, maxT); }
    00109         // トータルの最小値、最大値の更新
    00110         if(minT > totalMinT){ totalMinT = minT; }
    00111         if(maxT < totalMaxT){ totalMaxT = maxT; }
    00112         // Tの範囲をチェックする
    00113         if(totalMinT > totalMaxT){
    00114             return false;
    00115         }
    00116     }
    00117     return true;
    00118 }
    00119 //------------------------------------------------------------------------------
    00120 // 指向性ボックス
    00121 //------------------------------------------------------------------------------
    00122 // 指向性ボックス交差
    00123 bool AxisAlignedBoxIntersection::intersect(
    00124     const AxisAlignedBox& aab, const OrientedBox& ob){
    00125     Assert(false);
    00126     return false;
    00127 }
    00128 //------------------------------------------------------------------------------
    00129 // 平面
    00130 //------------------------------------------------------------------------------
    00131 // 平面交差
    00132 bool AxisAlignedBoxIntersection::intersect(
    00133     const AxisAlignedBox& aab, const Plane& plane){
    00134     // 最初のコーナーが面のどちら側にあるのか調べる
    00135     float distance = plane.dotProduct(aab.getCorner(0));
    00136     if(distance > 0.f){
    00137         // 平面の負方向に頂点があれば交差している
    00138         for(int i = 1; i < 8; i++){
    00139             distance = plane.dotProduct(aab.getCorner(i));
    00140             if(distance <= 0.f){ return true; }
    00141         }
    00142     }else if(distance < 0.f){
    00143         // 平面の正方向に頂点があれば交差している
    00144         for(int i = 1; i < 8; i++){
    00145             distance = plane.dotProduct(aab.getCorner(i));
    00146             if(distance >= 0.f){ return true; }
    00147         }
    00148     }else{
    00149         // サイズが0でなければ交差している
    00150         return (aab.getSize() != Vector3::zero);
    00151     }
    00152     return false;
    00153 }
    00154 //------------------------------------------------------------------------------
    00155 // レイ
    00156 //------------------------------------------------------------------------------
    00157 // レイ交差
    00158 bool AxisAlignedBoxIntersection::intersect(
    00159     const AxisAlignedBox& aab, const Ray& ray){
    00160     const Vector3& max = aab.getMaximum();
    00161     const Vector3& min = aab.getMinimum();
    00162     const Vector3& direction = ray.getDirection();
    00163     const Vector3& origin = ray.getOrigin();
    00164     float totalMinT = -Limit::floatMax;
    00165     float totalMaxT = Limit::floatMax;
    00166     // 各軸に関して調べる
    00167     for(int i = 0; i < 3; i++){
    00168         // レイの方向が軸に垂直か調べる
    00169         float axisDirection = direction.array[i];
    00170         if(Math::abs(axisDirection) <= Math::epsilon){
    00171             // 軸の値が変化しないのでレイの原点がその軸の範囲内に無いと交差しない
    00172             if((origin.array[i] < min.array[i]) ||
    00173                 (origin.array[i] > max.array[i])){ return false; }
    00174             continue;
    00175         }
    00176         // 最小値と最大値を投影する
    00177         float minT = (min.array[i] - origin.array[i]) / axisDirection;
    00178         float maxT = (max.array[i] - origin.array[i]) / axisDirection;
    00179         if(minT > maxT){ Math::swap(minT, maxT); }
    00180         // トータルの最小値、最大値の更新
    00181         if(minT > totalMinT){ totalMinT = minT; }
    00182         if(maxT < totalMaxT){ totalMaxT = maxT; }
    00183         // Tの範囲をチェックする
    00184         if(totalMinT > totalMaxT){ return false; }
    00185         if(totalMaxT < 0.f){ return false; }
    00186     }
    00187     return true;
    00188 }
    00189 //------------------------------------------------------------------------------
    00190 // セグメント
    00191 //------------------------------------------------------------------------------
    00192 // セグメント交差
    00193 bool AxisAlignedBoxIntersection::intersect(
    00194     const AxisAlignedBox& aab, const Segment& segment){
    00195     const Vector3& max = aab.getMaximum();
    00196     const Vector3& min = aab.getMinimum();
    00197     const Vector3& direction = segment.getDirection();
    00198     const Vector3& origin = segment.getOrigin();
    00199     float totalMinT = -Limit::floatMax;
    00200     float totalMaxT = Limit::floatMax;
    00201     // 各軸に関して調べる
    00202     for(int i = 0; i < 3; i++){
    00203         // セグメントの方向が軸に垂直か調べる
    00204         float axisDirection = direction.array[i];
    00205         if(Math::abs(axisDirection) <= Math::epsilon){
    00206             // 軸の値が変化しないのでセグメントの原点がその軸の範囲内に無いと交差しない
    00207             if((origin.array[i] < min.array[i]) ||
    00208                 (origin.array[i] > max.array[i])){ return false; }
    00209             continue;
    00210         }
    00211         // 最小値と最大値を投影する
    00212         float minT = (min.array[i] - origin.array[i]) / axisDirection;
    00213         float maxT = (max.array[i] - origin.array[i]) / axisDirection;
    00214         if(minT > maxT){ Math::swap(minT, maxT); }
    00215         // トータルの最小値、最大値の更新
    00216         if(minT > totalMinT){ totalMinT = minT; }
    00217         if(maxT < totalMaxT){ totalMaxT = maxT; }
    00218         // Tの範囲をチェックする
    00219         if(totalMinT > totalMaxT){ return false; }
    00220         if(totalMaxT < 0.f){ return false; }
    00221         if(totalMinT > 1.f){ return false; }
    00222     }
    00223     return true;
    00224 }
    00225 //------------------------------------------------------------------------------
    00226 // 球
    00227 //------------------------------------------------------------------------------
    00228 // 球交差
    00229 bool AxisAlignedBoxIntersection::intersect(
    00230     const AxisAlignedBox& aab, const Sphere& sphere){
    00231     const Vector3& max = aab.getMaximum();
    00232     const Vector3& min = aab.getMinimum();
    00233     const Vector3& center = sphere.getCenter();
    00234     float radius = sphere.getRadius();
    00235
    00236     // 各軸のはみ出した距離の総和が半径以上なら交差していない
    00237     float totalDitance = 0.f;
    00238     float distance;
    00239
    00240     distance = min.x - center.x;
    00241     if(distance > 0.f){ totalDitance += distance * distance; }
    00242     distance = center.x - max.x;
    00243     if(distance > 0.f){ totalDitance += distance * distance; }
    00244
    00245     distance = min.y - center.y;
    00246     if(distance > 0.f){ totalDitance += distance * distance; }
    00247     distance = center.y - max.y;
    00248     if(distance > 0.f){ totalDitance += distance * distance; }
    00249
    00250     distance = min.z - center.z;
    00251     if(distance > 0.f){ totalDitance += distance * distance; }
    00252     distance = center.z - max.z;
    00253     if(distance > 0.f){ totalDitance += distance * distance; }
    00254
    00255     return (totalDitance <= (radius * radius));
    00256 }
    00257 //------------------------------------------------------------------------------
    00258 // 三角
    00259 //------------------------------------------------------------------------------
    00260 // 三角交差
    00261 bool AxisAlignedBoxIntersection::intersect(
    00262     const AxisAlignedBox& aab, const Triangle& triangle){
    00263     Assert(false);
    00264     return false;
    00265 }
    00266 //------------------------------------------------------------------------------
    00267 } // End of namespace Lamp
    00268 //------------------------------------------------------------------------------