173 lines
5.0 KiB
C++
173 lines
5.0 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;
|
|
}
|