void FormatViewModelAttachment( Vector &vOrigin, bool bInverse ) { // Presumably, SetUpView has been called so we know our FOV and render origin. const CViewSetup *pViewSetup = view->GetPlayerViewSetup(); float worldx = tan( pViewSetup->fov * M_PI/360.0 ); float viewx = tan( pViewSetup->fovViewmodel * M_PI/360.0 ); // aspect ratio cancels out, so only need one factor // the difference between the screen coordinates of the 2 systems is the ratio // of the coefficients of the projection matrices (tan (fov/2) is that coefficient) float factorX = worldx / viewx; float factorY = factorX; // Get the coordinates in the viewer's space. Vector tmp = vOrigin - pViewSetup->origin; Vector vTransformed( MainViewRight().Dot( tmp ), MainViewUp().Dot( tmp ), MainViewForward().Dot( tmp ) ); // Now squash X and Y. if ( bInverse ) { if ( factorX != 0 && factorY != 0 ) { vTransformed.x /= factorX; vTransformed.y /= factorY; } else { vTransformed.x = 0.0f; vTransformed.y = 0.0f; } } else { vTransformed.x *= factorX; vTransformed.y *= factorY; } // Transform back to world space. Vector vOut = (MainViewRight() * vTransformed.x) + (MainViewUp() * vTransformed.y) + (MainViewForward() * vTransformed.z); vOrigin = pViewSetup->origin + vOut; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void C_EnvStarfield::ClientThink( void ) { if ( !m_bOn || !m_flDensity ) return; PMaterialHandle hParticleMaterial = m_pEmitter->GetPMaterial( "effects/spark_noz" ); // Find a start & end point for the particle // Start particles straight ahead of the client Vector vecViewOrigin = MainViewOrigin(engine->GetActiveSplitScreenPlayerSlot()); // Determine the number of particles m_flNumParticles += 1.0 * (m_flDensity); int iNumParticles = floor(m_flNumParticles); m_flNumParticles -= iNumParticles; // Add particles for ( int i = 0; i < iNumParticles; i++ ) { float flDiameter = cl_starfield_diameter.GetFloat(); Vector vecStart = vecViewOrigin + (MainViewForward(engine->GetActiveSplitScreenPlayerSlot()) * cl_starfield_distance.GetFloat() ); Vector vecEnd = vecViewOrigin + (MainViewRight(engine->GetActiveSplitScreenPlayerSlot()) * RandomFloat(-flDiameter,flDiameter)) + (MainViewUp(engine->GetActiveSplitScreenPlayerSlot()) * RandomFloat(-flDiameter,flDiameter)); Vector vecDir = (vecEnd - vecStart); float flDistance = VectorNormalize( vecDir ); float flTravelTime = 2.0; // Start a random amount along the path vecStart += vecDir * ( RandomFloat(0.1,0.3) * flDistance ); TrailParticle *pParticle = (TrailParticle *) m_pEmitter->AddParticle( sizeof(TrailParticle), hParticleMaterial, vecStart ); if ( pParticle ) { pParticle->m_vecVelocity = vecDir * (flDistance / flTravelTime); pParticle->m_flDieTime = flTravelTime; pParticle->m_flLifetime = 0; pParticle->m_flWidth = RandomFloat( 1, 3 ); pParticle->m_flLength = RandomFloat( 0.05, 0.4 ); pParticle->m_color.r = 255; pParticle->m_color.g = 255; pParticle->m_color.b = 255; pParticle->m_color.a = 255; } } }