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.
118 lines
3.2 KiB
118 lines
3.2 KiB
//========= 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; |
|
} |
|
|
|
|
|
|
|
|