00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
00066 landVisibilityPatch_ = patchGrid->getLandVisibilityPatch(x, y);
00067 }
00068
00069 targetVisibilityPatch_ = patchGrid->getTargetVisibilityPatch(x, y);
00070 }
00071 else if (size == 128)
00072 {
00073
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
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
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 }