K3dIntersection.cpp

Go to the documentation of this file.
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 "K3dIntersection.h"
00034 
00035 
00036 K3dIntersection::K3dIntersection(K3dGameData *_pGameData):
00037         K3dIntrLinSph(_pGameData)
00038 {
00039         m_pGameData = _pGameData;
00040         // Set this pointer to the game data
00041         m_pGameData->SetIntersection(this);
00042         m_pTrianglePlane = NULL;
00043 }
00044 
00045 K3dIntersection::~K3dIntersection(void)
00046 {
00047 }
00048 
00049 
00050 
00051 // Find the point where a ray intersect a plane
00052 bool K3dIntersection::RayPlane(const K3dRay &_rkRay, const K3dPlane &_rkPlane, K3dVector3Obj &_rkIPoint)
00053 {
00054         K3dVector3 kOrigin;
00055         float fOrigin;
00056         K3dVector3Obj kDirection;
00057         float fDirection;
00058         float fValue;
00059         K3dVector3Obj kRayDirection;
00060         K3dVector3 kPlaneDistance;
00061         K3dVector3 kSign;
00062         float fSign;
00063 
00064         // Calculate distance plane and ray origin point
00065         int iDistOrigin = (int) PointPlane(_rkPlane, *_rkRay.GetOrigin());
00066         // Calculate distance plane and ray direction point
00067         int iDistDirection = (int) PointPlane(_rkPlane, *_rkRay.GetDirection());
00068 
00069         // If sign of origin and direction is equal then return false
00070         // Ray direction outside of plane
00071         if(K3dMath::Sign(iDistOrigin) == K3dMath::Sign(iDistDirection))
00072         {
00073                 return false;
00074         }
00075 
00076         // Calc origin
00077         //fOrigin = kOrigin.Dot(*_rkPlane.GetNormal(), *_rkRay.GetOrigin());
00078         fOrigin = m_pGameData->GetVector3Work()->Dot(*_rkPlane.GetNormal(), *_rkRay.GetOrigin());
00079         fOrigin -= _rkPlane.GetDistance();
00080         
00081         // Calc Direction
00082         kRayDirection = *_rkRay.GetDirection() - *_rkRay.GetOrigin();
00083         //fDirection = kDirection.Dot(*_rkPlane.GetNormal(), kRayDirection);
00084         fDirection = m_pGameData->GetVector3Work()->Dot(*_rkPlane.GetNormal(), kRayDirection);
00085         
00086         // If direction is not zero then the Ray intersect the plane
00087         if(fDirection)
00088         {
00089                 // Calc sign plane Ray normal vector
00090                 //fSign = kSign.Dot(*_rkPlane.GetNormal(), *_rkRay.GetDirection());
00091                 fSign = m_pGameData->GetVector3Work()->Dot(*_rkPlane.GetNormal(), *_rkRay.GetDirection());
00092                 // If sign less zero, than no intersection
00093                 if(fSign < (float)0)
00094                 {
00095                         return false;
00096                 }
00097                 // Calculate t value
00098                 fValue = -fOrigin/fDirection; 
00099                 // Calculate point
00100                 _rkIPoint = *_rkRay.GetOrigin() + (kRayDirection * fValue);
00101                 return true;
00102         }
00103 
00104         _rkIPoint.Reset();
00105         return false;
00106 }
00107 
00108 
00109 // Find the point where a line intersect a triangle
00110 bool K3dIntersection::LineTriangle(const K3dRay &_rkEdge, const K3dTriangle &_rkTriangle)
00111 {
00112         K3dVector3Obj kE, kF, kG, kNE;
00113         float fDotF = 0.0f;
00114         float fDotG = 0.0f;
00115         float fResult = -1.0f;
00116         bool bInter = false;
00117 
00118         kE.Reset();
00119         kF.Reset();
00120         kG.Reset();
00121         kNE.Reset();
00122 //      rkIPoint.Reset();
00123 
00124         // Set triangle plane
00125         m_pGameData->GetPlaneWork()->CalcPlane(m_pTrianglePlane, *_rkTriangle.GetVertex(0), *_rkTriangle.GetNormal());
00126         // Calc intersection line and plane
00127         bInter = LinePlane(_rkEdge, *m_pTrianglePlane); 
00128 
00129         // If line and plane is parallel
00130         if(!bInter)
00131         {
00132                 return false;
00133         }
00134 
00135         // Go through all triangle edges
00136         for(int i=0; i<3; i++)
00137         {
00138                 // Calc 2D differences by formula
00139                 // E = P(i+1 mod 3) - P(i)
00140                 // F = P(i+2 mod 3) - P(i)
00141                 // G = P - P(i)
00142                 // Compute 2D differences
00143                 kE = *_rkTriangle.GetVertex((i+1)%3) - *_rkTriangle.GetVertex(i);  
00144                 kF = *_rkTriangle.GetVertex((i+2)%3) - *_rkTriangle.GetVertex(i);
00145                 kG = GetIntrPoint() - *_rkTriangle.GetVertex(i); 
00146 
00147                 // If rotate vector E about 90 degree (which direction is not important), 
00148                 // we can create a 2D normal vector to the edge E
00149                 kNE[0] = -kE[1];
00150                 kNE[1] = kE[0];
00151                 kNE = m_pGameData->GetVector3Work()->Normalize(kNE);
00152 
00153                 // If formula
00154                 // (Ne . F)(Ne . G) >= 0
00155                 // then point P lies inside the triangle
00156                 fDotF = m_pGameData->GetVector3Work()->Dot(kF, kNE);
00157                 fDotG = m_pGameData->GetVector3Work()->Dot(kG, kNE);
00158                 fResult = fDotF * fDotG;
00159                 if(fResult < 0)
00160                 {
00161                         return false;
00162                 }
00163         }
00164 
00165         return true;
00166 }
00167 
00168 // Find the point where a ray intersect a triangle
00169 bool K3dIntersection::RayTriangle(const K3dRay &_rkRay, const K3dTriangle &_rkTriangle, K3dVector3Obj &_rkIPoint)
00170 {
00171         K3dVector3Obj kE, kF, kG, kNE;
00172         float fDotF = 0.0f;
00173         float fDotG = 0.0f;
00174         float fResult = -1.0f;
00175         bool bInter = false;
00176 
00177 
00178         kE.Reset();
00179         kF.Reset();
00180         kG.Reset();
00181         kNE.Reset();
00182 
00183         // Set triangle plane
00184         m_pGameData->GetPlaneWork()->CalcPlane(m_pTrianglePlane, *_rkTriangle.GetVertex(0), *_rkTriangle.GetNormal());
00185         // Calc intersection ray and plane
00186         bInter = RayPlane(_rkRay, *m_pTrianglePlane, _rkIPoint);
00187         // Calc 2D differences by formula
00188         // E = P(i+1 mod 3) - P(i)
00189         // F = P(i+2 mod 3) - P(i)
00190         // G = P - P(i)
00191 
00192         // If Ray and plane is parallel
00193         if(!bInter)
00194         {
00195                 return false;
00196         }
00197 
00198         // Go through all triangle edges
00199         for(int i=0; i<3; i++)
00200         {
00201                 // Compute 2D differences
00202                 kE = *_rkTriangle.GetVertex((i+1)%3) - *_rkTriangle.GetVertex(i);  
00203                 kF = *_rkTriangle.GetVertex((i+2)%3) - *_rkTriangle.GetVertex(i);
00204                 kG = _rkIPoint - *_rkTriangle.GetVertex(i); 
00205 
00206                 // If rotate vector E about 90 degree (which direction is not important), 
00207                 // we can create a 2D normal vector to the edge E
00208                 kNE[0] = -kE[1];
00209                 kNE[1] = kE[0];
00210                 kNE = m_pGameData->GetVector3Work()->Normalize(kNE);
00211 
00212                 // If formula
00213                 // (Ne . F)(Ne . G) >= 0
00214                 // then point P lies inside the triangle
00215                 fDotF = m_pGameData->GetVector3Work()->Dot(kF, kNE);
00216                 fDotG = m_pGameData->GetVector3Work()->Dot(kG, kNE);
00217                 fResult = fDotF * fDotG;
00218                 if(fResult < 0)
00219                 {
00220                         return false;
00221                 }
00222         }
00223 
00224         return true;
00225 }

Generated on Thu Aug 16 23:53:27 2007 for K3dEngine by  doxygen 1.5.0