00001 /**************************************************************************** 00002 00003 This file is part of the GLC-lib library. 00004 Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net) 00005 Version 2.0.0 Beta 1, packaged on April 2010. 00006 00007 http://glc-lib.sourceforge.net 00008 00009 GLC-lib is free software; you can redistribute it and/or modify 00010 it under the terms of the GNU General Public License as published by 00011 the Free Software Foundation; either version 2 of the License, or 00012 (at your option) any later version. 00013 00014 GLC-lib is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 GNU General Public License for more details. 00018 00019 You should have received a copy of the GNU General Public License 00020 along with GLC-lib; if not, write to the Free Software 00021 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00022 00023 *****************************************************************************/ 00025 00026 #include "glc_frustum.h" 00027 #include "glc_viewport.h" 00028 00029 // Default constructor 00030 GLC_Frustum::GLC_Frustum() 00031 : m_PlaneList() 00032 , m_PreviousMatrix() 00033 { 00034 for (int i= 0; i < 6; ++i) 00035 { 00036 m_PlaneList.append(GLC_Plane()); 00037 } 00038 } 00039 00040 // Copy constructor 00041 GLC_Frustum::GLC_Frustum(const GLC_Frustum& frustum) 00042 : m_PlaneList(frustum.m_PlaneList) 00043 , m_PreviousMatrix(frustum.m_PreviousMatrix) 00044 { 00045 00046 } 00047 00048 GLC_Frustum::~GLC_Frustum() 00049 { 00050 00051 } 00052 00053 // Localize bounding box 00054 GLC_Frustum::Localisation GLC_Frustum::localizeBoundingBox(const GLC_BoundingBox& box) const 00055 { 00056 const GLC_Point3d center= box.center(); 00057 const double radius= box.boundingSphereRadius(); 00058 00059 return localizeSphere(center, radius); 00060 } 00061 00062 // Localize sphere 00063 GLC_Frustum::Localisation GLC_Frustum::localizeSphere(const GLC_Point3d& center, double radius) const 00064 { 00065 GLC_Frustum::Localisation localisationResult= InFrustum; 00066 00067 int i= 0; 00068 bool continu= true; 00069 while (continu && (i < 6)) 00070 { 00071 //qDebug() << "Localisation of plane " << i; 00072 localisationResult= static_cast<GLC_Frustum::Localisation>(localisationResult | localizeSphereToPlane(center, radius, m_PlaneList.at(i))); 00073 continu= (localisationResult != GLC_Frustum::OutFrustum); 00074 ++i; 00075 } 00076 00077 return localisationResult; 00078 } 00079 00080 // localize a bounding box to a plane 00081 GLC_Frustum::Localisation GLC_Frustum::localizeSphereToPlane(const GLC_Point3d& center, double radius, const GLC_Plane& plane) const 00082 { 00083 GLC_Frustum::Localisation localisationResult; 00084 const double signedDistance= plane.distanceToPoint(center); 00085 const double distance= fabs(signedDistance); 00086 //qDebug() << "radius " << radius; 00087 //qDebug() << "signed Distance " << signedDistance; 00088 if (distance > radius) 00089 { 00090 if (signedDistance > 0) localisationResult= GLC_Frustum::InFrustum; 00091 else localisationResult= GLC_Frustum::OutFrustum; 00092 } 00093 else 00094 { 00095 localisationResult= GLC_Frustum::IntersectFrustum; 00096 } 00097 00098 return localisationResult; 00099 } 00100 00101 // Update the frustum 00102 bool GLC_Frustum::update(const GLC_Matrix4x4& compMatrix) 00103 { 00104 00105 // Test if the frustum change 00106 if (compMatrix == m_PreviousMatrix) 00107 { 00108 //qDebug() << "No change in frustum"; 00109 return false; 00110 } 00111 else 00112 { 00113 //qDebug() << "-------------CHANGE---------------"; 00114 m_PreviousMatrix= compMatrix; 00115 // Left plane 00116 m_PlaneList[LeftPlane].setA(compMatrix.data()[3] + compMatrix.data()[0]); 00117 m_PlaneList[LeftPlane].setB(compMatrix.data()[7] + compMatrix.data()[4]); 00118 m_PlaneList[LeftPlane].setC(compMatrix.data()[11] + compMatrix.data()[8]); 00119 m_PlaneList[LeftPlane].setD(compMatrix.data()[15] + compMatrix.data()[12]); 00120 m_PlaneList[LeftPlane].normalize(); 00121 //qDebug() << "Left Plane : x=" << m_PlaneList[LeftPlane].coefA() << " y=" << m_PlaneList[LeftPlane].coefB() << " z=" << m_PlaneList[LeftPlane].coefC(); 00122 //qDebug() << "Left plane coef d=" << m_PlaneList[LeftPlane].coefD(); 00123 00124 // Right plane 00125 m_PlaneList[RightPlane].setA(compMatrix.data()[3] - compMatrix.data()[0]); 00126 m_PlaneList[RightPlane].setB(compMatrix.data()[7] - compMatrix.data()[4]); 00127 m_PlaneList[RightPlane].setC(compMatrix.data()[11] - compMatrix.data()[8]); 00128 m_PlaneList[RightPlane].setD(compMatrix.data()[15] - compMatrix.data()[12]); 00129 m_PlaneList[RightPlane].normalize(); 00130 //qDebug() << "Right Plane : x=" << m_PlaneList[RightPlane].coefA() << " y=" << m_PlaneList[RightPlane].coefB() << " z=" << m_PlaneList[RightPlane].coefC(); 00131 //qDebug() << "Right plane coef d=" << m_PlaneList[RightPlane].coefD(); 00132 00133 //Top plane 00134 m_PlaneList[TopPlane].setA(compMatrix.data()[3] + compMatrix.data()[1]); 00135 m_PlaneList[TopPlane].setB(compMatrix.data()[7] + compMatrix.data()[5]); 00136 m_PlaneList[TopPlane].setC(compMatrix.data()[11] + compMatrix.data()[9]); 00137 m_PlaneList[TopPlane].setD(compMatrix.data()[15] + compMatrix.data()[13]); 00138 m_PlaneList[TopPlane].normalize(); 00139 //qDebug() << "Top Plane : x=" << m_PlaneList[TopPlane].coefA() << " y=" << m_PlaneList[TopPlane].coefB() << " z=" << m_PlaneList[TopPlane].coefC(); 00140 //qDebug() << "Top plane coef d=" << m_PlaneList[TopPlane].coefD(); 00141 00142 //Bottom plane 00143 m_PlaneList[BottomPlane].setA(compMatrix.data()[3] - compMatrix.data()[1]); 00144 m_PlaneList[BottomPlane].setB(compMatrix.data()[7] - compMatrix.data()[5]); 00145 m_PlaneList[BottomPlane].setC(compMatrix.data()[11] - compMatrix.data()[9]); 00146 m_PlaneList[BottomPlane].setD(compMatrix.data()[15] - compMatrix.data()[13]); 00147 m_PlaneList[BottomPlane].normalize(); 00148 //qDebug() << "Bottom Plane : x=" << m_PlaneList[BottomPlane].coefA() << " y=" << m_PlaneList[BottomPlane].coefB() << " z=" << m_PlaneList[BottomPlane].coefC(); 00149 //qDebug() << "Bottom plane coef d=" << m_PlaneList[BottomPlane].coefD(); 00150 00151 //Near plane 00152 m_PlaneList[NearPlane].setA(compMatrix.data()[3] + compMatrix.data()[2]); 00153 m_PlaneList[NearPlane].setB(compMatrix.data()[7] + compMatrix.data()[6]); 00154 m_PlaneList[NearPlane].setC(compMatrix.data()[11] + compMatrix.data()[10]); 00155 m_PlaneList[NearPlane].setD(compMatrix.data()[15] + compMatrix.data()[14]); 00156 m_PlaneList[NearPlane].normalize(); 00157 00158 //Far plane 00159 m_PlaneList[FarPlane].setA(compMatrix.data()[3] - compMatrix.data()[2]); 00160 m_PlaneList[FarPlane].setB(compMatrix.data()[7] - compMatrix.data()[6]); 00161 m_PlaneList[FarPlane].setC(compMatrix.data()[11] - compMatrix.data()[10]); 00162 m_PlaneList[FarPlane].setD(compMatrix.data()[15] - compMatrix.data()[14]); 00163 m_PlaneList[FarPlane].normalize(); 00164 return true; 00165 } 00166 00167 }