VisibilityPatchQuad.cpp

Go to the documentation of this file.
00001 ////////////////////////////////////////////////////////////////////////////////
00002 //    Scorched3D (c) 2000-2009
00003 //
00004 //    This file is part of Scorched3D.
00005 //
00006 //    Scorched3D is free software; you can redistribute it and/or modify
00007 //    it under the terms of the GNU General Public License as published by
00008 //    the Free Software Foundation; either version 2 of the License, or
00009 //    (at your option) any later version.
00010 //
00011 //    Scorched3D is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //    GNU General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU General Public License
00017 //    along with Scorched3D; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 ////////////////////////////////////////////////////////////////////////////////
00020 
00021 #include <land/VisibilityPatchQuad.h>
00022 #include <land/VisibilityPatchGrid.h>
00023 #include <GLEXT/GLCameraFrustum.h>
00024 
00025 VisibilityPatchQuad::VisibilityPatchQuad() :
00026         topLeft_(0), topRight_(0),
00027         botLeft_(0), botRight_(0),
00028         landVisibilityPatch_(0),
00029         waterVisibilityPatch_(0),
00030         targetVisibilityPatch_(0)
00031 {
00032 }
00033 
00034 VisibilityPatchQuad::~VisibilityPatchQuad()
00035 {
00036         delete topLeft_; delete topRight_;
00037         delete botLeft_; delete botRight_;
00038 }
00039 
00040 void VisibilityPatchQuad::setLocation(VisibilityPatchGrid *patchGrid, int x, int y, int size,
00041         int mapwidth, int mapheight)
00042 {
00043         x_ = x; y_ = y; size_ = size;
00044         position_ = Vector(x_ + size_ / 2, y_ + size_ / 2);
00045 
00046         if (size > 32)
00047         {
00048                 topLeft_ = new VisibilityPatchQuad();
00049                 topRight_ = new VisibilityPatchQuad();
00050                 botLeft_ = new VisibilityPatchQuad();
00051                 botRight_ = new VisibilityPatchQuad();
00052 
00053                 topLeft_->setLocation(patchGrid, x, y, size / 2, mapwidth, mapheight);
00054                 topRight_->setLocation(patchGrid, x + size / 2, y, size / 2, mapwidth, mapheight);
00055                 botLeft_->setLocation(patchGrid, x, y + size / 2, size / 2, mapwidth, mapheight);
00056                 botRight_->setLocation(patchGrid, x + size / 2, y + size / 2, size / 2, mapwidth, mapheight);
00057         }
00058 
00059         if (size == 32)
00060         {
00061                 if ((x + size_) > 0 && 
00062                         (y + size_) > 0 &&
00063                         x < mapwidth && y < mapheight) 
00064                 {
00065                         // Land
00066                         landVisibilityPatch_ = patchGrid->getLandVisibilityPatch(x, y);
00067                 }
00068                 // Targets
00069                 targetVisibilityPatch_ = patchGrid->getTargetVisibilityPatch(x, y);
00070         }
00071         else if (size == 128)
00072         {
00073                 // Water
00074                 waterVisibilityPatch_ = patchGrid->getWaterVisibilityPatch(x, y);
00075         }
00076 }
00077 
00078 void VisibilityPatchQuad::setNotVisible(VisibilityPatchInfo &patchInfo, Vector &cameraPos)
00079 {
00080         if (landVisibilityPatch_) landVisibilityPatch_->setNotVisible();
00081         if (targetVisibilityPatch_) targetVisibilityPatch_->setNotVisible();
00082         if (waterVisibilityPatch_) waterVisibilityPatch_->setNotVisible();
00083 
00084         // Update Children
00085         if (topLeft_) topLeft_->setNotVisible(patchInfo, cameraPos);
00086         if (topRight_) topRight_->setNotVisible(patchInfo, cameraPos);
00087         if (botLeft_) botLeft_->setNotVisible(patchInfo, cameraPos);
00088         if (botRight_) botRight_->setNotVisible(patchInfo, cameraPos);
00089 }
00090 
00091 void VisibilityPatchQuad::setVisible(VisibilityPatchInfo &patchInfo, Vector &cameraPos)
00092 {
00093         if (landVisibilityPatch_)
00094         {
00095                 float distance = (cameraPos - landVisibilityPatch_->getPosition()).Magnitude();
00096                 if (landVisibilityPatch_->setVisible(distance))
00097                 {
00098                         patchInfo.getLandVisibility().add(landVisibilityPatch_);
00099                 }
00100         }
00101         if (targetVisibilityPatch_)
00102         {
00103                 if (targetVisibilityPatch_->hasTargets() ||
00104                         targetVisibilityPatch_->hasTrees())
00105                 {
00106                         float distance = (cameraPos - targetVisibilityPatch_->getPosition()).Magnitude();
00107                         if (targetVisibilityPatch_->setVisible(distance))
00108                         {
00109                                 if (targetVisibilityPatch_->hasTargets()) 
00110                                 {
00111                                         patchInfo.getTargetVisibility().add(targetVisibilityPatch_);
00112                                 }
00113                                 if (targetVisibilityPatch_->hasTrees()) 
00114                                 {
00115                                         patchInfo.getTreeVisibility().add(targetVisibilityPatch_);
00116                                 }
00117                         }
00118                 }
00119         }
00120 
00121         if (waterVisibilityPatch_)
00122         {
00123                 if (waterVisibilityPatch_->setVisible(cameraPos))
00124                 {
00125                         patchInfo.getWaterVisibility(waterVisibilityPatch_->getPatchIndex()).add(waterVisibilityPatch_);
00126                 }
00127         }
00128 
00129         // Update Children
00130         if (topLeft_) topLeft_->calculateVisibility(patchInfo, cameraPos);
00131         if (topRight_) topRight_->calculateVisibility(patchInfo, cameraPos);
00132         if (botLeft_) botLeft_->calculateVisibility(patchInfo, cameraPos);
00133         if (botRight_) botRight_->calculateVisibility(patchInfo, cameraPos);    
00134 }
00135 
00136 void VisibilityPatchQuad::calculateVisibility(VisibilityPatchInfo &patchInfo, Vector &cameraPos)
00137 {
00138         Vector *position = &position_;
00139         float size = float(size_);
00140         if (landVisibilityPatch_)
00141         {
00142                 position = &landVisibilityPatch_->getPosition();
00143                 size = landVisibilityPatch_->getBoundingSize();
00144         }
00145 
00146         bool visible = true;
00147         if (size_ == 32 || size_ == 128 || size_ == 512)
00148         {
00149                 visible = GLCameraFrustum::instance()->sphereInFrustum(*position, size);
00150         }
00151 
00152         if (!visible)
00153         {
00154                 setNotVisible(patchInfo, cameraPos);
00155         }
00156         else
00157         {
00158                 setVisible(patchInfo, cameraPos);
00159         }
00160 }

Generated on Mon Feb 16 15:14:47 2009 for Scorched3D by  doxygen 1.5.3