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.

187 lines
5.4 KiB

  1. //====== Copyright � 1996-2004, Valve Corporation, All rights reserved. =======
  2. //
  3. // The expression operator class - scalar math calculator
  4. // for a good list of operators and simple functions, see:
  5. // \\fileserver\user\MarcS\boxweb\aliveDistLite\v4.2.0\doc\alive\functions.txt
  6. // (although we'll want to implement elerp as the standard 3x^2 - 2x^3 with rescale)
  7. //
  8. //=============================================================================
  9. #include "movieobjects/dmeexpressionoperator.h"
  10. #include "movieobjects_interfaces.h"
  11. #include "datamodel/dmelementfactoryhelper.h"
  12. #include "datamodel/dmattribute.h"
  13. #include "mathlib/noise.h"
  14. #include "mathlib/vector.h"
  15. #include <ctype.h>
  16. // memdbgon must be the last include file in a .cpp file!!!
  17. #include "tier0/memdbgon.h"
  18. void TestCalculator( const char *expr, float answer )
  19. {
  20. CExpressionCalculator calc( expr );
  21. float result = 0.0f;
  22. #ifdef _DEBUG
  23. bool success =
  24. #endif
  25. calc.Evaluate( result );
  26. Assert( success && ( result == answer ) );
  27. }
  28. void TestCalculator( const char *expr, float answer, const char *var, float value )
  29. {
  30. CExpressionCalculator calc( expr );
  31. calc.SetVariable( var, value );
  32. float result = 0.0f;
  33. #ifdef _DEBUG
  34. bool success =
  35. #endif
  36. calc.Evaluate( result );
  37. Assert( success && ( result == answer ) );
  38. }
  39. void TestCalculator()
  40. {
  41. // TestCalculator( "-1", 1 );
  42. TestCalculator( "2 * 3 + 4", 10 );
  43. TestCalculator( "2 + 3 * 4", 14 );
  44. TestCalculator( "2 * 3 * 4", 24 );
  45. TestCalculator( "2 * -3 + 4", -2 );
  46. TestCalculator( "12.0 / 2.0", 6 );
  47. TestCalculator( "(2*3)+4", 10 );
  48. TestCalculator( "( 1 + 2 ) / (1+2)", 1 );
  49. TestCalculator( "(((5)))", 5 );
  50. TestCalculator( "--5", 5 );
  51. TestCalculator( "3.5 % 2", 1.5 );
  52. TestCalculator( "1e-2", 0.01 );
  53. TestCalculator( "9 == ( 3 * ( 1 + 2 ) )", 1 );
  54. TestCalculator( "9 != ( 3 * ( 1 + 2 ) )", 0 );
  55. TestCalculator( "9 <= ( 3 * ( 1 + 2 ) )", 1 );
  56. TestCalculator( "9 < ( 3 * ( 1 + 2 ) )", 0 );
  57. TestCalculator( "9 < 3", 0 );
  58. TestCalculator( "10 >= 5", 1 );
  59. // TestCalculator( "9 < ( 3 * ( 2 + 2 ) )", 0 );
  60. TestCalculator( "x + 1", 5, "x", 4 );
  61. TestCalculator( "pi - 3.14159", 0, "pi", 3.14159 );
  62. // TestCalculator( "pi / 2", 0, "pi", 3.14159 );
  63. TestCalculator( "abs(-10)", 10 );
  64. TestCalculator( "sqr(-5)", 25 );
  65. TestCalculator( "sqrt(9)", 3 );
  66. // TestCalculator( "sqrt(-9)", -3 );
  67. TestCalculator( "pow(2,3)", 8 );
  68. TestCalculator( "min(abs(-4),2+3/2)", 3.5 );
  69. TestCalculator( "round(0.5)", 1 );
  70. TestCalculator( "round(0.49)", 0 );
  71. TestCalculator( "round(-0.5)", 0 );
  72. TestCalculator( "round(-0.51)", -1 );
  73. TestCalculator( "inrange( 5, -8, 10 )", 1 );
  74. TestCalculator( "inrange( 5, 5, 10 )", 1 );
  75. TestCalculator( "inrange( 5, 6, 10 )", 0 );
  76. TestCalculator( "elerp( 1/4, 0, 1 )", 3/16.0f - 1/32.0f );
  77. TestCalculator( "rescale( 0.5, -1, 1, 0, 100 )", 75 );
  78. TestCalculator( "1 > 2 ? 6 : 9", 9 );
  79. TestCalculator( "1 ? 1 ? 2 : 4 : 1 ? 6 : 8", 2 );
  80. TestCalculator( "0 ? 1 ? 2 : 4 : 1 ? 6 : 8", 6 );
  81. TestCalculator( "noise( 0.123, 4.56, 78.9 )", ImprovedPerlinNoise( Vector( 0.123, 4.56, 78.9 ) ) );
  82. }
  83. //-----------------------------------------------------------------------------
  84. // Expose this class to the scene database
  85. //-----------------------------------------------------------------------------
  86. IMPLEMENT_ELEMENT_FACTORY( DmeExpressionOperator, CDmeExpressionOperator );
  87. //-----------------------------------------------------------------------------
  88. // Purpose:
  89. //-----------------------------------------------------------------------------
  90. void CDmeExpressionOperator::OnConstruction()
  91. {
  92. m_result.Init( this, "result" );
  93. m_expr.Init( this, "expr" );
  94. m_bSpewResult.Init( this, "spewresult" );
  95. #ifdef _DEBUG
  96. TestCalculator();
  97. #endif _DEBUG
  98. }
  99. void CDmeExpressionOperator::OnDestruction()
  100. {
  101. }
  102. //-----------------------------------------------------------------------------
  103. // Purpose:
  104. //-----------------------------------------------------------------------------
  105. bool CDmeExpressionOperator::IsInputAttribute( CDmAttribute *pAttribute )
  106. {
  107. const char *pName = pAttribute->GetName( );
  108. #if 0 // skip this test, since none of these are float attributes, but leave the code as a reminder
  109. if ( Q_strcmp( pName, "name" ) == 0 )
  110. return false;
  111. if ( Q_strcmp( pName, "expr" ) == 0 )
  112. return false;
  113. #endif
  114. if ( Q_strcmp( pName, "result" ) == 0 )
  115. return false;
  116. if ( pAttribute->GetType() != AT_FLOAT )
  117. return false;
  118. return true;
  119. }
  120. void CDmeExpressionOperator::Operate()
  121. {
  122. m_calc.SetExpression( m_expr.Get() );
  123. for ( CDmAttribute *pAttribute = FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
  124. {
  125. if ( IsInputAttribute( pAttribute ) )
  126. {
  127. const char *pName = pAttribute->GetName( );
  128. m_calc.SetVariable( pName, pAttribute->GetValue< float >() );
  129. }
  130. }
  131. float oldValue = m_result;
  132. m_calc.Evaluate( oldValue );
  133. m_result = oldValue;
  134. if ( m_bSpewResult )
  135. {
  136. Msg( "%s = '%f'\n", GetName(), (float)m_result );
  137. }
  138. }
  139. void CDmeExpressionOperator::GetInputAttributes( CUtlVector< CDmAttribute * > &attrs )
  140. {
  141. for ( CDmAttribute *pAttribute = FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
  142. {
  143. if ( IsInputAttribute( pAttribute ) )
  144. {
  145. attrs.AddToTail( pAttribute );
  146. }
  147. }
  148. attrs.AddToTail( m_expr.GetAttribute() );
  149. }
  150. void CDmeExpressionOperator::GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs )
  151. {
  152. attrs.AddToTail( m_result.GetAttribute() );
  153. }
  154. void CDmeExpressionOperator::SetSpewResult( bool state )
  155. {
  156. m_bSpewResult = state;
  157. }