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.

396 lines
12 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "graphicgroup.h"
  8. #include "gamegraphic.h"
  9. #include "gameuidefinition.h"
  10. #include "animdata.h"
  11. // memdbgon must be the last include file in a .cpp file!!!
  12. #include "tier0/memdbgon.h"
  13. BEGIN_DMXELEMENT_UNPACK ( CGraphicGroup )
  14. DMXELEMENT_UNPACK_FIELD_UTLSTRING( "name", "", m_pName )
  15. DMXELEMENT_UNPACK_FIELD( "center", "0 0", Vector2D, m_Geometry.m_Center )
  16. DMXELEMENT_UNPACK_FIELD( "scale", "1 1", Vector2D, m_Geometry.m_Scale )
  17. DMXELEMENT_UNPACK_FIELD( "rotation", "0", float, m_Geometry.m_Rotation )
  18. DMXELEMENT_UNPACK_FIELD( "maintainaspectratio", "0", bool, m_Geometry.m_bMaintainAspectRatio )
  19. DMXELEMENT_UNPACK_FIELD( "sublayertype", "0", int, m_Geometry.m_Sublayer )
  20. DMXELEMENT_UNPACK_FIELD( "visible", "1", bool, m_Geometry.m_bVisible )
  21. DMXELEMENT_UNPACK_FIELD( "initialstate", "-1", int, m_CurrentState )
  22. DMXELEMENT_UNPACK_FIELD( "horizgradient", "0", bool, m_Geometry.m_bHorizontalGradient )
  23. DMXELEMENT_UNPACK_FIELD( "color", "255 255 255 255", Color, m_Geometry.m_Color )
  24. DMXELEMENT_UNPACK_FIELD( "topcolor", "255 255 255 255", Color, m_Geometry.m_TopColor )
  25. DMXELEMENT_UNPACK_FIELD( "bottomcolor", "255 255 255 255", Color, m_Geometry.m_BottomColor )
  26. END_DMXELEMENT_UNPACK( CGraphicGroup, s_GraphicGroupUnpack )
  27. //-----------------------------------------------------------------------------
  28. //
  29. //-----------------------------------------------------------------------------
  30. CGraphicGroup::CGraphicGroup()
  31. {
  32. m_ResultantColor.r = 0;
  33. m_ResultantColor.g = 0;
  34. m_ResultantColor.b = 0;
  35. m_ResultantColor.a = 0;
  36. }
  37. CGraphicGroup::~CGraphicGroup()
  38. {
  39. }
  40. //-----------------------------------------------------------------------------
  41. // Load data from file.
  42. //-----------------------------------------------------------------------------
  43. bool CGraphicGroup::Unserialize( CDmxElement *pElement, CUtlDict< CGameGraphic *, int > &unserializedGraphicMapping )
  44. {
  45. pElement->UnpackIntoStructure( this, s_GraphicGroupUnpack );
  46. CDmxAttribute *pGroupElements = pElement->GetAttribute( "groupElements" );
  47. if ( !pGroupElements || pGroupElements->GetType() != AT_ELEMENT_ARRAY )
  48. {
  49. return false;
  50. }
  51. const CUtlVector< CDmxElement * > &elements = pGroupElements->GetArray< CDmxElement * >( );
  52. int nCount = elements.Count();
  53. for ( int i = 0; i < nCount; ++i )
  54. {
  55. // Find the element in the map.
  56. char pBuf[255];
  57. UniqueIdToString( elements[i]->GetId(), pBuf, 255 );
  58. int index = unserializedGraphicMapping.Find( pBuf );
  59. Assert( unserializedGraphicMapping.IsValidIndex( index ) );
  60. CGameGraphic *pGraphic = unserializedGraphicMapping.Element(index);
  61. pGraphic->SetGroup( this );
  62. m_MemberList.AddToTail( pGraphic );
  63. }
  64. // ANIMSTATES
  65. CDmxAttribute *pImageAnims = pElement->GetAttribute( "imageanims" );
  66. if ( !pImageAnims || pImageAnims->GetType() != AT_ELEMENT_ARRAY )
  67. {
  68. return false;
  69. }
  70. const CUtlVector< CDmxElement * > &imageanims = pImageAnims->GetArray< CDmxElement * >( );
  71. nCount = imageanims.Count();
  72. for ( int i = 0; i < nCount; ++i )
  73. {
  74. CAnimData *pAnimData = new CAnimData;
  75. if ( !pAnimData->Unserialize( imageanims[i] ) )
  76. {
  77. delete pAnimData;
  78. return false;
  79. }
  80. m_Anims.AddToTail( pAnimData );
  81. }
  82. char pBuf[255];
  83. UniqueIdToString( pElement->GetId(), pBuf, 255 );
  84. unserializedGraphicMapping.Insert( pBuf, this );
  85. // Ok the initial state is 0, which is (usually ) default.
  86. // default could be aliased to another state though so if it is fix the initial state here.
  87. // default might also not be the state that is 0 so this sets the graphic's initial
  88. // state to be the default one.
  89. SetState( "default" );
  90. return true;
  91. }
  92. //-----------------------------------------------------------------------------
  93. //
  94. //-----------------------------------------------------------------------------
  95. void CGraphicGroup::UpdateGeometry()
  96. {
  97. if ( m_CurrentState == -1 )
  98. return;
  99. DmeTime_t flAnimTime = GetAnimationTimePassed();
  100. // Update color
  101. m_Anims[ m_CurrentState ]->m_ColorAnim.GetValue( flAnimTime, &m_Geometry.m_Color );
  102. // Update center location
  103. m_Anims[ m_CurrentState ]->m_CenterPosAnim.GetValue( flAnimTime, &m_Geometry.m_Center );
  104. // Update scale
  105. m_Anims[ m_CurrentState ]->m_ScaleAnim.GetValue( flAnimTime, &m_Geometry.m_Scale );
  106. // Update rotation
  107. m_Anims[ m_CurrentState ]->m_RotationAnim.GetValue( flAnimTime, &m_Geometry.m_Rotation );
  108. for ( int i = 0; i < m_MemberList.Count(); ++i )
  109. {
  110. m_MemberList[i]->UpdateGeometry();
  111. }
  112. }
  113. //-----------------------------------------------------------------------------
  114. // Store the resultant color for groups so kids can just get that.
  115. //-----------------------------------------------------------------------------
  116. void CGraphicGroup::UpdateRenderData( color32 parentColor )
  117. {
  118. if ( !m_Geometry.m_bVisible )
  119. return;
  120. m_ResultantColor.r = (int)( (float)m_Geometry.m_Color.r * (float)(parentColor.r/255.0) );
  121. m_ResultantColor.g = (int)( (float)m_Geometry.m_Color.g * (float)(parentColor.g/255.0) );
  122. m_ResultantColor.b = (int)( (float)m_Geometry.m_Color.b * (float)(parentColor.b/255.0) );
  123. m_ResultantColor.a = (int)( (float)m_Geometry.m_Color.a * (float)(parentColor.a/255.0) );
  124. // Update any children that are groups
  125. // Graphic members are not done because the colors are calculated when we get the render data out.
  126. for ( int i = 0; i < m_MemberList.Count(); i++ )
  127. {
  128. if ( m_MemberList[i]->IsGroup() )
  129. {
  130. CGraphicGroup *pGroup = (CGraphicGroup *)m_MemberList[i];
  131. pGroup->UpdateRenderData( parentColor );
  132. }
  133. }
  134. }
  135. //-----------------------------------------------------------------------------
  136. // Populate lists for rendering
  137. //-----------------------------------------------------------------------------
  138. void CGraphicGroup::UpdateRenderTransforms( const StageRenderInfo_t &stageRenderInfo )
  139. {
  140. m_Geometry.UpdateRenderTransforms( stageRenderInfo, GetGroup() );
  141. // Create a matrix that ensures no aspect ratio changes.
  142. // Update positions relative to the center, texture coords, and vertex colors
  143. // If the group maintains aspect ratio it will already have handled this in its transform update.
  144. Vector2D center;
  145. // If this is the case we transform the center to screen coords first.
  146. // Then take into account any size scaling in the scalemat
  147. matrix3x4_t screenScalemat;
  148. SetScaleMatrix( stageRenderInfo.parentScale.x, stageRenderInfo.parentScale.y, 1, screenScalemat );
  149. Vector centerVec( m_Geometry.m_Center.x, m_Geometry.m_Center.y, 0 );
  150. Vector centerInScreen;
  151. VectorTransform( centerVec, screenScalemat, centerInScreen );
  152. center.x = centerInScreen.x;
  153. center.y = centerInScreen.y;
  154. matrix3x4_t transmat;
  155. Vector position( center.x, center.y, 0 );
  156. SetIdentityMatrix( transmat );
  157. PositionMatrix( position, transmat );
  158. matrix3x4_t scalemat;
  159. SetScaleMatrix( m_Geometry.m_Scale.x, m_Geometry.m_Scale.y, 1, scalemat );
  160. matrix3x4_t rotmat;
  161. Vector axis( 0, 0, 1 );
  162. MatrixBuildRotationAboutAxis( axis, m_Geometry.m_Rotation, rotmat );
  163. matrix3x4_t temp;
  164. MatrixMultiply( rotmat, scalemat, temp );
  165. matrix3x4_t rawToLocal;
  166. MatrixMultiply( transmat, temp, rawToLocal );
  167. matrix3x4_t groupToScreen;
  168. // Use the matrix that doesn't contain any scale changes if we should
  169. m_pGroup->GetRenderTransform( groupToScreen, true );
  170. MatrixMultiply( groupToScreen, rawToLocal, m_RelToScreenHoldAspectRatio );
  171. // Update all children
  172. for ( int i = 0; i < m_MemberList.Count(); i++ )
  173. {
  174. m_MemberList[i]->UpdateRenderTransforms( stageRenderInfo );
  175. }
  176. }
  177. //-----------------------------------------------------------------------------
  178. //
  179. //-----------------------------------------------------------------------------
  180. void CGraphicGroup::AddToGroup( CGameGraphic *pGraphic )
  181. {
  182. m_MemberList.AddToTail( pGraphic );
  183. }
  184. //-----------------------------------------------------------------------------
  185. //
  186. //-----------------------------------------------------------------------------
  187. void CGraphicGroup::RemoveFromGroup( CGameGraphic *pGraphic )
  188. {
  189. for ( int i = 0; i < m_MemberList.Count(); i++ )
  190. {
  191. // TODO, what if the graphic is a group?
  192. if ( m_MemberList[i] == pGraphic )
  193. {
  194. m_MemberList.Remove( i );
  195. return;
  196. }
  197. }
  198. }
  199. //-----------------------------------------------------------------------------
  200. // Returns true if any graphic in this group has the state.
  201. //-----------------------------------------------------------------------------
  202. bool CGraphicGroup::HasState( const char *pStateName )
  203. {
  204. if ( CGameGraphic::HasState( pStateName ) )
  205. return true;
  206. for ( int i = 0; i < m_MemberList.Count(); i++ )
  207. {
  208. if ( m_MemberList[i]->HasState( pStateName ) )
  209. return true;
  210. }
  211. return false;
  212. }
  213. //-----------------------------------------------------------------------------
  214. // Set the state of all members to this state
  215. //-----------------------------------------------------------------------------
  216. void CGraphicGroup::SetState( const char *pStateName )
  217. {
  218. CGameGraphic::SetState( pStateName );
  219. for ( int i = 0; i < m_MemberList.Count(); i++ )
  220. {
  221. m_MemberList[i]->SetState( pStateName );
  222. }
  223. }
  224. //-----------------------------------------------------------------------------
  225. // Start playing animations
  226. //-----------------------------------------------------------------------------
  227. void CGraphicGroup::StartPlaying()
  228. {
  229. CGameGraphic::StartPlaying();
  230. for ( int i = 0; i < m_MemberList.Count(); i++ )
  231. {
  232. m_MemberList[i]->StartPlaying();
  233. }
  234. }
  235. //-----------------------------------------------------------------------------
  236. // Stop playing animations
  237. //-----------------------------------------------------------------------------
  238. void CGraphicGroup::StopPlaying()
  239. {
  240. CGameGraphic::StopPlaying();
  241. for ( int i = 0; i < m_MemberList.Count(); i++ )
  242. {
  243. m_MemberList[i]->StopPlaying();
  244. }
  245. }
  246. //-----------------------------------------------------------------------------
  247. // Move all members to the next available state
  248. // Note this could put all of them into different states
  249. //-----------------------------------------------------------------------------
  250. void CGraphicGroup::AdvanceState()
  251. {
  252. CGameGraphic::AdvanceState();
  253. for ( int i = 0; i < m_MemberList.Count(); i++ )
  254. {
  255. m_MemberList[i]->AdvanceState();
  256. }
  257. }
  258. //-----------------------------------------------------------------------------
  259. // Return the first member of this group that can have keyfocus.
  260. //-----------------------------------------------------------------------------
  261. CHitArea *CGraphicGroup::GetKeyFocusRequestGraphic()
  262. {
  263. for ( int i = 0; i < m_MemberList.Count(); i++ )
  264. {
  265. if ( m_MemberList[i]->CanAcceptInput() )
  266. {
  267. return ( CHitArea * )m_MemberList[i];
  268. }
  269. }
  270. return NULL;
  271. }
  272. //-----------------------------------------------------------------------------
  273. // Does this graphic own a graphic with this name?
  274. //-----------------------------------------------------------------------------
  275. CGameGraphic *CGraphicGroup::FindGraphicByName( const char *pName ) const
  276. {
  277. int nGraphicCount = m_MemberList.Count();
  278. for ( int i = 0; i < nGraphicCount; ++i )
  279. {
  280. CGameGraphic *pMember = m_MemberList[i];
  281. if ( pMember->IsGraphicNamed( pName ) )
  282. {
  283. // Match.
  284. return pMember;
  285. }
  286. }
  287. return NULL;
  288. }
  289. //-----------------------------------------------------------------------------
  290. // Group visibility affects all children.
  291. //-----------------------------------------------------------------------------
  292. void CGraphicGroup::SetVisible( bool bVisible )
  293. {
  294. CGameGraphic::SetVisible( bVisible );
  295. int nGraphicCount = m_MemberList.Count();
  296. for ( int i = 0; i < nGraphicCount; ++i )
  297. {
  298. CGameGraphic *pMember = m_MemberList[i];
  299. pMember->SetVisible( bVisible );
  300. }
  301. }
  302. //-----------------------------------------------------------------------------
  303. // Return the appropriate render transform.
  304. // m_RelToScreenHoldAspectRatio is calculated for a stage aspect ratio that has not changed.
  305. //-----------------------------------------------------------------------------
  306. void CGraphicGroup::GetRenderTransform( matrix3x4_t &relToScreen, bool bMaintainAspectRatio ) const
  307. {
  308. if ( bMaintainAspectRatio )
  309. {
  310. relToScreen = m_RelToScreenHoldAspectRatio;
  311. }
  312. else
  313. {
  314. relToScreen = m_Geometry.m_RenderToScreen;
  315. }
  316. }
  317. //-----------------------------------------------------------------------------
  318. // If any parent of this group should maintain aspect ratio, this group should.
  319. //-----------------------------------------------------------------------------
  320. bool CGraphicGroup::MaintainAspectRatio() const
  321. {
  322. if ( m_pGroup && !m_Geometry.m_bMaintainAspectRatio )
  323. {
  324. return m_pGroup->MaintainAspectRatio();
  325. }
  326. return m_Geometry.m_bMaintainAspectRatio;
  327. }