csgo-2018-source/game/client/c_prop_hallucination.cpp
2021-07-24 21:11:47 -07:00

173 lines
4.8 KiB
C++

//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "c_baseanimating.h"
#include "materialsystem/imaterialsystem.h"
#include "model_types.h"
#include "viewrender.h"
#include "c_pixel_visibility.h"
extern view_id_t CurrentViewID();
extern bool IsMainView( view_id_t id );
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
class C_Prop_Hallucination : public C_BaseAnimating
{
public:
DECLARE_CLASS( C_Prop_Hallucination, C_BaseAnimating );
DECLARE_CLIENTCLASS();
virtual void Spawn( void );
virtual void UpdateOnRemove( void );
//virtual bool ShouldDraw( void );
virtual int DrawModel( int flags, const RenderableInstance_t &instance );
virtual ShadowType_t ShadowCastType( void );
virtual void OnDataChanged( DataUpdateType_t type );
COcclusionQuerySet m_OcclusionSet;
int m_iLastDrawCallFrame;
bool m_bVisibleInAnyViewLastFrame;
//float m_fVisibilityRemaining; //an ill defined measure of how much longer we're visible. When it reaches 0 we no longer show the hallucination until it's recharged to 1. Being occluded before reaching 0 is going to be up in the air on what to do.
double m_fLastStateChangeTime;
bool m_bVisibleEligible;
bool m_bEnabled;
float m_fVisibleTime;
float m_fRechargeTime;
static CMaterialReference sm_OcclusionProxyMaterial;
};
CMaterialReference C_Prop_Hallucination::sm_OcclusionProxyMaterial;
IMPLEMENT_CLIENTCLASS_DT( C_Prop_Hallucination, DT_Prop_Hallucination, CProp_Hallucination )
RecvPropBool( RECVINFO(m_bEnabled) ),
RecvPropFloat( RECVINFO(m_fVisibleTime) ),
RecvPropFloat( RECVINFO(m_fRechargeTime) ),
END_RECV_TABLE()
//ConVar cl_hallucination_dischargescale( "cl_hallucination_dischargescale", "3000.0", FCVAR_CHEAT, "(delta time) * (percentage of screen drawn to) * (this scale) is how much visibility charge (0.0-1.0) we use up per frame. When it's 0.0 the hallucination is invisible" );
//ConVar cl_hallucination_visibletime( "cl_hallucination_visibletime", "0.215", FCVAR_CHEAT, "the maximum time (in seconds) from first visible frame to when we stop drawing the hallucination" );
//ConVar cl_hallucination_rechargetime( "cl_hallucination_rechargetime", "2.0", FCVAR_CHEAT, "How much time must pass without drawing the hallucination before it's eligble to draw again" );
void C_Prop_Hallucination::Spawn( void )
{
if( !sm_OcclusionProxyMaterial.IsValid() )
{
sm_OcclusionProxyMaterial.Init( "engine/occlusionproxy", TEXTURE_GROUP_CLIENT_EFFECTS );
}
BaseClass::Spawn();
}
void C_Prop_Hallucination::UpdateOnRemove( void )
{
BaseClass::UpdateOnRemove();
}
void C_Prop_Hallucination::OnDataChanged( DataUpdateType_t type )
{
if( !m_bEnabled )
{
if( m_bVisibleEligible && (m_fLastStateChangeTime != 0.0f) )
{
m_fLastStateChangeTime = Plat_FloatTime();
}
m_bVisibleEligible = false;
}
}
int C_Prop_Hallucination::DrawModel( int flags, const RenderableInstance_t &instance )
{
switch( CurrentViewID() )
{
case VIEW_SHADOW_DEPTH_TEXTURE:
if( m_bVisibleEligible )
{
return BaseClass::DrawModel( flags, instance );
}
default:
if( IsMainView( CurrentViewID() ) ) //VIEW_MAIN and portal views are true
{
break;
}
else
{
return 0;
}
};
bool bSameFrame = (m_iLastDrawCallFrame == gpGlobals->framecount);
if( (flags & STUDIO_RENDER) && !bSameFrame )
{
bool bDrewLastFrame = (m_iLastDrawCallFrame == (gpGlobals->framecount - 1));
if( m_bVisibleEligible )
{
if( m_fLastStateChangeTime == 0.0 ) //waiting for the first frame of actual visibility mark the state change
{
if( bDrewLastFrame && (m_OcclusionSet.QueryNumPixelsRenderedForAllViewsLastFrame() > 0) )
{
m_fLastStateChangeTime = Plat_FloatTime();// - gpGlobals->realtime; //state change occurred last frame
}
}
else if( (Plat_FloatTime() - m_fLastStateChangeTime) > m_fVisibleTime )
{
m_bVisibleEligible = false;
}
}
else
{
if( ((m_fLastStateChangeTime == 0.0f) || (Plat_FloatTime() - m_fLastStateChangeTime) > m_fRechargeTime) &&
((m_OcclusionSet.QueryNumPixelsRenderedForAllViewsLastFrame() == 0) || !bDrewLastFrame) )
{
m_bVisibleEligible = true;
m_fLastStateChangeTime = 0.0f;
}
}
}
if( flags & STUDIO_RENDER )
{
if( !m_bVisibleEligible )
{
modelrender->ForcedMaterialOverride( sm_OcclusionProxyMaterial );
}
m_iLastDrawCallFrame = gpGlobals->framecount;
m_OcclusionSet.BeginQueryDrawing();
int iRetVal = BaseClass::DrawModel( flags, instance );
m_OcclusionSet.EndQueryDrawing();
if( !m_bVisibleEligible )
{
modelrender->ForcedMaterialOverride( NULL );
}
return iRetVal;
}
else
{
return BaseClass::DrawModel( flags, instance );
}
}
ShadowType_t C_Prop_Hallucination::ShadowCastType( void )
{
return SHADOWS_NONE;
}