aboutsummaryrefslogtreecommitdiff
path: root/sp/src/game/client/C_MaterialModifyControl.cpp
diff options
context:
space:
mode:
authorJørgen P. Tjernø <[email protected]>2013-12-02 19:31:46 -0800
committerJørgen P. Tjernø <[email protected]>2013-12-02 19:46:31 -0800
commitf56bb35301836e56582a575a75864392a0177875 (patch)
treede61ddd39de3e7df52759711950b4c288592f0dc /sp/src/game/client/C_MaterialModifyControl.cpp
parentMark some more files as text. (diff)
downloadsource-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz
source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip
Fix line endings. WHAMMY.
Diffstat (limited to 'sp/src/game/client/C_MaterialModifyControl.cpp')
-rw-r--r--sp/src/game/client/C_MaterialModifyControl.cpp1596
1 files changed, 798 insertions, 798 deletions
diff --git a/sp/src/game/client/C_MaterialModifyControl.cpp b/sp/src/game/client/C_MaterialModifyControl.cpp
index 55ff2ec5..f038022e 100644
--- a/sp/src/game/client/C_MaterialModifyControl.cpp
+++ b/sp/src/game/client/C_MaterialModifyControl.cpp
@@ -1,798 +1,798 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: Material Modify control entity.
-//
-//=============================================================================//
-
-#include "cbase.h"
-#include "proxyentity.h"
-#include "materialsystem/imaterial.h"
-#include "materialsystem/imaterialvar.h"
-#include "materialsystem/itexture.h"
-#include "iviewrender.h"
-#include "texture_group_names.h"
-#include "baseanimatedtextureproxy.h"
-#include "toolframework_client.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-#define MATERIAL_MODIFY_STRING_SIZE 255
-#define MATERIAL_MODIFY_ANIMATION_UNSET -1
-
-// Must match MaterialModifyControl.cpp
-enum MaterialModifyMode_t
-{
- MATERIAL_MODIFY_MODE_NONE = 0,
- MATERIAL_MODIFY_MODE_SETVAR = 1,
- MATERIAL_MODIFY_MODE_ANIM_SEQUENCE = 2,
- MATERIAL_MODIFY_MODE_FLOAT_LERP = 3,
-};
-
-// forward declarations
-void ToolFramework_RecordMaterialParams( IMaterial *pMaterial );
-
-ConVar debug_materialmodifycontrol_client( "debug_materialmodifycontrol_client", "0" );
-
-struct materialanimcommands_t
-{
- int iFrameStart;
- int iFrameEnd;
- bool bWrap;
- float flFrameRate;
-};
-
-struct materialfloatlerpcommands_t
-{
- int flStartValue;
- int flEndValue;
- float flTransitionTime;
-};
-
-//------------------------------------------------------------------------------
-// FIXME: This really should inherit from something more lightweight
-//------------------------------------------------------------------------------
-
-class C_MaterialModifyControl : public C_BaseEntity
-{
-public:
-
- DECLARE_CLASS( C_MaterialModifyControl, C_BaseEntity );
-
- C_MaterialModifyControl();
-
- void OnPreDataChanged( DataUpdateType_t updateType );
- void OnDataChanged( DataUpdateType_t updateType );
- bool ShouldDraw();
-
- IMaterial *GetMaterial( void ) { return m_pMaterial; }
- const char *GetMaterialVariableName( void ) { return m_szMaterialVar; }
- const char *GetMaterialVariableValue( void ) { return m_szMaterialVarValue; }
-
- DECLARE_CLIENTCLASS();
-
- // Animated texture and Float Lerp usage
- bool HasNewAnimationCommands( void ) { return m_bHasNewAnimationCommands; }
- void ClearAnimationCommands( void ) { m_bHasNewAnimationCommands = false; }
-
- // Animated texture usage
- void GetAnimationCommands( materialanimcommands_t *pCommands );
-
- // FloatLerp usage
- void GetFloatLerpCommands( materialfloatlerpcommands_t *pCommands );
-
- void SetAnimationStartTime( float flTime )
- {
- m_flAnimationStartTime = flTime;
- }
- float GetAnimationStartTime( void ) const
- {
- return m_flAnimationStartTime;
- }
-
- MaterialModifyMode_t GetModifyMode( void ) const
- {
- return ( MaterialModifyMode_t)m_nModifyMode;
- }
-private:
-
- char m_szMaterialName[MATERIAL_MODIFY_STRING_SIZE];
- char m_szMaterialVar[MATERIAL_MODIFY_STRING_SIZE];
- char m_szMaterialVarValue[MATERIAL_MODIFY_STRING_SIZE];
- IMaterial *m_pMaterial;
-
- bool m_bHasNewAnimationCommands;
-
- // Animation commands from the server
- int m_iFrameStart;
- int m_iFrameEnd;
- bool m_bWrap;
- float m_flFramerate;
- bool m_bNewAnimCommandsSemaphore;
- bool m_bOldAnimCommandsSemaphore;
-
- // Float lerp commands from the server
- float m_flFloatLerpStartValue;
- float m_flFloatLerpEndValue;
- float m_flFloatLerpTransitionTime;
- bool m_bFloatLerpWrap;
- float m_flAnimationStartTime;
-
- int m_nModifyMode;
-};
-
-IMPLEMENT_CLIENTCLASS_DT(C_MaterialModifyControl, DT_MaterialModifyControl, CMaterialModifyControl)
- RecvPropString( RECVINFO( m_szMaterialName ) ),
- RecvPropString( RECVINFO( m_szMaterialVar ) ),
- RecvPropString( RECVINFO( m_szMaterialVarValue ) ),
- RecvPropInt( RECVINFO(m_iFrameStart) ),
- RecvPropInt( RECVINFO(m_iFrameEnd) ),
- RecvPropInt( RECVINFO(m_bWrap) ),
- RecvPropFloat( RECVINFO(m_flFramerate) ),
- RecvPropInt( RECVINFO(m_bNewAnimCommandsSemaphore) ),
- RecvPropFloat( RECVINFO(m_flFloatLerpStartValue) ),
- RecvPropFloat( RECVINFO(m_flFloatLerpEndValue) ),
- RecvPropFloat( RECVINFO(m_flFloatLerpTransitionTime) ),
- RecvPropInt( RECVINFO(m_bFloatLerpWrap) ),
- RecvPropInt( RECVINFO(m_nModifyMode) ),
-END_RECV_TABLE()
-
-//------------------------------------------------------------------------------
-// Purpose:
-//------------------------------------------------------------------------------
-C_MaterialModifyControl::C_MaterialModifyControl()
-{
- m_pMaterial = NULL;
- m_bOldAnimCommandsSemaphore = false;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_MaterialModifyControl::OnPreDataChanged( DataUpdateType_t updateType )
-{
- BaseClass::OnPreDataChanged( updateType );
-
- m_bOldAnimCommandsSemaphore = m_bNewAnimCommandsSemaphore;
-}
-
-//------------------------------------------------------------------------------
-// Purpose:
-//------------------------------------------------------------------------------
-void C_MaterialModifyControl::OnDataChanged( DataUpdateType_t updateType )
-{
- if( updateType == DATA_UPDATE_CREATED )
- {
- m_pMaterial = materials->FindMaterial( m_szMaterialName, TEXTURE_GROUP_OTHER );
-
- // Clear out our variables
- m_bHasNewAnimationCommands = true;
- }
-
- // Detect changes in the anim commands
- if ( m_bNewAnimCommandsSemaphore != m_bOldAnimCommandsSemaphore )
- {
- m_bHasNewAnimationCommands = true;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_MaterialModifyControl::GetAnimationCommands( materialanimcommands_t *pCommands )
-{
- pCommands->iFrameStart = m_iFrameStart;
- pCommands->iFrameEnd = m_iFrameEnd;
- pCommands->bWrap = m_bWrap;
- pCommands->flFrameRate = m_flFramerate;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void C_MaterialModifyControl::GetFloatLerpCommands( materialfloatlerpcommands_t *pCommands )
-{
- pCommands->flStartValue = m_flFloatLerpStartValue;
- pCommands->flEndValue = m_flFloatLerpEndValue;
- pCommands->flTransitionTime = m_flFloatLerpTransitionTime;
-}
-
-//------------------------------------------------------------------------------
-// Purpose: We don't draw.
-//------------------------------------------------------------------------------
-bool C_MaterialModifyControl::ShouldDraw()
-{
- return false;
-}
-
-//=============================================================================
-//
-// THE MATERIALMODIFYPROXY ITSELF
-//
-class CMaterialModifyProxy : public CBaseAnimatedTextureProxy
-{
-public:
- CMaterialModifyProxy();
- virtual ~CMaterialModifyProxy();
- virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
- virtual void OnBind( void *pEntity );
- virtual IMaterial *GetMaterial();
-
-private:
- void OnBindSetVar( C_MaterialModifyControl *pControl );
- void OnBindAnimatedTexture( C_MaterialModifyControl *pControl );
- void OnBindFloatLerp( C_MaterialModifyControl *pControl );
- float GetAnimationStartTime( void* pArg );
- void AnimationWrapped( void* pArg );
-
- IMaterial *m_pMaterial;
-
- // texture animation stuff
- int m_iFrameStart;
- int m_iFrameEnd;
- bool m_bReachedEnd;
- bool m_bCustomWrap;
- float m_flCustomFramerate;
-
- // float lerp stuff
- IMaterialVar *m_pMaterialVar;
- int m_flStartValue;
- int m_flEndValue;
- float m_flStartTime;
- float m_flTransitionTime;
-};
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-CMaterialModifyProxy::CMaterialModifyProxy()
-{
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-CMaterialModifyProxy::~CMaterialModifyProxy()
-{
-}
-
-bool CMaterialModifyProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
-{
- // set var stuff
- m_pMaterial = pMaterial;
-
- // float lerp stuff
- m_flStartValue = MATERIAL_MODIFY_ANIMATION_UNSET;
- m_flEndValue = MATERIAL_MODIFY_ANIMATION_UNSET;
-
- // animated stuff
-// m_pMaterial = pMaterial;
-// m_iFrameStart = MATERIAL_MODIFY_ANIMATION_UNSET;
-// m_iFrameEnd = MATERIAL_MODIFY_ANIMATION_UNSET;
-// m_bReachedEnd = false;
-// return CBaseAnimatedTextureProxy::Init( pMaterial, pKeyValues );
-
- return true;
-}
-
-void CMaterialModifyProxy::OnBind( void *pEntity )
-{
- // Get the modified material vars from the entity input
- IClientRenderable *pRend = (IClientRenderable *)pEntity;
- if ( pRend )
- {
- C_BaseEntity *pBaseEntity = pRend->GetIClientUnknown()->GetBaseEntity();
-
- if ( pBaseEntity )
- {
- if( debug_materialmodifycontrol_client.GetBool() )
- {
-// DevMsg( 1, "%s\n", pBaseEntity->GetDebugName() );
- }
- int numChildren = 0;
- bool gotOne = false;
- for ( C_BaseEntity *pChild = pBaseEntity->FirstMoveChild(); pChild; pChild = pChild->NextMovePeer() )
- {
- numChildren++;
- C_MaterialModifyControl *pControl = dynamic_cast<C_MaterialModifyControl*>( pChild );
- if ( !pControl )
- continue;
-
- if( debug_materialmodifycontrol_client.GetBool() )
- {
-// DevMsg( 1, "pControl: 0x%p\n", pControl );
- }
-
- switch( pControl->GetModifyMode() )
- {
- case MATERIAL_MODIFY_MODE_NONE:
- break;
- case MATERIAL_MODIFY_MODE_SETVAR:
- gotOne = true;
- OnBindSetVar( pControl );
- break;
- case MATERIAL_MODIFY_MODE_ANIM_SEQUENCE:
- OnBindAnimatedTexture( pControl );
- break;
- case MATERIAL_MODIFY_MODE_FLOAT_LERP:
- OnBindFloatLerp( pControl );
- break;
- default:
- Assert( 0 );
- break;
- }
- }
- if( gotOne )
- {
-// DevMsg( 1, "numChildren: %d\n", numChildren );
- }
- }
- }
-
- if ( ToolsEnabled() )
- {
- ToolFramework_RecordMaterialParams( GetMaterial() );
- }
-}
-
-IMaterial *CMaterialModifyProxy::GetMaterial()
-{
- return m_pMaterial;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CMaterialModifyProxy::OnBindSetVar( C_MaterialModifyControl *pControl )
-{
- IMaterial *pMaterial = pControl->GetMaterial();
- if( !pMaterial )
- {
- Assert( 0 );
- return;
- }
-
- if ( pMaterial != m_pMaterial )
- {
-// Warning( "\t%s!=%s\n", pMaterial->GetName(), m_pMaterial->GetName() );
- return;
- }
-
- bool bFound;
- IMaterialVar *pMaterialVar = pMaterial->FindVar( pControl->GetMaterialVariableName(), &bFound, false );
- if ( !bFound )
- return;
-
- if( Q_strcmp( pControl->GetMaterialVariableValue(), "" ) )
- {
-// const char *pMaterialName = m_pMaterial->GetName();
-// const char *pMaterialVarName = pMaterialVar->GetName();
-// const char *pMaterialVarValue = pControl->GetMaterialVariableValue();
-// if( debug_materialmodifycontrol_client.GetBool()
-// && Q_stristr( m_pMaterial->GetName(), "faceandhair" )
-// && Q_stristr( pMaterialVar->GetName(), "self" )
-// )
-// {
-// static int count = 0;
-// DevMsg( 1, "CMaterialModifyProxy::OnBindSetVar \"%s\" %s=%s %d pControl=0x%p\n",
-// m_pMaterial->GetName(), pMaterialVar->GetName(), pControl->GetMaterialVariableValue(), count++, pControl );
-// }
- pMaterialVar->SetValueAutodetectType( pControl->GetMaterialVariableValue() );
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Does the dirty deed
-//-----------------------------------------------------------------------------
-void CMaterialModifyProxy::OnBindAnimatedTexture( C_MaterialModifyControl *pControl )
-{
- assert ( m_AnimatedTextureVar );
- if( m_AnimatedTextureVar->GetType() != MATERIAL_VAR_TYPE_TEXTURE )
- return;
-
- ITexture *pTexture;
- pTexture = m_AnimatedTextureVar->GetTextureValue();
-
- if ( !pControl )
- return;
-
- if ( pControl->HasNewAnimationCommands() )
- {
- // Read the data from the modify entity
- materialanimcommands_t sCommands;
- pControl->GetAnimationCommands( &sCommands );
-
- m_iFrameStart = sCommands.iFrameStart;
- m_iFrameEnd = sCommands.iFrameEnd;
- m_bCustomWrap = sCommands.bWrap;
- m_flCustomFramerate = sCommands.flFrameRate;
- m_bReachedEnd = false;
-
- m_flStartTime = gpGlobals->curtime;
-
- pControl->ClearAnimationCommands();
- }
-
- // Init all the vars based on whether we're using the base material settings,
- // or the custom ones from the entity input.
- int numFrames;
- bool bWrapAnimation;
- float flFrameRate;
- int iLastFrame;
-
- // Do we have a custom frame section from the server?
- if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
- {
- if ( m_iFrameEnd == MATERIAL_MODIFY_ANIMATION_UNSET )
- {
- m_iFrameEnd = pTexture->GetNumAnimationFrames();
- }
-
- numFrames = (m_iFrameEnd - m_iFrameStart) + 1;
- bWrapAnimation = m_bCustomWrap;
- flFrameRate = m_flCustomFramerate;
- iLastFrame = (m_iFrameEnd - 1);
- }
- else
- {
- numFrames = pTexture->GetNumAnimationFrames();
- bWrapAnimation = m_WrapAnimation;
- flFrameRate = m_FrameRate;
- iLastFrame = (numFrames - 1);
- }
-
- // Have we already reached the end? If so, stay there.
- if ( m_bReachedEnd && !bWrapAnimation )
- {
- m_AnimatedTextureFrameNumVar->SetIntValue( iLastFrame );
- return;
- }
-
- // NOTE: Must not use relative time based methods here
- // because the bind proxy can be called many times per frame.
- // Prevent multiple Wrap callbacks to be sent for no wrap mode
- float startTime;
- if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
- {
- startTime = m_flStartTime;
- }
- else
- {
- startTime = GetAnimationStartTime(pControl);
- }
- float deltaTime = gpGlobals->curtime - startTime;
- float prevTime = deltaTime - gpGlobals->frametime;
-
- // Clamp..
- if (deltaTime < 0.0f)
- deltaTime = 0.0f;
- if (prevTime < 0.0f)
- prevTime = 0.0f;
-
- float frame = flFrameRate * deltaTime;
- float prevFrame = flFrameRate * prevTime;
-
- int intFrame = ((int)frame) % numFrames;
- int intPrevFrame = ((int)prevFrame) % numFrames;
-
- if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
- {
- intFrame += m_iFrameStart;
- intPrevFrame += m_iFrameStart;
- }
-
- // Report wrap situation...
- if (intPrevFrame > intFrame)
- {
- m_bReachedEnd = true;
-
- if (bWrapAnimation)
- {
- AnimationWrapped( pControl );
- }
- else
- {
- // Only sent the wrapped message once.
- // when we're in non-wrapping mode
- if (prevFrame < numFrames)
- AnimationWrapped( pControl );
- intFrame = numFrames - 1;
- }
- }
-
- m_AnimatedTextureFrameNumVar->SetIntValue( intFrame );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-float CMaterialModifyProxy::GetAnimationStartTime( void* pArg )
-{
- IClientRenderable *pRend = (IClientRenderable *)pArg;
- if (!pRend)
- return 0.0f;
-
- C_BaseEntity* pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
- if (pEntity)
- {
- return pEntity->GetTextureAnimationStartTime();
- }
- return 0.0f;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CMaterialModifyProxy::AnimationWrapped( void* pArg )
-{
- IClientRenderable *pRend = (IClientRenderable *)pArg;
- if (!pRend)
- return;
-
- C_BaseEntity* pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
- if (pEntity)
- {
- pEntity->TextureAnimationWrapped();
- }
-}
-
-//-----------------------------------------------------------------------------
-// Does the dirty deed
-//-----------------------------------------------------------------------------
-void CMaterialModifyProxy::OnBindFloatLerp( C_MaterialModifyControl *pControl )
-{
- if ( !pControl )
- return;
-
- if ( pControl->HasNewAnimationCommands() )
- {
- pControl->SetAnimationStartTime( gpGlobals->curtime );
- pControl->ClearAnimationCommands();
- }
-
- // Read the data from the modify entity
- materialfloatlerpcommands_t sCommands;
- pControl->GetFloatLerpCommands( &sCommands );
-
- m_flStartValue = sCommands.flStartValue;
- m_flEndValue = sCommands.flEndValue;
- m_flTransitionTime = sCommands.flTransitionTime;
- m_flStartTime = pControl->GetAnimationStartTime();
- bool bFound;
- m_pMaterialVar = m_pMaterial->FindVar( pControl->GetMaterialVariableName(), &bFound, false );
-
- if( bFound )
- {
- float currentValue;
- if( m_flTransitionTime > 0.0f )
- {
- currentValue = m_flStartValue + ( m_flEndValue - m_flStartValue ) * clamp( ( ( gpGlobals->curtime - m_flStartTime ) / m_flTransitionTime ), 0.0f, 1.0f );
- }
- else
- {
- currentValue = m_flEndValue;
- }
-
- if( debug_materialmodifycontrol_client.GetBool() && Q_stristr( m_pMaterial->GetName(), "faceandhair" ) && Q_stristr( m_pMaterialVar->GetName(), "warp" ) )
- {
- static int count = 0;
- DevMsg( 1, "CMaterialFloatLerpProxy::OnBind \"%s\" %s=%f %d\n", m_pMaterial->GetName(), m_pMaterialVar->GetName(), currentValue, count++ );
- }
- m_pMaterialVar->SetFloatValue( currentValue );
- }
-}
-
-//=============================================================================
-//
-// MATERIALMODIFYANIMATED PROXY
-//
-class CMaterialModifyAnimatedProxy : public CBaseAnimatedTextureProxy
-{
-public:
- CMaterialModifyAnimatedProxy() {};
- virtual ~CMaterialModifyAnimatedProxy() {};
- virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
- virtual void OnBind( void *pEntity );
-
- virtual float GetAnimationStartTime( void* pBaseEntity );
- virtual void AnimationWrapped( void* pC_BaseEntity );
-
-private:
- IMaterial *m_pMaterial;
- int m_iFrameStart;
- int m_iFrameEnd;
- bool m_bReachedEnd;
- float m_flStartTime;
- bool m_bCustomWrap;
- float m_flCustomFramerate;
-};
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-bool CMaterialModifyAnimatedProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
-{
- m_pMaterial = pMaterial;
- m_iFrameStart = MATERIAL_MODIFY_ANIMATION_UNSET;
- m_iFrameEnd = MATERIAL_MODIFY_ANIMATION_UNSET;
- m_bReachedEnd = false;
- return CBaseAnimatedTextureProxy::Init( pMaterial, pKeyValues );
-}
-
-//-----------------------------------------------------------------------------
-// Does the dirty deed
-//-----------------------------------------------------------------------------
-void CMaterialModifyAnimatedProxy::OnBind( void *pEntity )
-{
- assert ( m_AnimatedTextureVar );
- if( m_AnimatedTextureVar->GetType() != MATERIAL_VAR_TYPE_TEXTURE )
- return;
-
- ITexture *pTexture;
- pTexture = m_AnimatedTextureVar->GetTextureValue();
-
- // Get the modified material vars from the entity input
- IClientRenderable *pRend = (IClientRenderable *)pEntity;
- if ( pRend )
- {
- C_BaseEntity *pBaseEntity = pRend->GetIClientUnknown()->GetBaseEntity();
- if ( pBaseEntity )
- {
- for ( C_BaseEntity *pChild = pBaseEntity->FirstMoveChild(); pChild; pChild = pChild->NextMovePeer() )
- {
- C_MaterialModifyControl *pControl = dynamic_cast<C_MaterialModifyControl*>( pChild );
- if ( !pControl )
- continue;
-
- if ( !pControl->HasNewAnimationCommands() )
- continue;
-
- // Read the data from the modify entity
- materialanimcommands_t sCommands;
- pControl->GetAnimationCommands( &sCommands );
-
- m_iFrameStart = sCommands.iFrameStart;
- m_iFrameEnd = sCommands.iFrameEnd;
- m_bCustomWrap = sCommands.bWrap;
- m_flCustomFramerate = sCommands.flFrameRate;
- m_bReachedEnd = false;
-
- m_flStartTime = gpGlobals->curtime;
-
- pControl->ClearAnimationCommands();
- }
- }
- }
-
- // Init all the vars based on whether we're using the base material settings,
- // or the custom ones from the entity input.
- int numFrames;
- bool bWrapAnimation;
- float flFrameRate;
- int iLastFrame;
-
- // Do we have a custom frame section from the server?
- if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
- {
- if ( m_iFrameEnd == MATERIAL_MODIFY_ANIMATION_UNSET )
- {
- m_iFrameEnd = pTexture->GetNumAnimationFrames();
- }
-
- numFrames = (m_iFrameEnd - m_iFrameStart) + 1;
- bWrapAnimation = m_bCustomWrap;
- flFrameRate = m_flCustomFramerate;
- iLastFrame = (m_iFrameEnd - 1);
- }
- else
- {
- numFrames = pTexture->GetNumAnimationFrames();
- bWrapAnimation = m_WrapAnimation;
- flFrameRate = m_FrameRate;
- iLastFrame = (numFrames - 1);
- }
-
- // Have we already reached the end? If so, stay there.
- if ( m_bReachedEnd && !bWrapAnimation )
- {
- m_AnimatedTextureFrameNumVar->SetIntValue( iLastFrame );
- return;
- }
-
- // NOTE: Must not use relative time based methods here
- // because the bind proxy can be called many times per frame.
- // Prevent multiple Wrap callbacks to be sent for no wrap mode
- float startTime;
- if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
- {
- startTime = m_flStartTime;
- }
- else
- {
- startTime = GetAnimationStartTime(pEntity);
- }
- float deltaTime = gpGlobals->curtime - startTime;
- float prevTime = deltaTime - gpGlobals->frametime;
-
- // Clamp..
- if (deltaTime < 0.0f)
- deltaTime = 0.0f;
- if (prevTime < 0.0f)
- prevTime = 0.0f;
-
- float frame = flFrameRate * deltaTime;
- float prevFrame = flFrameRate * prevTime;
-
- int intFrame = ((int)frame) % numFrames;
- int intPrevFrame = ((int)prevFrame) % numFrames;
-
- if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
- {
- intFrame += m_iFrameStart;
- intPrevFrame += m_iFrameStart;
- }
-
- // Report wrap situation...
- if (intPrevFrame > intFrame)
- {
- m_bReachedEnd = true;
-
- if (bWrapAnimation)
- {
- AnimationWrapped( pEntity );
- }
- else
- {
- // Only sent the wrapped message once.
- // when we're in non-wrapping mode
- if (prevFrame < numFrames)
- AnimationWrapped( pEntity );
- intFrame = numFrames - 1;
- }
- }
-
- m_AnimatedTextureFrameNumVar->SetIntValue( intFrame );
-
- if ( ToolsEnabled() )
- {
- ToolFramework_RecordMaterialParams( GetMaterial() );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-float CMaterialModifyAnimatedProxy::GetAnimationStartTime( void* pArg )
-{
- IClientRenderable *pRend = (IClientRenderable *)pArg;
- if (!pRend)
- return 0.0f;
-
- C_BaseEntity* pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
- if (pEntity)
- {
- return pEntity->GetTextureAnimationStartTime();
- }
- return 0.0f;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CMaterialModifyAnimatedProxy::AnimationWrapped( void* pArg )
-{
- IClientRenderable *pRend = (IClientRenderable *)pArg;
- if (!pRend)
- return;
-
- C_BaseEntity* pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
- if (pEntity)
- {
- pEntity->TextureAnimationWrapped();
- }
-}
-
-
-EXPOSE_INTERFACE( CMaterialModifyProxy, IMaterialProxy, "MaterialModify" IMATERIAL_PROXY_INTERFACE_VERSION );
-EXPOSE_INTERFACE( CMaterialModifyAnimatedProxy, IMaterialProxy, "MaterialModifyAnimated" IMATERIAL_PROXY_INTERFACE_VERSION );
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Material Modify control entity.
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "proxyentity.h"
+#include "materialsystem/imaterial.h"
+#include "materialsystem/imaterialvar.h"
+#include "materialsystem/itexture.h"
+#include "iviewrender.h"
+#include "texture_group_names.h"
+#include "baseanimatedtextureproxy.h"
+#include "toolframework_client.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+#define MATERIAL_MODIFY_STRING_SIZE 255
+#define MATERIAL_MODIFY_ANIMATION_UNSET -1
+
+// Must match MaterialModifyControl.cpp
+enum MaterialModifyMode_t
+{
+ MATERIAL_MODIFY_MODE_NONE = 0,
+ MATERIAL_MODIFY_MODE_SETVAR = 1,
+ MATERIAL_MODIFY_MODE_ANIM_SEQUENCE = 2,
+ MATERIAL_MODIFY_MODE_FLOAT_LERP = 3,
+};
+
+// forward declarations
+void ToolFramework_RecordMaterialParams( IMaterial *pMaterial );
+
+ConVar debug_materialmodifycontrol_client( "debug_materialmodifycontrol_client", "0" );
+
+struct materialanimcommands_t
+{
+ int iFrameStart;
+ int iFrameEnd;
+ bool bWrap;
+ float flFrameRate;
+};
+
+struct materialfloatlerpcommands_t
+{
+ int flStartValue;
+ int flEndValue;
+ float flTransitionTime;
+};
+
+//------------------------------------------------------------------------------
+// FIXME: This really should inherit from something more lightweight
+//------------------------------------------------------------------------------
+
+class C_MaterialModifyControl : public C_BaseEntity
+{
+public:
+
+ DECLARE_CLASS( C_MaterialModifyControl, C_BaseEntity );
+
+ C_MaterialModifyControl();
+
+ void OnPreDataChanged( DataUpdateType_t updateType );
+ void OnDataChanged( DataUpdateType_t updateType );
+ bool ShouldDraw();
+
+ IMaterial *GetMaterial( void ) { return m_pMaterial; }
+ const char *GetMaterialVariableName( void ) { return m_szMaterialVar; }
+ const char *GetMaterialVariableValue( void ) { return m_szMaterialVarValue; }
+
+ DECLARE_CLIENTCLASS();
+
+ // Animated texture and Float Lerp usage
+ bool HasNewAnimationCommands( void ) { return m_bHasNewAnimationCommands; }
+ void ClearAnimationCommands( void ) { m_bHasNewAnimationCommands = false; }
+
+ // Animated texture usage
+ void GetAnimationCommands( materialanimcommands_t *pCommands );
+
+ // FloatLerp usage
+ void GetFloatLerpCommands( materialfloatlerpcommands_t *pCommands );
+
+ void SetAnimationStartTime( float flTime )
+ {
+ m_flAnimationStartTime = flTime;
+ }
+ float GetAnimationStartTime( void ) const
+ {
+ return m_flAnimationStartTime;
+ }
+
+ MaterialModifyMode_t GetModifyMode( void ) const
+ {
+ return ( MaterialModifyMode_t)m_nModifyMode;
+ }
+private:
+
+ char m_szMaterialName[MATERIAL_MODIFY_STRING_SIZE];
+ char m_szMaterialVar[MATERIAL_MODIFY_STRING_SIZE];
+ char m_szMaterialVarValue[MATERIAL_MODIFY_STRING_SIZE];
+ IMaterial *m_pMaterial;
+
+ bool m_bHasNewAnimationCommands;
+
+ // Animation commands from the server
+ int m_iFrameStart;
+ int m_iFrameEnd;
+ bool m_bWrap;
+ float m_flFramerate;
+ bool m_bNewAnimCommandsSemaphore;
+ bool m_bOldAnimCommandsSemaphore;
+
+ // Float lerp commands from the server
+ float m_flFloatLerpStartValue;
+ float m_flFloatLerpEndValue;
+ float m_flFloatLerpTransitionTime;
+ bool m_bFloatLerpWrap;
+ float m_flAnimationStartTime;
+
+ int m_nModifyMode;
+};
+
+IMPLEMENT_CLIENTCLASS_DT(C_MaterialModifyControl, DT_MaterialModifyControl, CMaterialModifyControl)
+ RecvPropString( RECVINFO( m_szMaterialName ) ),
+ RecvPropString( RECVINFO( m_szMaterialVar ) ),
+ RecvPropString( RECVINFO( m_szMaterialVarValue ) ),
+ RecvPropInt( RECVINFO(m_iFrameStart) ),
+ RecvPropInt( RECVINFO(m_iFrameEnd) ),
+ RecvPropInt( RECVINFO(m_bWrap) ),
+ RecvPropFloat( RECVINFO(m_flFramerate) ),
+ RecvPropInt( RECVINFO(m_bNewAnimCommandsSemaphore) ),
+ RecvPropFloat( RECVINFO(m_flFloatLerpStartValue) ),
+ RecvPropFloat( RECVINFO(m_flFloatLerpEndValue) ),
+ RecvPropFloat( RECVINFO(m_flFloatLerpTransitionTime) ),
+ RecvPropInt( RECVINFO(m_bFloatLerpWrap) ),
+ RecvPropInt( RECVINFO(m_nModifyMode) ),
+END_RECV_TABLE()
+
+//------------------------------------------------------------------------------
+// Purpose:
+//------------------------------------------------------------------------------
+C_MaterialModifyControl::C_MaterialModifyControl()
+{
+ m_pMaterial = NULL;
+ m_bOldAnimCommandsSemaphore = false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_MaterialModifyControl::OnPreDataChanged( DataUpdateType_t updateType )
+{
+ BaseClass::OnPreDataChanged( updateType );
+
+ m_bOldAnimCommandsSemaphore = m_bNewAnimCommandsSemaphore;
+}
+
+//------------------------------------------------------------------------------
+// Purpose:
+//------------------------------------------------------------------------------
+void C_MaterialModifyControl::OnDataChanged( DataUpdateType_t updateType )
+{
+ if( updateType == DATA_UPDATE_CREATED )
+ {
+ m_pMaterial = materials->FindMaterial( m_szMaterialName, TEXTURE_GROUP_OTHER );
+
+ // Clear out our variables
+ m_bHasNewAnimationCommands = true;
+ }
+
+ // Detect changes in the anim commands
+ if ( m_bNewAnimCommandsSemaphore != m_bOldAnimCommandsSemaphore )
+ {
+ m_bHasNewAnimationCommands = true;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_MaterialModifyControl::GetAnimationCommands( materialanimcommands_t *pCommands )
+{
+ pCommands->iFrameStart = m_iFrameStart;
+ pCommands->iFrameEnd = m_iFrameEnd;
+ pCommands->bWrap = m_bWrap;
+ pCommands->flFrameRate = m_flFramerate;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_MaterialModifyControl::GetFloatLerpCommands( materialfloatlerpcommands_t *pCommands )
+{
+ pCommands->flStartValue = m_flFloatLerpStartValue;
+ pCommands->flEndValue = m_flFloatLerpEndValue;
+ pCommands->flTransitionTime = m_flFloatLerpTransitionTime;
+}
+
+//------------------------------------------------------------------------------
+// Purpose: We don't draw.
+//------------------------------------------------------------------------------
+bool C_MaterialModifyControl::ShouldDraw()
+{
+ return false;
+}
+
+//=============================================================================
+//
+// THE MATERIALMODIFYPROXY ITSELF
+//
+class CMaterialModifyProxy : public CBaseAnimatedTextureProxy
+{
+public:
+ CMaterialModifyProxy();
+ virtual ~CMaterialModifyProxy();
+ virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
+ virtual void OnBind( void *pEntity );
+ virtual IMaterial *GetMaterial();
+
+private:
+ void OnBindSetVar( C_MaterialModifyControl *pControl );
+ void OnBindAnimatedTexture( C_MaterialModifyControl *pControl );
+ void OnBindFloatLerp( C_MaterialModifyControl *pControl );
+ float GetAnimationStartTime( void* pArg );
+ void AnimationWrapped( void* pArg );
+
+ IMaterial *m_pMaterial;
+
+ // texture animation stuff
+ int m_iFrameStart;
+ int m_iFrameEnd;
+ bool m_bReachedEnd;
+ bool m_bCustomWrap;
+ float m_flCustomFramerate;
+
+ // float lerp stuff
+ IMaterialVar *m_pMaterialVar;
+ int m_flStartValue;
+ int m_flEndValue;
+ float m_flStartTime;
+ float m_flTransitionTime;
+};
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CMaterialModifyProxy::CMaterialModifyProxy()
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CMaterialModifyProxy::~CMaterialModifyProxy()
+{
+}
+
+bool CMaterialModifyProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
+{
+ // set var stuff
+ m_pMaterial = pMaterial;
+
+ // float lerp stuff
+ m_flStartValue = MATERIAL_MODIFY_ANIMATION_UNSET;
+ m_flEndValue = MATERIAL_MODIFY_ANIMATION_UNSET;
+
+ // animated stuff
+// m_pMaterial = pMaterial;
+// m_iFrameStart = MATERIAL_MODIFY_ANIMATION_UNSET;
+// m_iFrameEnd = MATERIAL_MODIFY_ANIMATION_UNSET;
+// m_bReachedEnd = false;
+// return CBaseAnimatedTextureProxy::Init( pMaterial, pKeyValues );
+
+ return true;
+}
+
+void CMaterialModifyProxy::OnBind( void *pEntity )
+{
+ // Get the modified material vars from the entity input
+ IClientRenderable *pRend = (IClientRenderable *)pEntity;
+ if ( pRend )
+ {
+ C_BaseEntity *pBaseEntity = pRend->GetIClientUnknown()->GetBaseEntity();
+
+ if ( pBaseEntity )
+ {
+ if( debug_materialmodifycontrol_client.GetBool() )
+ {
+// DevMsg( 1, "%s\n", pBaseEntity->GetDebugName() );
+ }
+ int numChildren = 0;
+ bool gotOne = false;
+ for ( C_BaseEntity *pChild = pBaseEntity->FirstMoveChild(); pChild; pChild = pChild->NextMovePeer() )
+ {
+ numChildren++;
+ C_MaterialModifyControl *pControl = dynamic_cast<C_MaterialModifyControl*>( pChild );
+ if ( !pControl )
+ continue;
+
+ if( debug_materialmodifycontrol_client.GetBool() )
+ {
+// DevMsg( 1, "pControl: 0x%p\n", pControl );
+ }
+
+ switch( pControl->GetModifyMode() )
+ {
+ case MATERIAL_MODIFY_MODE_NONE:
+ break;
+ case MATERIAL_MODIFY_MODE_SETVAR:
+ gotOne = true;
+ OnBindSetVar( pControl );
+ break;
+ case MATERIAL_MODIFY_MODE_ANIM_SEQUENCE:
+ OnBindAnimatedTexture( pControl );
+ break;
+ case MATERIAL_MODIFY_MODE_FLOAT_LERP:
+ OnBindFloatLerp( pControl );
+ break;
+ default:
+ Assert( 0 );
+ break;
+ }
+ }
+ if( gotOne )
+ {
+// DevMsg( 1, "numChildren: %d\n", numChildren );
+ }
+ }
+ }
+
+ if ( ToolsEnabled() )
+ {
+ ToolFramework_RecordMaterialParams( GetMaterial() );
+ }
+}
+
+IMaterial *CMaterialModifyProxy::GetMaterial()
+{
+ return m_pMaterial;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CMaterialModifyProxy::OnBindSetVar( C_MaterialModifyControl *pControl )
+{
+ IMaterial *pMaterial = pControl->GetMaterial();
+ if( !pMaterial )
+ {
+ Assert( 0 );
+ return;
+ }
+
+ if ( pMaterial != m_pMaterial )
+ {
+// Warning( "\t%s!=%s\n", pMaterial->GetName(), m_pMaterial->GetName() );
+ return;
+ }
+
+ bool bFound;
+ IMaterialVar *pMaterialVar = pMaterial->FindVar( pControl->GetMaterialVariableName(), &bFound, false );
+ if ( !bFound )
+ return;
+
+ if( Q_strcmp( pControl->GetMaterialVariableValue(), "" ) )
+ {
+// const char *pMaterialName = m_pMaterial->GetName();
+// const char *pMaterialVarName = pMaterialVar->GetName();
+// const char *pMaterialVarValue = pControl->GetMaterialVariableValue();
+// if( debug_materialmodifycontrol_client.GetBool()
+// && Q_stristr( m_pMaterial->GetName(), "faceandhair" )
+// && Q_stristr( pMaterialVar->GetName(), "self" )
+// )
+// {
+// static int count = 0;
+// DevMsg( 1, "CMaterialModifyProxy::OnBindSetVar \"%s\" %s=%s %d pControl=0x%p\n",
+// m_pMaterial->GetName(), pMaterialVar->GetName(), pControl->GetMaterialVariableValue(), count++, pControl );
+// }
+ pMaterialVar->SetValueAutodetectType( pControl->GetMaterialVariableValue() );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Does the dirty deed
+//-----------------------------------------------------------------------------
+void CMaterialModifyProxy::OnBindAnimatedTexture( C_MaterialModifyControl *pControl )
+{
+ assert ( m_AnimatedTextureVar );
+ if( m_AnimatedTextureVar->GetType() != MATERIAL_VAR_TYPE_TEXTURE )
+ return;
+
+ ITexture *pTexture;
+ pTexture = m_AnimatedTextureVar->GetTextureValue();
+
+ if ( !pControl )
+ return;
+
+ if ( pControl->HasNewAnimationCommands() )
+ {
+ // Read the data from the modify entity
+ materialanimcommands_t sCommands;
+ pControl->GetAnimationCommands( &sCommands );
+
+ m_iFrameStart = sCommands.iFrameStart;
+ m_iFrameEnd = sCommands.iFrameEnd;
+ m_bCustomWrap = sCommands.bWrap;
+ m_flCustomFramerate = sCommands.flFrameRate;
+ m_bReachedEnd = false;
+
+ m_flStartTime = gpGlobals->curtime;
+
+ pControl->ClearAnimationCommands();
+ }
+
+ // Init all the vars based on whether we're using the base material settings,
+ // or the custom ones from the entity input.
+ int numFrames;
+ bool bWrapAnimation;
+ float flFrameRate;
+ int iLastFrame;
+
+ // Do we have a custom frame section from the server?
+ if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
+ {
+ if ( m_iFrameEnd == MATERIAL_MODIFY_ANIMATION_UNSET )
+ {
+ m_iFrameEnd = pTexture->GetNumAnimationFrames();
+ }
+
+ numFrames = (m_iFrameEnd - m_iFrameStart) + 1;
+ bWrapAnimation = m_bCustomWrap;
+ flFrameRate = m_flCustomFramerate;
+ iLastFrame = (m_iFrameEnd - 1);
+ }
+ else
+ {
+ numFrames = pTexture->GetNumAnimationFrames();
+ bWrapAnimation = m_WrapAnimation;
+ flFrameRate = m_FrameRate;
+ iLastFrame = (numFrames - 1);
+ }
+
+ // Have we already reached the end? If so, stay there.
+ if ( m_bReachedEnd && !bWrapAnimation )
+ {
+ m_AnimatedTextureFrameNumVar->SetIntValue( iLastFrame );
+ return;
+ }
+
+ // NOTE: Must not use relative time based methods here
+ // because the bind proxy can be called many times per frame.
+ // Prevent multiple Wrap callbacks to be sent for no wrap mode
+ float startTime;
+ if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
+ {
+ startTime = m_flStartTime;
+ }
+ else
+ {
+ startTime = GetAnimationStartTime(pControl);
+ }
+ float deltaTime = gpGlobals->curtime - startTime;
+ float prevTime = deltaTime - gpGlobals->frametime;
+
+ // Clamp..
+ if (deltaTime < 0.0f)
+ deltaTime = 0.0f;
+ if (prevTime < 0.0f)
+ prevTime = 0.0f;
+
+ float frame = flFrameRate * deltaTime;
+ float prevFrame = flFrameRate * prevTime;
+
+ int intFrame = ((int)frame) % numFrames;
+ int intPrevFrame = ((int)prevFrame) % numFrames;
+
+ if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
+ {
+ intFrame += m_iFrameStart;
+ intPrevFrame += m_iFrameStart;
+ }
+
+ // Report wrap situation...
+ if (intPrevFrame > intFrame)
+ {
+ m_bReachedEnd = true;
+
+ if (bWrapAnimation)
+ {
+ AnimationWrapped( pControl );
+ }
+ else
+ {
+ // Only sent the wrapped message once.
+ // when we're in non-wrapping mode
+ if (prevFrame < numFrames)
+ AnimationWrapped( pControl );
+ intFrame = numFrames - 1;
+ }
+ }
+
+ m_AnimatedTextureFrameNumVar->SetIntValue( intFrame );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+float CMaterialModifyProxy::GetAnimationStartTime( void* pArg )
+{
+ IClientRenderable *pRend = (IClientRenderable *)pArg;
+ if (!pRend)
+ return 0.0f;
+
+ C_BaseEntity* pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
+ if (pEntity)
+ {
+ return pEntity->GetTextureAnimationStartTime();
+ }
+ return 0.0f;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CMaterialModifyProxy::AnimationWrapped( void* pArg )
+{
+ IClientRenderable *pRend = (IClientRenderable *)pArg;
+ if (!pRend)
+ return;
+
+ C_BaseEntity* pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
+ if (pEntity)
+ {
+ pEntity->TextureAnimationWrapped();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Does the dirty deed
+//-----------------------------------------------------------------------------
+void CMaterialModifyProxy::OnBindFloatLerp( C_MaterialModifyControl *pControl )
+{
+ if ( !pControl )
+ return;
+
+ if ( pControl->HasNewAnimationCommands() )
+ {
+ pControl->SetAnimationStartTime( gpGlobals->curtime );
+ pControl->ClearAnimationCommands();
+ }
+
+ // Read the data from the modify entity
+ materialfloatlerpcommands_t sCommands;
+ pControl->GetFloatLerpCommands( &sCommands );
+
+ m_flStartValue = sCommands.flStartValue;
+ m_flEndValue = sCommands.flEndValue;
+ m_flTransitionTime = sCommands.flTransitionTime;
+ m_flStartTime = pControl->GetAnimationStartTime();
+ bool bFound;
+ m_pMaterialVar = m_pMaterial->FindVar( pControl->GetMaterialVariableName(), &bFound, false );
+
+ if( bFound )
+ {
+ float currentValue;
+ if( m_flTransitionTime > 0.0f )
+ {
+ currentValue = m_flStartValue + ( m_flEndValue - m_flStartValue ) * clamp( ( ( gpGlobals->curtime - m_flStartTime ) / m_flTransitionTime ), 0.0f, 1.0f );
+ }
+ else
+ {
+ currentValue = m_flEndValue;
+ }
+
+ if( debug_materialmodifycontrol_client.GetBool() && Q_stristr( m_pMaterial->GetName(), "faceandhair" ) && Q_stristr( m_pMaterialVar->GetName(), "warp" ) )
+ {
+ static int count = 0;
+ DevMsg( 1, "CMaterialFloatLerpProxy::OnBind \"%s\" %s=%f %d\n", m_pMaterial->GetName(), m_pMaterialVar->GetName(), currentValue, count++ );
+ }
+ m_pMaterialVar->SetFloatValue( currentValue );
+ }
+}
+
+//=============================================================================
+//
+// MATERIALMODIFYANIMATED PROXY
+//
+class CMaterialModifyAnimatedProxy : public CBaseAnimatedTextureProxy
+{
+public:
+ CMaterialModifyAnimatedProxy() {};
+ virtual ~CMaterialModifyAnimatedProxy() {};
+ virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
+ virtual void OnBind( void *pEntity );
+
+ virtual float GetAnimationStartTime( void* pBaseEntity );
+ virtual void AnimationWrapped( void* pC_BaseEntity );
+
+private:
+ IMaterial *m_pMaterial;
+ int m_iFrameStart;
+ int m_iFrameEnd;
+ bool m_bReachedEnd;
+ float m_flStartTime;
+ bool m_bCustomWrap;
+ float m_flCustomFramerate;
+};
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool CMaterialModifyAnimatedProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
+{
+ m_pMaterial = pMaterial;
+ m_iFrameStart = MATERIAL_MODIFY_ANIMATION_UNSET;
+ m_iFrameEnd = MATERIAL_MODIFY_ANIMATION_UNSET;
+ m_bReachedEnd = false;
+ return CBaseAnimatedTextureProxy::Init( pMaterial, pKeyValues );
+}
+
+//-----------------------------------------------------------------------------
+// Does the dirty deed
+//-----------------------------------------------------------------------------
+void CMaterialModifyAnimatedProxy::OnBind( void *pEntity )
+{
+ assert ( m_AnimatedTextureVar );
+ if( m_AnimatedTextureVar->GetType() != MATERIAL_VAR_TYPE_TEXTURE )
+ return;
+
+ ITexture *pTexture;
+ pTexture = m_AnimatedTextureVar->GetTextureValue();
+
+ // Get the modified material vars from the entity input
+ IClientRenderable *pRend = (IClientRenderable *)pEntity;
+ if ( pRend )
+ {
+ C_BaseEntity *pBaseEntity = pRend->GetIClientUnknown()->GetBaseEntity();
+ if ( pBaseEntity )
+ {
+ for ( C_BaseEntity *pChild = pBaseEntity->FirstMoveChild(); pChild; pChild = pChild->NextMovePeer() )
+ {
+ C_MaterialModifyControl *pControl = dynamic_cast<C_MaterialModifyControl*>( pChild );
+ if ( !pControl )
+ continue;
+
+ if ( !pControl->HasNewAnimationCommands() )
+ continue;
+
+ // Read the data from the modify entity
+ materialanimcommands_t sCommands;
+ pControl->GetAnimationCommands( &sCommands );
+
+ m_iFrameStart = sCommands.iFrameStart;
+ m_iFrameEnd = sCommands.iFrameEnd;
+ m_bCustomWrap = sCommands.bWrap;
+ m_flCustomFramerate = sCommands.flFrameRate;
+ m_bReachedEnd = false;
+
+ m_flStartTime = gpGlobals->curtime;
+
+ pControl->ClearAnimationCommands();
+ }
+ }
+ }
+
+ // Init all the vars based on whether we're using the base material settings,
+ // or the custom ones from the entity input.
+ int numFrames;
+ bool bWrapAnimation;
+ float flFrameRate;
+ int iLastFrame;
+
+ // Do we have a custom frame section from the server?
+ if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
+ {
+ if ( m_iFrameEnd == MATERIAL_MODIFY_ANIMATION_UNSET )
+ {
+ m_iFrameEnd = pTexture->GetNumAnimationFrames();
+ }
+
+ numFrames = (m_iFrameEnd - m_iFrameStart) + 1;
+ bWrapAnimation = m_bCustomWrap;
+ flFrameRate = m_flCustomFramerate;
+ iLastFrame = (m_iFrameEnd - 1);
+ }
+ else
+ {
+ numFrames = pTexture->GetNumAnimationFrames();
+ bWrapAnimation = m_WrapAnimation;
+ flFrameRate = m_FrameRate;
+ iLastFrame = (numFrames - 1);
+ }
+
+ // Have we already reached the end? If so, stay there.
+ if ( m_bReachedEnd && !bWrapAnimation )
+ {
+ m_AnimatedTextureFrameNumVar->SetIntValue( iLastFrame );
+ return;
+ }
+
+ // NOTE: Must not use relative time based methods here
+ // because the bind proxy can be called many times per frame.
+ // Prevent multiple Wrap callbacks to be sent for no wrap mode
+ float startTime;
+ if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
+ {
+ startTime = m_flStartTime;
+ }
+ else
+ {
+ startTime = GetAnimationStartTime(pEntity);
+ }
+ float deltaTime = gpGlobals->curtime - startTime;
+ float prevTime = deltaTime - gpGlobals->frametime;
+
+ // Clamp..
+ if (deltaTime < 0.0f)
+ deltaTime = 0.0f;
+ if (prevTime < 0.0f)
+ prevTime = 0.0f;
+
+ float frame = flFrameRate * deltaTime;
+ float prevFrame = flFrameRate * prevTime;
+
+ int intFrame = ((int)frame) % numFrames;
+ int intPrevFrame = ((int)prevFrame) % numFrames;
+
+ if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
+ {
+ intFrame += m_iFrameStart;
+ intPrevFrame += m_iFrameStart;
+ }
+
+ // Report wrap situation...
+ if (intPrevFrame > intFrame)
+ {
+ m_bReachedEnd = true;
+
+ if (bWrapAnimation)
+ {
+ AnimationWrapped( pEntity );
+ }
+ else
+ {
+ // Only sent the wrapped message once.
+ // when we're in non-wrapping mode
+ if (prevFrame < numFrames)
+ AnimationWrapped( pEntity );
+ intFrame = numFrames - 1;
+ }
+ }
+
+ m_AnimatedTextureFrameNumVar->SetIntValue( intFrame );
+
+ if ( ToolsEnabled() )
+ {
+ ToolFramework_RecordMaterialParams( GetMaterial() );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+float CMaterialModifyAnimatedProxy::GetAnimationStartTime( void* pArg )
+{
+ IClientRenderable *pRend = (IClientRenderable *)pArg;
+ if (!pRend)
+ return 0.0f;
+
+ C_BaseEntity* pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
+ if (pEntity)
+ {
+ return pEntity->GetTextureAnimationStartTime();
+ }
+ return 0.0f;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CMaterialModifyAnimatedProxy::AnimationWrapped( void* pArg )
+{
+ IClientRenderable *pRend = (IClientRenderable *)pArg;
+ if (!pRend)
+ return;
+
+ C_BaseEntity* pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
+ if (pEntity)
+ {
+ pEntity->TextureAnimationWrapped();
+ }
+}
+
+
+EXPOSE_INTERFACE( CMaterialModifyProxy, IMaterialProxy, "MaterialModify" IMATERIAL_PROXY_INTERFACE_VERSION );
+EXPOSE_INTERFACE( CMaterialModifyAnimatedProxy, IMaterialProxy, "MaterialModifyAnimated" IMATERIAL_PROXY_INTERFACE_VERSION );