Team Fortress 2 Source Code as on 22/4/2020
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

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //===========================================================================//
  7. #include "cbase.h"
  8. #include "view_shared.h"
  9. // memdbgon must be the last include file in a .cpp file!!!
  10. #include "tier0/memdbgon.h"
  11. class C_FuncReflectiveGlass : public C_BaseEntity
  12. {
  13. public:
  14. DECLARE_CLASS( C_FuncReflectiveGlass, C_BaseEntity );
  15. DECLARE_CLIENTCLASS();
  16. // C_BaseEntity.
  17. public:
  18. C_FuncReflectiveGlass();
  19. virtual ~C_FuncReflectiveGlass();
  20. virtual bool ShouldDraw();
  21. C_FuncReflectiveGlass *m_pNext;
  22. };
  23. IMPLEMENT_CLIENTCLASS_DT( C_FuncReflectiveGlass, DT_FuncReflectiveGlass, CFuncReflectiveGlass )
  24. END_RECV_TABLE()
  25. //-----------------------------------------------------------------------------
  26. // Globals
  27. //-----------------------------------------------------------------------------
  28. C_EntityClassList<C_FuncReflectiveGlass> g_ReflectiveGlassList;
  29. template<> C_FuncReflectiveGlass *C_EntityClassList<C_FuncReflectiveGlass>::m_pClassList = NULL;
  30. C_FuncReflectiveGlass* GetReflectiveGlassList()
  31. {
  32. return g_ReflectiveGlassList.m_pClassList;
  33. }
  34. //-----------------------------------------------------------------------------
  35. // Constructor, destructor
  36. //-----------------------------------------------------------------------------
  37. C_FuncReflectiveGlass::C_FuncReflectiveGlass()
  38. {
  39. g_ReflectiveGlassList.Insert( this );
  40. }
  41. C_FuncReflectiveGlass::~C_FuncReflectiveGlass()
  42. {
  43. g_ReflectiveGlassList.Remove( this );
  44. }
  45. bool C_FuncReflectiveGlass::ShouldDraw()
  46. {
  47. return true;
  48. }
  49. //-----------------------------------------------------------------------------
  50. // Do we have reflective glass in view?
  51. //-----------------------------------------------------------------------------
  52. bool IsReflectiveGlassInView( const CViewSetup& view, cplane_t &plane )
  53. {
  54. // Early out if no cameras
  55. C_FuncReflectiveGlass *pReflectiveGlass = GetReflectiveGlassList();
  56. if ( !pReflectiveGlass )
  57. return false;
  58. Frustum_t frustum;
  59. GeneratePerspectiveFrustum( view.origin, view.angles, view.zNear, view.zFar, view.fov, view.m_flAspectRatio, frustum );
  60. cplane_t localPlane;
  61. Vector vecOrigin, vecWorld, vecDelta, vecForward;
  62. AngleVectors( view.angles, &vecForward, NULL, NULL );
  63. for ( ; pReflectiveGlass != NULL; pReflectiveGlass = pReflectiveGlass->m_pNext )
  64. {
  65. if ( pReflectiveGlass->IsDormant() )
  66. continue;
  67. Vector vecMins, vecMaxs;
  68. pReflectiveGlass->GetRenderBoundsWorldspace( vecMins, vecMaxs );
  69. if ( R_CullBox( vecMins, vecMaxs, frustum ) )
  70. continue;
  71. const model_t *pModel = pReflectiveGlass->GetModel();
  72. const matrix3x4_t& mat = pReflectiveGlass->EntityToWorldTransform();
  73. int nCount = modelinfo->GetBrushModelPlaneCount( pModel );
  74. for ( int i = 0; i < nCount; ++i )
  75. {
  76. modelinfo->GetBrushModelPlane( pModel, i, localPlane, &vecOrigin );
  77. MatrixTransformPlane( mat, localPlane, plane ); // Transform to world space
  78. VectorTransform( vecOrigin, mat, vecWorld );
  79. if ( view.origin.Dot( plane.normal ) <= plane.dist ) // Check for view behind plane
  80. continue;
  81. VectorSubtract( vecWorld, view.origin, vecDelta ); // Backface cull
  82. if ( vecDelta.Dot( plane.normal ) >= 0 )
  83. continue;
  84. return true;
  85. }
  86. }
  87. return false;
  88. }