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.

343 lines
11 KiB

  1. //====== Copyright � 1996-2005, Valve Corporation, All rights reserved. =======
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "dmecommentarynodeentity.h"
  7. #include "datamodel/dmelementfactoryhelper.h"
  8. #include "toolframework/itoolentity.h"
  9. #include "materialsystem/imesh.h"
  10. #include "materialsystem/imaterial.h"
  11. #include "materialsystem/imaterialsystem.h"
  12. #include "engine/iclientleafsystem.h"
  13. #include "toolutils/enginetools_int.h"
  14. #include "commedittool.h"
  15. #include "keyvalues.h"
  16. // memdbgon must be the last include file in a .cpp file!!!
  17. #include "tier0/memdbgon.h"
  18. #define SPHERE_RADIUS 16
  19. //-----------------------------------------------------------------------------
  20. // Expose this class to the scene database
  21. //-----------------------------------------------------------------------------
  22. IMPLEMENT_ELEMENT_FACTORY( DmeCommentaryNodeEntity, CDmeCommentaryNodeEntity );
  23. //-----------------------------------------------------------------------------
  24. // Purpose:
  25. //-----------------------------------------------------------------------------
  26. void CDmeCommentaryNodeEntity::OnConstruction()
  27. {
  28. m_ClassName.InitAndSet( this, "classname", false, FATTRIB_HAS_CALLBACK );
  29. m_TargetName.Init( this, "targetname" );
  30. m_bIsPlaceholder.InitAndSet( this, "_placeholder", false, FATTRIB_DONTSAVE );
  31. m_vecLocalOrigin.Init( this, "origin" );
  32. m_vecLocalAngles.Init( this, "angles" );
  33. // Used to make sure these aren't saved if they aren't changed
  34. m_TargetName.GetAttribute()->AddFlag( FATTRIB_DONTSAVE | FATTRIB_HAS_CALLBACK );
  35. m_vecLocalAngles.GetAttribute()->AddFlag( FATTRIB_DONTSAVE | FATTRIB_HAS_CALLBACK );
  36. m_bInfoTarget = false;
  37. m_bIsDirty = false;
  38. m_hEngineEntity = HTOOLHANDLE_INVALID;
  39. KeyValues *pVMTKeyValues = new KeyValues( "UnlitGeneric" );
  40. pVMTKeyValues->SetString( "$basetexture", "editor/info_target" );
  41. pVMTKeyValues->SetInt( "$nocull", 1 );
  42. pVMTKeyValues->SetInt( "$vertexcolor", 1 );
  43. pVMTKeyValues->SetInt( "$vertexalpha", 1 );
  44. pVMTKeyValues->SetInt( "$no_fullbright", 1 );
  45. pVMTKeyValues->SetInt( "$translucent", 1 );
  46. m_InfoTargetSprite.Init( "__commentary_info_target", pVMTKeyValues );
  47. pVMTKeyValues = new KeyValues( "UnlitGeneric" );
  48. pVMTKeyValues->SetInt( "$nocull", 1 );
  49. pVMTKeyValues->SetString( "$color", "{255 0 0}" );
  50. pVMTKeyValues->SetInt( "$vertexalpha", 1 );
  51. pVMTKeyValues->SetInt( "$no_fullbright", 1 );
  52. pVMTKeyValues->SetInt( "$additive", 1 );
  53. m_SelectedInfoTarget.Init( "__selected_commentary_info_target", pVMTKeyValues );
  54. }
  55. void CDmeCommentaryNodeEntity::OnDestruction()
  56. {
  57. // Unhook it from the engine
  58. AttachToEngineEntity( HTOOLHANDLE_INVALID );
  59. m_SelectedInfoTarget.Shutdown();
  60. m_InfoTargetSprite.Shutdown();
  61. }
  62. //-----------------------------------------------------------------------------
  63. // Called whem attributes change
  64. //-----------------------------------------------------------------------------
  65. void CDmeCommentaryNodeEntity::OnAttributeChanged( CDmAttribute *pAttribute )
  66. {
  67. BaseClass::OnAttributeChanged( pAttribute );
  68. // Once these have changed, then save them out, and don't bother calling back
  69. if ( pAttribute == m_TargetName.GetAttribute() ||
  70. pAttribute == m_vecLocalAngles.GetAttribute() )
  71. {
  72. pAttribute->RemoveFlag( FATTRIB_DONTSAVE | FATTRIB_HAS_CALLBACK );
  73. return;
  74. }
  75. if ( pAttribute == m_ClassName.GetAttribute() )
  76. {
  77. m_bInfoTarget = !Q_strncmp( m_ClassName, "info_target", 11 ) || !Q_strcmp( m_ClassName, "info_remarkable" );
  78. if ( !Q_stricmp( m_ClassName, "point_commentary_node" ) )
  79. {
  80. SetModelName( "models/extras/info_speech.mdl" );
  81. GetMDL()->m_flPlaybackRate = 0.0f;
  82. }
  83. else
  84. {
  85. SetModelName( NULL );
  86. }
  87. OnTranslucencyTypeChanged();
  88. return;
  89. }
  90. }
  91. //-----------------------------------------------------------------------------
  92. // Returns the entity ID
  93. //-----------------------------------------------------------------------------
  94. int CDmeCommentaryNodeEntity::GetEntityId() const
  95. {
  96. return atoi( GetName() );
  97. }
  98. //-----------------------------------------------------------------------------
  99. // Mark the entity as being dirty
  100. //-----------------------------------------------------------------------------
  101. void CDmeCommentaryNodeEntity::MarkDirty( bool bDirty )
  102. {
  103. m_bIsDirty = bDirty;
  104. OnTranslucencyTypeChanged();
  105. }
  106. //-----------------------------------------------------------------------------
  107. // Is the renderable transparent?
  108. //-----------------------------------------------------------------------------
  109. RenderableTranslucencyType_t CDmeCommentaryNodeEntity::ComputeTranslucencyType( void )
  110. {
  111. if ( m_bIsDirty || m_bInfoTarget )
  112. return RENDERABLE_IS_TRANSLUCENT;
  113. return BaseClass::ComputeTranslucencyType();
  114. }
  115. //-----------------------------------------------------------------------------
  116. // Entity Key iteration
  117. //-----------------------------------------------------------------------------
  118. bool CDmeCommentaryNodeEntity::IsEntityKey( CDmAttribute *pEntityKey )
  119. {
  120. return pEntityKey->IsFlagSet( FATTRIB_USERDEFINED );
  121. }
  122. //-----------------------------------------------------------------------------
  123. // Purpose:
  124. //-----------------------------------------------------------------------------
  125. CDmAttribute *CDmeCommentaryNodeEntity::FirstEntityKey()
  126. {
  127. for ( CDmAttribute *pAttribute = FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
  128. {
  129. if ( IsEntityKey( pAttribute ) )
  130. return pAttribute;
  131. }
  132. return NULL;
  133. }
  134. //-----------------------------------------------------------------------------
  135. // Purpose:
  136. //-----------------------------------------------------------------------------
  137. CDmAttribute *CDmeCommentaryNodeEntity::NextEntityKey( CDmAttribute *pEntityKey )
  138. {
  139. if ( !pEntityKey )
  140. return NULL;
  141. for ( CDmAttribute *pAttribute = pEntityKey->NextAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
  142. {
  143. if ( IsEntityKey( pAttribute ) )
  144. return pAttribute;
  145. }
  146. return NULL;
  147. }
  148. //-----------------------------------------------------------------------------
  149. // Attach/detach from an engine entity with the same editor index
  150. //-----------------------------------------------------------------------------
  151. void CDmeCommentaryNodeEntity::AttachToEngineEntity( HTOOLHANDLE hToolHandle )
  152. {
  153. if ( m_hEngineEntity != HTOOLHANDLE_INVALID )
  154. {
  155. clienttools->SetEnabled( m_hEngineEntity, true );
  156. }
  157. m_hEngineEntity = hToolHandle;
  158. if ( m_hEngineEntity != HTOOLHANDLE_INVALID )
  159. {
  160. clienttools->SetEnabled( m_hEngineEntity, false );
  161. }
  162. }
  163. //-----------------------------------------------------------------------------
  164. // Position and bounds for the model
  165. //-----------------------------------------------------------------------------
  166. const Vector &CDmeCommentaryNodeEntity::GetRenderOrigin( void )
  167. {
  168. return m_vecLocalOrigin;
  169. }
  170. const QAngle &CDmeCommentaryNodeEntity::GetRenderAngles( void )
  171. {
  172. return *(QAngle*)(&m_vecLocalAngles.Get());
  173. }
  174. //-----------------------------------------------------------------------------
  175. // Draws the helper for the entity
  176. //-----------------------------------------------------------------------------
  177. void CDmeCommentaryNodeEntity::DrawSprite( IMaterial *pMaterial )
  178. {
  179. float t = 0.5f * sin( Plat_FloatTime() * M_PI / 1.0f ) + 0.5f;
  180. CMatRenderContextPtr pRenderContext( materials );
  181. pRenderContext->Bind( pMaterial );
  182. IMesh* pMesh = pRenderContext->GetDynamicMesh();
  183. CMeshBuilder meshBuilder;
  184. meshBuilder.Begin( pMesh, MATERIAL_TRIANGLE_STRIP, 4, 4 );
  185. unsigned char nBaseR = 255;
  186. unsigned char nBaseG = 255;
  187. unsigned char nBaseB = 255;
  188. unsigned char nAlpha = m_bIsDirty ? (unsigned char)(255 * t) : 255;
  189. meshBuilder.Position3f( -SPHERE_RADIUS, -SPHERE_RADIUS, 0.0f );
  190. meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha );
  191. meshBuilder.TexCoord2f( 0, 0.0f, 1.0f );
  192. meshBuilder.AdvanceVertex();
  193. meshBuilder.Position3f( SPHERE_RADIUS, -SPHERE_RADIUS, 0.0f );
  194. meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha );
  195. meshBuilder.TexCoord2f( 0, 1.0f, 1.0f );
  196. meshBuilder.AdvanceVertex();
  197. meshBuilder.Position3f( SPHERE_RADIUS, SPHERE_RADIUS, 0.0f );
  198. meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha );
  199. meshBuilder.TexCoord2f( 0, 1.0f, 0.0f );
  200. meshBuilder.AdvanceVertex();
  201. meshBuilder.Position3f( -SPHERE_RADIUS, SPHERE_RADIUS, 0.0f );
  202. meshBuilder.Color4ub( nBaseR, nBaseG, nBaseB, nAlpha );
  203. meshBuilder.TexCoord2f( 0, 0.0f, 0.0f );
  204. meshBuilder.AdvanceVertex();
  205. meshBuilder.FastIndex( 0 );
  206. meshBuilder.FastIndex( 1 );
  207. meshBuilder.FastIndex( 3 );
  208. meshBuilder.FastIndex( 2 );
  209. meshBuilder.End();
  210. pMesh->Draw();
  211. }
  212. //-----------------------------------------------------------------------------
  213. // Draws the helper for the entity
  214. //-----------------------------------------------------------------------------
  215. int CDmeCommentaryNodeEntity::DrawModel( int flags, const RenderableInstance_t &instance )
  216. {
  217. bool bSelected = ( g_pCommEditTool->GetCurrentEntity().Get() == this );
  218. if ( !m_bInfoTarget )
  219. {
  220. // If we have a visible engine entity, we don't need to draw it here
  221. // info targets always draw though, because they have no visible model.
  222. CDisableUndoScopeGuard guard;
  223. float t = 0.5f * sin( Plat_FloatTime() * M_PI / 1.0f ) + 0.5f;
  224. unsigned char nAlpha = m_bIsDirty ? (unsigned char)(255 * t) : 255;
  225. if ( bSelected )
  226. {
  227. GetMDL()->m_Color.SetColor( 255, 64, 64, nAlpha );
  228. }
  229. else
  230. {
  231. GetMDL()->m_Color.SetColor( 255, 255, 255, nAlpha );
  232. }
  233. return BaseClass::DrawModel( flags, instance );
  234. }
  235. Assert( IsDrawingInEngine() );
  236. CMatRenderContextPtr pRenderContext( materials );
  237. matrix3x4_t mat;
  238. VMatrix worldToCamera, cameraToWorld;
  239. pRenderContext->GetMatrix( MATERIAL_VIEW, &worldToCamera );
  240. MatrixInverseTR( worldToCamera, cameraToWorld );
  241. MatrixCopy( cameraToWorld.As3x4(), mat );
  242. MatrixSetColumn( m_vecLocalOrigin, 3, mat );
  243. pRenderContext->MatrixMode( MATERIAL_MODEL );
  244. pRenderContext->PushMatrix();
  245. pRenderContext->LoadMatrix( mat );
  246. pRenderContext->FogMode( MATERIAL_FOG_NONE );
  247. pRenderContext->SetNumBoneWeights( 0 );
  248. pRenderContext->CullMode( MATERIAL_CULLMODE_CW );
  249. DrawSprite( m_InfoTargetSprite );
  250. if ( bSelected )
  251. {
  252. DrawSprite( m_SelectedInfoTarget );
  253. }
  254. pRenderContext->CullMode( MATERIAL_CULLMODE_CCW );
  255. pRenderContext->MatrixMode( MATERIAL_MODEL );
  256. pRenderContext->PopMatrix();
  257. return 1;
  258. }
  259. //-----------------------------------------------------------------------------
  260. // Position and bounds for the model
  261. //-----------------------------------------------------------------------------
  262. void CDmeCommentaryNodeEntity::GetRenderBounds( Vector& mins, Vector& maxs )
  263. {
  264. if ( !m_bInfoTarget )
  265. {
  266. BaseClass::GetRenderBounds( mins, maxs );
  267. return;
  268. }
  269. mins.Init( -SPHERE_RADIUS, -SPHERE_RADIUS, -SPHERE_RADIUS );
  270. maxs.Init( SPHERE_RADIUS, SPHERE_RADIUS, SPHERE_RADIUS );
  271. }
  272. //-----------------------------------------------------------------------------
  273. // Update renderable position
  274. //-----------------------------------------------------------------------------
  275. void CDmeCommentaryNodeEntity::SetRenderOrigin( const Vector &vecOrigin )
  276. {
  277. m_vecLocalOrigin = vecOrigin;
  278. clienttools->MarkClientRenderableDirty( this );
  279. }
  280. void CDmeCommentaryNodeEntity::SetRenderAngles( const QAngle &angles )
  281. {
  282. m_vecLocalAngles = *(Vector*)&angles;
  283. clienttools->MarkClientRenderableDirty( this );
  284. }