diff options
| author | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
|---|---|---|
| committer | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
| commit | 39ed87570bdb2f86969d4be821c94b722dc71179 (patch) | |
| tree | abc53757f75f40c80278e87650ea92808274aa59 /mp/src/game/client/particles_localspace.cpp | |
| download | source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip | |
First version of the SOurce SDK 2013
Diffstat (limited to 'mp/src/game/client/particles_localspace.cpp')
| -rw-r--r-- | mp/src/game/client/particles_localspace.cpp | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/mp/src/game/client/particles_localspace.cpp b/mp/src/game/client/particles_localspace.cpp new file mode 100644 index 00000000..0cb1117e --- /dev/null +++ b/mp/src/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 );
+}
+
|