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.

340 lines
11 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Base decorator class to make a DME renderable
  4. //
  5. //===========================================================================//
  6. #ifndef DMERENDERABLE_H
  7. #define DMERENDERABLE_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "iclientunknown.h"
  12. #include "iclientrenderable.h"
  13. #include "datamodel/dmelement.h"
  14. #include "datamodel/dmattributevar.h"
  15. #include "mathlib/mathlib.h"
  16. #include "basehandle.h"
  17. #include "toolutils/enginetools_int.h"
  18. #include "engine/iclientleafsystem.h"
  19. #include "datamodel/dmelementfactoryhelper.h"
  20. //-----------------------------------------------------------------------------
  21. // Deals with the base implementation for turning a Dme into a renderable
  22. //-----------------------------------------------------------------------------
  23. template < class T >
  24. class CDmeRenderable : public T, public IClientUnknown, public IClientRenderable
  25. {
  26. DEFINE_UNINSTANCEABLE_ELEMENT( CDmeRenderable, T );
  27. protected:
  28. virtual void OnAttributeChanged( CDmAttribute *pAttribute );
  29. // IClientUnknown implementation.
  30. public:
  31. virtual void SetRefEHandle( const CBaseHandle &handle );
  32. virtual const CBaseHandle& GetRefEHandle() const;
  33. virtual IClientUnknown* GetIClientUnknown() { return this; }
  34. virtual ICollideable* GetCollideable() { return 0; }
  35. virtual IClientRenderable* GetClientRenderable() { return this; }
  36. virtual IClientNetworkable* GetClientNetworkable() { return 0; }
  37. virtual IClientEntity* GetIClientEntity() { return 0; }
  38. virtual C_BaseEntity* GetBaseEntity() { return 0; }
  39. virtual IClientThinkable* GetClientThinkable() { return 0; }
  40. // virtual const Vector & GetRenderOrigin( void ) { return vec3_origin; }
  41. // virtual const QAngle & GetRenderAngles( void ) { return vec3_angle; }
  42. virtual bool ShouldDraw( void ) { return false; }
  43. virtual bool IsTransparent( void ) { return false; }
  44. virtual bool IsTwoPass( void ) { return false; }
  45. virtual void OnThreadedDrawSetup() {}
  46. virtual bool UsesPowerOfTwoFrameBufferTexture() { return false; }
  47. virtual bool UsesFullFrameBufferTexture() { return false; }
  48. virtual ClientShadowHandle_t GetShadowHandle() const;
  49. virtual ClientRenderHandle_t& RenderHandle();
  50. virtual int GetBody() { return 0; }
  51. virtual int GetSkin() { return 0; }
  52. virtual const model_t* GetModel( ) const { return NULL; }
  53. // virtual int DrawModel( int flags );
  54. virtual void ComputeFxBlend( ) { return; }
  55. virtual int GetFxBlend( ) { return 255; }
  56. virtual bool LODTest() { return true; }
  57. virtual bool SetupBones( matrix3x4_t *pBoneToWorldOut, int nMaxBones, int boneMask, float currentTime ) { return true; }
  58. virtual void SetupWeights( const matrix3x4_t *pBoneToWorld, int nFlexWeightCount, float *pFlexWeights, float *pFlexDelayedWeights ) {}
  59. virtual bool UsesFlexDelayedWeights() { return false; }
  60. virtual void DoAnimationEvents( void ) {}
  61. virtual IPVSNotify* GetPVSNotifyInterface() { return NULL; }
  62. virtual void GetRenderBoundsWorldspace( Vector& absMins, Vector& absMaxs );
  63. virtual void GetColorModulation( float* color );
  64. // virtual void GetRenderBounds( Vector& mins, Vector& maxs );
  65. virtual bool ShouldReceiveProjectedTextures( int flags ) { return false; }
  66. virtual bool GetShadowCastDistance( float *pDist, ShadowType_t shadowType ) const { return false; }
  67. virtual bool GetShadowCastDirection( Vector *pDirection, ShadowType_t shadowType ) const { return false; }
  68. virtual void GetShadowRenderBounds( Vector &mins, Vector &maxs, ShadowType_t shadowType );
  69. virtual bool IsShadowDirty( ) { return false; }
  70. virtual void MarkShadowDirty( bool bDirty ) {}
  71. virtual IClientRenderable *GetShadowParent() { return NULL; }
  72. virtual IClientRenderable *FirstShadowChild(){ return NULL; }
  73. virtual IClientRenderable *NextShadowPeer() { return NULL; }
  74. virtual ShadowType_t ShadowCastType() { return SHADOWS_NONE; }
  75. virtual void CreateModelInstance() {}
  76. virtual ModelInstanceHandle_t GetModelInstance() { return MODEL_INSTANCE_INVALID; }
  77. virtual const matrix3x4_t &RenderableToWorldTransform();
  78. virtual int LookupAttachment( const char *pAttachmentName ) { return -1; }
  79. virtual bool GetAttachment( int number, Vector &origin, QAngle &angles );
  80. virtual bool GetAttachment( int number, matrix3x4_t &matrix );
  81. virtual float *GetRenderClipPlane() { return NULL; }
  82. virtual void RecordToolMessage() {}
  83. virtual bool IgnoresZBuffer( void ) const { return false; }
  84. // Add/remove to engine from drawing
  85. void DrawInEngine( bool bDrawInEngine );
  86. bool IsDrawingInEngine() const;
  87. protected:
  88. virtual CDmAttribute* GetVisibilityAttribute() { return NULL; }
  89. virtual CDmAttribute* GetDrawnInEngineAttribute() { return m_bWantsToBeDrawnInEngine.GetAttribute(); }
  90. Vector m_vecRenderOrigin;
  91. QAngle m_angRenderAngles;
  92. protected:
  93. CDmaVar<bool> m_bWantsToBeDrawnInEngine;
  94. bool m_bIsDrawingInEngine;
  95. CBaseHandle m_RefEHandle; // Reference ehandle. Used to generate ehandles off this entity.
  96. ClientRenderHandle_t m_hRenderHandle;
  97. };
  98. //-----------------------------------------------------------------------------
  99. // Construction, destruction
  100. //-----------------------------------------------------------------------------
  101. template < class T >
  102. void CDmeRenderable<T>::OnConstruction()
  103. {
  104. m_hRenderHandle = INVALID_CLIENT_RENDER_HANDLE;
  105. m_bWantsToBeDrawnInEngine.InitAndSet( this, "wantsToBeDrawnInEngine", false, FATTRIB_DONTSAVE | FATTRIB_HAS_CALLBACK );
  106. m_bIsDrawingInEngine = false;
  107. }
  108. template < class T >
  109. void CDmeRenderable<T>::OnDestruction()
  110. {
  111. if ( m_bIsDrawingInEngine )
  112. {
  113. if ( clienttools )
  114. {
  115. clienttools->RemoveClientRenderable( this );
  116. }
  117. m_bIsDrawingInEngine = false;
  118. }
  119. }
  120. //-----------------------------------------------------------------------------
  121. // EHandles
  122. //-----------------------------------------------------------------------------
  123. template < class T >
  124. void CDmeRenderable<T>::SetRefEHandle( const CBaseHandle &handle )
  125. {
  126. m_RefEHandle = handle;
  127. }
  128. template < class T >
  129. const CBaseHandle& CDmeRenderable<T>::GetRefEHandle() const
  130. {
  131. return m_RefEHandle;
  132. }
  133. //-----------------------------------------------------------------------------
  134. // Add/remove to engine from drawing
  135. //-----------------------------------------------------------------------------
  136. template < class T >
  137. void CDmeRenderable<T>::DrawInEngine( bool bDrawInEngine )
  138. {
  139. m_bWantsToBeDrawnInEngine = bDrawInEngine;
  140. }
  141. template < class T >
  142. bool CDmeRenderable<T>::IsDrawingInEngine() const
  143. {
  144. return m_bIsDrawingInEngine;
  145. }
  146. //-----------------------------------------------------------------------------
  147. // Called when attributes changed
  148. //-----------------------------------------------------------------------------
  149. template < class T >
  150. void CDmeRenderable<T>::OnAttributeChanged( CDmAttribute *pAttribute )
  151. {
  152. T::OnAttributeChanged( pAttribute );
  153. CDmAttribute *pVisibilityAttribute = GetVisibilityAttribute();
  154. if ( pAttribute == pVisibilityAttribute || pAttribute == m_bWantsToBeDrawnInEngine.GetAttribute() )
  155. {
  156. bool bIsVisible = pVisibilityAttribute ? pVisibilityAttribute->GetValue<bool>() : true;
  157. bool bShouldDrawInEngine = m_bWantsToBeDrawnInEngine && bIsVisible;
  158. if ( m_bIsDrawingInEngine != bShouldDrawInEngine )
  159. {
  160. m_bIsDrawingInEngine = bShouldDrawInEngine;
  161. if ( clienttools )
  162. {
  163. if ( m_bIsDrawingInEngine )
  164. {
  165. clienttools->AddClientRenderable( this, IsTransparent() ? RENDER_GROUP_TRANSLUCENT_ENTITY : RENDER_GROUP_OPAQUE_ENTITY );
  166. }
  167. else
  168. {
  169. clienttools->RemoveClientRenderable( this );
  170. }
  171. }
  172. }
  173. }
  174. }
  175. //-----------------------------------------------------------------------------
  176. // Color modulation
  177. //-----------------------------------------------------------------------------
  178. template < class T >
  179. void CDmeRenderable<T>::GetColorModulation( float* color )
  180. {
  181. Assert(color);
  182. color[0] = color[1] = color[2] = 1.0f;
  183. }
  184. //-----------------------------------------------------------------------------
  185. // Attachments
  186. //-----------------------------------------------------------------------------
  187. template < class T >
  188. bool CDmeRenderable<T>::GetAttachment( int number, Vector &origin, QAngle &angles )
  189. {
  190. origin = GetRenderOrigin();
  191. angles = GetRenderAngles();
  192. return true;
  193. }
  194. template < class T >
  195. bool CDmeRenderable<T>::GetAttachment( int number, matrix3x4_t &matrix )
  196. {
  197. MatrixCopy( RenderableToWorldTransform(), matrix );
  198. return true;
  199. }
  200. //-----------------------------------------------------------------------------
  201. // Other methods
  202. //-----------------------------------------------------------------------------
  203. template < class T >
  204. void CDmeRenderable<T>::GetShadowRenderBounds( Vector &mins, Vector &maxs, ShadowType_t shadowType )
  205. {
  206. GetRenderBounds( mins, maxs );
  207. }
  208. template < class T >
  209. inline ClientShadowHandle_t CDmeRenderable<T>::GetShadowHandle() const
  210. {
  211. return CLIENTSHADOW_INVALID_HANDLE;
  212. }
  213. template < class T >
  214. inline ClientRenderHandle_t& CDmeRenderable<T>::RenderHandle()
  215. {
  216. return m_hRenderHandle;
  217. }
  218. template < class T >
  219. void CDmeRenderable<T>::GetRenderBoundsWorldspace( Vector& absMins, Vector& absMaxs )
  220. {
  221. Vector mins, maxs;
  222. GetRenderBounds( mins, maxs );
  223. // FIXME: Should I just use a sphere here?
  224. // Another option is to pass the OBB down the tree; makes for a better fit
  225. // Generate a world-aligned AABB
  226. const QAngle& angles = GetRenderAngles();
  227. const Vector& origin = GetRenderOrigin();
  228. if ( angles == vec3_angle )
  229. {
  230. VectorAdd( mins, origin, absMins );
  231. VectorAdd( maxs, origin, absMaxs );
  232. }
  233. else
  234. {
  235. matrix3x4_t boxToWorld;
  236. AngleMatrix( angles, origin, boxToWorld );
  237. TransformAABB( boxToWorld, mins, maxs, absMins, absMaxs );
  238. }
  239. Assert( absMins.IsValid() && absMaxs.IsValid() );
  240. }
  241. template < class T >
  242. const matrix3x4_t &CDmeRenderable<T>::RenderableToWorldTransform()
  243. {
  244. static matrix3x4_t mat;
  245. AngleMatrix( GetRenderAngles(), GetRenderOrigin(), mat );
  246. return mat;
  247. }
  248. //-----------------------------------------------------------------------------
  249. // Adds a 'visibility' attribute onto renderables that need it
  250. //-----------------------------------------------------------------------------
  251. template < class T >
  252. class CDmeVisibilityControl : public T
  253. {
  254. DEFINE_UNINSTANCEABLE_ELEMENT( CDmeVisibilityControl, T );
  255. public:
  256. // Control visibility
  257. bool IsVisible() const;
  258. void SetVisible( bool bVisible );
  259. private:
  260. virtual CDmAttribute* GetVisibilityAttribute() { return m_bIsVisible.GetAttribute(); }
  261. CDmaVar< bool > m_bIsVisible;
  262. };
  263. //-----------------------------------------------------------------------------
  264. // Construction, destruction
  265. //-----------------------------------------------------------------------------
  266. template < class T >
  267. void CDmeVisibilityControl<T>::OnConstruction()
  268. {
  269. m_bIsVisible.InitAndSet( this, "visible", true, FATTRIB_HAS_CALLBACK );
  270. }
  271. template < class T >
  272. void CDmeVisibilityControl<T>::OnDestruction()
  273. {
  274. }
  275. //-----------------------------------------------------------------------------
  276. // Deal with visibility
  277. //-----------------------------------------------------------------------------
  278. template < class T >
  279. void CDmeVisibilityControl<T>::SetVisible( bool bVisible )
  280. {
  281. if ( bVisible != m_bIsVisible )
  282. {
  283. m_bIsVisible = bVisible;
  284. }
  285. }
  286. template < class T >
  287. bool CDmeVisibilityControl<T>::IsVisible() const
  288. {
  289. return m_bIsVisible;
  290. }
  291. #endif // DMERENDERABLE_H