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.

443 lines
12 KiB

  1. //====== Copyright � 1996-2009, Valve Corporation, All rights reserved. =======
  2. //
  3. // DmeEyeball
  4. //
  5. //=============================================================================
  6. // Standard includes
  7. #include <ctype.h>
  8. // Valve includes
  9. #include "datamodel/dmelementfactoryhelper.h"
  10. #include "movieobjects/dmecombinationoperator.h"
  11. #include "movieobjects/dmeexpressionoperator.h"
  12. #include "movieobjects/dmeflexrules.h"
  13. // Last include
  14. #include "tier0/memdbgon.h"
  15. //-----------------------------------------------------------------------------
  16. // Expose this class to the scene database
  17. //-----------------------------------------------------------------------------
  18. IMPLEMENT_ELEMENT_FACTORY( DmeFlexRuleBase, CDmeFlexRuleBase );
  19. //-----------------------------------------------------------------------------
  20. //
  21. //-----------------------------------------------------------------------------
  22. void CDmeFlexRuleBase::OnConstruction()
  23. {
  24. m_flResult.Init( this, "result" );
  25. }
  26. //-----------------------------------------------------------------------------
  27. //
  28. //-----------------------------------------------------------------------------
  29. void CDmeFlexRuleBase::OnDestruction()
  30. {
  31. }
  32. //-----------------------------------------------------------------------------
  33. //
  34. //-----------------------------------------------------------------------------
  35. void CDmeFlexRuleBase::GetInputAttributes ( CUtlVector< CDmAttribute * > &attrs )
  36. {
  37. BaseClass::GetInputAttributes( attrs );
  38. CDmeFlexRules *pDmeFlexRules = GetFlexRules();
  39. if ( pDmeFlexRules )
  40. {
  41. attrs.AddToTail( pDmeFlexRules->m_vDeltaStateWeights.GetAttribute() );
  42. }
  43. }
  44. //-----------------------------------------------------------------------------
  45. //
  46. //-----------------------------------------------------------------------------
  47. void CDmeFlexRuleBase::GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs )
  48. {
  49. BaseClass::GetOutputAttributes( attrs );
  50. attrs.AddToTail( m_flResult.GetAttribute() );
  51. }
  52. //-----------------------------------------------------------------------------
  53. // Returns the first DmeExpressionRules element that refers to this element
  54. //-----------------------------------------------------------------------------
  55. CDmeFlexRules *CDmeFlexRuleBase::GetFlexRules() const
  56. {
  57. return FindReferringElement< CDmeFlexRules >( this, "deltaStates" );
  58. }
  59. //-----------------------------------------------------------------------------
  60. // Expose this class to the scene database
  61. //-----------------------------------------------------------------------------
  62. IMPLEMENT_ELEMENT_FACTORY( DmeFlexRulePassThrough, CDmeFlexRulePassThrough );
  63. //-----------------------------------------------------------------------------
  64. //
  65. //-----------------------------------------------------------------------------
  66. void CDmeFlexRulePassThrough::OnConstruction()
  67. {
  68. }
  69. //-----------------------------------------------------------------------------
  70. //
  71. //-----------------------------------------------------------------------------
  72. void CDmeFlexRulePassThrough::OnDestruction()
  73. {
  74. }
  75. //-----------------------------------------------------------------------------
  76. //
  77. //-----------------------------------------------------------------------------
  78. void CDmeFlexRulePassThrough::Operate()
  79. {
  80. CDmeFlexRules *pDmeFlexRules = GetFlexRules();
  81. if ( !pDmeFlexRules )
  82. return;
  83. const float flResult = pDmeFlexRules->GetDeltaStateWeight( GetName() );
  84. m_flResult.Set( flResult );
  85. }
  86. //-----------------------------------------------------------------------------
  87. // Expose this class to the scene database
  88. //-----------------------------------------------------------------------------
  89. IMPLEMENT_ELEMENT_FACTORY( DmeFlexRuleExpression, CDmeFlexRuleExpression );
  90. //-----------------------------------------------------------------------------
  91. //
  92. //-----------------------------------------------------------------------------
  93. void CDmeFlexRuleExpression::OnConstruction()
  94. {
  95. m_expr.Init( this, "expr" );
  96. }
  97. //-----------------------------------------------------------------------------
  98. //
  99. //-----------------------------------------------------------------------------
  100. void CDmeFlexRuleExpression::OnDestruction()
  101. {
  102. }
  103. //-----------------------------------------------------------------------------
  104. //
  105. //-----------------------------------------------------------------------------
  106. void CDmeFlexRuleExpression::Operate()
  107. {
  108. CDmeFlexRules *pDmeFlexRules = GetFlexRules();
  109. if ( pDmeFlexRules )
  110. {
  111. for ( int i = 0; i < m_calc.VariableCount(); ++i )
  112. {
  113. m_calc.SetVariable( i, pDmeFlexRules->GetDeltaStateWeight( m_calc.VariableName( i ) ) );
  114. }
  115. }
  116. float flVal = 0.0f;
  117. if ( m_calc.Evaluate( flVal ) )
  118. {
  119. m_flResult.Set( flVal );
  120. }
  121. }
  122. //-----------------------------------------------------------------------------
  123. //
  124. //-----------------------------------------------------------------------------
  125. void CDmeFlexRuleExpression::Resolve()
  126. {
  127. if ( m_expr.IsDirty() )
  128. {
  129. m_calc.SetExpression( m_expr.Get() );
  130. m_calc.BuildVariableListFromExpression();
  131. }
  132. }
  133. //-----------------------------------------------------------------------------
  134. //
  135. //-----------------------------------------------------------------------------
  136. bool CDmeFlexRuleExpression::SetExpression( const char *pszExpression )
  137. {
  138. if ( !pszExpression || *pszExpression == '\0' )
  139. return false;
  140. bool bReturn = false;
  141. CUtlVector< char *, CUtlMemory< char *, int > > pathStrings;
  142. V_SplitString( pszExpression, "=", pathStrings );
  143. if ( pathStrings.Count() == 2 )
  144. {
  145. char *pszLhs = pathStrings[0];
  146. while ( V_isspace( *pszLhs ) )
  147. {
  148. ++pszLhs;
  149. }
  150. for ( char *pszChar = pszLhs + V_strlen( pszLhs ) - 1; V_isspace( *pszChar ) && pszChar >= pszLhs; --pszChar )
  151. {
  152. *pszChar = '\0';
  153. }
  154. char *pszRhs = pathStrings[1];
  155. while ( V_isspace( *pszRhs ) )
  156. {
  157. ++pszRhs;
  158. }
  159. for ( char *pszChar = pszRhs + V_strlen( pszRhs ) - 1; V_isspace( *pszChar ) && pszChar >= pszRhs; --pszChar )
  160. {
  161. *pszChar = '\0';
  162. }
  163. m_expr = pszRhs;
  164. Resolve();
  165. // It's assumed the name of the node is the same as the variable on the left hand side of the expression
  166. Assert( !V_strcmp( pszLhs, GetName() ) );
  167. }
  168. pathStrings.PurgeAndDeleteElements();
  169. return bReturn;
  170. }
  171. //-----------------------------------------------------------------------------
  172. // Expose this class to the scene database
  173. //-----------------------------------------------------------------------------
  174. IMPLEMENT_ELEMENT_FACTORY( DmeFlexRuleLocalVar, CDmeFlexRuleLocalVar );
  175. //-----------------------------------------------------------------------------
  176. //
  177. //-----------------------------------------------------------------------------
  178. void CDmeFlexRuleLocalVar::OnConstruction()
  179. {
  180. }
  181. //-----------------------------------------------------------------------------
  182. //
  183. //-----------------------------------------------------------------------------
  184. void CDmeFlexRuleLocalVar::OnDestruction()
  185. {
  186. }
  187. //-----------------------------------------------------------------------------
  188. // Expose this class to the scene database
  189. //-----------------------------------------------------------------------------
  190. IMPLEMENT_ELEMENT_FACTORY( DmeFlexRules, CDmeFlexRules );
  191. //-----------------------------------------------------------------------------
  192. //
  193. //-----------------------------------------------------------------------------
  194. void CDmeFlexRules::OnConstruction()
  195. {
  196. // Required to drive this node from a DmeCombinationOperator
  197. m_eDeltaStates.Init( this, "deltaStates" );
  198. m_vDeltaStateWeights.Init( this, "deltaStateWeights" );
  199. m_eTarget.Init( this, "target" );
  200. }
  201. //-----------------------------------------------------------------------------
  202. //
  203. //-----------------------------------------------------------------------------
  204. void CDmeFlexRules::OnDestruction()
  205. {
  206. }
  207. //-----------------------------------------------------------------------------
  208. //
  209. //-----------------------------------------------------------------------------
  210. void CDmeFlexRules::Operate()
  211. {
  212. if ( m_deltaToTargetMap.Count() <= 0 )
  213. {
  214. Resolve();
  215. }
  216. const int nDeltaCount = MIN( m_eDeltaStates.Count(), m_deltaToTargetMap.Count() );
  217. CDmrArray< Vector2D > targetWeights( m_eTarget, "deltaStateWeights" );
  218. const int nTargetWeightCount = targetWeights.Count();
  219. for ( int i = 0; i < nDeltaCount; ++i )
  220. {
  221. const int nTargetIndex = m_deltaToTargetMap[i];
  222. if ( nTargetIndex < 0 || nTargetIndex >= nTargetWeightCount )
  223. continue;
  224. CDmeFlexRuleBase *pDmeFlexRuleBase = m_eDeltaStates[i];
  225. if ( !pDmeFlexRuleBase )
  226. continue;
  227. const CDmAttribute *pDmResultAttr = pDmeFlexRuleBase->ResultAttr();
  228. if ( !pDmResultAttr )
  229. continue;
  230. const float flVal = pDmResultAttr->GetValue< float >();
  231. targetWeights.Set( nTargetIndex, Vector2D( flVal, flVal ) ); // FlexRules ignore the built in stereo
  232. }
  233. }
  234. //-----------------------------------------------------------------------------
  235. //
  236. //-----------------------------------------------------------------------------
  237. void CDmeFlexRules::Resolve()
  238. {
  239. if ( m_deltaToTargetMap.Count() <= 0 || m_eTarget.IsDirty() || m_eDeltaStates.IsDirty() )
  240. {
  241. m_deltaToTargetMap.SetCountNonDestructively( m_eDeltaStates.Count() );
  242. const CDmrElementArrayConst< CDmElement > targetStates( m_eTarget, "deltaStates" );
  243. for ( int i = 0; i < m_eDeltaStates.Count(); ++i )
  244. {
  245. m_deltaToTargetMap[i] = -1;
  246. CDmeFlexRuleBase *pDmeFlexRuleBase = m_eDeltaStates[i];
  247. if ( !pDmeFlexRuleBase )
  248. continue;
  249. for ( int j = 0; j < targetStates.Count(); ++j )
  250. {
  251. if ( !V_strcmp( targetStates[j]->GetName(), pDmeFlexRuleBase->GetName() ) )
  252. {
  253. m_deltaToTargetMap[i] = j;
  254. break;
  255. }
  256. }
  257. }
  258. }
  259. }
  260. //-----------------------------------------------------------------------------
  261. //
  262. //-----------------------------------------------------------------------------
  263. void CDmeFlexRules::GetInputAttributes( CUtlVector< CDmAttribute * > &attrs )
  264. {
  265. attrs.AddToTail( m_eDeltaStates.GetAttribute() );
  266. attrs.AddToTail( m_vDeltaStateWeights.GetAttribute() );
  267. for ( int i = 0; i < m_eDeltaStates.Count(); ++i )
  268. {
  269. m_eDeltaStates[i]->GetOutputAttributes( attrs );
  270. }
  271. }
  272. //-----------------------------------------------------------------------------
  273. //
  274. //-----------------------------------------------------------------------------
  275. void CDmeFlexRules::GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs )
  276. {
  277. CDmrArray<Vector2D> targetWeights( m_eTarget, "deltaStateWeights" );
  278. if ( targetWeights.IsValid() )
  279. {
  280. attrs.AddToTail( targetWeights.GetAttribute() );
  281. }
  282. }
  283. //-----------------------------------------------------------------------------
  284. //
  285. //-----------------------------------------------------------------------------
  286. void CDmeFlexRules::AddFlexRule( CDmeFlexRuleBase *pDmeFlexRule )
  287. {
  288. if ( !pDmeFlexRule )
  289. return;
  290. m_eDeltaStates.AddToTail( pDmeFlexRule );
  291. m_vDeltaStateWeights.AddToTail();
  292. }
  293. //-----------------------------------------------------------------------------
  294. //
  295. //-----------------------------------------------------------------------------
  296. void CDmeFlexRules::RemoveAllRules()
  297. {
  298. m_eDeltaStates.RemoveAll();
  299. m_vDeltaStateWeights.RemoveAll();
  300. }
  301. //-----------------------------------------------------------------------------
  302. //
  303. //-----------------------------------------------------------------------------
  304. void CDmeFlexRules::SetTarget( CDmElement *pDmElement )
  305. {
  306. if ( !pDmElement )
  307. return;
  308. m_eTarget = pDmElement;
  309. }
  310. //-----------------------------------------------------------------------------
  311. //
  312. //-----------------------------------------------------------------------------
  313. int CDmeFlexRules::GetDeltaStateIndex( const char *pszDeltaName ) const
  314. {
  315. for ( int i = 0; i < m_eDeltaStates.Count(); ++i )
  316. {
  317. if ( !V_strcmp( pszDeltaName, m_eDeltaStates[i]->GetName() ) )
  318. return i;
  319. }
  320. return -1;
  321. }
  322. //-----------------------------------------------------------------------------
  323. //
  324. //-----------------------------------------------------------------------------
  325. float CDmeFlexRules::GetDeltaStateWeight( const char *pszDeltaName ) const
  326. {
  327. const int nDeltaStateIndex = GetDeltaStateIndex( pszDeltaName );
  328. if ( nDeltaStateIndex < 0 || nDeltaStateIndex >= m_vDeltaStateWeights.Count() )
  329. return 0.0f;
  330. return m_vDeltaStateWeights[nDeltaStateIndex].x; // Weights are stereo...
  331. }
  332. //-----------------------------------------------------------------------------
  333. //
  334. //-----------------------------------------------------------------------------
  335. CDmeCombinationOperator *CDmeFlexRules::GetComboOp() const
  336. {
  337. return FindReferringElement< CDmeCombinationOperator >( this, m_vDeltaStateWeights.GetAttribute()->GetName() );
  338. }