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
196 lines
5.5 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//============================================================================= |
|
|
|
#include "cbase.h" |
|
|
|
class C_PropScalable : public C_BaseAnimating |
|
{ |
|
DECLARE_CLASS( C_PropScalable, C_BaseAnimating ); |
|
DECLARE_CLIENTCLASS(); |
|
DECLARE_DATADESC(); |
|
|
|
public: |
|
|
|
C_PropScalable(); |
|
|
|
virtual void ApplyBoneMatrixTransform( matrix3x4_t& transform ); |
|
virtual void GetRenderBounds( Vector &theMins, Vector &theMaxs ); |
|
|
|
// Must be available to proxy functions |
|
float m_flScaleX; |
|
float m_flScaleY; |
|
float m_flScaleZ; |
|
|
|
float m_flLerpTimeX; |
|
float m_flLerpTimeY; |
|
float m_flLerpTimeZ; |
|
|
|
float m_flGoalTimeX; |
|
float m_flGoalTimeY; |
|
float m_flGoalTimeZ; |
|
|
|
float m_flCurrentScale[3]; |
|
bool m_bRunningScale[3]; |
|
float m_flTargetScale[3]; |
|
|
|
private: |
|
|
|
void CalculateScale( void ); |
|
float m_nCalcFrame; // Frame the last calculation was made at |
|
}; |
|
|
|
void RecvProxy_ScaleX( const CRecvProxyData *pData, void *pStruct, void *pOut ) |
|
{ |
|
C_PropScalable *pCoreData = (C_PropScalable *) pStruct; |
|
|
|
pCoreData->m_flScaleX = pData->m_Value.m_Float; |
|
|
|
if ( pCoreData->m_bRunningScale[0] == true ) |
|
{ |
|
pCoreData->m_flTargetScale[0] = pCoreData->m_flCurrentScale[0]; |
|
} |
|
} |
|
|
|
void RecvProxy_ScaleY( const CRecvProxyData *pData, void *pStruct, void *pOut ) |
|
{ |
|
C_PropScalable *pCoreData = (C_PropScalable *) pStruct; |
|
|
|
pCoreData->m_flScaleY = pData->m_Value.m_Float; |
|
|
|
if ( pCoreData->m_bRunningScale[1] == true ) |
|
{ |
|
pCoreData->m_flTargetScale[1] = pCoreData->m_flCurrentScale[1]; |
|
} |
|
} |
|
|
|
void RecvProxy_ScaleZ( const CRecvProxyData *pData, void *pStruct, void *pOut ) |
|
{ |
|
C_PropScalable *pCoreData = (C_PropScalable *) pStruct; |
|
|
|
pCoreData->m_flScaleZ = pData->m_Value.m_Float; |
|
|
|
if ( pCoreData->m_bRunningScale[2] == true ) |
|
{ |
|
pCoreData->m_flTargetScale[2] = pCoreData->m_flCurrentScale[2]; |
|
} |
|
} |
|
|
|
IMPLEMENT_CLIENTCLASS_DT( C_PropScalable, DT_PropScalable, CPropScalable ) |
|
RecvPropFloat( RECVINFO( m_flScaleX ), 0, RecvProxy_ScaleX ), |
|
RecvPropFloat( RECVINFO( m_flScaleY ), 0, RecvProxy_ScaleY ), |
|
RecvPropFloat( RECVINFO( m_flScaleZ ), 0, RecvProxy_ScaleZ ), |
|
|
|
RecvPropFloat( RECVINFO( m_flLerpTimeX ) ), |
|
RecvPropFloat( RECVINFO( m_flLerpTimeY ) ), |
|
RecvPropFloat( RECVINFO( m_flLerpTimeZ ) ), |
|
|
|
RecvPropFloat( RECVINFO( m_flGoalTimeX ) ), |
|
RecvPropFloat( RECVINFO( m_flGoalTimeY ) ), |
|
RecvPropFloat( RECVINFO( m_flGoalTimeZ ) ), |
|
END_RECV_TABLE() |
|
|
|
|
|
BEGIN_DATADESC( C_PropScalable ) |
|
DEFINE_AUTO_ARRAY( m_flTargetScale, FIELD_FLOAT ), |
|
DEFINE_AUTO_ARRAY( m_bRunningScale, FIELD_BOOLEAN ), |
|
END_DATADESC() |
|
|
|
C_PropScalable::C_PropScalable( void ) |
|
{ |
|
m_flTargetScale[0] = 1.0f; |
|
m_flTargetScale[1] = 1.0f; |
|
m_flTargetScale[2] = 1.0f; |
|
|
|
m_bRunningScale[0] = false; |
|
m_bRunningScale[1] = false; |
|
m_bRunningScale[2] = false; |
|
|
|
m_nCalcFrame = 0; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Calculates the scake of the object once per frame |
|
//----------------------------------------------------------------------------- |
|
void C_PropScalable::CalculateScale( void ) |
|
{ |
|
// Don't bother to calculate this for a second time in the same frame |
|
if ( m_nCalcFrame == gpGlobals->framecount ) |
|
return; |
|
|
|
// Mark that we cached this value for the frame |
|
m_nCalcFrame = gpGlobals->framecount; |
|
|
|
float flVal[3] = { m_flTargetScale[0], m_flTargetScale[1], m_flTargetScale[2] }; |
|
float *flTargetScale[3] = { &m_flTargetScale[0], &m_flTargetScale[1], &m_flTargetScale[2] }; |
|
float flScale[3] = { m_flScaleX, m_flScaleY, m_flScaleZ }; |
|
float flLerpTime[3] = { m_flLerpTimeX, m_flLerpTimeY, m_flLerpTimeZ }; |
|
float flGoalTime[3] = { m_flGoalTimeX, m_flGoalTimeY, m_flGoalTimeZ }; |
|
bool *bRunning[3] = { &m_bRunningScale[0], &m_bRunningScale[1], &m_bRunningScale[2] }; |
|
|
|
for ( int i = 0; i < 3; i++ ) |
|
{ |
|
if ( *flTargetScale[i] != flScale[i] ) |
|
{ |
|
float deltaTime = (float)( gpGlobals->curtime - flGoalTime[i]) / flLerpTime[i]; |
|
float flRemapVal = SimpleSplineRemapValClamped( deltaTime, 0.0f, 1.0f, *flTargetScale[i], flScale[i] ); |
|
|
|
*bRunning[i] = true; |
|
|
|
if ( deltaTime >= 1.0f ) |
|
{ |
|
*flTargetScale[i] = flScale[i]; |
|
*bRunning[i] = false; |
|
} |
|
|
|
flVal[i] = flRemapVal; |
|
m_flCurrentScale[i] = flVal[i]; |
|
} |
|
else |
|
{ |
|
m_flCurrentScale[i] = m_flTargetScale[i]; |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Scales the bones based on the current scales |
|
//----------------------------------------------------------------------------- |
|
void C_PropScalable::ApplyBoneMatrixTransform( matrix3x4_t& transform ) |
|
{ |
|
BaseClass::ApplyBoneMatrixTransform( transform ); |
|
|
|
// Find the scale for this frame |
|
CalculateScale(); |
|
|
|
VectorScale( transform[0], m_flCurrentScale[0], transform[0] ); |
|
VectorScale( transform[1], m_flCurrentScale[1], transform[1] ); |
|
VectorScale( transform[2], m_flCurrentScale[2], transform[2] ); |
|
|
|
UpdateVisibility(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Ensures the render bounds match the scales |
|
//----------------------------------------------------------------------------- |
|
void C_PropScalable::GetRenderBounds( Vector &theMins, Vector &theMaxs ) |
|
{ |
|
BaseClass::GetRenderBounds( theMins, theMaxs ); |
|
|
|
// Find the scale for this frame |
|
CalculateScale(); |
|
|
|
// Extend our render bounds to encompass the scaled object |
|
theMins.x *= m_flCurrentScale[0]; |
|
theMins.y *= m_flCurrentScale[1]; |
|
theMins.z *= m_flCurrentScale[2]; |
|
|
|
theMaxs.x *= m_flCurrentScale[0]; |
|
theMaxs.y *= m_flCurrentScale[1]; |
|
theMaxs.z *= m_flCurrentScale[2]; |
|
|
|
Assert( theMins.IsValid() && theMaxs.IsValid() ); |
|
|
|
}
|
|
|