00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <tankgraph/TargetRendererImpl.h>
00022 #include <tankgraph/TargetParticleRenderer.h>
00023 #include <target/TargetShield.h>
00024 #include <target/TargetState.h>
00025 #include <target/TargetLife.h>
00026 #include <client/ScorchedClient.h>
00027 #include <graph/ParticleEngine.h>
00028 #include <graph/OptionsDisplay.h>
00029 #include <common/Defines.h>
00030 #include <sky/Hemisphere.h>
00031 #include <weapons/ShieldRound.h>
00032 #include <weapons/ShieldSquare.h>
00033 #include <weapons/Accessory.h>
00034 #include <actions/TankFalling.h>
00035 #include <GLEXT/GLState.h>
00036 #include <GLEXT/GLTexture.h>
00037 #include <image/ImageFactory.h>
00038 #include <GLEXT/GLViewPort.h>
00039 #include <GLEXT/GLCameraFrustum.h>
00040 #include <GLEXT/GLCamera.h>
00041 #include <land/VisibilityPatchGrid.h>
00042
00043 TargetRendererImpl::HighlightType TargetRendererImpl::highlightType_ =
00044 TargetRendererImpl::eNoHighlight;
00045
00046 TargetRendererImpl::TargetRendererImpl(Target *target) :
00047 target_(target),
00048 particleMade_(false), tree_(false), matrixCached_(false),
00049 posX_(0.0f), posY_(0.0f), posZ_(0.0f),
00050 currentVisibilityPatch_(0), patchEpoc_(-1)
00051 {
00052
00053 }
00054
00055 TargetRendererImpl::~TargetRendererImpl()
00056 {
00057 setMovedPatch(0);
00058 }
00059
00060 void TargetRendererImpl::moved()
00061 {
00062 if (VisibilityPatchGrid::instance()->getEpocNumber() == 0) return;
00063
00064 TargetVisibilityPatch *newPatch = 0;
00065 if (target_->getAlive())
00066 {
00067 FixedVector &position = target_->getLife().getTargetPosition();
00068 newPatch = VisibilityPatchGrid::instance()->getTargetVisibilityPatch(
00069 position[0].asInt(), position[1].asInt());
00070 }
00071 setMovedPatch(newPatch);
00072 matrixCached_ = false;
00073 }
00074
00075 void TargetRendererImpl::setMovedPatch(TargetVisibilityPatch *newPatch)
00076 {
00077 float boundingSize = target_->getLife().getFloatBoundingSize();
00078 if (boundingSize > 32.0f)
00079 {
00080 if (newPatch) TargetVisibilityPatch::addLargeTarget(target_);
00081 else TargetVisibilityPatch::removeLargeTarget(target_);
00082
00083 return;
00084 }
00085
00086 if (patchEpoc_ != VisibilityPatchGrid::instance()->getEpocNumber())
00087 {
00088 currentVisibilityPatch_ = 0;
00089 patchEpoc_ = VisibilityPatchGrid::instance()->getEpocNumber();
00090 }
00091 if (newPatch != currentVisibilityPatch_)
00092 {
00093 if (currentVisibilityPatch_)
00094 {
00095 if (!tree_)
00096 {
00097 currentVisibilityPatch_->removeTarget(target_);
00098 if (!target_->getTargetName().empty())
00099 currentVisibilityPatch_->removeTooltip(target_);
00100 }
00101 else
00102 {
00103 currentVisibilityPatch_->removeTree(target_);
00104 }
00105 }
00106 if (newPatch)
00107 {
00108 if (!tree_)
00109 {
00110 newPatch->addTarget(target_);
00111 if (!target_->getTargetName().empty())
00112 newPatch->addTooltip(target_);
00113 }
00114 else
00115 {
00116 newPatch->addTree(target_);
00117 }
00118 }
00119 currentVisibilityPatch_ = newPatch;
00120 }
00121 }
00122
00123 bool TargetRendererImpl::getVisible()
00124 {
00125 if (!currentVisibilityPatch_ || !currentVisibilityPatch_->getVisible()) return false;
00126 if (!target_->getAlive()) return false;
00127
00128 return true;
00129 }
00130
00131 void TargetRendererImpl::drawShield(float shieldHit, float totalTime)
00132 {
00133
00134 static GLTexture *shieldtexture = 0;
00135 static GLTexture *texture = 0;
00136 static GLTexture *texture2 = 0;
00137 static GLTexture *magtexture = 0;
00138 static GLUquadric *obj = 0;
00139 if (!texture)
00140 {
00141 std::string file1 = S3D::getDataFile("data/textures/bordershield/grid2.bmp");
00142 ImageHandle map = ImageFactory::loadImageHandle(file1.c_str(), file1.c_str(), false);
00143 texture = new GLTexture;
00144 texture->create(map, true);
00145
00146 std::string file2 = S3D::getDataFile("data/textures/bordershield/grid22.bmp");
00147 ImageHandle map2 = ImageFactory::loadImageHandle(file2.c_str(), file2.c_str(), false);
00148 texture2 = new GLTexture;
00149 texture2->create(map2, true);
00150
00151 std::string file3 = S3D::getDataFile("data/textures/shield2.bmp");
00152 ImageHandle map3 = ImageFactory::loadImageHandle(file3.c_str(), file3.c_str(), false);
00153 magtexture = new GLTexture;
00154 magtexture->create(map3, true);
00155
00156 std::string file4 = S3D::getDataFile("data/textures/shield.bmp");
00157 std::string file5 = S3D::getDataFile("data/textures/shielda.bmp");
00158 ImageHandle map4 = ImageFactory::loadImageHandle(file4.c_str(), file5.c_str(), false);
00159
00160 shieldtexture = new GLTexture;
00161 shieldtexture->create(map4, true);
00162
00163 obj = gluNewQuadric();
00164 gluQuadricTexture(obj, GL_TRUE);
00165 }
00166
00167
00168 static unsigned int squareListNo = 0;
00169 static unsigned int smallListNo = 0;
00170 static unsigned int smallHalfListNo = 0;
00171 static unsigned int spiralListNo = 0;
00172 GLTexture magTexture;
00173 if (!smallListNo)
00174 {
00175 glNewList(smallListNo = glGenLists(1), GL_COMPILE);
00176 gluSphere(obj, 1.0f, 8, 8);
00177 glEndList();
00178 glNewList(squareListNo = glGenLists(1), GL_COMPILE);
00179 glBegin(GL_QUADS);
00180 glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, 1.0f,-1.0f);
00181 glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, 1.0f,-1.0f);
00182 glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
00183 glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
00184
00185 glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f,-1.0f, 1.0f);
00186 glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f,-1.0f, 1.0f);
00187 glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,-1.0f,-1.0f);
00188 glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,-1.0f,-1.0f);
00189
00190 glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
00191 glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
00192 glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,-1.0f, 1.0f);
00193 glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,-1.0f, 1.0f);
00194
00195 glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f,-1.0f,-1.0f);
00196 glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f,-1.0f,-1.0f);
00197 glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f,-1.0f);
00198 glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f,-1.0f);
00199
00200 glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
00201 glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, 1.0f,-1.0f);
00202 glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,-1.0f,-1.0f);
00203 glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,-1.0f, 1.0f);
00204
00205 glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, 1.0f,-1.0f);
00206 glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
00207 glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,-1.0f, 1.0f);
00208 glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,-1.0f,-1.0f);
00209 glEnd();
00210 glEndList();
00211 glNewList(smallHalfListNo = glGenLists(1), GL_COMPILE);
00212 Hemisphere::draw(1.0f, 1.0f, 10, 10, 6, 0, 10, 10, true);
00213 Hemisphere::draw(1.0f, 1.0f, 10, 10, 6, 0, 10, 10, false);
00214 glEndList();
00215 glNewList(spiralListNo = glGenLists(1), GL_COMPILE);
00216 float height = 0.0f;
00217 float width = 0.0f;
00218 float totalA = 5.0f * PI;
00219 float aInc = PI / 6.0f;
00220 glBegin(GL_QUAD_STRIP);
00221 for (float a=0.0f; a<totalA; a+=aInc)
00222 {
00223 height += 0.05f;
00224 width += 0.05f;
00225 float x = getFastSin(a) * width;
00226 float y = getFastCos(a) * width;
00227 float z = height;
00228 glTexCoord2f(a / totalA, 0.0f);
00229 glVertex3f(x, y, z);
00230 glTexCoord2f(a / totalA, 1.0f);
00231 glVertex3f(x, y, z - 0.4f);
00232 }
00233 glEnd();
00234
00235 height = 0.0f;
00236 width = 0.0f;
00237 glBegin(GL_QUAD_STRIP);
00238 for (float a=0.0f; a<5.0f * PI; a+=PI/6.0f)
00239 {
00240 height += 0.05f;
00241 width += 0.05f;
00242 float x = getFastSin(a) * width;
00243 float y = getFastCos(a) * width;
00244 float z = height;
00245 glTexCoord2f(a / totalA, 0.0f);
00246 glVertex3f(x, y, z - 0.4f);
00247 glTexCoord2f(a / totalA, 1.0f);
00248 glVertex3f(x, y, z);
00249 }
00250 glEnd();
00251 glEndList();
00252 }
00253
00254
00255 Accessory *accessory = target_->getShield().getCurrentShield();
00256 if (!accessory) return;
00257 Shield *shield = (Shield *) accessory->getAction();
00258
00259 GLState state(GLState::BLEND_ON | GLState::TEXTURE_ON);
00260 Vector &position = target_->getLife().getFloatPosition();
00261 Vector &color = shield->getColor();
00262
00263 if (shield->getRound())
00264 {
00265 ShieldRound *round = (ShieldRound *) shield;
00266 if (shield->getShieldType() == Shield::ShieldTypeRoundMag)
00267 {
00268 magtexture->draw();
00269
00270 glDepthMask(GL_FALSE);
00271 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
00272 glColor4f(color[0], color[1], color[2], 0.4f);
00273 glPushMatrix();
00274 glTranslatef(position[0], position[1], position[2] + 1.0f);
00275 float scale = round->getActualRadius().asFloat() / 3.0f;
00276 glScalef(scale, scale, scale);
00277
00278 glRotatef(totalTime * 800.0f, 0.0f, 0.0f, 1.0f);
00279 glCallList(spiralListNo);
00280 glRotatef(120.0f, 0.0f, 0.0f, 1.0f);
00281 glCallList(spiralListNo);
00282 glRotatef(120.0f, 0.0f, 0.0f, 1.0f);
00283 glCallList(spiralListNo);
00284 glPopMatrix();
00285 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00286 glDepthMask(GL_TRUE);
00287 }
00288 else if (round->getHalfShield())
00289 {
00290 texture->draw();
00291 glPushMatrix();
00292 glColor4f(color[0], color[1], color[2], 0.5f + shieldHit);
00293 glTranslatef(position[0], position[1], position[2]);
00294 glScalef(
00295 round->getActualRadius().asFloat(),
00296 round->getActualRadius().asFloat(),
00297 round->getActualRadius().asFloat());
00298 glCallList(smallHalfListNo);
00299 glPopMatrix();
00300 }
00301 else
00302 {
00303 texture->draw();
00304 glPushMatrix();
00305 glColor4f(color[0], color[1], color[2], 0.5f + shieldHit);
00306 glTranslatef(position[0], position[1], position[2]);
00307 glScalef(
00308 round->getActualRadius().asFloat(),
00309 round->getActualRadius().asFloat(),
00310 round->getActualRadius().asFloat());
00311 glCallList(smallListNo);
00312 glPopMatrix();
00313
00314 if (round->getGlow())
00315 {
00316 shieldtexture->draw();
00317 GLCameraFrustum::instance()->drawBilboard(
00318 position,
00319 color,
00320 1.0f - shieldHit,
00321 round->getActualRadius().asFloat() * 0.95f,
00322 round->getActualRadius().asFloat() * 0.95f,
00323 true,
00324 0);
00325 }
00326 }
00327 }
00328 else
00329 {
00330 ShieldSquare *square = (ShieldSquare *) shield;
00331
00332 texture->draw();
00333 glPushMatrix();
00334 glColor4f(color[0], color[1], color[2], 0.5f + shieldHit);
00335 glTranslatef(position[0], position[1], position[2]);
00336 glScalef(
00337 square->getSize()[0].asFloat(),
00338 square->getSize()[1].asFloat(),
00339 square->getSize()[2].asFloat());
00340 glCallList(squareListNo);
00341 glPopMatrix();
00342 }
00343 }
00344
00345 void TargetRendererImpl::drawParachute()
00346 {
00347 static GLuint listNo = 0;
00348 if (!listNo)
00349 {
00350 float a;
00351 glNewList(listNo = glGenLists(1), GL_COMPILE);
00352 glColor3f(1.0f, 1.0f, 1.0f);
00353 glBegin(GL_LINES);
00354 for (a=0.0f; a< 3.14f*2.0f; a+=3.14f / 4.0f)
00355 {
00356 glVertex3f(0.0f, 0.0f, 0.0f);
00357 glVertex3f(sinf(a) * 2.0f, cosf(a) * 2.0f, 2.0f);
00358 }
00359 glEnd();
00360 glBegin(GL_TRIANGLE_FAN);
00361 glVertex3f(0.0f, 0.0f, 3.0f);
00362
00363 glColor3f(0.5f, 0.5f, 0.5f);
00364 for (a=3.14f*2.0f; a> 0.0f; a-=3.14f / 4.0f)
00365 {
00366 glVertex3f(sinf(a) * 2.0f, cosf(a) * 2.0f, 2.0f);
00367 }
00368 glEnd();
00369 glEndList();
00370 }
00371
00372
00373 if (!target_->getTargetState().getFalling()) return;
00374
00375
00376 if (!target_->getTargetState().getFalling()->getParachute())
00377 {
00378 return;
00379 }
00380
00381 Vector &position = target_->getLife().getFloatPosition();
00382 GLState state(GLState::TEXTURE_OFF);
00383 glPushMatrix();
00384 glTranslatef(position[0], position[1], position[2]);
00385 glCallList(listNo);
00386 glPopMatrix();
00387 }
00388
00389 void TargetRendererImpl::createParticle()
00390 {
00391
00392
00393
00394 if (particleMade_) return;
00395
00396
00397
00398 if (target_->isTarget())
00399 {
00400 if (!target_->getShield().getCurrentShield() &&
00401 (tree_ || !target_->getTargetState().getFalling()))
00402 {
00403 return;
00404 }
00405 }
00406
00407
00408 {
00409
00410
00411
00412
00413 Particle *particle =
00414 ScorchedClient::instance()->getParticleEngine().
00415 getNextAliveParticle();
00416 if (particle)
00417 {
00418 particle->setParticle(
00419 1000.0f, 1.0f, 1.0f,
00420 Vector::getNullVector(), Vector::getNullVector(),
00421 Vector::getNullVector(), Vector::getNullVector(),
00422 Vector::getNullVector(), Vector::getNullVector(),
00423 1.0f, 0.0f,
00424 false,
00425 false);
00426
00427 particleMade_ = true;
00428 particle->life_ = 1000.0f;
00429 particle->renderer_ = TargetParticleRenderer::getInstance();
00430 particle->userData_ = new TargetParticleUserData(target_->getPlayerId());
00431 }
00432 }
00433 }
00434
00435 float TargetRendererImpl::getTargetSize()
00436 {
00437
00438 float targetSize = target_->getLife().getFloatBoundingSize();
00439 float shieldSize = target_->getShield().getShieldBoundingSize().asFloat();
00440 float size = MAX(targetSize, shieldSize);
00441 return size;
00442 }
00443
00444 float TargetRendererImpl::getTargetFade(float distance, float size)
00445 {
00446
00447 float drawCullingDistance = OptionsDisplay::instance()->getDrawCullingDistance() * size;
00448 float drawFadeStartDistance = OptionsDisplay::instance()->getDrawFadeStartDistance();
00449 float drawFadeDistance = drawCullingDistance - drawFadeStartDistance;
00450 float fade = 1.0f;
00451 if (distance > drawFadeStartDistance)
00452 {
00453 fade = 1.0f - ((distance - drawFadeStartDistance) / drawFadeDistance);
00454 }
00455
00456 return fade;
00457 }
00458
00459 void TargetRendererImpl::storeTarget2DPos()
00460 {
00461 if (target_->getTargetName().empty()) return;
00462
00463 Vector &tankTurretPos =
00464 target_->getLife().getFloatCenterPosition();
00465 Vector camDir =
00466 GLCamera::getCurrentCamera()->getLookAt() -
00467 GLCamera::getCurrentCamera()->getCurrentPos();
00468 Vector tankDir = tankTurretPos -
00469 GLCamera::getCurrentCamera()->getCurrentPos();
00470
00471 if (camDir.dotP(tankDir) < 0.0f)
00472 {
00473 posX_ = - 1000.0;
00474 }
00475 else
00476 {
00477 static GLdouble modelMatrix[16];
00478 static GLdouble projMatrix[16];
00479 static GLint viewport[4];
00480
00481 glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
00482 glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
00483 glGetIntegerv(GL_VIEWPORT, viewport);
00484
00485 viewport[2] = GLViewPort::getWidth();
00486 viewport[3] = GLViewPort::getHeight();
00487 int result = gluProject(
00488 tankTurretPos[0],
00489 tankTurretPos[1],
00490 tankTurretPos[2],
00491 modelMatrix, projMatrix, viewport,
00492 &posX_,
00493 &posY_,
00494 &posZ_);
00495 }
00496 }