00001 00012 /*************************************************************************** 00013 * Copyright (C) 2007 by Jan Koci * 00014 * honza.koci@email.cz * 00015 * http://kengine.sourceforge.net/tutorial/ 00016 * * 00017 * This program is free software; you can redistribute it and/or modify * 00018 * it under the terms of the GNU General Public License as published by * 00019 * the Free Software Foundation; either version 2 of the License, or * 00020 * (at your option) any later version. * 00021 * * 00022 * This program is distributed in the hope that it will be useful, * 00023 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00025 * GNU General Public License for more details. * 00026 * * 00027 * You should have received a copy of the GNU General Public License * 00028 * along with this program; if not, write to the * 00029 * Free Software Foundation, Inc., * 00030 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 00031 ***************************************************************************/ 00032 00033 #include "K3dIntrLinSph.h" 00034 00035 K3dIntrLinSph::K3dIntrLinSph(K3dGameData *_pGameData): 00036 K3dIntrLinePlane(_pGameData) 00037 { 00038 m_pGameData = _pGameData; 00039 } 00040 00041 K3dIntrLinSph::~K3dIntrLinSph(void) 00042 { 00043 } 00044 00046 bool K3dIntrLinSph::RaySphere(const K3dRay &_rkRay, const K3dSphere &_rkSphere) 00047 { 00048 float fSqrDist = (float) 0; 00049 float fSqr = (float) 0; 00050 00051 fSqrDist = SqrPointRay(*_rkSphere.GetPosition(),_rkRay, 0); 00052 fSqr = _rkSphere.GetRadius()*_rkSphere.GetRadius(); 00053 if(fSqrDist<=fSqr) 00054 { 00055 return true; 00056 } 00057 return false; 00058 } 00059 00060 //----------------------------------------------------------------------------------------------------// 00061 /* 00062 // Test intersection ray and sphere 00063 bool CIntrLinSph::TestIntersection (const CRay kRay, const CSphere kSphere) 00064 { 00065 CDistance kDistance; 00066 float fSqrDist = (float) 0; 00067 float fSqr = (float) 0; 00068 00069 fSqrDist = kDistance.SqrPointRay(kSphere.Center(),kRay, 0); 00070 fSqr = kSphere.Radius()*kSphere.Radius(); 00071 if(fSqrDist<=fSqr) 00072 { 00073 return true; 00074 } 00075 00076 return false; 00077 00078 00079 } 00080 00081 //----------------------------------------------------------------------------------------------------// 00082 00083 // Find the point where a line intersect a sphere 00084 bool CIntrLinSph::FindLineSphere(const CLine kLine, const CSphere kSphere, int& riQuantity, CVector3 akPoint[2]) 00085 { 00086 float fA = (float) 0.0; 00087 float fInvA = (float) 0.0; 00088 float fB = (float) 0.0; 00089 float fC = (float) 0.0; 00090 float fD = (float) 0.0; 00091 float afT[2];// = (float) 0.0; 00092 float fRoot = (float) 0.0; 00093 CVector3 kDiff, kLineDirection; 00094 00095 // Calc line direction 00096 kLineDirection = kLine.Direction() - kLine.Origin(); 00097 // Calc difference between line ortigin and sphere center 00098 kDiff = kLine.Origin() - kSphere.Center(); 00099 // Set up quadratic Q(t) = a*t^2 + 2*b*t + c 00100 fA = kLineDirection.SquaredLength(); 00101 fB = kDiff.Dot(kLineDirection); 00102 fC = kDiff.SquaredLength() - kSphere.Radius() * kSphere.Radius(); 00103 fD = fB*fB - fA*fC; 00104 // If D < 0 then no intersection occurs 00105 // if D = 0 then the line is tangent to the sphere 00106 // if D > 0 then there are two distinct point 00107 if(fD < (float)0.0) 00108 { 00109 riQuantity = 0; 00110 return false; 00111 } 00112 else if(fD > (float)0.0) 00113 { 00114 fRoot = (float)sqrt(fD); 00115 if(fA) 00116 { 00117 fInvA = ((float)1.0)/fA; 00118 riQuantity = 2; 00119 afT[0] = (-fB - fRoot)*fInvA; 00120 afT[1] = (-fB + fRoot)*fInvA; 00121 //kLineDirection = kLine.Direction() - kLine.Origin(); 00122 akPoint[0] = kLine.Origin() + ( kLineDirection*afT[0]); 00123 akPoint[1] = kLine.Origin() + ( kLineDirection*afT[1]); 00124 return true; 00125 } 00126 } 00127 else 00128 { 00129 if(fA) 00130 { 00131 riQuantity = 1; 00132 afT[0] = -fB/fA; 00133 akPoint[0] = kLine.Origin() + ( kLineDirection*afT[0]); 00134 return true; 00135 } 00136 } 00137 00138 return false; 00139 } 00140 00141 //----------------------------------------------------------------------------------------------------// 00142 00143 // Find the point where a ray intersect a sphere 00144 bool CIntrLinSph::FindRaySphere(const CRay kRay, const CSphere kSphere, int& riQuantity, CVector3 akPoint[2]) 00145 { 00146 float fA = (float) 0.0; 00147 float fInvA = (float) 0.0; 00148 float fB = (float) 0.0; 00149 float fC = (float) 0.0; 00150 float fD = (float) 0.0; 00151 float afT[2];// = (float) 0.0; 00152 float fRoot = (float) 0.0; 00153 CVector3 kDiff, kRayDirection; 00154 00155 // Calc Ray direction 00156 kRayDirection = kRay.Direction() - kRay.Origin(); 00157 // Calc difference between Ray ortigin and sphere center 00158 kDiff = kRay.Origin() - kSphere.Center(); 00159 // Set up quadratic Q(t) = a*t^2 + 2*b*t + c 00160 fA = kRayDirection.SquaredLength(); 00161 fB = kDiff.Dot(kRayDirection); 00162 fC = kDiff.SquaredLength() - kSphere.Radius() * kSphere.Radius(); 00163 fD = fB*fB - fA*fC; 00164 // If D < 0 then no intersection occurs 00165 // if D = 0 then the Ray is tangent to the sphere 00166 // if D > 0 then there are two distinct point 00167 if(fD < (float)0.0) 00168 { 00169 riQuantity = 0; 00170 return false; 00171 } 00172 else if(fD > (float)0.0) 00173 { 00174 fRoot = (float)sqrt(fD); 00175 if(fA) 00176 { 00177 fInvA = ((float)1.0)/fA; 00178 riQuantity = 2; 00179 afT[0] = (-fB - fRoot)*fInvA; 00180 afT[1] = (-fB + fRoot)*fInvA; 00181 if ( afT[0] >= (float)0.0 ) 00182 { 00183 riQuantity = 2; 00184 akPoint[0] = kRay.Origin() + ( kRayDirection*afT[0]); 00185 akPoint[1] = kRay.Origin() + ( kRayDirection*afT[1]); 00186 return true; 00187 } 00188 else if ( afT[1] >= (float)0.0 ) 00189 { 00190 riQuantity = 1; 00191 akPoint[0] = kRay.Origin() + ( kRayDirection*afT[1]); 00192 return true; 00193 } 00194 else 00195 { 00196 riQuantity = 0; 00197 return false; 00198 } 00199 } 00200 } 00201 else 00202 { 00203 if(fA) 00204 { 00205 riQuantity = 1; 00206 afT[0] = -fB/fA; 00207 if ( afT[0] >= (float)0.0 ) 00208 { 00209 riQuantity = 1; 00210 akPoint[0] = kRay.Origin() + ( kRayDirection*afT[0]); 00211 return true; 00212 } 00213 else 00214 { 00215 riQuantity = 0; 00216 return false; 00217 } 00218 } 00219 } 00220 00221 return false; 00222 } 00223 */