void CGlowOverlay::CalcBasis( const Vector &vToGlow, float flHorzSize, float flVertSize, Vector &vBasePt, Vector &vUp, Vector &vRight ) { const float flOverlayDist = 100; vBasePt = CurrentViewOrigin() + vToGlow * flOverlayDist; vUp.Init( 0, 0, 1 ); vRight = vToGlow.Cross( vUp ); VectorNormalize( vRight ); vUp = vRight.Cross( vToGlow ); VectorNormalize( vUp ); vRight *= flHorzSize; vUp *= flVertSize; }
void CLampHaloProxy::OnBind( C_BaseEntity *pEnt ) { if ( !m_pFadeValue ) return; Vector vecLocal = pEnt->GetAbsOrigin() - CurrentViewOrigin(); VectorNormalize( vecLocal ); float fade = fabs( vecLocal.z ); // I hate these magic numbers here, will have to revise // (sjb) if( fade < 0.25 ) { fade = 0.0; } else { fade = MIN( (fade - 0.25) * 1.35, 1.0f ); } m_pFadeValue->SetFloatValue( fade ); }
void CCamoMaterialProxy::GetColors( Vector &diffuseColor, Vector &baseColor, int index, const Vector &boxMin, const Vector &boxExtents, const Vector &forward, const Vector &right, const Vector &up, const Vector& entityPosition ) { Vector position, transformedPosition; // hack // m_pointsInNormalizedBox[index] = Vector( 0.5f, 0.5f, 1.0f ); position[0] = m_pointsInNormalizedBox[index][0] * boxExtents[0] + boxMin[0]; position[1] = m_pointsInNormalizedBox[index][1] * boxExtents[1] + boxMin[1]; position[2] = m_pointsInNormalizedBox[index][2] * boxExtents[2] + boxMin[2]; transformedPosition[0] = right[0] * position[0] + forward[0] * position[1] + up[0] * position[2]; transformedPosition[1] = right[1] * position[0] + forward[1] * position[1] + up[1] * position[2]; transformedPosition[2] = right[2] * position[0] + forward[2] * position[1] + up[2] * position[2]; transformedPosition = transformedPosition + entityPosition; Vector direction = transformedPosition - CurrentViewOrigin(); VectorNormalize( direction ); direction = direction * ( COORD_EXTENT * 1.74f ); Vector endPoint = position + direction; // baseColor is already in gamma space // engine->TraceLineMaterialAndLighting( g_vecInstantaneousRenderOrigin, endPoint, diffuseColor, baseColor ); engine->TraceLineMaterialAndLighting( transformedPosition, endPoint, diffuseColor, baseColor ); // hack - optimize! - convert from linear to gamma space - this should be hidden diffuseColor[0] = pow( diffuseColor[0], 1.0f / 2.2f ); diffuseColor[1] = pow( diffuseColor[1], 1.0f / 2.2f ); diffuseColor[2] = pow( diffuseColor[2], 1.0f / 2.2f ); #if 0 Msg( "%f %f %f\n", diffuseColor[0], diffuseColor[1], diffuseColor[2] ); #endif #if 0 float max; max = diffuseColor[0]; if( diffuseColor[1] > max ) { max = diffuseColor[1]; } if( diffuseColor[2] > max ) { max = diffuseColor[2]; } if( max > 1.0f ) { max = 1.0f / max; diffuseColor = diffuseColor * max; } #else if( diffuseColor[0] > 1.0f ) { diffuseColor[0] = 1.0f; } if( diffuseColor[1] > 1.0f ) { diffuseColor[1] = 1.0f; } if( diffuseColor[2] > 1.0f ) { diffuseColor[2] = 1.0f; } #endif // hack //baseColor = Vector( 1.0f, 1.0f, 1.0f ); //diffuseColor = Vector( 1.0f, 1.0f, 1.0f ); }
void CGlowOverlay::Draw( bool bCacheFullSceneState ) { extern ConVar r_drawsprites; if( !r_drawsprites.GetBool() ) return; // Get the vector to the sun. Vector vToGlow; if( m_bDirectional ) vToGlow = m_vDirection; else vToGlow = m_vPos - CurrentViewOrigin(); VectorNormalize( vToGlow ); float flDot = vToGlow.Dot( CurrentViewForward() ); UpdateGlowObstruction( vToGlow, bCacheFullSceneState ); if( m_flGlowObstructionScale == 0 ) return; bool bWireframe = ShouldDrawInWireFrameMode() || (r_drawsprites.GetInt() == 2); CMatRenderContextPtr pRenderContext( materials ); for( int iSprite=0; iSprite < m_nSprites; iSprite++ ) { CGlowSprite *pSprite = &m_Sprites[iSprite]; // Figure out the color and size to draw it. float flHorzSize, flVertSize; Vector vColor; CalcSpriteColorAndSize( flDot, pSprite, &flHorzSize, &flVertSize, &vColor ); // If we're alpha'd out, then don't bother if ( vColor.LengthSqr() < 0.00001f ) continue; // Setup the basis to draw the sprite. Vector vBasePt, vUp, vRight; CalcBasis( vToGlow, flHorzSize, flVertSize, vBasePt, vUp, vRight ); //Get our diagonal radius float radius = (vRight+vUp).Length(); if ( R_CullSphere( view->GetFrustum(), 5, &vBasePt, radius ) ) continue; // Get our material (deferred default load) if ( m_Sprites[iSprite].m_pMaterial == NULL ) { m_Sprites[iSprite].m_pMaterial = materials->FindMaterial( "sprites/light_glow02_add_noz", TEXTURE_GROUP_CLIENT_EFFECTS ); } Assert( m_Sprites[iSprite].m_pMaterial ); static unsigned int nHDRColorScaleCache = 0; IMaterialVar *pHDRColorScaleVar = m_Sprites[iSprite].m_pMaterial->FindVarFast( "$hdrcolorscale", &nHDRColorScaleCache ); if( pHDRColorScaleVar ) { pHDRColorScaleVar->SetFloatValue( m_flHDRColorScale ); } // Draw the sprite. IMesh *pMesh = pRenderContext->GetDynamicMesh( false, 0, 0, m_Sprites[iSprite].m_pMaterial ); CMeshBuilder builder; builder.Begin( pMesh, MATERIAL_QUADS, 1 ); Vector vPt; vPt = vBasePt - vRight + vUp; builder.Position3fv( vPt.Base() ); builder.Color4f( VectorExpand(vColor), 1 ); builder.TexCoord2f( 0, 0, 1 ); builder.AdvanceVertex(); vPt = vBasePt + vRight + vUp; builder.Position3fv( vPt.Base() ); builder.Color4f( VectorExpand(vColor), 1 ); builder.TexCoord2f( 0, 1, 1 ); builder.AdvanceVertex(); vPt = vBasePt + vRight - vUp; builder.Position3fv( vPt.Base() ); builder.Color4f( VectorExpand(vColor), 1 ); builder.TexCoord2f( 0, 1, 0 ); builder.AdvanceVertex(); vPt = vBasePt - vRight - vUp; builder.Position3fv( vPt.Base() ); builder.Color4f( VectorExpand(vColor), 1 ); builder.TexCoord2f( 0, 0, 0 ); builder.AdvanceVertex(); builder.End( false, true ); if( bWireframe ) { IMaterial *pWireframeMaterial = materials->FindMaterial( "debug/debugwireframevertexcolor", TEXTURE_GROUP_OTHER ); pRenderContext->Bind( pWireframeMaterial ); // Draw the sprite. IMesh *pMesh = pRenderContext->GetDynamicMesh( false, 0, 0, pWireframeMaterial ); CMeshBuilder builder; builder.Begin( pMesh, MATERIAL_QUADS, 1 ); Vector vPt; vPt = vBasePt - vRight + vUp; builder.Position3fv( vPt.Base() ); builder.Color3f( 1.0f, 0.0f, 0.0f ); builder.AdvanceVertex(); vPt = vBasePt + vRight + vUp; builder.Position3fv( vPt.Base() ); builder.Color3f( 1.0f, 0.0f, 0.0f ); builder.AdvanceVertex(); vPt = vBasePt + vRight - vUp; builder.Position3fv( vPt.Base() ); builder.Color3f( 1.0f, 0.0f, 0.0f ); builder.AdvanceVertex(); vPt = vBasePt - vRight - vUp; builder.Position3fv( vPt.Base() ); builder.Color3f( 1.0f, 0.0f, 0.0f ); builder.AdvanceVertex(); builder.End( false, true ); } } }
void CGlowOverlay::UpdateGlowObstruction( const Vector &vToGlow, bool bCacheFullSceneState ) { // If we already cached the glow obstruction and are still using that, early-out if ( bCacheFullSceneState && m_bCacheGlowObstruction ) return; if ( bCacheFullSceneState && !m_bCacheGlowObstruction ) // If turning on sky obstruction caching mode { m_bCacheGlowObstruction = true; } if ( !bCacheFullSceneState && m_bCacheGlowObstruction ) { m_bCacheGlowObstruction = false; } if ( PixelVisibility_IsAvailable() ) { if ( m_bInSky ) { const CViewSetup *pViewSetup = view->GetViewSetup(); Vector pos = CurrentViewOrigin() + m_vDirection * (pViewSetup->zFar * 0.99f); // GSTRINGMIGRATION pixelvis_queryparams_t params; params.Init( pos, m_flProxyRadius, CalcGlowAspect() ); params.bSizeInScreenspace = true; // use a pixel query to occlude with models m_flGlowObstructionScale = PixelVisibility_FractionVisible( params, &m_queryHandle ) * m_skyObstructionScale; } else { // If it's not in the sky, then we need a valid position or else we don't // know what's in front of it. Assert( !m_bDirectional ); pixelvis_queryparams_t params; params.Init( m_vPos, m_flProxyRadius, CalcGlowAspect() ); m_flGlowObstructionScale = PixelVisibility_FractionVisible( params, &m_queryHandle ); } return; } bool bFade = false; if ( m_bInSky ) { // Trace a ray at the object. trace_t trace; UTIL_TraceLine( CurrentViewOrigin(), CurrentViewOrigin() + (vToGlow*MAX_TRACE_LENGTH), CONTENTS_SOLID, NULL, COLLISION_GROUP_NONE, &trace ); bFade = (trace.fraction < 1 && !(trace.surface.flags & SURF_SKY)); } else { // If it's not in the sky, then we need a valid position or else we don't // know what's in front of it. Assert( !m_bDirectional ); pixelvis_queryparams_t params; params.Init( m_vPos, m_flProxyRadius ); bFade = PixelVisibility_FractionVisible( params, &m_queryHandle ) < 1.0f ? true : false; } if ( bFade ) { if ( building_cubemaps.GetBool() ) { m_flGlowObstructionScale = 0.0f; } else { m_flGlowObstructionScale -= gpGlobals->frametime / cl_sun_decay_rate.GetFloat(); m_flGlowObstructionScale = MAX( m_flGlowObstructionScale, 0.0f ); } } else { if ( building_cubemaps.GetBool() ) { m_flGlowObstructionScale = 1.0f; } else { m_flGlowObstructionScale += gpGlobals->frametime / cl_sun_decay_rate.GetFloat(); m_flGlowObstructionScale = MIN( m_flGlowObstructionScale, 1.0f ); } } }
//----------------------------------------------------------------------------- // Purpose: // Input : frametime - //----------------------------------------------------------------------------- void CFXLine::Draw( double frametime ) { // Update the effect Update( frametime ); Vector lineDir, viewDir; //Get the proper orientation for the line VectorSubtract( m_FXData.m_vecStart, m_FXData.m_vecEnd, lineDir ); VectorSubtract( m_FXData.m_vecEnd, CurrentViewOrigin(), viewDir ); Vector cross = lineDir.Cross( viewDir ); VectorNormalize( cross ); CMatRenderContextPtr pRenderContext( materials ); //Bind the material IMesh* pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, m_FXData.m_pMaterial ); CMeshBuilder meshBuilder; Vector tmp; meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 ); float scaleTimePerc = ( m_FXData.m_flLifeTime / m_FXData.m_flDieTime ); float scale = m_FXData.m_flStartScale + ( ( m_FXData.m_flEndScale - m_FXData.m_flStartScale ) * scaleTimePerc ); color32 color = {255,255,255,255}; float alpha = m_FXData.m_flStartAlpha + ( ( m_FXData.m_flEndAlpha - m_FXData.m_flStartAlpha ) * scaleTimePerc ); alpha = clamp( alpha, 0.0f, 1.0f ); color.a *= alpha; // Start VectorMA( m_FXData.m_vecStart, -scale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 1.0f, 1.0f ); meshBuilder.Color4ub( color.r, color.g, color.b, color.a ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); VectorMA( m_FXData.m_vecStart, scale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 0.0f, 1.0f ); meshBuilder.Color4ub( color.r, color.g, color.b, color.a ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); // End VectorMA( m_FXData.m_vecEnd, scale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 0.0f, 0.0f ); meshBuilder.Color4ub( color.r, color.g, color.b, color.a ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); VectorMA( m_FXData.m_vecEnd, -scale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 1.0f, 0.0f ); meshBuilder.Color4ub( color.r, color.g, color.b, color.a ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); meshBuilder.End(); pMesh->Draw(); }
void FX_DrawLineFade( const Vector &start, const Vector &end, float scale, IMaterial *pMaterial, const color32 &color, float fadeDist ) { Vector lineDir, viewDir; //Get the proper orientation for the line VectorSubtract( end, start, lineDir ); VectorSubtract( end, CurrentViewOrigin(), viewDir ); float lineLength = lineDir.Length(); float t0 = 0.25f; float t1 = 0.75f; if ( lineLength > 0 ) { t0 = fadeDist / lineLength; t0 = clamp( t0, 0.0f, 0.25f ); t1 = 1.0f - t0; } Vector cross = lineDir.Cross( viewDir ); VectorNormalize( cross ); CMatRenderContextPtr pRenderContext( materials ); //Bind the material IMesh* pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, pMaterial ); CMeshBuilder meshBuilder; Vector tmp; meshBuilder.Begin( pMesh, MATERIAL_TRIANGLES, 8, 24 ); // 2 5 // 0 1 4 7 // 3 6 // 0,2,1 - 0,1,3 - 7,4,5 - 7,6,4 - 1,4,6, 1,6,3 - 1,5,4 - 1,2,5 // v0 meshBuilder.Position3fv( start.Base() ); meshBuilder.TexCoord2f( 0, 0.5f, 0.0f ); meshBuilder.Color4ub( 0, 0, 0, 0 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); // v1 Vector v1 = start + t0 * lineDir; meshBuilder.Position3fv( v1.Base() ); meshBuilder.TexCoord2f( 0, 0.5f, t0 ); meshBuilder.Color4ub( color.r, color.g, color.b, color.a ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); // v2 tmp = v1 - scale*cross; meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 1.0f, t0 ); meshBuilder.Color4ub( color.r, color.g, color.b, color.a ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); // v3 tmp = v1 + scale*cross; meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 0.0f, t0 ); meshBuilder.Color4ub( color.r, color.g, color.b, color.a ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); // v4 Vector v4 = start + t1 * lineDir; meshBuilder.Position3fv( v4.Base() ); meshBuilder.TexCoord2f( 0, 0.5f, t1 ); meshBuilder.Color4ub( color.r, color.g, color.b, color.a ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); // v5 tmp = v4 - scale*cross; meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 1.0f, t1 ); meshBuilder.Color4ub( color.r, color.g, color.b, color.a ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); // v6 tmp = v4 + scale*cross; meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 0.0f, t1 ); meshBuilder.Color4ub( color.r, color.g, color.b, color.a ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); // v7 meshBuilder.Position3fv( end.Base() ); meshBuilder.TexCoord2f( 0, 0.5f, 1.0f ); meshBuilder.Color4ub( 0, 0, 0, 0 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); // triangles - 0,2,1 - 0,1,3 - 7,4,5 - 7,6,4 - 1,4,6, 1,6,3 - 1,5,4 - 1,2,5 meshBuilder.FastIndex( 0 ); meshBuilder.FastIndex( 2 ); meshBuilder.FastIndex( 1 ); meshBuilder.FastIndex( 0 ); meshBuilder.FastIndex( 1 ); meshBuilder.FastIndex( 3 ); meshBuilder.FastIndex( 7 ); meshBuilder.FastIndex( 4 ); meshBuilder.FastIndex( 5 ); meshBuilder.FastIndex( 7 ); meshBuilder.FastIndex( 6 ); meshBuilder.FastIndex( 4 ); meshBuilder.FastIndex( 1 ); meshBuilder.FastIndex( 4 ); meshBuilder.FastIndex( 6 ); meshBuilder.FastIndex( 1 ); meshBuilder.FastIndex( 6 ); meshBuilder.FastIndex( 3 ); meshBuilder.FastIndex( 1 ); meshBuilder.FastIndex( 5 ); meshBuilder.FastIndex( 4 ); meshBuilder.FastIndex( 1 ); meshBuilder.FastIndex( 2 ); meshBuilder.FastIndex( 5 ); meshBuilder.End(); pMesh->Draw(); }
static void DrawSpriteTangentSpace( const Vector &vecOrigin, float flWidth, float flHeight, color32 color ) { unsigned char pColor[4] = { color.r, color.g, color.b, color.a }; // Generate half-widths flWidth *= 0.5f; flHeight *= 0.5f; // Compute direction vectors for the sprite Vector fwd, right( 1, 0, 0 ), up( 0, 1, 0 ); VectorSubtract( CurrentViewOrigin(), vecOrigin, fwd ); float flDist = VectorNormalize( fwd ); if (flDist >= 1e-3) { CrossProduct( CurrentViewUp(), fwd, right ); flDist = VectorNormalize( right ); if (flDist >= 1e-3) { CrossProduct( fwd, right, up ); } else { // In this case, fwd == g_vecVUp, it's right above or // below us in screen space CrossProduct( fwd, CurrentViewRight(), up ); VectorNormalize( up ); CrossProduct( up, fwd, right ); } } Vector left = -right; Vector down = -up; Vector back = -fwd; CMeshBuilder meshBuilder; Vector point; IMesh* pMesh = materials->GetDynamicMesh( ); meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 ); meshBuilder.Color4ubv (pColor); meshBuilder.TexCoord2f (0, 0, 1); VectorMA (vecOrigin, -flHeight, up, point); VectorMA (point, -flWidth, right, point); meshBuilder.TangentS3fv( left.Base() ); meshBuilder.TangentT3fv( down.Base() ); meshBuilder.Normal3fv( back.Base() ); meshBuilder.Position3fv (point.Base()); meshBuilder.AdvanceVertex(); meshBuilder.Color4ubv (pColor); meshBuilder.TexCoord2f (0, 0, 0); VectorMA (vecOrigin, flHeight, up, point); VectorMA (point, -flWidth, right, point); meshBuilder.TangentS3fv( left.Base() ); meshBuilder.TangentT3fv( down.Base() ); meshBuilder.Normal3fv( back.Base() ); meshBuilder.Position3fv (point.Base()); meshBuilder.AdvanceVertex(); meshBuilder.Color4ubv (pColor); meshBuilder.TexCoord2f (0, 1, 0); VectorMA (vecOrigin, flHeight, up, point); VectorMA (point, flWidth, right, point); meshBuilder.TangentS3fv( left.Base() ); meshBuilder.TangentT3fv( down.Base() ); meshBuilder.Normal3fv( back.Base() ); meshBuilder.Position3fv (point.Base()); meshBuilder.AdvanceVertex(); meshBuilder.Color4ubv (pColor); meshBuilder.TexCoord2f (0, 1, 1); VectorMA (vecOrigin, -flHeight, up, point); VectorMA (point, flWidth, right, point); meshBuilder.TangentS3fv( left.Base() ); meshBuilder.TangentT3fv( down.Base() ); meshBuilder.Normal3fv( back.Base() ); meshBuilder.Position3fv (point.Base()); meshBuilder.AdvanceVertex(); meshBuilder.End(); pMesh->Draw(); }
void CFXStaticLine::Draw( double frametime ) { Vector lineDir, viewDir, cross; Vector tmp; // Update the effect Update( frametime ); // Get the proper orientation for the line VectorSubtract( m_vecEnd, m_vecStart, lineDir ); VectorSubtract( m_vecEnd, CurrentViewOrigin(), viewDir ); cross = lineDir.Cross( viewDir ); VectorNormalize( cross ); CMatRenderContextPtr pRenderContext( materials ); //Bind the material IMesh* pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, m_pMaterial ); CMeshBuilder meshBuilder; meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 ); bool flipVertical = (m_uiFlags & FXSTATICLINE_FLIP_VERTICAL) != 0; bool flipHorizontal = (m_uiFlags & FXSTATICLINE_FLIP_HORIZONTAL ) != 0; //Setup our points VectorMA( m_vecStart, -m_fScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.Normal3fv( cross.Base() ); if (flipHorizontal) meshBuilder.TexCoord2f( 0, 0.0f, 1.0f ); else if (flipVertical) meshBuilder.TexCoord2f( 0, 0.0f, 0.0f ); else meshBuilder.TexCoord2f( 0, 1.0f, 1.0f ); meshBuilder.Color4ub( 255, 255, 255, 255 ); meshBuilder.AdvanceVertex(); VectorMA( m_vecStart, m_fScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.Normal3fv( cross.Base() ); if (flipHorizontal) meshBuilder.TexCoord2f( 0, 1.0f, 1.0f ); else if (flipVertical) meshBuilder.TexCoord2f( 0, 1.0f, 0.0f ); else meshBuilder.TexCoord2f( 0, 0.0f, 1.0f ); meshBuilder.Color4ub( 255, 255, 255, 255 ); meshBuilder.AdvanceVertex(); VectorMA( m_vecEnd, m_fScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.Normal3fv( cross.Base() ); if (flipHorizontal) meshBuilder.TexCoord2f( 0, 1.0f, 0.0f ); else if (flipVertical) meshBuilder.TexCoord2f( 0, 1.0f, 1.0f ); else meshBuilder.TexCoord2f( 0, 0.0f, 0.0f ); meshBuilder.Color4ub( 255, 255, 255, 255 ); meshBuilder.AdvanceVertex(); VectorMA( m_vecEnd, -m_fScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.Normal3fv( cross.Base() ); if (flipHorizontal) meshBuilder.TexCoord2f( 0, 0.0f, 0.0f ); else if (flipVertical) meshBuilder.TexCoord2f( 0, 0.0f, 1.0f ); else meshBuilder.TexCoord2f( 0, 1.0f, 0.0f ); meshBuilder.Color4ub( 255, 255, 255, 255 ); meshBuilder.AdvanceVertex(); meshBuilder.End(); pMesh->Draw(); }
//----------------------------------------------------------------------------- // Purpose: // Input : timeDelta - //----------------------------------------------------------------------------- void C_SignalFlare::Update( float timeDelta ) { CSimpleEmitter::Update( timeDelta ); //Make sure our stored resources are up to date RestoreResources(); //Don't do this if the console is down if ( timeDelta <= 0.0f ) return; float fColor; float baseScale = m_flScale; //Account for fading out if ( ( m_flDuration != -1.0f ) && ( ( m_flDuration - gpGlobals->curtime ) <= 10.0f ) ) { baseScale *= ( ( m_flDuration - gpGlobals->curtime ) / 10.0f ); } //Clamp the scale if vanished if ( baseScale < 0.01f ) { baseScale = 0.0f; if ( m_pParticle[0] != NULL ) { m_pParticle[0]->m_flDieTime = gpGlobals->curtime; m_pParticle[0]->m_uchStartSize = m_pParticle[0]->m_uchEndSize = 0; m_pParticle[0]->m_uchColor[0] = 0; m_pParticle[0]->m_uchColor[1] = 0; m_pParticle[0]->m_uchColor[2] = 0; } if ( m_pParticle[1] != NULL ) { m_pParticle[1]->m_flDieTime = gpGlobals->curtime; m_pParticle[1]->m_uchStartSize = m_pParticle[1]->m_uchEndSize = 0; m_pParticle[1]->m_uchColor[0] = 0; m_pParticle[1]->m_uchColor[1] = 0; m_pParticle[1]->m_uchColor[2] = 0; } return; } // // Dynamic light // if ( m_bLight ) { dlight_t *dl= effects->CL_AllocDlight( index ); dl->origin = GetAbsOrigin(); dl->color.r = 255; dl->color.g = dl->color.b = random->RandomInt( 32, 64 ); dl->radius = baseScale * random->RandomFloat( 110.0f, 128.0f ); dl->die = gpGlobals->curtime; } // // Smoke // if ( m_bSmoke ) { Vector smokeOrg = GetAbsOrigin(); Vector flareScreenDir = ( smokeOrg - CurrentViewOrigin() ); VectorNormalize( flareScreenDir ); smokeOrg = smokeOrg + ( flareScreenDir * 2.0f ); smokeOrg[2] += baseScale * 4.0f; SimpleParticle *sParticle = (SimpleParticle *) AddParticle( sizeof( SimpleParticle ), g_Mat_DustPuff[1], smokeOrg ); if ( sParticle == NULL ) return; sParticle->m_flLifetime = 0.0f; sParticle->m_flDieTime = 1.0f; sParticle->m_vecVelocity = Vector( random->RandomFloat( -16.0f, 16.0f ), random->RandomFloat( -16.0f, 16.0f ), random->RandomFloat( 8.0f, 16.0f ) + 32.0f ); fColor = random->RandomInt( 64, 128 ); sParticle->m_uchColor[0] = fColor+64; sParticle->m_uchColor[1] = fColor; sParticle->m_uchColor[2] = fColor; sParticle->m_uchStartAlpha = random->RandomInt( 16, 32 ); sParticle->m_uchEndAlpha = 0; sParticle->m_uchStartSize = random->RandomInt( 2, 4 ); sParticle->m_uchEndSize = sParticle->m_uchStartSize * 6.0f; sParticle->m_flRoll = random->RandomInt( 0, 360 ); sParticle->m_flRollDelta = random->RandomFloat( -2.0f, 2.0f ); } //Check for LOS if ( EffectOccluded( GetAbsOrigin() ) ) { if ( m_pParticle[0] != NULL ) { m_pParticle[0]->m_uchColor[0] *= 0.5f; m_pParticle[0]->m_uchColor[1] *= 0.5f; m_pParticle[0]->m_uchColor[2] *= 0.5f; } if ( m_pParticle[1] != NULL ) { m_pParticle[1]->m_uchColor[0] *= 0.25f; m_pParticle[1]->m_uchColor[1] *= 0.25f; m_pParticle[1]->m_uchColor[2] *= 0.25f; } return; } // // Outer glow // Vector offset; //Cause the base of the effect to shake offset.Random( -0.5f * baseScale, 0.5f * baseScale ); offset += GetAbsOrigin(); if ( m_pParticle[0] != NULL ) { m_pParticle[0]->m_Pos = offset; m_pParticle[0]->m_flLifetime = 0.0f; m_pParticle[0]->m_flDieTime = 2.0f; m_pParticle[0]->m_vecVelocity.Init(); fColor = random->RandomInt( 100.0f, 128.0f ); m_pParticle[0]->m_uchColor[0] = fColor; m_pParticle[0]->m_uchColor[1] = fColor; m_pParticle[0]->m_uchColor[2] = fColor; m_pParticle[0]->m_uchStartAlpha = fColor; m_pParticle[0]->m_uchEndAlpha = fColor; m_pParticle[0]->m_uchStartSize = baseScale * (float) random->RandomInt( 32, 48 ); m_pParticle[0]->m_uchEndSize = m_pParticle[0]->m_uchStartSize; m_pParticle[0]->m_flRollDelta = 0.0f; if ( random->RandomInt( 0, 4 ) == 3 ) { m_pParticle[0]->m_flRoll += random->RandomInt( 2, 8 ); } } // // Inner core // //Cause the base of the effect to shake offset.Random( -1.0f * baseScale, 1.0f * baseScale ); offset += GetAbsOrigin(); if ( m_pParticle[1] != NULL ) { m_pParticle[1]->m_Pos = offset; m_pParticle[1]->m_flLifetime = 0.0f; m_pParticle[1]->m_flDieTime = 2.0f; m_pParticle[1]->m_vecVelocity.Init(); fColor = 255; m_pParticle[1]->m_uchColor[0] = fColor; m_pParticle[1]->m_uchColor[1] = fColor; m_pParticle[1]->m_uchColor[2] = fColor; m_pParticle[1]->m_uchStartAlpha = fColor; m_pParticle[1]->m_uchEndAlpha = fColor; m_pParticle[1]->m_uchStartSize = baseScale * (float) random->RandomInt( 2, 4 ); m_pParticle[1]->m_uchEndSize = m_pParticle[0]->m_uchStartSize; m_pParticle[1]->m_flRoll = random->RandomInt( 0, 360 ); } }
//----------------------------------------------------------------------------- // Purpose: Special draw for the warped overlay //----------------------------------------------------------------------------- void CWarpOverlay::Draw( bool bCacheFullSceneState ) { // Get the vector to the sun. Vector vToGlow; if( m_bDirectional ) vToGlow = m_vDirection; else vToGlow = m_vPos - CurrentViewOrigin(); VectorNormalize( vToGlow ); float flDot = vToGlow.Dot( CurrentViewForward() ); if( flDot <= g_flOverlayRange ) return; UpdateGlowObstruction( vToGlow, bCacheFullSceneState ); if( m_flGlowObstructionScale == 0 ) return; CMatRenderContextPtr pRenderContext( materials ); //FIXME: Allow multiple? for( int iSprite=0; iSprite < m_nSprites; iSprite++ ) { CGlowSprite *pSprite = &m_Sprites[iSprite]; // Figure out the color and size to draw it. float flHorzSize, flVertSize; Vector vColor; CalcSpriteColorAndSize( flDot, pSprite, &flHorzSize, &flVertSize, &vColor ); // Setup the basis to draw the sprite. Vector vBasePt, vUp, vRight; CalcBasis( vToGlow, flHorzSize, flVertSize, vBasePt, vUp, vRight ); // Draw the sprite. IMaterial *pMaterial = materials->FindMaterial( "sun/overlay", TEXTURE_GROUP_CLIENT_EFFECTS ); IMesh *pMesh = pRenderContext->GetDynamicMesh( false, 0, 0, pMaterial ); CMeshBuilder builder; builder.Begin( pMesh, MATERIAL_QUADS, 1 ); Vector vPt; vPt = vBasePt - vRight + vUp; builder.Position3fv( vPt.Base() ); builder.Color4f( VectorExpand(vColor), 1 ); builder.TexCoord2f( 0, 0, 1 ); builder.AdvanceVertex(); vPt = vBasePt + vRight + vUp; builder.Position3fv( vPt.Base() ); builder.Color4f( VectorExpand(vColor), 1 ); builder.TexCoord2f( 0, 1, 1 ); builder.AdvanceVertex(); vPt = vBasePt + vRight - vUp; builder.Position3fv( vPt.Base() ); builder.Color4f( VectorExpand(vColor), 1 ); builder.TexCoord2f( 0, 1, 0 ); builder.AdvanceVertex(); vPt = vBasePt - vRight - vUp; builder.Position3fv( vPt.Base() ); builder.Color4f( VectorExpand(vColor), 1 ); builder.TexCoord2f( 0, 0, 0 ); builder.AdvanceVertex(); builder.End( false, true ); } }
//----------------------------------------------------------------------------- // Purpose: // TFTODO: Make the sniper dot get brighter the more damage it will do. //----------------------------------------------------------------------------- int CSniperDot::DrawModel( int flags ) { // Get the owning player. C_TFPlayer *pPlayer = ToTFPlayer( GetOwnerEntity() ); if ( !pPlayer ) return -1; // Get the sprite rendering position. Vector vecEndPos; float flSize = 6.0; if ( !pPlayer->IsDormant() ) { Vector vecAttachment, vecDir; QAngle angles; float flDist = MAX_TRACE_LENGTH; // Always draw the dot in front of our faces when in first-person. if ( pPlayer->IsLocalPlayer() ) { // Take our view position and orientation vecAttachment = CurrentViewOrigin(); vecDir = CurrentViewForward(); // Clamp the forward distance for the sniper's firstperson flDist = 384; flSize = 2.0; } else { // Take the owning player eye position and direction. vecAttachment = pPlayer->EyePosition(); QAngle angles = pPlayer->EyeAngles(); AngleVectors( angles, &vecDir ); } trace_t tr; UTIL_TraceLine( vecAttachment, vecAttachment + ( vecDir * flDist ), MASK_SHOT, pPlayer, COLLISION_GROUP_NONE, &tr ); // Backup off the hit plane, towards the source vecEndPos = tr.endpos + vecDir * -4; } else { // Just use our position if we can't predict it otherwise. vecEndPos = GetAbsOrigin(); } // Draw our laser dot in space. CMatRenderContextPtr pRenderContext( materials ); pRenderContext->Bind( m_hSpriteMaterial, this ); float flLifeTime = gpGlobals->curtime - m_flChargeStartTime; float flStrength = RemapValClamped( flLifeTime, 0.0, TF_WEAPON_SNIPERRIFLE_DAMAGE_MAX / TF_WEAPON_SNIPERRIFLE_CHARGE_PER_SEC, 0.1, 1.0 ); color32 innercolor = { 255, 255, 255, 255 }; color32 outercolor = { 255, 255, 255, 128 }; DrawSprite( vecEndPos, flSize, flSize, outercolor ); DrawSprite( vecEndPos, flSize * flStrength, flSize * flStrength, innercolor ); // Successful. return 1; }
//----------------------------------------------------------------------------- // Purpose: // TFTODO: Make the sniper dot get brighter the more damage it will do. //----------------------------------------------------------------------------- int CSniperDot::DrawModel( int flags ) { // Get the owning player. C_TFPlayer *pPlayer = ToTFPlayer( GetOwnerEntity() ); if ( !pPlayer ) return -1; // Get the sprite rendering position. Vector vecEndPos; float flSize = 6.0; if ( !pPlayer->IsDormant() ) { Vector vecAttachment, vecDir; QAngle angles; float flDist = MAX_TRACE_LENGTH; // Always draw the dot in front of our faces when in first-person. if ( pPlayer->IsLocalPlayer() ) { // Take our view position and orientation vecAttachment = CurrentViewOrigin(); vecDir = CurrentViewForward(); // Clamp the forward distance for the sniper's firstperson flDist = 384; flSize = 2.0; } else { // Take the owning player eye position and direction. vecAttachment = pPlayer->EyePosition(); QAngle angles = pPlayer->EyeAngles(); AngleVectors( angles, &vecDir ); } trace_t tr; UTIL_TraceLine( vecAttachment, vecAttachment + ( vecDir * flDist ), MASK_SHOT, pPlayer, COLLISION_GROUP_NONE, &tr ); // Backup off the hit plane, towards the source vecEndPos = tr.endpos + vecDir * -4; } else { // Just use our position if we can't predict it otherwise. vecEndPos = GetAbsOrigin(); } // Draw our laser dot in space. CMatRenderContextPtr pRenderContext( materials ); pRenderContext->Bind( m_hSpriteMaterial, this ); float flLifeTime = gpGlobals->curtime - m_flChargeStartTime; float flStrength = RemapValClamped( flLifeTime, 0.0, TF_WEAPON_SNIPERRIFLE_DAMAGE_MAX / TF_WEAPON_SNIPERRIFLE_CHARGE_PER_SEC, 0.1, 1.0 ); color32 innercolor = { 255, 255, 255, 255 }; color32 outercolor = { 255, 255, 255, 128 }; // PistonMiner: DM sniper point coloring if (TFGameRules()->IsDeathmatch()) { // Get the color of the mercenary we are drawing the dot of. C_TF_PlayerResource *tf_PR = dynamic_cast<C_TF_PlayerResource *>(g_PR); Color ownercolor = tf_PR->GetPlayerColor(pPlayer->index); // Convert to HSV so we can edit the color better. Vector hsv, rgb; RGBtoHSV(Vector(ownercolor.r() / 255.f, ownercolor.g() / 255.f, ownercolor.b() / 255.f), hsv); // Set the Value to max for constant brightness. hsv.z = 1.0; // Convert back to RGB HSVtoRGB(hsv, rgb); // Apply the color to our sprite. m_hSpriteMaterial->ColorModulate( rgb.x, rgb.y, rgb.z ); } DrawSprite( vecEndPos, flSize, flSize, outercolor ); DrawSprite( vecEndPos, flSize * flStrength, flSize * flStrength, innercolor ); // Successful. return 1; }
float PixelVisibility_DrawProxy( IMatRenderContext *pRenderContext, OcclusionQueryObjectHandle_t queryHandle, Vector origin, float scale, float proxyAspect, IMaterial *pMaterial, bool screenspace ) { Vector point; // don't expand this with distance to fit pixels or the sprite will poke through // only expand the parts perpendicular to the view float forwardScale = scale; // draw a pyramid of points touching a sphere of radius "scale" at origin float pixelsPerUnit = pRenderContext->ComputePixelDiameterOfSphere( origin, 1.0f ); pixelsPerUnit = MAX( pixelsPerUnit, 1e-4f ); if ( screenspace ) { // Force this to be the size of a sphere of diameter "scale" at some reference distance (1.0 unit) float pixelsPerUnit2 = pRenderContext->ComputePixelDiameterOfSphere( CurrentViewOrigin() + CurrentViewForward()*1.0f, scale*0.5f ); // force drawing of "scale" pixels scale = pixelsPerUnit2 / pixelsPerUnit; } else { float pixels = scale * pixelsPerUnit; // make the radius larger to ensure a minimum screen space size of the proxy geometry if ( pixels < MIN_PROXY_PIXELS ) { scale = MIN_PROXY_PIXELS / pixelsPerUnit; } } // collapses the pyramid to a plane - so this could be a quad instead Vector dir = origin - CurrentViewOrigin(); VectorNormalize(dir); origin -= dir * forwardScale; forwardScale = 0.0f; // Vector verts[5]; const float sqrt2 = 0.707106781f; // sqrt(2) - keeps all vectors the same length from origin scale *= sqrt2; float scale45x = scale; float scale45y = scale / proxyAspect; verts[0] = origin - CurrentViewForward() * forwardScale; // the apex of the pyramid verts[1] = origin + CurrentViewUp() * scale45y - CurrentViewRight() * scale45x; // these four form the base verts[2] = origin + CurrentViewUp() * scale45y + CurrentViewRight() * scale45x; // the pyramid is a sprite with a point that verts[3] = origin - CurrentViewUp() * scale45y + CurrentViewRight() * scale45x; // pokes back toward the camera through any nearby verts[4] = origin - CurrentViewUp() * scale45y - CurrentViewRight() * scale45x; // geometry // get screen coords of edges Vector screen[4]; for ( int i = 0; i < 4; i++ ) { extern int ScreenTransform( const Vector& point, Vector& screen ); if ( ScreenTransform( verts[i+1], screen[i] ) ) return -1; } // compute area and screen-clipped area float w = screen[1].x - screen[0].x; float h = screen[0].y - screen[3].y; float ws = MIN(1.0f, screen[1].x) - MAX(-1.0f, screen[0].x); float hs = MIN(1.0f, screen[0].y) - MAX(-1.0f, screen[3].y); float area = w*h; // area can be zero when we ALT-TAB float areaClipped = ws*hs; float ratio = 0.0f; if ( area != 0 ) { // compute the ratio of the area not clipped by the frustum to total area ratio = areaClipped / area; ratio = clamp(ratio, 0.0f, 1.0f); } pRenderContext->BeginOcclusionQueryDrawing( queryHandle ); CMeshBuilder meshBuilder; IMesh* pMesh = pRenderContext->GetDynamicMesh( false, NULL, NULL, pMaterial ); meshBuilder.Begin( pMesh, MATERIAL_TRIANGLES, 4 ); // draw a pyramid for ( int i = 0; i < 4; i++ ) { int a = i+1; int b = (a%4)+1; meshBuilder.Position3fv( verts[0].Base() ); meshBuilder.AdvanceVertex(); meshBuilder.Position3fv( verts[a].Base() ); meshBuilder.AdvanceVertex(); meshBuilder.Position3fv( verts[b].Base() ); meshBuilder.AdvanceVertex(); } meshBuilder.End(); pMesh->Draw(); // sprite/quad proxy #if 0 meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 ); VectorMA (origin, -scale, CurrentViewUp(), point); VectorMA (point, -scale, CurrentViewRight(), point); meshBuilder.Position3fv (point.Base()); meshBuilder.AdvanceVertex(); VectorMA (origin, scale, CurrentViewUp(), point); VectorMA (point, -scale, CurrentViewRight(), point); meshBuilder.Position3fv (point.Base()); meshBuilder.AdvanceVertex(); VectorMA (origin, scale, CurrentViewUp(), point); VectorMA (point, scale, CurrentViewRight(), point); meshBuilder.Position3fv (point.Base()); meshBuilder.AdvanceVertex(); VectorMA (origin, -scale, CurrentViewUp(), point); VectorMA (point, scale, CurrentViewRight(), point); meshBuilder.Position3fv (point.Base()); meshBuilder.AdvanceVertex(); meshBuilder.End(); pMesh->Draw(); #endif pRenderContext->EndOcclusionQueryDrawing( queryHandle ); // fraction clipped by frustum return ratio; }
//----------------------------------------------------------------------------- // Purpose: Simulate and render the particle in this system // Input : *pInParticle - particle to consider // *pDraw - drawing utilities // &sortKey - sorting key // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CSimple3DEmitter::SimulateAndRender( Particle *pInParticle, ParticleDraw *pDraw, float &sortKey ) { Particle3D *pParticle = (Particle3D *) pInParticle; const float timeDelta = pDraw->GetTimeDelta(); //Should this particle die? pParticle->m_flLifetime += timeDelta; if ( pParticle->m_flLifetime >= pParticle->m_flDieTime ) return false; sortKey = CurrentViewForward().Dot( CurrentViewOrigin() - pParticle->m_Pos ); // ------------------------------------------------------- // Set color based on direction towards camera // ------------------------------------------------------- Vector color; Vector vFaceNorm; Vector vCameraToFace = (pParticle->m_Pos - CurrentViewOrigin()); AngleVectors(pParticle->m_vAngles,&vFaceNorm); float flFacing = DotProduct(vCameraToFace,vFaceNorm); if (flFacing <= 0) { color[0] = pParticle->m_uchFrontColor[0] / 255.0f; color[1] = pParticle->m_uchFrontColor[1] / 255.0f; color[2] = pParticle->m_uchFrontColor[2] / 255.0f; } else { color[0] = pParticle->m_uchBackColor[0] / 255.0f; color[1] = pParticle->m_uchBackColor[1] / 255.0f; color[2] = pParticle->m_uchBackColor[2] / 255.0f; } // Angular rotation pParticle->m_vAngles.x += pParticle->m_flAngSpeed * timeDelta; pParticle->m_vAngles.y += pParticle->m_flAngSpeed * timeDelta; pParticle->m_vAngles.z += pParticle->m_flAngSpeed * timeDelta; //Render it in world space RenderParticle_ColorSizeAngles( pDraw, pParticle->m_Pos, color, 1.0f - (pParticle->m_flLifetime / pParticle->m_flDieTime), pParticle->m_uchSize, pParticle->m_vAngles); //Simulate the movement with collision trace_t trace; m_ParticleCollision.MoveParticle( pParticle->m_Pos, pParticle->m_vecVelocity, &pParticle->m_flAngSpeed, timeDelta, &trace ); // --------------------------------------- // Decay towards flat // --------------------------------------- if (pParticle->m_flAngSpeed == 0 || trace.fraction != 1.0) { pParticle->m_vAngles.x = anglemod(pParticle->m_vAngles.x); if (pParticle->m_vAngles.x < 180) { if (fabs(pParticle->m_vAngles.x - 90) > 0.5) { pParticle->m_vAngles.x = 0.5*pParticle->m_vAngles.x + 46; } } else { if (fabs(pParticle->m_vAngles.x - 270) > 0.5) { pParticle->m_vAngles.x = 0.5*pParticle->m_vAngles.x + 135; } } pParticle->m_vAngles.y = anglemod(pParticle->m_vAngles.y); if (fabs(pParticle->m_vAngles.y) > 0.5) { pParticle->m_vAngles.y = 0.5*pParticle->m_vAngles.z; } } return true; }
//----------------------------------------------------------------------------- // Compute the bounding box's center, size, and basis //----------------------------------------------------------------------------- void C_EntityDissolve::ComputeRenderInfo( mstudiobbox_t *pHitBox, const matrix3x4_t &hitboxToWorld, Vector *pVecAbsOrigin, Vector *pXVec, Vector *pYVec ) { // Compute the center of the hitbox in worldspace Vector vecHitboxCenter; VectorAdd( pHitBox->bbmin, pHitBox->bbmax, vecHitboxCenter ); vecHitboxCenter *= 0.5f; VectorTransform( vecHitboxCenter, hitboxToWorld, *pVecAbsOrigin ); // Get the object's basis Vector vec[3]; MatrixGetColumn( hitboxToWorld, 0, vec[0] ); MatrixGetColumn( hitboxToWorld, 1, vec[1] ); MatrixGetColumn( hitboxToWorld, 2, vec[2] ); // vec[1] *= -1.0f; Vector vecViewDir; VectorSubtract( CurrentViewOrigin(), *pVecAbsOrigin, vecViewDir ); VectorNormalize( vecViewDir ); // Project the shadow casting direction into the space of the hitbox Vector localViewDir; localViewDir[0] = DotProduct( vec[0], vecViewDir ); localViewDir[1] = DotProduct( vec[1], vecViewDir ); localViewDir[2] = DotProduct( vec[2], vecViewDir ); // Figure out which vector has the largest component perpendicular // to the view direction... // Sort by how perpendicular it is int vecIdx[3]; SortAbsVectorComponents( localViewDir, vecIdx ); // Here's our hitbox basis vectors; namely the ones that are // most perpendicular to the view direction *pXVec = vec[vecIdx[0]]; *pYVec = vec[vecIdx[1]]; // Project them into a plane perpendicular to the view direction *pXVec -= vecViewDir * DotProduct( vecViewDir, *pXVec ); *pYVec -= vecViewDir * DotProduct( vecViewDir, *pYVec ); VectorNormalize( *pXVec ); VectorNormalize( *pYVec ); // Compute the hitbox size Vector boxSize; VectorSubtract( pHitBox->bbmax, pHitBox->bbmin, boxSize ); // We project the two longest sides into the vectors perpendicular // to the projection direction, then add in the projection of the perp direction Vector2D size( boxSize[vecIdx[0]], boxSize[vecIdx[1]] ); size.x *= fabs( DotProduct( vec[vecIdx[0]], *pXVec ) ); size.y *= fabs( DotProduct( vec[vecIdx[1]], *pYVec ) ); // Add the third component into x and y size.x += boxSize[vecIdx[2]] * fabs( DotProduct( vec[vecIdx[2]], *pXVec ) ); size.y += boxSize[vecIdx[2]] * fabs( DotProduct( vec[vecIdx[2]], *pYVec ) ); // Bloat a bit, since the shadow wants to extend outside the model a bit size *= 2.0f; // Clamp the minimum size Vector2DMax( size, Vector2D(10.0f, 10.0f), size ); // Factor the size into the xvec + yvec (*pXVec) *= size.x * 0.5f; (*pYVec) *= size.y * 0.5f; }
void CFXDiscreetLine::Draw( double frametime ) { Vector lineDir, viewDir, cross; Vector vecEnd, vecStart; Vector tmp; // Update the effect Update( frametime ); // Calculate our distance along our path float sDistance = m_fVelocity * m_fStartTime; float eDistance = sDistance - m_fLength; //Clip to start sDistance = MAX( 0.0f, sDistance ); eDistance = MAX( 0.0f, eDistance ); if ( ( sDistance == 0.0f ) && ( eDistance == 0.0f ) ) return; // Clip it if ( m_fClipLength != 0.0f ) { sDistance = MIN( sDistance, m_fClipLength ); eDistance = MIN( eDistance, m_fClipLength ); } // Get our delta to calculate the tc offset float dDistance = fabs( sDistance - eDistance ); float dTotal = ( m_fLength != 0.0f ) ? m_fLength : 0.01f; float fOffset = ( dDistance / dTotal ); // Find our points along our path VectorMA( m_vecOrigin, sDistance, m_vecDirection, vecEnd ); VectorMA( m_vecOrigin, eDistance, m_vecDirection, vecStart ); //Setup our info for drawing the line VectorSubtract( vecEnd, vecStart, lineDir ); VectorSubtract( vecEnd, CurrentViewOrigin(), viewDir ); cross = lineDir.Cross( viewDir ); VectorNormalize( cross ); CMeshBuilder meshBuilder; IMesh *pMesh; CMatRenderContextPtr pRenderContext( materials ); // Better, more visible tracers if ( tracer_extra.GetBool() ) { float flScreenWidth = ScreenWidth(); float flHalfScreenWidth = flScreenWidth * 0.5f; float zCoord = CurrentViewForward().Dot( vecStart - CurrentViewOrigin() ); float flScreenSpaceWidth = m_fScale * flHalfScreenWidth / zCoord; float flAlpha; float flScale; if ( flScreenSpaceWidth < 0.5f ) { flAlpha = RemapVal( flScreenSpaceWidth, 0.25f, 2.0f, 0.3f, 1.0f ); flAlpha = clamp( flAlpha, 0.25f, 1.0f ); flScale = 0.5f * zCoord / flHalfScreenWidth; } else { flAlpha = 1.0f; flScale = m_fScale; } //Bind the material pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, m_pMaterial ); meshBuilder.Begin( pMesh, MATERIAL_QUADS, 2 ); float color = (int) 255.0f * flAlpha; //FIXME: for now no coloration VectorMA( vecStart, -flScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 1.0f, 0.0f ); meshBuilder.Color4ub( color, color, color, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); VectorMA( vecStart, flScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 0.0f, 0.0f ); meshBuilder.Color4ub( color, color, color, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); VectorMA( vecEnd, flScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 0.0f, fOffset ); meshBuilder.Color4ub( color, color, color, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); VectorMA( vecEnd, -flScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 1.0f, fOffset ); meshBuilder.Color4ub( color, color, color, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); flScale = flScale * 2.0f; color = (int) 64.0f * flAlpha; // Soft outline VectorMA( vecStart, -flScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 1.0f, 0.0f ); meshBuilder.Color4ub( color, color, color, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); VectorMA( vecStart, flScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 0.0f, 0.0f ); meshBuilder.Color4ub( color, color, color, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); VectorMA( vecEnd, flScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 0.0f, fOffset ); meshBuilder.Color4ub( color, color, color, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); VectorMA( vecEnd, -flScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 1.0f, fOffset ); meshBuilder.Color4ub( color, color, color, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); } else { //Bind the material pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, m_pMaterial ); meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 ); //FIXME: for now no coloration VectorMA( vecStart, -m_fScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 1.0f, 0.0f ); meshBuilder.Color4ub( 255, 255, 255, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); VectorMA( vecStart, m_fScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 0.0f, 0.0f ); meshBuilder.Color4ub( 255, 255, 255, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); VectorMA( vecEnd, m_fScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 0.0f, fOffset ); meshBuilder.Color4ub( 255, 255, 255, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); VectorMA( vecEnd, -m_fScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 1.0f, fOffset ); meshBuilder.Color4ub( 255, 255, 255, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); } meshBuilder.End(); pMesh->Draw(); }