diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/client/particles_localspace.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'game/client/particles_localspace.cpp')
| -rw-r--r-- | game/client/particles_localspace.cpp | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/game/client/particles_localspace.cpp b/game/client/particles_localspace.cpp new file mode 100644 index 0000000..5a42601 --- /dev/null +++ b/game/client/particles_localspace.cpp @@ -0,0 +1,160 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Particles which are simulated locally to some space (attachment, bone, etc) +// +//=============================================================================// + +#include "cbase.h" +#include "particles_simple.h" +#include "particles_localspace.h" + +#include "tier0/memdbgon.h" + +//----------------------------------------------------------------------------- +// Constructor +//----------------------------------------------------------------------------- +CLocalSpaceEmitter::CLocalSpaceEmitter( const char *pDebugName ) : + CSimpleEmitter( pDebugName ) +{ +} + + +inline const matrix3x4_t& CLocalSpaceEmitter::GetTransformMatrix() const +{ + return m_ParticleEffect.GetLocalSpaceTransform(); +} + + +//----------------------------------------------------------------------------- +// Purpose: Creates a local space emitter +//----------------------------------------------------------------------------- +CSmartPtr<CLocalSpaceEmitter> CLocalSpaceEmitter::Create( const char *pDebugName, + ClientEntityHandle_t hEntity, int nAttachment, int fFlags ) +{ + CLocalSpaceEmitter *pRet = new CLocalSpaceEmitter( pDebugName ); + pRet->SetDynamicallyAllocated( true ); + pRet->m_hEntity = hEntity; + pRet->m_nAttachment = nAttachment; + pRet->m_fFlags = fFlags; + + pRet->SetupTransformMatrix(); + + return pRet; +} + +//----------------------------------------------------------------------------- +// Purpose: Used to build the transformation matrix for this frame +//----------------------------------------------------------------------------- +void CLocalSpaceEmitter::Update( float flTimeDelta ) +{ + SetupTransformMatrix(); +} + +extern void FormatViewModelAttachment( Vector &vOrigin, bool bInverse ); + + +void CLocalSpaceEmitter::SimulateParticles( CParticleSimulateIterator *pIterator ) +{ + float timeDelta = pIterator->GetTimeDelta(); + + SimpleParticle *pParticle = (SimpleParticle*)pIterator->GetFirst(); + while ( pParticle ) + { + // Update velocity + UpdateVelocity( pParticle, timeDelta ); + pParticle->m_Pos += pParticle->m_vecVelocity * timeDelta; + + // Should this particle die? + pParticle->m_flLifetime += timeDelta; + UpdateRoll( pParticle, timeDelta ); + + // If we're dead, we're done + if ( pParticle->m_flLifetime >= pParticle->m_flDieTime ) + { + pIterator->RemoveParticle( pParticle ); + } + + pParticle = (SimpleParticle*)pIterator->GetNext(); + } +} + + +void CLocalSpaceEmitter::RenderParticles( CParticleRenderIterator *pIterator ) +{ + const matrix3x4_t &mLocalToWorld = GetTransformMatrix(); + const VMatrix &mModelView = ParticleMgr()->GetModelView(); + + const SimpleParticle *pParticle = (const SimpleParticle *)pIterator->GetFirst(); + while ( pParticle ) + { + // Transform it + Vector screenPos, worldPos; + VectorTransform( pParticle->m_Pos, mLocalToWorld, worldPos ); + + // Correct viewmodel squashing + if ( m_fFlags & FLE_VIEWMODEL ) + { + FormatViewModelAttachment( worldPos, false ); + } + + TransformParticle( mModelView, worldPos, screenPos ); + + float sortKey = (int) screenPos.z; + + // Render it + RenderParticle_ColorSizeAngle( + pIterator->GetParticleDraw(), + screenPos, + UpdateColor( pParticle ), + UpdateAlpha( pParticle ) * GetAlphaDistanceFade( screenPos, m_flNearClipMin, m_flNearClipMax ), + UpdateScale( pParticle ), + pParticle->m_flRoll + ); + + pParticle = (const SimpleParticle *)pIterator->GetNext( sortKey ); + } +} + + + +//----------------------------------------------------------------------------- +// Purpose: Create the matrix by which we'll transform the particle's local +// space into world space, via the attachment's transform +//----------------------------------------------------------------------------- +void CLocalSpaceEmitter::SetupTransformMatrix( void ) +{ + IClientRenderable *pRenderable = ClientEntityList().GetClientRenderableFromHandle( m_hEntity ); + if ( pRenderable ) + { + matrix3x4_t mat; + if ( pRenderable->GetAttachment( m_nAttachment, mat ) == false ) + { + // This attachment is bogus! + Assert(0); + } + + // Tell the particle effect so it knows + Vector origin; + MatrixGetColumn( mat, 3, origin ); + m_ParticleEffect.SetLocalSpaceTransform( mat ); + SetSortOrigin( origin ); + + C_BaseEntity *pEnt = pRenderable->GetIClientUnknown()->GetBaseEntity(); + if ( pEnt ) + { + Vector vWorldMins, vWorldMaxs; + float scale = pEnt->CollisionProp()->BoundingRadius(); + vWorldMins[0] = origin[0] - scale; + vWorldMins[1] = origin[1] - scale; + vWorldMins[2] = origin[2] - scale; + vWorldMaxs[0] = origin[0] + scale; + vWorldMaxs[1] = origin[1] + scale; + vWorldMaxs[2] = origin[2] + scale; + GetBinding().SetBBox( vWorldMins, vWorldMaxs, true ); + } + } + + // We preapply the local transform because we need to squash it for viewmodel FOV. + m_ParticleEffect.SetAutoApplyLocalTransform( false ); +} + |