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.

377 lines
9.4 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include "C_PortalGhostRenderable.h"
  9. #include "PortalRender.h"
  10. #include "c_portal_player.h"
  11. #include "model_types.h"
  12. C_PortalGhostRenderable::C_PortalGhostRenderable( C_Prop_Portal *pOwningPortal, C_BaseEntity *pGhostSource, RenderGroup_t sourceRenderGroup, const VMatrix &matGhostTransform, float *pSharedRenderClipPlane, bool bLocalPlayer )
  13. : m_pGhostedRenderable( pGhostSource ),
  14. m_matGhostTransform( matGhostTransform ),
  15. m_pSharedRenderClipPlane( pSharedRenderClipPlane ),
  16. m_bLocalPlayer( bLocalPlayer ),
  17. m_pOwningPortal( pOwningPortal )
  18. {
  19. m_bSourceIsBaseAnimating = (dynamic_cast<C_BaseAnimating *>(pGhostSource) != NULL);
  20. cl_entitylist->AddNonNetworkableEntity( GetIClientUnknown() );
  21. g_pClientLeafSystem->AddRenderable( this, sourceRenderGroup );
  22. }
  23. C_PortalGhostRenderable::~C_PortalGhostRenderable( void )
  24. {
  25. m_pGhostedRenderable = NULL;
  26. g_pClientLeafSystem->RemoveRenderable( RenderHandle() );
  27. cl_entitylist->RemoveEntity( GetIClientUnknown()->GetRefEHandle() );
  28. DestroyModelInstance();
  29. }
  30. void C_PortalGhostRenderable::PerFrameUpdate( void )
  31. {
  32. if( m_pGhostedRenderable )
  33. {
  34. SetModelName( m_pGhostedRenderable->GetModelName() );
  35. SetModelIndex( m_pGhostedRenderable->GetModelIndex() );
  36. SetEffects( m_pGhostedRenderable->GetEffects() | EF_NOINTERP );
  37. m_flAnimTime = m_pGhostedRenderable->m_flAnimTime;
  38. if( m_bSourceIsBaseAnimating )
  39. {
  40. C_BaseAnimating *pSource = (C_BaseAnimating *)m_pGhostedRenderable;
  41. SetCycle( pSource->GetCycle() );
  42. SetSequence( pSource->GetSequence() );
  43. m_nBody = pSource->m_nBody;
  44. m_nSkin = pSource->m_nSkin;
  45. }
  46. }
  47. // Set position and angles relative to the object it's ghosting
  48. Vector ptNewOrigin = m_matGhostTransform * m_pGhostedRenderable->GetAbsOrigin();
  49. QAngle qNewAngles = TransformAnglesToWorldSpace( m_pGhostedRenderable->GetAbsAngles(), m_matGhostTransform.As3x4() );
  50. SetAbsOrigin( ptNewOrigin );
  51. SetAbsAngles( qNewAngles );
  52. AddEffects( EF_NOINTERP );
  53. RemoveFromInterpolationList();
  54. g_pClientLeafSystem->RenderableChanged( RenderHandle() );
  55. }
  56. Vector const& C_PortalGhostRenderable::GetRenderOrigin( void )
  57. {
  58. if( m_pGhostedRenderable == NULL )
  59. return m_ReferencedReturns.vRenderOrigin;
  60. m_ReferencedReturns.vRenderOrigin = m_matGhostTransform * m_pGhostedRenderable->GetRenderOrigin();
  61. return m_ReferencedReturns.vRenderOrigin;
  62. }
  63. QAngle const& C_PortalGhostRenderable::GetRenderAngles( void )
  64. {
  65. if( m_pGhostedRenderable == NULL )
  66. return m_ReferencedReturns.qRenderAngle;
  67. m_ReferencedReturns.qRenderAngle = TransformAnglesToWorldSpace( m_pGhostedRenderable->GetRenderAngles(), m_matGhostTransform.As3x4() );
  68. return m_ReferencedReturns.qRenderAngle;
  69. }
  70. bool C_PortalGhostRenderable::SetupBones( matrix3x4_t *pBoneToWorldOut, int nMaxBones, int boneMask, float currentTime )
  71. {
  72. if( m_pGhostedRenderable == NULL )
  73. return false;
  74. int nModelIndex = 0;
  75. CBaseCombatWeapon *pParent = dynamic_cast<CBaseCombatWeapon*>( m_pGhostedRenderable );
  76. if ( pParent )
  77. {
  78. nModelIndex = pParent->GetModelIndex();
  79. pParent->SetModelIndex( pParent->GetWorldModelIndex() );
  80. }
  81. if( m_pGhostedRenderable->SetupBones( pBoneToWorldOut, nMaxBones, boneMask, currentTime ) )
  82. {
  83. if( pBoneToWorldOut )
  84. {
  85. for( int i = 0; i != nMaxBones; ++i ) //FIXME: nMaxBones is most definitely greater than the actual number of bone transforms actually used, find the subset somehow
  86. {
  87. pBoneToWorldOut[i] = (m_matGhostTransform * pBoneToWorldOut[i]).As3x4();
  88. }
  89. }
  90. return true;
  91. }
  92. if ( pParent )
  93. {
  94. pParent->SetModelIndex( nModelIndex );
  95. }
  96. return false;
  97. }
  98. void C_PortalGhostRenderable::GetRenderBounds( Vector& mins, Vector& maxs )
  99. {
  100. if( m_pGhostedRenderable == NULL )
  101. {
  102. mins = maxs = vec3_origin;
  103. return;
  104. }
  105. m_pGhostedRenderable->GetRenderBounds( mins, maxs );
  106. }
  107. void C_PortalGhostRenderable::GetRenderBoundsWorldspace( Vector& mins, Vector& maxs )
  108. {
  109. if( m_pGhostedRenderable == NULL )
  110. {
  111. mins = maxs = vec3_origin;
  112. return;
  113. }
  114. m_pGhostedRenderable->GetRenderBoundsWorldspace( mins, maxs );
  115. TransformAABB( m_matGhostTransform.As3x4(), mins, maxs, mins, maxs );
  116. }
  117. void C_PortalGhostRenderable::GetShadowRenderBounds( Vector &mins, Vector &maxs, ShadowType_t shadowType )
  118. {
  119. m_pGhostedRenderable->GetShadowRenderBounds( mins, maxs, shadowType );
  120. TransformAABB( m_matGhostTransform.As3x4(), mins, maxs, mins, maxs );
  121. }
  122. /*bool C_PortalGhostRenderable::GetShadowCastDistance( float *pDist, ShadowType_t shadowType ) const
  123. {
  124. if( m_pGhostedRenderable == NULL )
  125. return false;
  126. return m_pGhostedRenderable->GetShadowCastDistance( pDist, shadowType );
  127. }
  128. bool C_PortalGhostRenderable::GetShadowCastDirection( Vector *pDirection, ShadowType_t shadowType ) const
  129. {
  130. if( m_pGhostedRenderable == NULL )
  131. return false;
  132. if( m_pGhostedRenderable->GetShadowCastDirection( pDirection, shadowType ) )
  133. {
  134. if( pDirection )
  135. *pDirection = m_matGhostTransform.ApplyRotation( *pDirection );
  136. return true;
  137. }
  138. return false;
  139. }*/
  140. const matrix3x4_t & C_PortalGhostRenderable::RenderableToWorldTransform()
  141. {
  142. if( m_pGhostedRenderable == NULL )
  143. return m_ReferencedReturns.matRenderableToWorldTransform;
  144. ConcatTransforms( m_matGhostTransform.As3x4(), m_pGhostedRenderable->RenderableToWorldTransform(), m_ReferencedReturns.matRenderableToWorldTransform );
  145. return m_ReferencedReturns.matRenderableToWorldTransform;
  146. }
  147. bool C_PortalGhostRenderable::GetAttachment( int number, Vector &origin, QAngle &angles )
  148. {
  149. if( m_pGhostedRenderable == NULL )
  150. return false;
  151. if( m_pGhostedRenderable->GetAttachment( number, origin, angles ) )
  152. {
  153. origin = m_matGhostTransform * origin;
  154. angles = TransformAnglesToWorldSpace( angles, m_matGhostTransform.As3x4() );
  155. return true;
  156. }
  157. return false;
  158. }
  159. bool C_PortalGhostRenderable::GetAttachment( int number, matrix3x4_t &matrix )
  160. {
  161. if( m_pGhostedRenderable == NULL )
  162. return false;
  163. if( m_pGhostedRenderable->GetAttachment( number, matrix ) )
  164. {
  165. ConcatTransforms( m_matGhostTransform.As3x4(), matrix, matrix );
  166. return true;
  167. }
  168. return false;
  169. }
  170. bool C_PortalGhostRenderable::GetAttachment( int number, Vector &origin )
  171. {
  172. if( m_pGhostedRenderable == NULL )
  173. return false;
  174. if( m_pGhostedRenderable->GetAttachment( number, origin ) )
  175. {
  176. origin = m_matGhostTransform * origin;
  177. return true;
  178. }
  179. return false;
  180. }
  181. bool C_PortalGhostRenderable::GetAttachmentVelocity( int number, Vector &originVel, Quaternion &angleVel )
  182. {
  183. if( m_pGhostedRenderable == NULL )
  184. return false;
  185. Vector ghostVel;
  186. if( m_pGhostedRenderable->GetAttachmentVelocity( number, ghostVel, angleVel ) )
  187. {
  188. Vector3DMultiply( m_matGhostTransform, ghostVel, originVel );
  189. Vector3DMultiply( m_matGhostTransform, *(Vector*)( &angleVel ), *(Vector*)( &angleVel ) );
  190. return true;
  191. }
  192. return false;
  193. }
  194. int C_PortalGhostRenderable::DrawModel( int flags )
  195. {
  196. if( m_bSourceIsBaseAnimating )
  197. {
  198. if( m_bLocalPlayer )
  199. {
  200. C_Portal_Player *pPlayer = C_Portal_Player::GetLocalPlayer();
  201. if ( !pPlayer->IsAlive() )
  202. {
  203. // Dead player uses a ragdoll to draw, so don't ghost the dead entity
  204. return 0;
  205. }
  206. else if( g_pPortalRender->GetViewRecursionLevel() == 0 )
  207. {
  208. if( pPlayer->m_bEyePositionIsTransformedByPortal )
  209. return 0;
  210. }
  211. else if( g_pPortalRender->GetViewRecursionLevel() == 1 )
  212. {
  213. if( !pPlayer->m_bEyePositionIsTransformedByPortal )
  214. return 0;
  215. }
  216. }
  217. return C_BaseAnimating::DrawModel( flags );
  218. }
  219. else
  220. {
  221. DrawBrushModelMode_t mode = DBM_DRAW_ALL;
  222. if ( flags & STUDIO_TWOPASS )
  223. {
  224. mode = ( flags & STUDIO_TRANSPARENCY ) ? DBM_DRAW_TRANSLUCENT_ONLY : DBM_DRAW_OPAQUE_ONLY;
  225. }
  226. render->DrawBrushModelEx( m_pGhostedRenderable,
  227. (model_t *)m_pGhostedRenderable->GetModel(),
  228. GetRenderOrigin(),
  229. GetRenderAngles(),
  230. mode );
  231. return 1;
  232. }
  233. return 0;
  234. }
  235. ModelInstanceHandle_t C_PortalGhostRenderable::GetModelInstance()
  236. {
  237. if ( m_pGhostedRenderable )
  238. return m_pGhostedRenderable->GetModelInstance();
  239. return BaseClass::GetModelInstance();
  240. }
  241. bool C_PortalGhostRenderable::IsTransparent( void )
  242. {
  243. if( m_pGhostedRenderable == NULL )
  244. return false;
  245. return m_pGhostedRenderable->IsTransparent();
  246. }
  247. bool C_PortalGhostRenderable::UsesPowerOfTwoFrameBufferTexture()
  248. {
  249. if( m_pGhostedRenderable == NULL )
  250. return false;
  251. return m_pGhostedRenderable->UsesPowerOfTwoFrameBufferTexture();
  252. }
  253. /*const model_t* C_PortalGhostRenderable::GetModel( ) const
  254. {
  255. if( m_pGhostedRenderable == NULL )
  256. return NULL;
  257. return m_pGhostedRenderable->GetModel();
  258. }
  259. int C_PortalGhostRenderable::GetBody()
  260. {
  261. if( m_pGhostedRenderable == NULL )
  262. return 0;
  263. return m_pGhostedRenderable->GetBody();
  264. }*/
  265. void C_PortalGhostRenderable::GetColorModulation( float* color )
  266. {
  267. if( m_pGhostedRenderable == NULL )
  268. return;
  269. return m_pGhostedRenderable->GetColorModulation( color );
  270. }
  271. /*ShadowType_t C_PortalGhostRenderable::ShadowCastType()
  272. {
  273. if( m_pGhostedRenderable == NULL )
  274. return SHADOWS_NONE;
  275. return m_pGhostedRenderable->ShadowCastType();
  276. }*/
  277. int C_PortalGhostRenderable::LookupAttachment( const char *pAttachmentName )
  278. {
  279. if( m_pGhostedRenderable == NULL )
  280. return -1;
  281. return m_pGhostedRenderable->LookupAttachment( pAttachmentName );
  282. }
  283. /*int C_PortalGhostRenderable::GetSkin()
  284. {
  285. if( m_pGhostedRenderable == NULL )
  286. return -1;
  287. return m_pGhostedRenderable->GetSkin();
  288. }
  289. bool C_PortalGhostRenderable::IsTwoPass( void )
  290. {
  291. if( m_pGhostedRenderable == NULL )
  292. return false;
  293. return m_pGhostedRenderable->IsTwoPass();
  294. }*/