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