static inline void d3d_GetSpriteColor(LTObject *pObject, RGBColor *pColor) { LTVector dynamicLightAdd, color; LTRGBColor theColor; pColor->rgb.a = (uint8)pObject->m_ColorA; if((pObject->m_Flags & FLAG_NOLIGHT) || !g_have_world || (!g_CV_DynamicLightSprites.m_Val)) { // Default case if the other stuff doesn't work. pColor->rgb.r = pObject->m_ColorR; pColor->rgb.g = pObject->m_ColorG; pColor->rgb.b = pObject->m_ColorB; } else { w_DoLightLookup(world_bsp_shared->LightTable(), &pObject->GetPos(), &theColor); d3d_CalcLightAdd(pObject, &dynamicLightAdd); color.x = (float)pObject->m_ColorR + (float)theColor.rgb.r + dynamicLightAdd.x; color.x = LTCLAMP(color.x, 0.0f, 255.0f); color.y = (float)pObject->m_ColorG + (float)theColor.rgb.g + dynamicLightAdd.y; color.y = LTCLAMP(color.y, 0.0f, 255.0f); color.z = (float)pObject->m_ColorB + (float)theColor.rgb.b + dynamicLightAdd.z; color.z = LTCLAMP(color.z, 0.0f, 255.0f); pColor->rgb.r = (uint8)RoundFloatToInt(color.x); pColor->rgb.g = (uint8)RoundFloatToInt(color.y); pColor->rgb.b = (uint8)RoundFloatToInt(color.z); } }
void CGroundLine::Paint( ) { vgui::Panel *pPanel = GetParent(); int wide, tall; pPanel->GetSize( wide, tall ); float tPrev = 0; float xPrev, yPrev; CMinimapPanel::MinimapPanel()->WorldToMinimap( MINIMAP_NOCLIP, m_vStart, xPrev, yPrev ); int nSegs = 20; for( int iSeg=1; iSeg <= nSegs; iSeg++ ) { float t = (float)iSeg / nSegs; Vector v3DPos; VectorLerp( m_vStart, m_vEnd, t, v3DPos ); float x, y; CMinimapPanel::MinimapPanel()->WorldToMinimap( MINIMAP_NOCLIP, v3DPos, x, y ); // Clip the line segment on X, then Y. if( ClipLine( xPrev, yPrev, x, y, 0, 1 ) && ClipLine( xPrev, yPrev, x, y, wide, -1 ) && ClipLine( yPrev, xPrev, y, x, 0, 1 ) && ClipLine( yPrev, xPrev, y, x, tall, -1 ) ) { Vector vColor; VectorLerp( m_vStartColor, m_vEndColor, t, vColor ); vColor *= 255.9f; vgui::surface()->DrawSetColor( (unsigned char)RoundFloatToInt( vColor.x ), (unsigned char)RoundFloatToInt( vColor.y ), (unsigned char)RoundFloatToInt( vColor.z ), 255 ); vgui::surface()->DrawLine( xPrev, yPrev, x, y ); } tPrev = t; xPrev = x; yPrev = y; } // Draw a marker at the endpoint. float xEnd, yEnd; if( CMinimapPanel::MinimapPanel()->WorldToMinimap( MINIMAP_NOCLIP, m_vEnd, xEnd, yEnd ) ) { int ix = RoundFloatToInt( xEnd ); int iy = RoundFloatToInt( yEnd ); int rectSize=1; vgui::surface()->DrawSetColor( 255, 255, 255, 255 ); vgui::surface()->DrawOutlinedRect( ix-rectSize, iy-rectSize, ix+rectSize, iy+rectSize ); } }
void DrawRectangle(int x_in, int y_in, int width, int height, Framebuffer fbo, Vector4 color) { if(x_in > fbo.width) width = 0; if((x_in + width) > fbo.width) width = fbo.width - x_in; if(y_in > fbo.height) height = 0; if((y_in + height) > fbo.height) height = fbo.height - y_in; if(x_in < 0) { width = width + x_in; x_in = 0; } if((x_in + width) < 0) width = 0; if(y_in < 0) { height = height + y_in; y_in = 0; } if((y_in + height) < 0) height = 0; for (int x = x_in; x < (x_in + width); x++) { for(int y = y_in; y < (y_in + height); y++) { uint32_t old_color = *(fbo.pixels + (y * fbo.width) + x); float oldr = ((float)((old_color & 0x00FF0000) >> 16)) / 255.0f; float oldg = ((float)((old_color & 0x0000FF00) >> 8)) / 255.0f; float oldb = ((float)((old_color & 0x000000FF) >> 0)) / 255.0f; float newr = color.a * color.r + (1 - color.a) * oldr; float newg = color.a * color.g + (1 - color.a) * oldg; float newb = color.a * color.b + (1 - color.a) * oldb; uint32_t color32 = (RoundFloatToInt(color.a * 255) < 24) | (RoundFloatToInt(newr * 255) << 16) | (RoundFloatToInt(newg * 255) << 8) | (RoundFloatToInt(newb * 255) << 0); *(fbo.pixels + (y * fbo.width) + x) = color32; } } }
// Render a quad on the screen where you pass in color and size. // Normal is random and "flutters" inline void RenderParticle_ColorSizePerturbNormal( ParticleDraw* pDraw, const Vector &pos, const Vector &color, const float alpha, const float size ) { // Don't render totally transparent particles. if( alpha < 0.001f ) return; CMeshBuilder *pBuilder = pDraw->GetMeshBuilder(); if( !pBuilder ) return; unsigned char ubColor[4]; ubColor[0] = (unsigned char)RoundFloatToInt( color.x * 254.9f ); ubColor[1] = (unsigned char)RoundFloatToInt( color.y * 254.9f ); ubColor[2] = (unsigned char)RoundFloatToInt( color.z * 254.9f ); ubColor[3] = (unsigned char)RoundFloatToInt( alpha * 254.9f ); Vector vNorm; vNorm.Random( -1.0f, 1.0f ); // Add the 4 corner vertices. pBuilder->Position3f( pos.x-size, pos.y-size, pos.z ); pBuilder->Color4ubv( ubColor ); pBuilder->Normal3fv( vNorm.Base() ); pBuilder->TexCoord2f( 0, 0, 1.0f ); pBuilder->AdvanceVertex(); pBuilder->Position3f( pos.x-size, pos.y+size, pos.z ); pBuilder->Color4ubv( ubColor ); pBuilder->Normal3fv( vNorm.Base() ); pBuilder->TexCoord2f( 0, 0, 0 ); pBuilder->AdvanceVertex(); pBuilder->Position3f( pos.x+size, pos.y+size, pos.z ); pBuilder->Color4ubv( ubColor ); pBuilder->Normal3fv( vNorm.Base() ); pBuilder->TexCoord2f( 0, 1.0f, 0 ); pBuilder->AdvanceVertex(); pBuilder->Position3f( pos.x+size, pos.y-size, pos.z ); pBuilder->Color4ubv( ubColor ); pBuilder->Normal3fv( vNorm.Base() ); pBuilder->TexCoord2f( 0, 1.0f, 1.0f ); pBuilder->AdvanceVertex(); }
void DmeFramerate_t::SetFramerate( float flFrameRate ) { if ( IsIntegralValue( flFrameRate ) ) { SetFramerate( RoundFloatToInt( flFrameRate ) ); } else if ( IsIntegralValue( flFrameRate * 1001.0f / 1000.0f ) ) // 1001 is the ntsc divisor (30*1000/1001 = 29.97, etc) { SetFramerateNTSC( RoundFloatToInt( flFrameRate * 1001.0f / 1000.0f ) ); } else { Assert( 0 ); SetFramerate( RoundFloatToInt( flFrameRate ) ); } }
//----------------------------------------------------------------------------- // Purpose: Input handler for changing volume. // Input : Float new volume, from 0 - 10. //----------------------------------------------------------------------------- void CAmbientGeneric::InputVolume( inputdata_t &inputdata ) { // // Multiply the input value by ten since volumes are expected to be from 0 - 100. // m_dpv.vol = clamp( RoundFloatToInt( inputdata.value.Float() * 10.f ), 0, 100 ); m_dpv.volfrac = m_dpv.vol << 8; SendSound( SND_CHANGE_VOL ); }
float LinearToGamma( float linear ) { Assert( s_bMathlibInitialized ); if ( linear < 0.0f ) { return 0.0f; } if ( linear > 1.0f ) { // Use LinearToGammaFullRange maybe if you trip this. Assert( 0 ); return 1.0f; } int index = RoundFloatToInt( linear * 255.0f ); Assert( index >= 0 && index < 256 ); return g_Mathlib_LinearToGamma[index]; }
float GammaToLinear( float gamma ) { Assert( s_bMathlibInitialized ); if ( gamma < 0.0f ) { return 0.0f; } if ( gamma >= 0.95f ) { // Use GammaToLinearFullRange maybe if you trip this. // X360TEMP // Assert( gamma <= 1.0f ); return 1.0f; } int index = RoundFloatToInt( gamma * 255.0f ); Assert( index >= 0 && index < 256 ); return g_Mathlib_GammaToLinear[index]; }
void DrawBitmap(int x_in, int y_in, int width, int height, Framebuffer fbo, LoadedBitmap bitmap) { int x_offset = 0; int y_offset = 0; if(x_in > fbo.width) width = 0; if((x_in + width) > fbo.width) width = fbo.width - x_in; if(y_in > fbo.height) height = 0; if((y_in + height) > fbo.height) height = fbo.height - y_in; if(x_in < 0) { x_offset = -x_in; width = width + x_in; x_in = 0; } if((x_in + width) < 0) width = 0; if(y_in < 0) { y_offset = -y_in; height = height + y_in; y_in = 0; } if((y_in + height) < 0) height = 0; for (int x = 0; (x + x_in) < (x_in + width); x++) { for(int y = 0; (y + y_in) < (y_in + height); y++) { uint32_t old_color = *(fbo.pixels + ((y + y_in) * fbo.width) + (x + x_in)); float oldr = ((float)((old_color & 0x00FF0000) >> 16)) / 255.0f; float oldg = ((float)((old_color & 0x0000FF00) >> 8)) / 255.0f; float oldb = ((float)((old_color & 0x000000FF) >> 0)) / 255.0f; uint32_t texel_color = *(bitmap.pixels + ((y + y_offset) * bitmap.width) + x + x_offset); float texelr = ((float)((texel_color & 0x00FF0000) >> 16)) / 255.0f; float texelg = ((float)((texel_color & 0x0000FF00) >> 8)) / 255.0f; float texelb = ((float)((texel_color & 0x000000FF) >> 0)) / 255.0f; float texela = ((float)((texel_color & 0xFF000000) >> 24)) / 255.0f; float newr = texela * texelr + (1 - texela) * oldr; float newg = texela * texelg + (1 - texela) * oldg; float newb = texela * texelb + (1 - texela) * oldb; uint32_t color32 = (RoundFloatToInt(texela * 255) < 24) | (RoundFloatToInt(newr * 255) << 16) | (RoundFloatToInt(newg * 255) << 8) | (RoundFloatToInt(newb * 255) << 0); *(fbo.pixels + ((y + y_in) * fbo.width) + (x + x_in)) = color32; } } }
void BuildGammaTable( float gamma, float texGamma, float brightness, int overbright ) { int i, inf; float g1, g3; // Con_Printf("BuildGammaTable %.1f %.1f %.1f\n", g, v_lightgamma.GetFloat(), v_texgamma.GetFloat() ); float g = gamma; if (g > 3.0) { g = 3.0; } g = 1.0 / g; g1 = texGamma * g; if (brightness <= 0.0) { g3 = 0.125; } else if (brightness > 1.0) { g3 = 0.05; } else { g3 = 0.125 - (brightness * brightness) * 0.075; } for (i=0 ; i<256 ; i++) { inf = static_cast<int>(255 * pow ( i/255.f, g1 )); if (inf < 0) inf = 0; if (inf > 255) inf = 255; texgammatable[i] = inf; } for (i=0 ; i<1024 ; i++) { float f; f = i / 1023.0; // scale up if (brightness > 1.0) f = f * brightness; // shift up if (f <= g3) f = (f / g3) * 0.125; else f = 0.125 + ((f - g3) / (1.0 - g3)) * 0.875; // convert linear space to desired gamma space inf = static_cast<int>(255 * pow ( f, g )); if (inf < 0) inf = 0; if (inf > 255) inf = 255; lineartoscreen[i] = inf; } /* for (i=0 ; i<1024 ; i++) { // convert from screen gamma space to linear space lineargammatable[i] = 1023 * pow ( i/1023.0, v_gamma.GetFloat() ); // convert from linear gamma space to screen space screengammatable[i] = 1023 * pow ( i/1023.0, 1.0 / v_gamma.GetFloat() ); } */ for (i=0 ; i<256 ; i++) { // convert from nonlinear texture space (0..255) to linear space (0..1) texturetolinear[i] = pow( i / 255.f, texGamma ); // convert from linear space (0..1) to nonlinear (sRGB) space (0..1) g_Mathlib_LinearToGamma[i] = LinearToGammaFullRange( i / 255.f ); // convert from sRGB gamma space (0..1) to linear space (0..1) g_Mathlib_GammaToLinear[i] = GammaToLinearFullRange( i / 255.f ); } for (i=0 ; i<1024 ; i++) { // convert from linear space (0..1) to nonlinear texture space (0..255) lineartotexture[i] = static_cast<int>(pow( i / 1023.0, 1.0 / texGamma ) * 255); } #if 0 for (i=0 ; i<256 ; i++) { float f; // convert from nonlinear lightmap space (0..255) to linear space (0..4) // f = (i / 255.0) * sqrt( 4 ); f = i * (2.0 / 255.0); f = f * f; texlighttolinear[i] = f; } #endif { float f; float overbrightFactor = 1.0f; // Can't do overbright without texcombine // UNDONE: Add GAMMA ramp to rectify this if ( overbright == 2 ) { overbrightFactor = 0.5; } else if ( overbright == 4 ) { overbrightFactor = 0.25; } for (i=0 ; i<4096 ; i++) { // convert from linear 0..4 (x1024) to screen corrected vertex space (0..1?) f = pow ( i/1024.0, 1.0 / gamma ); lineartovertex[i] = f * overbrightFactor; if (lineartovertex[i] > 1) lineartovertex[i] = 1; int nLightmap = RoundFloatToInt( f * 255 * overbrightFactor ); nLightmap = clamp( nLightmap, 0, 255 ); lineartolightmap[i] = (unsigned char)nLightmap; } } }
bool CEventLog::PrintPlayerEvent( IGameEvent *event ) { const char * eventName = event->GetName(); const int userid = event->GetInt( "userid" ); if ( !Q_strncmp( eventName, "player_connect", Q_strlen("player_connect") ) ) // player connect is before the CBasePlayer pointer is setup { const char *name = event->GetString( "name" ); const char *address = event->GetString( "address" ); const char *networkid = event->GetString("networkid" ); UTIL_LogPrintf( "\"%s<%i><%s><>\" connected, address \"%s\"\n", name, userid, networkid, address); return true; } else if ( !Q_strncmp( eventName, "player_disconnect", Q_strlen("player_disconnect") ) ) { const char *reason = event->GetString("reason" ); const char *name = event->GetString("name" ); const char *networkid = event->GetString("networkid" ); CTeam *team = NULL; CBasePlayer *pPlayer = UTIL_PlayerByUserId( userid ); if ( pPlayer ) { team = pPlayer->GetTeam(); } UTIL_LogPrintf( "\"%s<%i><%s><%s>\" disconnected (reason \"%s\")\n", name, userid, networkid, team ? team->GetName() : "", reason ); return true; } CBasePlayer *pPlayer = UTIL_PlayerByUserId( userid ); if ( !pPlayer) { DevMsg( "CEventLog::PrintPlayerEvent: Failed to find player (userid: %i, event: %s)\n", userid, eventName ); return false; } if ( !Q_strncmp( eventName, "player_team", Q_strlen("player_team") ) ) { const bool bDisconnecting = event->GetBool( "disconnect" ); if ( !bDisconnecting ) { const int newTeam = event->GetInt( "team" ); const int oldTeam = event->GetInt( "oldteam" ); CTeam *team = GetGlobalTeam( newTeam ); CTeam *oldteam = GetGlobalTeam( oldTeam ); UTIL_LogPrintf( "\"%s<%i><%s><%s>\" joined team \"%s\"\n", pPlayer->GetPlayerName(), pPlayer->GetUserID(), pPlayer->GetNetworkIDString(), oldteam->GetName(), team->GetName() ); } return true; } else if ( !Q_strncmp( eventName, "player_death", Q_strlen("player_death") ) ) { const int attackerid = event->GetInt("attacker" ); #ifdef HL2MP const char *weapon = event->GetString( "weapon" ); #endif CBasePlayer *pAttacker = UTIL_PlayerByUserId( attackerid ); CTeam *team = pPlayer->GetTeam(); CTeam *attackerTeam = NULL; if ( pAttacker ) { attackerTeam = pAttacker->GetTeam(); } if ( pPlayer == pAttacker && pPlayer ) { UTIL_LogPrintf( "\"%s<%i><%s><%s>\" committed suicide with \"%s\"\n", pPlayer->GetPlayerName(), userid, pPlayer->GetNetworkIDString(), team ? team->GetName() : "", weapon ); } else if ( pAttacker ) { CTeam *attackerTeam = pAttacker->GetTeam(); //BG2 - Display killer and victim positions in log files for HLStatsX support. -HairyPotter Vector APos = pAttacker->GetAbsOrigin(), VPos = pPlayer->GetAbsOrigin(); UTIL_LogPrintf("\"%s<%i><%s><%s>\" killed \"%s<%i><%s><%s>\" with \"%s\" (attacker_position \"%i %i %i\" ) (victim_position \"%i %i %i\" )\n", pAttacker->GetPlayerName(), attackerid, pAttacker->GetNetworkIDString(), attackerTeam ? attackerTeam->GetName() : "", pPlayer->GetPlayerName(), userid, pPlayer->GetNetworkIDString(), team ? team->GetName() : "", weapon, RoundFloatToInt(APos.x), RoundFloatToInt( APos.y ), RoundFloatToInt( APos.z ), RoundFloatToInt( VPos.x ), RoundFloatToInt( VPos.y ), RoundFloatToInt( VPos.z ) ); } else { // killed by the world UTIL_LogPrintf( "\"%s<%i><%s><%s>\" committed suicide with \"world\"\n", pPlayer->GetPlayerName(), userid, pPlayer->GetNetworkIDString(), team ? team->GetName() : "" ); } return true; } else if ( !Q_strncmp( eventName, "player_activate", Q_strlen("player_activate") ) ) { UTIL_LogPrintf( "\"%s<%i><%s><>\" entered the game\n", pPlayer->GetPlayerName(), userid, pPlayer->GetNetworkIDString() ); return true; } else if ( !Q_strncmp( eventName, "player_changename", Q_strlen("player_changename") ) ) { const char *newName = event->GetString( "newname" ); const char *oldName = event->GetString( "oldname" ); CTeam *team = pPlayer->GetTeam(); UTIL_LogPrintf( "\"%s<%i><%s><%s>\" changed name to \"%s\"\n", oldName, userid, pPlayer->GetNetworkIDString(), team ? team->GetName() : "", newName ); return true; } // ignored events //player_hurt return false; }
// Sets up pParams. // pPos and pRotation are the view position and orientation. // pRect is the rectangle on the screen that the viewing window maps into. // pScale is an extra scale that scales all the coordinates up. bool d3d_InitFrustum2(ViewParams *pParams, ViewBoxDef *pViewBox, float screenMinX, float screenMinY, float screenMaxX, float screenMaxY, const LTMatrix *pMat, const LTVector& vScale, ViewParams::ERenderMode eMode) { LTMatrix mTempWorld, mRotation, mScale; LTMatrix mFOVScale, mBackTransform; LTMatrix mDevice, mBackTranslate; float leftX, rightX, topY, bottomY, normalZ; uint32 i; LTVector forwardVec, zPlanePos, vTrans; LTMatrix mProjectionTransform; //mUnit, mPerspective; pParams->m_mIdentity.Identity(); pParams->m_mInvView = *pMat; // Here's how the viewing works: // The world to camera transformation rotates and translates // the world into camera space. // The camera to clip transformation just scales the sides so the // field of view is 90 degrees (faster to clip in). // Clipping takes place on NEARZ and g_ViewParams.m_FarZ. // In terms of Z buffer calculations, the maximum Z is MAX_FARZ (that way, // when the farZ clipping plane is changed, sz and rhw stay the same). /////// Copy stuff in and setup view limits. memcpy(&pParams->m_ViewBox, pViewBox, sizeof(pParams->m_ViewBox)); pMat->GetTranslation(pParams->m_Pos); pParams->m_FarZ = pViewBox->m_FarZ; if(pParams->m_FarZ < 3.0f) pParams->m_FarZ = 3.0f; if(pParams->m_FarZ > MAX_FARZ) pParams->m_FarZ = MAX_FARZ; pParams->m_NearZ = pViewBox->m_NearZ; pParams->m_Rect.left = (int)RoundFloatToInt(screenMinX); pParams->m_Rect.top = (int)RoundFloatToInt(screenMinY); pParams->m_Rect.right = (int)RoundFloatToInt(screenMaxX); pParams->m_Rect.bottom = (int)RoundFloatToInt(screenMaxY); /////// Setup all the matrices. // Setup the rotation and translation transforms. mRotation = *pMat; mRotation.SetTranslation(0.0f, 0.0f, 0.0f); Mat_GetBasisVectors(&mRotation, &pParams->m_Right, &pParams->m_Up, &pParams->m_Forward); // We want to transpose (ie: when we're looking left, rotate the world to the right..) MatTranspose3x3(&mRotation); mBackTranslate.Init( 1, 0, 0, -pParams->m_Pos.x, 0, 1, 0, -pParams->m_Pos.y, 0, 0, 1, -pParams->m_Pos.z, 0, 0, 0, 1); MatMul(&mTempWorld, &mRotation, &mBackTranslate); // Scale it to get the full world transform. mScale.Init( vScale.x, 0, 0, 0, 0, vScale.y, 0, 0, 0, 0, vScale.z, 0, 0, 0, 0, 1); MatMul(&pParams->m_mView, &mScale, &mTempWorld); // Shear so the center of projection is (0,0,COP.z) LTMatrix mShear; mShear.Init( 1.0f, 0.0f, -pViewBox->m_COP.x/pViewBox->m_COP.z, 0.0f, 0.0f, 1.0f, -pViewBox->m_COP.y/pViewBox->m_COP.z, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); // Figure out X and Y scale to get frustum into unit slopes. float fFovXScale = pViewBox->m_COP.z / pViewBox->m_WindowSize[0]; float fFovYScale = pViewBox->m_COP.z / pViewBox->m_WindowSize[1]; // Squash the sides to 45 degree angles. mFOVScale.Init( fFovXScale, 0.0f, 0.0f, 0.0f, 0.0f, fFovYScale, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); // Setup the projection transform. d3d_SetupPerspectiveMatrix(&mProjectionTransform, pViewBox->m_NearZ, pParams->m_FarZ); // Setup the projection space (-1<x<1) to device space transformation. pParams->m_fScreenWidth = (screenMaxX - screenMinX); pParams->m_fScreenHeight = (screenMaxY - screenMinY); // Setup the device transform. It subtracts 0.4 to account for the FP's tendency // to slip above and below 0.5. Mat_Identity(&mDevice); mDevice.m[0][0] = pParams->m_fScreenWidth * 0.5f - 0.0001f; mDevice.m[0][3] = screenMinX + pParams->m_fScreenWidth * 0.5f; mDevice.m[1][1] = -(pParams->m_fScreenHeight * 0.5f - 0.0001f); mDevice.m[1][3] = screenMinY + pParams->m_fScreenHeight * 0.5f; // Precalculate useful matrices. pParams->m_DeviceTimesProjection = mDevice * mProjectionTransform; pParams->m_FullTransform = pParams->m_DeviceTimesProjection * mFOVScale * mShear * pParams->m_mView; pParams->m_mProjection = mProjectionTransform * mFOVScale * mShear; /////// Setup the view frustum points in camera space. float xNearZ, yNearZ, xFarZ, yFarZ; xNearZ = (pParams->m_NearZ * pViewBox->m_WindowSize[0]) / pViewBox->m_COP.z; yNearZ = (pParams->m_NearZ * pViewBox->m_WindowSize[1]) / pViewBox->m_COP.z; xFarZ = (pParams->m_FarZ * pViewBox->m_WindowSize[0]) / pViewBox->m_COP.z; yFarZ = (pParams->m_FarZ * pViewBox->m_WindowSize[1]) / pViewBox->m_COP.z; pParams->m_ViewPoints[0].Init(-xNearZ, yNearZ, pParams->m_NearZ); // Near Top Left pParams->m_ViewPoints[1].Init(xNearZ, yNearZ, pParams->m_NearZ); // Near Top Right pParams->m_ViewPoints[2].Init(-xNearZ, -yNearZ, pParams->m_NearZ); // Near Bottom Left pParams->m_ViewPoints[3].Init(xNearZ, -yNearZ, pParams->m_NearZ); // Near Bottom Right pParams->m_ViewPoints[4].Init(-xFarZ, yFarZ, pParams->m_FarZ); // Far Top Left pParams->m_ViewPoints[5].Init(xFarZ, yFarZ, pParams->m_FarZ); // Far Top Right pParams->m_ViewPoints[6].Init(-xFarZ, -yFarZ, pParams->m_FarZ); // Far Bottom Left pParams->m_ViewPoints[7].Init(xFarZ, -yFarZ, pParams->m_FarZ); // Far Bottom Right // Transform them into world space. for(i=0; i < 8; i++) { MatVMul_InPlace_Transposed3x3(&pParams->m_mView, &pParams->m_ViewPoints[i]); pParams->m_ViewPoints[i] += pParams->m_Pos; } // Get the AABB of the view frustum pParams->m_ViewAABBMin = pParams->m_ViewPoints[0]; pParams->m_ViewAABBMax = pParams->m_ViewPoints[0]; for(i=1; i < 8; i++) { VEC_MIN(pParams->m_ViewAABBMin, pParams->m_ViewAABBMin, pParams->m_ViewPoints[i]); VEC_MAX(pParams->m_ViewAABBMax, pParams->m_ViewAABBMax, pParams->m_ViewPoints[i]); } /////// Setup the camera-space clipping planes. leftX = pViewBox->m_COP.x - pViewBox->m_WindowSize[0]; rightX = pViewBox->m_COP.x + pViewBox->m_WindowSize[0]; topY = pViewBox->m_COP.y + pViewBox->m_WindowSize[1]; bottomY = pViewBox->m_COP.y - pViewBox->m_WindowSize[1]; normalZ = pViewBox->m_COP.z; LTPlane CSClipPlanes[NUM_CLIPPLANES]; CSClipPlanes[CPLANE_NEAR_INDEX].m_Normal.Init(0.0f, 0.0f, 1.0f); // Near Z CSClipPlanes[CPLANE_NEAR_INDEX].m_Dist = 1.0f; CSClipPlanes[CPLANE_FAR_INDEX].m_Normal.Init(0.0f, 0.0f, -1.0f); // Far Z CSClipPlanes[CPLANE_FAR_INDEX].m_Dist = -pParams->m_FarZ; CSClipPlanes[CPLANE_LEFT_INDEX].m_Normal.Init(normalZ, 0.0f, -leftX); // Left CSClipPlanes[CPLANE_RIGHT_INDEX].m_Normal.Init(-normalZ, 0.0f, rightX); // Right CSClipPlanes[CPLANE_TOP_INDEX].m_Normal.Init(0.0f, -normalZ, topY); // Top CSClipPlanes[CPLANE_BOTTOM_INDEX].m_Normal.Init(0.0f, normalZ, -bottomY); // Bottom CSClipPlanes[CPLANE_LEFT_INDEX].m_Normal.Norm(); CSClipPlanes[CPLANE_TOP_INDEX].m_Normal.Norm(); CSClipPlanes[CPLANE_RIGHT_INDEX].m_Normal.Norm(); CSClipPlanes[CPLANE_BOTTOM_INDEX].m_Normal.Norm(); CSClipPlanes[CPLANE_LEFT_INDEX].m_Dist = CSClipPlanes[CPLANE_RIGHT_INDEX].m_Dist = 0.0f; CSClipPlanes[CPLANE_TOP_INDEX].m_Dist = CSClipPlanes[CPLANE_BOTTOM_INDEX].m_Dist = 0.0f; // Now setup the world space clipping planes. mBackTransform = pParams->m_mView; MatTranspose3x3(&mBackTransform); for(i=0; i < NUM_CLIPPLANES; i++) { if(i != CPLANE_NEAR_INDEX && i != CPLANE_FAR_INDEX) { MatVMul_3x3(&pParams->m_ClipPlanes[i].m_Normal, &mBackTransform, &CSClipPlanes[i].m_Normal); pParams->m_ClipPlanes[i].m_Dist = pParams->m_ClipPlanes[i].m_Normal.Dot(pParams->m_Pos); } } // The Z planes need to be handled a little differently. forwardVec.Init(mRotation.m[2][0], mRotation.m[2][1], mRotation.m[2][2]); zPlanePos = forwardVec * pViewBox->m_NearZ; zPlanePos += pParams->m_Pos; MatVMul_3x3(&pParams->m_ClipPlanes[CPLANE_NEAR_INDEX].m_Normal, &mBackTransform, &CSClipPlanes[CPLANE_NEAR_INDEX].m_Normal); pParams->m_ClipPlanes[CPLANE_NEAR_INDEX].m_Dist = pParams->m_ClipPlanes[CPLANE_NEAR_INDEX].m_Normal.Dot(zPlanePos); zPlanePos = forwardVec * pParams->m_FarZ; zPlanePos += pParams->m_Pos; MatVMul_3x3(&pParams->m_ClipPlanes[CPLANE_FAR_INDEX].m_Normal, &mBackTransform, &CSClipPlanes[CPLANE_FAR_INDEX].m_Normal); pParams->m_ClipPlanes[CPLANE_FAR_INDEX].m_Dist = pParams->m_ClipPlanes[CPLANE_FAR_INDEX].m_Normal.Dot(zPlanePos); // Remember AABB Corners the planes are pointing at for (uint32 nPlaneLoop = 0; nPlaneLoop < NUM_CLIPPLANES; ++nPlaneLoop) { pParams->m_AABBPlaneCorner[nPlaneLoop] = GetAABBPlaneCorner(pParams->m_ClipPlanes[nPlaneLoop].m_Normal); } // Default the world transform to identity pParams->m_mInvWorld.Identity(); //setup the environment mapping info pParams->m_mWorldEnvMap.SetBasisVectors(&pParams->m_Right, &pParams->m_Up, &pParams->m_Forward); //turn off glowing by default pParams->m_eRenderMode = eMode; d3d_SetupSkyStuff(g_pSceneDesc->m_SkyDef, pParams); return true; }
bool IsIntegralValue( float flValue, float flTolerance = 0.001f ) { return fabs( RoundFloatToInt( flValue ) - flValue ) < flTolerance; }