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.
225 lines
6.7 KiB
225 lines
6.7 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
//=====================================================================================// |
|
#include "cbase.h" |
|
#include "proxyentity.h" |
|
#include "materialsystem/imaterial.h" |
|
#include "materialsystem/imaterialvar.h" |
|
#include "debugoverlay_shared.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
class C_FleshEffectTarget; |
|
void AddFleshProxyTarget( C_FleshEffectTarget *pTarget ); |
|
void RemoveFleshProxy( C_FleshEffectTarget *pTarget ); |
|
|
|
//============================================================================= |
|
// |
|
// Flesh effect target (used for orchestrating the "Invisible Alyx" moment |
|
// |
|
//============================================================================= |
|
|
|
class C_FleshEffectTarget : public C_BaseEntity |
|
{ |
|
DECLARE_CLASS( C_FleshEffectTarget, C_BaseEntity ); |
|
|
|
public: |
|
float GetRadius( void ) |
|
{ |
|
if ( m_flScaleTime <= 0.0f ) |
|
return m_flRadius; |
|
|
|
float dt = ( gpGlobals->curtime - m_flScaleStartTime ); |
|
if ( dt >= m_flScaleTime ) |
|
return m_flRadius; |
|
|
|
return SimpleSplineRemapVal( ( dt / m_flScaleTime ), 0.0f, 1.0f, m_flStartRadius, m_flRadius ); |
|
} |
|
|
|
virtual void Release( void ) |
|
{ |
|
// Remove us from the list of targets |
|
RemoveFleshProxy( this ); |
|
} |
|
|
|
virtual void OnDataChanged( DataUpdateType_t updateType ) |
|
{ |
|
BaseClass::OnDataChanged( updateType ); |
|
|
|
if ( updateType == DATA_UPDATE_CREATED ) |
|
{ |
|
// Add us to the list of flesh proxy targets |
|
AddFleshProxyTarget( this ); |
|
} |
|
} |
|
|
|
float m_flRadius; |
|
float m_flStartRadius; |
|
float m_flScaleStartTime; |
|
float m_flScaleTime; |
|
|
|
DECLARE_CLIENTCLASS(); |
|
}; |
|
|
|
void RecvProxy_FleshEffect_Radius( const CRecvProxyData *pData, void *pStruct, void *pOut ) |
|
{ |
|
C_FleshEffectTarget *pTarget = (C_FleshEffectTarget *) pStruct; |
|
float flRadius = pData->m_Value.m_Float; |
|
|
|
//If changed, update our internal information |
|
if ( pTarget->m_flRadius != flRadius ) |
|
{ |
|
pTarget->m_flStartRadius = pTarget->m_flRadius; |
|
pTarget->m_flScaleStartTime = gpGlobals->curtime; |
|
} |
|
|
|
pTarget->m_flRadius = flRadius; |
|
} |
|
|
|
IMPLEMENT_CLIENTCLASS_DT( C_FleshEffectTarget, DT_FleshEffectTarget, CFleshEffectTarget ) |
|
RecvPropFloat( RECVINFO(m_flRadius), 0, RecvProxy_FleshEffect_Radius ), |
|
RecvPropFloat( RECVINFO(m_flScaleTime) ), |
|
END_RECV_TABLE() |
|
|
|
CUtlVector< C_FleshEffectTarget * > g_FleshProxyTargets; |
|
|
|
void AddFleshProxyTarget( C_FleshEffectTarget *pTarget ) |
|
{ |
|
// Take it! |
|
g_FleshProxyTargets.AddToTail( pTarget ); |
|
} |
|
|
|
void RemoveFleshProxy( C_FleshEffectTarget *pTarget ) |
|
{ |
|
int nIndex = g_FleshProxyTargets.Find( pTarget ); |
|
if ( nIndex != g_FleshProxyTargets.InvalidIndex() ) |
|
{ |
|
g_FleshProxyTargets.Remove( nIndex ); |
|
} |
|
} |
|
|
|
// $sineVar : name of variable that controls the FleshInterior level (float) |
|
class CFleshInteriorMaterialProxy : public CEntityMaterialProxy |
|
{ |
|
public: |
|
CFleshInteriorMaterialProxy(); |
|
virtual ~CFleshInteriorMaterialProxy(); |
|
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues ); |
|
virtual void OnBind( C_BaseEntity *pEntity ); |
|
virtual IMaterial *GetMaterial(); |
|
|
|
private: |
|
IMaterialVar *m_pMaterialParamFleshEffectCenterRadius1; |
|
IMaterialVar *m_pMaterialParamFleshEffectCenterRadius2; |
|
IMaterialVar *m_pMaterialParamFleshEffectCenterRadius3; |
|
IMaterialVar *m_pMaterialParamFleshEffectCenterRadius4; |
|
IMaterialVar *m_pMaterialParamFleshGlobalOpacity; |
|
IMaterialVar *m_pMaterialParamFleshSubsurfaceTint; |
|
}; |
|
|
|
CFleshInteriorMaterialProxy::CFleshInteriorMaterialProxy() |
|
{ |
|
m_pMaterialParamFleshEffectCenterRadius1 = NULL; |
|
m_pMaterialParamFleshEffectCenterRadius2 = NULL; |
|
m_pMaterialParamFleshEffectCenterRadius3 = NULL; |
|
m_pMaterialParamFleshEffectCenterRadius4 = NULL; |
|
m_pMaterialParamFleshGlobalOpacity = NULL; |
|
m_pMaterialParamFleshSubsurfaceTint = NULL; |
|
} |
|
|
|
CFleshInteriorMaterialProxy::~CFleshInteriorMaterialProxy() |
|
{ |
|
// Do nothing |
|
} |
|
|
|
bool CFleshInteriorMaterialProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues ) |
|
{ |
|
bool bFoundVar = false; |
|
|
|
m_pMaterialParamFleshEffectCenterRadius1 = pMaterial->FindVar( "$FleshEffectCenterRadius1", &bFoundVar, false ); |
|
if ( bFoundVar == false) |
|
return false; |
|
|
|
m_pMaterialParamFleshEffectCenterRadius2 = pMaterial->FindVar( "$FleshEffectCenterRadius2", &bFoundVar, false ); |
|
if ( bFoundVar == false) |
|
return false; |
|
|
|
m_pMaterialParamFleshEffectCenterRadius3 = pMaterial->FindVar( "$FleshEffectCenterRadius3", &bFoundVar, false ); |
|
if ( bFoundVar == false) |
|
return false; |
|
|
|
m_pMaterialParamFleshEffectCenterRadius4 = pMaterial->FindVar( "$FleshEffectCenterRadius4", &bFoundVar, false ); |
|
if ( bFoundVar == false) |
|
return false; |
|
|
|
m_pMaterialParamFleshGlobalOpacity = pMaterial->FindVar( "$FleshGlobalOpacity", &bFoundVar, false ); |
|
if ( bFoundVar == false) |
|
return false; |
|
|
|
m_pMaterialParamFleshSubsurfaceTint = pMaterial->FindVar( "$FleshSubsurfaceTint", &bFoundVar, false ); |
|
if ( bFoundVar == false) |
|
return false; |
|
|
|
return true; |
|
} |
|
|
|
void CFleshInteriorMaterialProxy::OnBind( C_BaseEntity *pEnt ) |
|
{ |
|
IMaterialVar *pParams[] = |
|
{ |
|
m_pMaterialParamFleshEffectCenterRadius1, |
|
m_pMaterialParamFleshEffectCenterRadius2, |
|
m_pMaterialParamFleshEffectCenterRadius3, |
|
m_pMaterialParamFleshEffectCenterRadius4 |
|
}; |
|
|
|
float vEffectCenterRadius[4]; |
|
for ( int i = 0; i < ARRAYSIZE( pParams ); i++ ) |
|
{ |
|
if ( i < g_FleshProxyTargets.Count() ) |
|
{ |
|
// Setup the target |
|
if ( g_FleshProxyTargets[i]->IsAbsQueriesValid() == false ) |
|
continue; |
|
|
|
Vector vecAbsOrigin = g_FleshProxyTargets[i]->GetAbsOrigin(); |
|
vEffectCenterRadius[0] = vecAbsOrigin.x; |
|
vEffectCenterRadius[1] = vecAbsOrigin.y; |
|
vEffectCenterRadius[2] = vecAbsOrigin.z; |
|
vEffectCenterRadius[3] = g_FleshProxyTargets[i]->GetRadius(); |
|
} |
|
else |
|
{ |
|
// Clear the target |
|
vEffectCenterRadius[0] = vEffectCenterRadius[1] = vEffectCenterRadius[2] = vEffectCenterRadius[3] = 0.0f; |
|
} |
|
|
|
// Set the value either way |
|
pParams[i]->SetVecValue( vEffectCenterRadius, 4 ); |
|
} |
|
|
|
// Subsurface texture. NOTE: This texture bleeds through the color of the flesh texture so expect |
|
// to have to set this brighter than white to really see the subsurface texture glow through. |
|
if ( m_pMaterialParamFleshSubsurfaceTint != NULL ) |
|
{ |
|
float vSubsurfaceTintColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; |
|
|
|
// !!! Test code. REPLACE ME! |
|
// vSubsurfaceTintColor[0] = vSubsurfaceTintColor[1] = vSubsurfaceTintColor[2] = sinf( gpGlobals->curtime * 3.0f ) + 1.0f; // * 0.5f + 0.5f; |
|
|
|
m_pMaterialParamFleshSubsurfaceTint->SetVecValue( vSubsurfaceTintColor, 4 ); |
|
} |
|
} |
|
|
|
IMaterial *CFleshInteriorMaterialProxy::GetMaterial() |
|
{ |
|
if ( m_pMaterialParamFleshEffectCenterRadius1 == NULL) |
|
return NULL; |
|
|
|
return m_pMaterialParamFleshEffectCenterRadius1->GetOwningMaterial(); |
|
} |
|
|
|
EXPOSE_INTERFACE( CFleshInteriorMaterialProxy, IMaterialProxy, "FleshInterior" IMATERIAL_PROXY_INTERFACE_VERSION );
|
|
|