Counter Strike : Global Offensive Source Code
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.

416 lines
14 KiB

  1. //====== Copyright � 1996-2005, 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. virtual void OnAdoptedFromUndo();
  30. virtual void OnOrphanedToUndo();
  31. void UpdateIsDrawingInEngine();
  32. // IClientUnknown implementation.
  33. public:
  34. virtual void SetRefEHandle( const CBaseHandle &handle );
  35. virtual const CBaseHandle& GetRefEHandle() const;
  36. virtual IClientUnknown* GetIClientUnknown() { return this; }
  37. virtual ICollideable* GetCollideable() { return 0; }
  38. virtual IClientRenderable* GetClientRenderable() { return this; }
  39. virtual IClientNetworkable* GetClientNetworkable() { return 0; }
  40. virtual IClientEntity* GetIClientEntity() { return 0; }
  41. virtual C_BaseEntity* GetBaseEntity() { return 0; }
  42. virtual IClientThinkable* GetClientThinkable() { return 0; }
  43. virtual IClientAlphaProperty* GetClientAlphaProperty() { return 0; }
  44. // virtual const Vector & GetRenderOrigin( void ) { return vec3_origin; }
  45. // virtual const QAngle & GetRenderAngles( void ) { return vec3_angle; }
  46. virtual bool ShouldDraw( void ) { return false; }
  47. virtual void OnThreadedDrawSetup() {}
  48. virtual int GetRenderFlags( void ) { return 0; }
  49. virtual ClientShadowHandle_t GetShadowHandle() const;
  50. virtual ClientRenderHandle_t& RenderHandle();
  51. virtual int GetBody() { return 0; }
  52. virtual int GetSkin() { return 0; }
  53. virtual const model_t* GetModel( ) const { return NULL; }
  54. // virtual int DrawModel( int flags, const RenderableInstance_t &instance );
  55. virtual uint8 OverrideAlphaModulation( uint8 nAlpha ) { return nAlpha; }
  56. virtual uint8 OverrideShadowAlphaModulation( uint8 nAlpha ) { return nAlpha; }
  57. virtual bool LODTest() { return true; }
  58. virtual bool SetupBones( matrix3x4a_t *pBoneToWorldOut, int nMaxBones, int boneMask, float currentTime ) { return true; }
  59. virtual void SetupWeights( const matrix3x4_t *pBoneToWorld, int nFlexWeightCount, float *pFlexWeights, float *pFlexDelayedWeights ) {}
  60. virtual bool UsesFlexDelayedWeights() { return false; }
  61. virtual void DoAnimationEvents( void ) {}
  62. virtual IPVSNotify* GetPVSNotifyInterface() { return NULL; }
  63. virtual void GetRenderBoundsWorldspace( Vector& absMins, Vector& absMaxs );
  64. virtual void GetColorModulation( float* color );
  65. // virtual void GetRenderBounds( Vector& mins, Vector& maxs );
  66. virtual bool ShouldReceiveProjectedTextures( int flags ) { return false; }
  67. virtual bool GetShadowCastDistance( float *pDist, ShadowType_t shadowType ) const { return false; }
  68. virtual bool GetShadowCastDirection( Vector *pDirection, ShadowType_t shadowType ) const { return false; }
  69. virtual void GetShadowRenderBounds( Vector &mins, Vector &maxs, ShadowType_t shadowType );
  70. virtual bool IsShadowDirty( ) { return false; }
  71. virtual void MarkShadowDirty( bool bDirty ) {}
  72. virtual IClientRenderable *GetShadowParent() { return NULL; }
  73. virtual IClientRenderable *FirstShadowChild(){ return NULL; }
  74. virtual IClientRenderable *NextShadowPeer() { return NULL; }
  75. virtual ShadowType_t ShadowCastType() { return SHADOWS_NONE; }
  76. virtual void CreateModelInstance() {}
  77. virtual ModelInstanceHandle_t GetModelInstance() { return MODEL_INSTANCE_INVALID; }
  78. virtual const matrix3x4_t &RenderableToWorldTransform();
  79. virtual int LookupAttachment( const char *pAttachmentName ) { return -1; }
  80. virtual bool GetAttachment( int number, Vector &origin, QAngle &angles );
  81. virtual bool GetAttachment( int number, matrix3x4_t &matrix );
  82. virtual bool ComputeLightingOrigin( int nAttachmentIndex, Vector modelLightingCenter, const matrix3x4_t &matrix, Vector &transformedLightingCenter );
  83. virtual float *GetRenderClipPlane() { return NULL; }
  84. virtual void RecordToolMessage() {}
  85. virtual bool IgnoresZBuffer( void ) const { return false; }
  86. virtual bool ShouldDrawForSplitScreenUser( int nSlot ) { return true; }
  87. virtual IClientModelRenderable* GetClientModelRenderable() { return 0; }
  88. // Add/remove to engine from drawing
  89. void DrawInEngine( bool bDrawInEngine );
  90. bool IsDrawingInEngine() const;
  91. // Call this when the translucency type has changed for this renderable
  92. void OnTranslucencyTypeChanged();
  93. protected:
  94. virtual CDmAttribute* GetVisibilityAttribute() { return NULL; }
  95. virtual CDmAttribute* GetDrawnInEngineAttribute() { return m_bWantsToBeDrawnInEngine.GetAttribute(); }
  96. // NOTE: The goal of this function is different from IsTranslucent().
  97. // Here, we need to determine whether a renderable is inherently translucent
  98. // when run-time alpha modulation or any other game code is not taken into account
  99. virtual RenderableTranslucencyType_t ComputeTranslucencyType( );
  100. protected:
  101. Vector m_vecRenderOrigin;
  102. QAngle m_angRenderAngles;
  103. CDmaVar<bool> m_bWantsToBeDrawnInEngine;
  104. bool m_bIsDrawingInEngine;
  105. CBaseHandle m_RefEHandle; // Reference ehandle. Used to generate ehandles off this entity.
  106. ClientRenderHandle_t m_hRenderHandle;
  107. };
  108. //-----------------------------------------------------------------------------
  109. // Construction, destruction
  110. //-----------------------------------------------------------------------------
  111. template < class T >
  112. void CDmeRenderable<T>::OnConstruction()
  113. {
  114. m_hRenderHandle = INVALID_CLIENT_RENDER_HANDLE;
  115. m_bWantsToBeDrawnInEngine.InitAndSet( this, "wantsToBeDrawnInEngine", false, FATTRIB_DONTSAVE | FATTRIB_HAS_CALLBACK );
  116. m_bIsDrawingInEngine = false;
  117. }
  118. template < class T >
  119. void CDmeRenderable<T>::OnDestruction()
  120. {
  121. if ( m_bIsDrawingInEngine )
  122. {
  123. if ( clienttools )
  124. {
  125. clienttools->RemoveClientRenderable( this );
  126. }
  127. m_bIsDrawingInEngine = false;
  128. }
  129. }
  130. template < class T >
  131. void CDmeRenderable<T>::OnAdoptedFromUndo()
  132. {
  133. UpdateIsDrawingInEngine();
  134. }
  135. template < class T >
  136. void CDmeRenderable<T>::OnOrphanedToUndo()
  137. {
  138. if ( m_bIsDrawingInEngine )
  139. {
  140. if ( clienttools )
  141. {
  142. clienttools->RemoveClientRenderable( this );
  143. }
  144. m_bIsDrawingInEngine = false;
  145. }
  146. }
  147. //-----------------------------------------------------------------------------
  148. // EHandles
  149. //-----------------------------------------------------------------------------
  150. template < class T >
  151. void CDmeRenderable<T>::SetRefEHandle( const CBaseHandle &handle )
  152. {
  153. m_RefEHandle = handle;
  154. }
  155. template < class T >
  156. const CBaseHandle& CDmeRenderable<T>::GetRefEHandle() const
  157. {
  158. return m_RefEHandle;
  159. }
  160. //-----------------------------------------------------------------------------
  161. // Add/remove to engine from drawing
  162. //-----------------------------------------------------------------------------
  163. template < class T >
  164. void CDmeRenderable<T>::DrawInEngine( bool bDrawInEngine )
  165. {
  166. m_bWantsToBeDrawnInEngine = bDrawInEngine;
  167. }
  168. template < class T >
  169. bool CDmeRenderable<T>::IsDrawingInEngine() const
  170. {
  171. return m_bIsDrawingInEngine;
  172. }
  173. //-----------------------------------------------------------------------------
  174. // Here, we need to determine whether a renderable is inherently translucent
  175. // when run-time alpha modulation or any other game code is not taken into account
  176. //-----------------------------------------------------------------------------
  177. template < class T >
  178. RenderableTranslucencyType_t CDmeRenderable<T>::ComputeTranslucencyType( )
  179. {
  180. return modelinfoclient->ComputeTranslucencyType( GetModel(), GetSkin(), GetBody() );
  181. }
  182. //-----------------------------------------------------------------------------
  183. // Call this when the translucency type has changed for this renderable
  184. //-----------------------------------------------------------------------------
  185. template < class T >
  186. void CDmeRenderable<T>::OnTranslucencyTypeChanged()
  187. {
  188. RenderableTranslucencyType_t nType = ComputeTranslucencyType( );
  189. clienttools->SetTranslucencyType( this, nType );
  190. }
  191. //-----------------------------------------------------------------------------
  192. // Called when attributes changed
  193. //-----------------------------------------------------------------------------
  194. template < class T >
  195. void CDmeRenderable<T>::OnAttributeChanged( CDmAttribute *pAttribute )
  196. {
  197. T::OnAttributeChanged( pAttribute );
  198. CDmAttribute *pVisibilityAttribute = GetVisibilityAttribute();
  199. if ( pAttribute == pVisibilityAttribute || pAttribute == m_bWantsToBeDrawnInEngine.GetAttribute() )
  200. {
  201. UpdateIsDrawingInEngine();
  202. }
  203. }
  204. template < class T >
  205. void CDmeRenderable<T>::UpdateIsDrawingInEngine()
  206. {
  207. CDmAttribute *pVisibilityAttribute = GetVisibilityAttribute();
  208. bool bIsVisible = pVisibilityAttribute ? pVisibilityAttribute->GetValue<bool>() : true;
  209. bool bShouldDrawInEngine = m_bWantsToBeDrawnInEngine && bIsVisible;
  210. if ( m_bIsDrawingInEngine != bShouldDrawInEngine )
  211. {
  212. m_bIsDrawingInEngine = bShouldDrawInEngine;
  213. if ( clienttools && modelinfoclient )
  214. {
  215. if ( m_bIsDrawingInEngine )
  216. {
  217. RenderableTranslucencyType_t nType = ComputeTranslucencyType( );
  218. clienttools->AddClientRenderable( this, false, nType );
  219. }
  220. else
  221. {
  222. clienttools->RemoveClientRenderable( this );
  223. }
  224. }
  225. }
  226. }
  227. //-----------------------------------------------------------------------------
  228. // Color modulation
  229. //-----------------------------------------------------------------------------
  230. template < class T >
  231. void CDmeRenderable<T>::GetColorModulation( float* color )
  232. {
  233. Assert(color);
  234. color[0] = color[1] = color[2] = 1.0f;
  235. }
  236. //-----------------------------------------------------------------------------
  237. // Attachments
  238. //-----------------------------------------------------------------------------
  239. template < class T >
  240. bool CDmeRenderable<T>::GetAttachment( int number, Vector &origin, QAngle &angles )
  241. {
  242. origin = GetRenderOrigin();
  243. angles = GetRenderAngles();
  244. return true;
  245. }
  246. template < class T >
  247. bool CDmeRenderable<T>::GetAttachment( int number, matrix3x4_t &matrix )
  248. {
  249. MatrixCopy( RenderableToWorldTransform(), matrix );
  250. return true;
  251. }
  252. template < class T >
  253. bool CDmeRenderable<T>::ComputeLightingOrigin( int nAttachmentIndex, Vector modelLightingCenter, const matrix3x4_t &matrix, Vector &transformedLightingCenter )
  254. {
  255. if ( nAttachmentIndex <= 0 )
  256. {
  257. VectorTransform( modelLightingCenter, matrix, transformedLightingCenter );
  258. }
  259. else
  260. {
  261. matrix3x4_t attachmentTransform;
  262. GetAttachment( nAttachmentIndex, attachmentTransform );
  263. VectorTransform( modelLightingCenter, attachmentTransform, transformedLightingCenter );
  264. }
  265. return true;
  266. }
  267. //-----------------------------------------------------------------------------
  268. // Other methods
  269. //-----------------------------------------------------------------------------
  270. template < class T >
  271. void CDmeRenderable<T>::GetShadowRenderBounds( Vector &mins, Vector &maxs, ShadowType_t shadowType )
  272. {
  273. GetRenderBounds( mins, maxs );
  274. }
  275. template < class T >
  276. inline ClientShadowHandle_t CDmeRenderable<T>::GetShadowHandle() const
  277. {
  278. return CLIENTSHADOW_INVALID_HANDLE;
  279. }
  280. template < class T >
  281. inline ClientRenderHandle_t& CDmeRenderable<T>::RenderHandle()
  282. {
  283. return m_hRenderHandle;
  284. }
  285. template < class T >
  286. void CDmeRenderable<T>::GetRenderBoundsWorldspace( Vector& absMins, Vector& absMaxs )
  287. {
  288. Vector mins, maxs;
  289. GetRenderBounds( mins, maxs );
  290. // FIXME: Should I just use a sphere here?
  291. // Another option is to pass the OBB down the tree; makes for a better fit
  292. // Generate a world-aligned AABB
  293. const QAngle& angles = GetRenderAngles();
  294. const Vector& origin = GetRenderOrigin();
  295. if ( angles == vec3_angle )
  296. {
  297. VectorAdd( mins, origin, absMins );
  298. VectorAdd( maxs, origin, absMaxs );
  299. }
  300. else
  301. {
  302. matrix3x4_t boxToWorld;
  303. AngleMatrix( angles, origin, boxToWorld );
  304. TransformAABB( boxToWorld, mins, maxs, absMins, absMaxs );
  305. }
  306. Assert( absMins.IsValid() && absMaxs.IsValid() );
  307. }
  308. template < class T >
  309. const matrix3x4_t &CDmeRenderable<T>::RenderableToWorldTransform()
  310. {
  311. static matrix3x4_t mat;
  312. AngleMatrix( GetRenderAngles(), GetRenderOrigin(), mat );
  313. return mat;
  314. }
  315. //-----------------------------------------------------------------------------
  316. // Adds a 'visibility' attribute onto renderables that need it
  317. //-----------------------------------------------------------------------------
  318. template < class T >
  319. class CDmeVisibilityControl : public T
  320. {
  321. DEFINE_UNINSTANCEABLE_ELEMENT( CDmeVisibilityControl, T );
  322. public:
  323. // Control visibility
  324. bool IsVisible() const;
  325. void SetVisible( bool bVisible );
  326. private:
  327. virtual CDmAttribute* GetVisibilityAttribute() { return m_bIsVisible.GetAttribute(); }
  328. CDmaVar< bool > m_bIsVisible;
  329. };
  330. //-----------------------------------------------------------------------------
  331. // Construction, destruction
  332. //-----------------------------------------------------------------------------
  333. template < class T >
  334. void CDmeVisibilityControl<T>::OnConstruction()
  335. {
  336. m_bIsVisible.InitAndSet( this, "visible", true, FATTRIB_HAS_CALLBACK );
  337. }
  338. template < class T >
  339. void CDmeVisibilityControl<T>::OnDestruction()
  340. {
  341. }
  342. //-----------------------------------------------------------------------------
  343. // Deal with visibility
  344. //-----------------------------------------------------------------------------
  345. template < class T >
  346. void CDmeVisibilityControl<T>::SetVisible( bool bVisible )
  347. {
  348. if ( bVisible != m_bIsVisible )
  349. {
  350. m_bIsVisible = bVisible;
  351. }
  352. }
  353. template < class T >
  354. bool CDmeVisibilityControl<T>::IsVisible() const
  355. {
  356. return m_bIsVisible;
  357. }
  358. #endif // DMERENDERABLE_H