Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

160 lines
4.8 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Particles which are simulated locally to some space (attachment, bone, etc)
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "particles_simple.h"
  8. #include "particles_localspace.h"
  9. #include "tier0/memdbgon.h"
  10. //-----------------------------------------------------------------------------
  11. // Constructor
  12. //-----------------------------------------------------------------------------
  13. CLocalSpaceEmitter::CLocalSpaceEmitter( const char *pDebugName ) :
  14. CSimpleEmitter( pDebugName )
  15. {
  16. }
  17. inline const matrix3x4_t& CLocalSpaceEmitter::GetTransformMatrix() const
  18. {
  19. return m_ParticleEffect.GetLocalSpaceTransform();
  20. }
  21. //-----------------------------------------------------------------------------
  22. // Purpose: Creates a local space emitter
  23. //-----------------------------------------------------------------------------
  24. CSmartPtr<CLocalSpaceEmitter> CLocalSpaceEmitter::Create( const char *pDebugName,
  25. ClientEntityHandle_t hEntity, int nAttachment, int fFlags )
  26. {
  27. CLocalSpaceEmitter *pRet = new CLocalSpaceEmitter( pDebugName );
  28. pRet->SetDynamicallyAllocated( true );
  29. pRet->m_hEntity = hEntity;
  30. pRet->m_nAttachment = nAttachment;
  31. pRet->m_fFlags = fFlags;
  32. pRet->SetupTransformMatrix();
  33. return pRet;
  34. }
  35. //-----------------------------------------------------------------------------
  36. // Purpose: Used to build the transformation matrix for this frame
  37. //-----------------------------------------------------------------------------
  38. void CLocalSpaceEmitter::Update( float flTimeDelta )
  39. {
  40. SetupTransformMatrix();
  41. }
  42. extern void FormatViewModelAttachment( C_BasePlayer *pPlayer, Vector &vOrigin, bool bInverse );
  43. void CLocalSpaceEmitter::SimulateParticles( CParticleSimulateIterator *pIterator )
  44. {
  45. float timeDelta = pIterator->GetTimeDelta();
  46. SimpleParticle *pParticle = (SimpleParticle*)pIterator->GetFirst();
  47. while ( pParticle )
  48. {
  49. // Update velocity
  50. UpdateVelocity( pParticle, timeDelta );
  51. pParticle->m_Pos += pParticle->m_vecVelocity * timeDelta;
  52. // Should this particle die?
  53. pParticle->m_flLifetime += timeDelta;
  54. UpdateRoll( pParticle, timeDelta );
  55. // If we're dead, we're done
  56. if ( pParticle->m_flLifetime >= pParticle->m_flDieTime )
  57. {
  58. pIterator->RemoveParticle( pParticle );
  59. }
  60. pParticle = (SimpleParticle*)pIterator->GetNext();
  61. }
  62. }
  63. void CLocalSpaceEmitter::RenderParticles( CParticleRenderIterator *pIterator )
  64. {
  65. const matrix3x4_t &mLocalToWorld = GetTransformMatrix();
  66. const VMatrix &mModelView = ParticleMgr()->GetModelView();
  67. const SimpleParticle *pParticle = (const SimpleParticle *)pIterator->GetFirst();
  68. while ( pParticle )
  69. {
  70. // Transform it
  71. Vector screenPos, worldPos;
  72. VectorTransform( pParticle->m_Pos, mLocalToWorld, worldPos );
  73. // Correct viewmodel squashing
  74. if ( m_fFlags & FLE_VIEWMODEL )
  75. {
  76. FormatViewModelAttachment( NULL, worldPos, false );
  77. }
  78. TransformParticle( mModelView, worldPos, screenPos );
  79. float sortKey = (int) screenPos.z;
  80. // Render it
  81. RenderParticle_ColorSizeAngle(
  82. pIterator->GetParticleDraw(),
  83. screenPos,
  84. UpdateColor( pParticle ),
  85. UpdateAlpha( pParticle ) * GetAlphaDistanceFade( screenPos, m_flNearClipMin, m_flNearClipMax ),
  86. UpdateScale( pParticle ),
  87. pParticle->m_flRoll
  88. );
  89. pParticle = (const SimpleParticle *)pIterator->GetNext( sortKey );
  90. }
  91. }
  92. //-----------------------------------------------------------------------------
  93. // Purpose: Create the matrix by which we'll transform the particle's local
  94. // space into world space, via the attachment's transform
  95. //-----------------------------------------------------------------------------
  96. void CLocalSpaceEmitter::SetupTransformMatrix( void )
  97. {
  98. IClientRenderable *pRenderable = ClientEntityList().GetClientRenderableFromHandle( m_hEntity );
  99. if ( pRenderable )
  100. {
  101. matrix3x4_t mat;
  102. if ( pRenderable->GetAttachment( m_nAttachment, mat ) == false )
  103. {
  104. // This attachment is bogus!
  105. Assert(0);
  106. }
  107. // Tell the particle effect so it knows
  108. Vector origin;
  109. MatrixGetColumn( mat, 3, origin );
  110. m_ParticleEffect.SetLocalSpaceTransform( mat );
  111. SetSortOrigin( origin );
  112. C_BaseEntity *pEnt = pRenderable->GetIClientUnknown()->GetBaseEntity();
  113. if ( pEnt )
  114. {
  115. Vector vWorldMins, vWorldMaxs;
  116. float scale = pEnt->CollisionProp()->BoundingRadius();
  117. vWorldMins[0] = origin[0] - scale;
  118. vWorldMins[1] = origin[1] - scale;
  119. vWorldMins[2] = origin[2] - scale;
  120. vWorldMaxs[0] = origin[0] + scale;
  121. vWorldMaxs[1] = origin[1] + scale;
  122. vWorldMaxs[2] = origin[2] + scale;
  123. GetBinding().SetBBox( vWorldMins, vWorldMaxs, true );
  124. }
  125. }
  126. // We preapply the local transform because we need to squash it for viewmodel FOV.
  127. m_ParticleEffect.SetAutoApplyLocalTransform( false );
  128. }