diff options
Diffstat (limited to 'game/client/c_func_reflective_glass.cpp')
| -rw-r--r-- | game/client/c_func_reflective_glass.cpp | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/game/client/c_func_reflective_glass.cpp b/game/client/c_func_reflective_glass.cpp new file mode 100644 index 0000000..994d62b --- /dev/null +++ b/game/client/c_func_reflective_glass.cpp @@ -0,0 +1,118 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// +#include "cbase.h" +#include "view_shared.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +class C_FuncReflectiveGlass : public C_BaseEntity +{ +public: + DECLARE_CLASS( C_FuncReflectiveGlass, C_BaseEntity ); + DECLARE_CLIENTCLASS(); + +// C_BaseEntity. +public: + C_FuncReflectiveGlass(); + virtual ~C_FuncReflectiveGlass(); + + virtual bool ShouldDraw(); + + C_FuncReflectiveGlass *m_pNext; +}; + +IMPLEMENT_CLIENTCLASS_DT( C_FuncReflectiveGlass, DT_FuncReflectiveGlass, CFuncReflectiveGlass ) +END_RECV_TABLE() + + +//----------------------------------------------------------------------------- +// Globals +//----------------------------------------------------------------------------- +C_EntityClassList<C_FuncReflectiveGlass> g_ReflectiveGlassList; +template<> C_FuncReflectiveGlass *C_EntityClassList<C_FuncReflectiveGlass>::m_pClassList = NULL; + +C_FuncReflectiveGlass* GetReflectiveGlassList() +{ + return g_ReflectiveGlassList.m_pClassList; +} + + +//----------------------------------------------------------------------------- +// Constructor, destructor +//----------------------------------------------------------------------------- +C_FuncReflectiveGlass::C_FuncReflectiveGlass() +{ + g_ReflectiveGlassList.Insert( this ); +} + +C_FuncReflectiveGlass::~C_FuncReflectiveGlass() +{ + g_ReflectiveGlassList.Remove( this ); +} + + +bool C_FuncReflectiveGlass::ShouldDraw() +{ + return true; +} + + +//----------------------------------------------------------------------------- +// Do we have reflective glass in view? +//----------------------------------------------------------------------------- +bool IsReflectiveGlassInView( const CViewSetup& view, cplane_t &plane ) +{ + // Early out if no cameras + C_FuncReflectiveGlass *pReflectiveGlass = GetReflectiveGlassList(); + if ( !pReflectiveGlass ) + return false; + + Frustum_t frustum; + GeneratePerspectiveFrustum( view.origin, view.angles, view.zNear, view.zFar, view.fov, view.m_flAspectRatio, frustum ); + + cplane_t localPlane; + Vector vecOrigin, vecWorld, vecDelta, vecForward; + AngleVectors( view.angles, &vecForward, NULL, NULL ); + + for ( ; pReflectiveGlass != NULL; pReflectiveGlass = pReflectiveGlass->m_pNext ) + { + if ( pReflectiveGlass->IsDormant() ) + continue; + + Vector vecMins, vecMaxs; + pReflectiveGlass->GetRenderBoundsWorldspace( vecMins, vecMaxs ); + if ( R_CullBox( vecMins, vecMaxs, frustum ) ) + continue; + + const model_t *pModel = pReflectiveGlass->GetModel(); + const matrix3x4_t& mat = pReflectiveGlass->EntityToWorldTransform(); + + int nCount = modelinfo->GetBrushModelPlaneCount( pModel ); + for ( int i = 0; i < nCount; ++i ) + { + modelinfo->GetBrushModelPlane( pModel, i, localPlane, &vecOrigin ); + + MatrixTransformPlane( mat, localPlane, plane ); // Transform to world space + VectorTransform( vecOrigin, mat, vecWorld ); + + if ( view.origin.Dot( plane.normal ) <= plane.dist ) // Check for view behind plane + continue; + + VectorSubtract( vecWorld, view.origin, vecDelta ); // Backface cull + if ( vecDelta.Dot( plane.normal ) >= 0 ) + continue; + + return true; + } + } + + return false; +} + + + |