Team Fortress 2 Source Code as on 22/4/2020
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.

196 lines
5.5 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "cbase.h"
  7. class C_PropScalable : public C_BaseAnimating
  8. {
  9. DECLARE_CLASS( C_PropScalable, C_BaseAnimating );
  10. DECLARE_CLIENTCLASS();
  11. DECLARE_DATADESC();
  12. public:
  13. C_PropScalable();
  14. virtual void ApplyBoneMatrixTransform( matrix3x4_t& transform );
  15. virtual void GetRenderBounds( Vector &theMins, Vector &theMaxs );
  16. // Must be available to proxy functions
  17. float m_flScaleX;
  18. float m_flScaleY;
  19. float m_flScaleZ;
  20. float m_flLerpTimeX;
  21. float m_flLerpTimeY;
  22. float m_flLerpTimeZ;
  23. float m_flGoalTimeX;
  24. float m_flGoalTimeY;
  25. float m_flGoalTimeZ;
  26. float m_flCurrentScale[3];
  27. bool m_bRunningScale[3];
  28. float m_flTargetScale[3];
  29. private:
  30. void CalculateScale( void );
  31. float m_nCalcFrame; // Frame the last calculation was made at
  32. };
  33. void RecvProxy_ScaleX( const CRecvProxyData *pData, void *pStruct, void *pOut )
  34. {
  35. C_PropScalable *pCoreData = (C_PropScalable *) pStruct;
  36. pCoreData->m_flScaleX = pData->m_Value.m_Float;
  37. if ( pCoreData->m_bRunningScale[0] == true )
  38. {
  39. pCoreData->m_flTargetScale[0] = pCoreData->m_flCurrentScale[0];
  40. }
  41. }
  42. void RecvProxy_ScaleY( const CRecvProxyData *pData, void *pStruct, void *pOut )
  43. {
  44. C_PropScalable *pCoreData = (C_PropScalable *) pStruct;
  45. pCoreData->m_flScaleY = pData->m_Value.m_Float;
  46. if ( pCoreData->m_bRunningScale[1] == true )
  47. {
  48. pCoreData->m_flTargetScale[1] = pCoreData->m_flCurrentScale[1];
  49. }
  50. }
  51. void RecvProxy_ScaleZ( const CRecvProxyData *pData, void *pStruct, void *pOut )
  52. {
  53. C_PropScalable *pCoreData = (C_PropScalable *) pStruct;
  54. pCoreData->m_flScaleZ = pData->m_Value.m_Float;
  55. if ( pCoreData->m_bRunningScale[2] == true )
  56. {
  57. pCoreData->m_flTargetScale[2] = pCoreData->m_flCurrentScale[2];
  58. }
  59. }
  60. IMPLEMENT_CLIENTCLASS_DT( C_PropScalable, DT_PropScalable, CPropScalable )
  61. RecvPropFloat( RECVINFO( m_flScaleX ), 0, RecvProxy_ScaleX ),
  62. RecvPropFloat( RECVINFO( m_flScaleY ), 0, RecvProxy_ScaleY ),
  63. RecvPropFloat( RECVINFO( m_flScaleZ ), 0, RecvProxy_ScaleZ ),
  64. RecvPropFloat( RECVINFO( m_flLerpTimeX ) ),
  65. RecvPropFloat( RECVINFO( m_flLerpTimeY ) ),
  66. RecvPropFloat( RECVINFO( m_flLerpTimeZ ) ),
  67. RecvPropFloat( RECVINFO( m_flGoalTimeX ) ),
  68. RecvPropFloat( RECVINFO( m_flGoalTimeY ) ),
  69. RecvPropFloat( RECVINFO( m_flGoalTimeZ ) ),
  70. END_RECV_TABLE()
  71. BEGIN_DATADESC( C_PropScalable )
  72. DEFINE_AUTO_ARRAY( m_flTargetScale, FIELD_FLOAT ),
  73. DEFINE_AUTO_ARRAY( m_bRunningScale, FIELD_BOOLEAN ),
  74. END_DATADESC()
  75. C_PropScalable::C_PropScalable( void )
  76. {
  77. m_flTargetScale[0] = 1.0f;
  78. m_flTargetScale[1] = 1.0f;
  79. m_flTargetScale[2] = 1.0f;
  80. m_bRunningScale[0] = false;
  81. m_bRunningScale[1] = false;
  82. m_bRunningScale[2] = false;
  83. m_nCalcFrame = 0;
  84. }
  85. //-----------------------------------------------------------------------------
  86. // Purpose: Calculates the scake of the object once per frame
  87. //-----------------------------------------------------------------------------
  88. void C_PropScalable::CalculateScale( void )
  89. {
  90. // Don't bother to calculate this for a second time in the same frame
  91. if ( m_nCalcFrame == gpGlobals->framecount )
  92. return;
  93. // Mark that we cached this value for the frame
  94. m_nCalcFrame = gpGlobals->framecount;
  95. float flVal[3] = { m_flTargetScale[0], m_flTargetScale[1], m_flTargetScale[2] };
  96. float *flTargetScale[3] = { &m_flTargetScale[0], &m_flTargetScale[1], &m_flTargetScale[2] };
  97. float flScale[3] = { m_flScaleX, m_flScaleY, m_flScaleZ };
  98. float flLerpTime[3] = { m_flLerpTimeX, m_flLerpTimeY, m_flLerpTimeZ };
  99. float flGoalTime[3] = { m_flGoalTimeX, m_flGoalTimeY, m_flGoalTimeZ };
  100. bool *bRunning[3] = { &m_bRunningScale[0], &m_bRunningScale[1], &m_bRunningScale[2] };
  101. for ( int i = 0; i < 3; i++ )
  102. {
  103. if ( *flTargetScale[i] != flScale[i] )
  104. {
  105. float deltaTime = (float)( gpGlobals->curtime - flGoalTime[i]) / flLerpTime[i];
  106. float flRemapVal = SimpleSplineRemapValClamped( deltaTime, 0.0f, 1.0f, *flTargetScale[i], flScale[i] );
  107. *bRunning[i] = true;
  108. if ( deltaTime >= 1.0f )
  109. {
  110. *flTargetScale[i] = flScale[i];
  111. *bRunning[i] = false;
  112. }
  113. flVal[i] = flRemapVal;
  114. m_flCurrentScale[i] = flVal[i];
  115. }
  116. else
  117. {
  118. m_flCurrentScale[i] = m_flTargetScale[i];
  119. }
  120. }
  121. }
  122. //-----------------------------------------------------------------------------
  123. // Purpose: Scales the bones based on the current scales
  124. //-----------------------------------------------------------------------------
  125. void C_PropScalable::ApplyBoneMatrixTransform( matrix3x4_t& transform )
  126. {
  127. BaseClass::ApplyBoneMatrixTransform( transform );
  128. // Find the scale for this frame
  129. CalculateScale();
  130. VectorScale( transform[0], m_flCurrentScale[0], transform[0] );
  131. VectorScale( transform[1], m_flCurrentScale[1], transform[1] );
  132. VectorScale( transform[2], m_flCurrentScale[2], transform[2] );
  133. UpdateVisibility();
  134. }
  135. //-----------------------------------------------------------------------------
  136. // Purpose: Ensures the render bounds match the scales
  137. //-----------------------------------------------------------------------------
  138. void C_PropScalable::GetRenderBounds( Vector &theMins, Vector &theMaxs )
  139. {
  140. BaseClass::GetRenderBounds( theMins, theMaxs );
  141. // Find the scale for this frame
  142. CalculateScale();
  143. // Extend our render bounds to encompass the scaled object
  144. theMins.x *= m_flCurrentScale[0];
  145. theMins.y *= m_flCurrentScale[1];
  146. theMins.z *= m_flCurrentScale[2];
  147. theMaxs.x *= m_flCurrentScale[0];
  148. theMaxs.y *= m_flCurrentScale[1];
  149. theMaxs.z *= m_flCurrentScale[2];
  150. Assert( theMins.IsValid() && theMaxs.IsValid() );
  151. }