float Turret::elevation (float dx, float dy, float dz) { float angle = -m_atan (dx, dy); float newX; newX = (dx * m_cos (angle)) - (dy * m_sin (angle)); return m_atan (-dz, newX) - (M_PI / 2); }
void LensFlare::render(TSRenderContext &rc) { if (!renderDetail) { renderCount = 0; return; } GFXSurface *gfxSurface = rc.getSurface(); if(!visible || !flares.size() || !(gfxSurface->getCaps() & GFX_DEVCAP_SUPPORTS_CONST_ALPHA)) { renderCount = 0; return; } renderCount++; if (obscured && renderCount%15 != 1) // if something was in the way last time we checked LOS, and it isn't time // to check LOS again, bail out early return; TS::PointArray *pointArray = rc.getPointArray(); pointArray->reset(); pointArray->useIntensities(false); pointArray->useTextures(textCoord); pointArray->useTextures(true); pointArray->setVisibility( TS::ClipMask ); pointArray->useHazes(false); gfxSurface->setHazeSource(GFX_HAZE_NONE); gfxSurface->setShadeSource(GFX_SHADE_NONE); gfxSurface->setTransparency(FALSE); gfxSurface->setTexturePerspective(FALSE); gfxSurface->setFillMode(GFX_FILL_TEXTURE); gfxSurface->setTransparency(TRUE); gfxSurface->setAlphaSource(GFX_ALPHA_TEXTURE); TS::VertexIndexPair V[4]; // if it was in the screen, go ahead and draw the lens flare. TSCamera *camera = rc.getCamera(); RectI const &screenVp = camera->getScreenViewport(); const Point2F vpSize(screenVp.lowerR.x - screenVp.upperL.x, screenVp.upperL.y + screenVp.lowerR.y); // preserve relative size of the textures, they should be // 1:1 on a 640x480 viewport Point2F vpScale(vpSize.x/640.0f, vpSize.y/480.0f); float scrSize = min(vpSize.x, vpSize.y); Point2F sunP(sunPosProjected.x, sunPosProjected.y); Point2F delta((screenVp.upperL.x + screenVp.lowerR.x) >> 1, (screenVp.upperL.y + screenVp.lowerR.y) >> 1); // find vector of the flare delta -= sunP; float deltaLen = delta.len(); float deltaFrac = 2.0f*deltaLen / scrSize; float constAlpha = .5f*(1.0f - deltaFrac); if (constAlpha <= 0.0f) { if (renderCount == 1) renderCount = 0; return; } if (root && renderCount%15 == 1) { // do a LOS query, see if anything is in the way SimCollisionInfo collision; SimContainerQuery query; query.id = 0; query.type = SimContainerQuery::DefaultDetail; query.mask = -1; Vector3F v = sunPosWorld - camera->getTCW().p; v.normalizef(); v *= 2.0f; query.box.fMin = camera->getTCW().p + v; query.box.fMax = sunPosWorld; if (root->findLOS(query, &collision, SimCollisionImageQuery::High)) { obscured = true; return; } } obscured = false; gfxSurface->setConstantAlpha(constAlpha); // generate rotated box info float angle; if (delta.x == 0.0f && delta.y == 0.0f) angle = 0.0f; else angle = m_atan(delta.x, delta.y) - M_PI/2.0f; float c = m_cos(angle), s = m_sin(angle); float a = c*(-1.0f) - s*(-1.0f), b = s*(-1.0f) + c*(-1.0f); Point2F rotPoints[4]; rotPoints[0].x = a; rotPoints[0].y = b; rotPoints[1].x = -b; rotPoints[1].y = a; rotPoints[2].x = -a; rotPoints[2].y = -b; rotPoints[3].x = b; rotPoints[3].y = -a; for (int i = 0; i < flares.size(); i++) { const FlareInfo &flare = flares[i]; Point2F flarePos = delta; flarePos *= flare.dist; flarePos += sunP; const GFXBitmap *bitmap = hMaterialList->getMaterial(flare.textureIndex).getTextureMap(); gfxSurface->setTextureMap(bitmap); Point2F dimension(bitmap->width*vpScale.x, bitmap->height*vpScale.y); const float scale = 0.5*(flare.minScale + (1.0f - deltaFrac)*flare.scaleRange); for (int j = 0; j < 4; j++) { Point3F drawPoint; if (flare.rotate) drawPoint.set(rotPoints[j].x*dimension.x, rotPoints[j].y*dimension.y, 0); else drawPoint.set(boxPoints[j][0]*dimension.x, boxPoints[j][1]*dimension.y, 0); drawPoint *= scale; drawPoint += Point3F(flarePos.x, flarePos.y, 1.0); V[j].fVertexIndex = pointArray->addProjectedPoint(drawPoint); V[j].fTextureIndex = j; } pointArray->drawProjectedPoly(4, V, 0); } gfxSurface->setTransparency(FALSE); if(deltaFrac < .3) { pointArray->useTextures(false); gfxSurface->setAlphaSource(GFX_ALPHA_CONSTANT); gfxSurface->setFillMode(GFX_FILL_CONSTANT); gfxSurface->setConstantAlpha(3.3 * (.3 - deltaFrac)); gfxSurface->setFillColor(&color); V[0].fVertexIndex = pointArray->addProjectedPoint(Point3F(screenVp.upperL.x, screenVp.upperL.y, 1.0)); V[1].fVertexIndex = pointArray->addProjectedPoint(Point3F(screenVp.lowerR.x, screenVp.upperL.y, 1.0)); V[2].fVertexIndex = pointArray->addProjectedPoint(Point3F(screenVp.lowerR.x, screenVp.lowerR.y, 1.0)); V[3].fVertexIndex = pointArray->addProjectedPoint(Point3F(screenVp.upperL.x, screenVp.lowerR.y, 1.0)); pointArray->drawProjectedPoly(4, V, 0); } gfxSurface->setAlphaSource(GFX_ALPHA_NONE); }
float Turret::rotation (float dx, float dy) { float angle = m_atan (dx, dy) + (M_PI / 2); return angle; }