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.

1028 lines
24 KiB

  1. //========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include "sharedInterface.h"
  9. #include "materialsystem/imaterial.h"
  10. #include <keyvalues.h>
  11. #include "materialsystem/imaterialvar.h"
  12. #include "functionproxy.h"
  13. #include "imaterialproxydict.h"
  14. // memdbgon must be the last include file in a .cpp file!!!
  15. #include "tier0/memdbgon.h"
  16. class C_BaseEntity;
  17. //-----------------------------------------------------------------------------
  18. // Adds two vars...
  19. //-----------------------------------------------------------------------------
  20. class CAddProxy : public CFunctionProxy
  21. {
  22. public:
  23. bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
  24. void OnBind( void *pC_BaseEntity );
  25. };
  26. bool CAddProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
  27. {
  28. // Requires 2 args..
  29. bool ok = CFunctionProxy::Init( pMaterial, pKeyValues );
  30. ok = ok && m_pSrc2;
  31. return ok;
  32. }
  33. void CAddProxy::OnBind( void *pC_BaseEntity )
  34. {
  35. Assert( m_pSrc1 && m_pSrc2 && m_pResult );
  36. MaterialVarType_t resultType;
  37. int vecSize;
  38. ComputeResultType( resultType, vecSize );
  39. switch( resultType )
  40. {
  41. case MATERIAL_VAR_TYPE_VECTOR:
  42. {
  43. Vector a, b, c;
  44. m_pSrc1->GetVecValue( a.Base(), vecSize );
  45. m_pSrc2->GetVecValue( b.Base(), vecSize );
  46. VectorAdd( a, b, c );
  47. m_pResult->SetVecValue( c.Base(), vecSize );
  48. }
  49. break;
  50. case MATERIAL_VAR_TYPE_FLOAT:
  51. SetFloatResult( m_pSrc1->GetFloatValue() + m_pSrc2->GetFloatValue() );
  52. break;
  53. case MATERIAL_VAR_TYPE_INT:
  54. m_pResult->SetFloatValue( m_pSrc1->GetIntValue() + m_pSrc2->GetIntValue() );
  55. break;
  56. }
  57. }
  58. EXPOSE_MATERIAL_PROXY( CAddProxy, Add );
  59. //-----------------------------------------------------------------------------
  60. // modulo
  61. //-----------------------------------------------------------------------------
  62. class CModProxy : public CFunctionProxy
  63. {
  64. public:
  65. bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
  66. void OnBind( void *pC_BaseEntity );
  67. };
  68. bool CModProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
  69. {
  70. // Requires 2 args..
  71. bool ok = CFunctionProxy::Init( pMaterial, pKeyValues );
  72. ok = ok && m_pSrc2;
  73. return ok;
  74. }
  75. void CModProxy::OnBind( void *pC_BaseEntity )
  76. {
  77. Assert( m_pSrc1 && m_pSrc2 && m_pResult );
  78. SetFloatResult( fmod( m_pSrc1->GetFloatValue(), m_pSrc2->GetFloatValue() ) );
  79. }
  80. EXPOSE_MATERIAL_PROXY( CModProxy, Modulo );
  81. //-----------------------------------------------------------------------------
  82. // Subtracts two vars...
  83. //-----------------------------------------------------------------------------
  84. class CSubtractProxy : public CFunctionProxy
  85. {
  86. public:
  87. bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
  88. void OnBind( void *pC_BaseEntity );
  89. };
  90. bool CSubtractProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
  91. {
  92. // Requires 2 args..
  93. bool ok = CFunctionProxy::Init( pMaterial, pKeyValues );
  94. ok = ok && m_pSrc2;
  95. return ok;
  96. }
  97. void CSubtractProxy::OnBind( void *pC_BaseEntity )
  98. {
  99. Assert( m_pSrc1 && m_pSrc2 && m_pResult );
  100. MaterialVarType_t resultType;
  101. int vecSize;
  102. ComputeResultType( resultType, vecSize );
  103. switch( resultType )
  104. {
  105. case MATERIAL_VAR_TYPE_VECTOR:
  106. {
  107. Vector a, b, c;
  108. m_pSrc1->GetVecValue( a.Base(), vecSize );
  109. m_pSrc2->GetVecValue( b.Base(), vecSize );
  110. VectorSubtract( a, b, c );
  111. m_pResult->SetVecValue( c.Base(), vecSize );
  112. }
  113. break;
  114. case MATERIAL_VAR_TYPE_FLOAT:
  115. SetFloatResult( m_pSrc1->GetFloatValue() - m_pSrc2->GetFloatValue() );
  116. break;
  117. case MATERIAL_VAR_TYPE_INT:
  118. m_pResult->SetFloatValue( m_pSrc1->GetIntValue() - m_pSrc2->GetIntValue() );
  119. break;
  120. }
  121. }
  122. EXPOSE_MATERIAL_PROXY( CSubtractProxy, Subtract );
  123. //-----------------------------------------------------------------------------
  124. // Multiplies two vars...
  125. //-----------------------------------------------------------------------------
  126. class CMultiplyProxy : public CFunctionProxy
  127. {
  128. public:
  129. bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
  130. void OnBind( void *pC_BaseEntity );
  131. };
  132. bool CMultiplyProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
  133. {
  134. // Requires 2 args..
  135. bool ok = CFunctionProxy::Init( pMaterial, pKeyValues );
  136. ok = ok && m_pSrc2;
  137. return ok;
  138. }
  139. void CMultiplyProxy::OnBind( void *pC_BaseEntity )
  140. {
  141. Assert( m_pSrc1 && m_pSrc2 && m_pResult );
  142. MaterialVarType_t resultType;
  143. int vecSize;
  144. ComputeResultType( resultType, vecSize );
  145. switch( resultType )
  146. {
  147. case MATERIAL_VAR_TYPE_VECTOR:
  148. {
  149. Vector a, b, c;
  150. m_pSrc1->GetVecValue( a.Base(), vecSize );
  151. m_pSrc2->GetVecValue( b.Base(), vecSize );
  152. VectorMultiply( a, b, c );
  153. m_pResult->SetVecValue( c.Base(), vecSize );
  154. }
  155. break;
  156. case MATERIAL_VAR_TYPE_FLOAT:
  157. SetFloatResult( m_pSrc1->GetFloatValue() * m_pSrc2->GetFloatValue() );
  158. break;
  159. case MATERIAL_VAR_TYPE_INT:
  160. m_pResult->SetFloatValue( m_pSrc1->GetIntValue() * m_pSrc2->GetIntValue() );
  161. break;
  162. }
  163. }
  164. EXPOSE_MATERIAL_PROXY( CMultiplyProxy, Multiply );
  165. //-----------------------------------------------------------------------------
  166. // divides two vars...
  167. //-----------------------------------------------------------------------------
  168. class CDivideProxy : public CFunctionProxy
  169. {
  170. public:
  171. bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
  172. void OnBind( void *pC_BaseEntity );
  173. };
  174. bool CDivideProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
  175. {
  176. // Requires 2 args..
  177. bool ok = CFunctionProxy::Init( pMaterial, pKeyValues );
  178. ok = ok && m_pSrc2;
  179. return ok;
  180. }
  181. void CDivideProxy::OnBind( void *pC_BaseEntity )
  182. {
  183. Assert( m_pSrc1 && m_pSrc2 && m_pResult );
  184. MaterialVarType_t resultType;
  185. int vecSize;
  186. ComputeResultType( resultType, vecSize );
  187. switch( resultType )
  188. {
  189. case MATERIAL_VAR_TYPE_VECTOR:
  190. {
  191. Vector a, b, c;
  192. m_pSrc1->GetVecValue( a.Base(), vecSize );
  193. m_pSrc2->GetVecValue( b.Base(), vecSize );
  194. VectorDivide( a, b, c );
  195. m_pResult->SetVecValue( c.Base(), vecSize );
  196. }
  197. break;
  198. case MATERIAL_VAR_TYPE_FLOAT:
  199. if (m_pSrc2->GetFloatValue() != 0)
  200. {
  201. SetFloatResult( m_pSrc1->GetFloatValue() / m_pSrc2->GetFloatValue() );
  202. }
  203. else
  204. {
  205. SetFloatResult( m_pSrc1->GetFloatValue() );
  206. }
  207. break;
  208. case MATERIAL_VAR_TYPE_INT:
  209. if (m_pSrc2->GetIntValue() != 0)
  210. {
  211. m_pResult->SetFloatValue( m_pSrc1->GetIntValue() / m_pSrc2->GetIntValue() );
  212. }
  213. else
  214. {
  215. m_pResult->SetFloatValue( m_pSrc1->GetIntValue() );
  216. }
  217. break;
  218. }
  219. }
  220. EXPOSE_MATERIAL_PROXY( CDivideProxy, Divide );
  221. //-----------------------------------------------------------------------------
  222. // clamps a var...
  223. //-----------------------------------------------------------------------------
  224. class CClampProxy : public CFunctionProxy
  225. {
  226. public:
  227. bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
  228. void OnBind( void *pC_BaseEntity );
  229. private:
  230. CFloatInput m_Min;
  231. CFloatInput m_Max;
  232. };
  233. bool CClampProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
  234. {
  235. if (!CFunctionProxy::Init( pMaterial, pKeyValues ))
  236. return false;
  237. if (!m_Min.Init( pMaterial, pKeyValues, "min", 0 ))
  238. return false;
  239. if (!m_Max.Init( pMaterial, pKeyValues, "max", 1 ))
  240. return false;
  241. return true;
  242. }
  243. void CClampProxy::OnBind( void *pC_BaseEntity )
  244. {
  245. Assert( m_pSrc1 && m_pResult );
  246. MaterialVarType_t resultType;
  247. int vecSize;
  248. ComputeResultType( resultType, vecSize );
  249. float flMin = m_Min.GetFloat();
  250. float flMax = m_Max.GetFloat();
  251. if (flMin > flMax)
  252. {
  253. float flTemp = flMin;
  254. flMin = flMax;
  255. flMax = flTemp;
  256. }
  257. switch( resultType )
  258. {
  259. case MATERIAL_VAR_TYPE_VECTOR:
  260. {
  261. Vector a;
  262. m_pSrc1->GetVecValue( a.Base(), vecSize );
  263. for (int i = 0; i < vecSize; ++i)
  264. {
  265. if (a[i] < flMin)
  266. a[i] = flMin;
  267. else if (a[i] > flMax)
  268. a[i] = flMax;
  269. }
  270. m_pResult->SetVecValue( a.Base(), vecSize );
  271. }
  272. break;
  273. case MATERIAL_VAR_TYPE_FLOAT:
  274. {
  275. float src = m_pSrc1->GetFloatValue();
  276. if (src < flMin)
  277. src = flMin;
  278. else if (src > flMax)
  279. src = flMax;
  280. SetFloatResult( src );
  281. }
  282. break;
  283. case MATERIAL_VAR_TYPE_INT:
  284. {
  285. int src = m_pSrc1->GetIntValue();
  286. if (src < flMin)
  287. src = flMin;
  288. else if (src > flMax)
  289. src = flMax;
  290. m_pResult->SetIntValue( src );
  291. }
  292. break;
  293. }
  294. }
  295. EXPOSE_MATERIAL_PROXY( CClampProxy, Clamp );
  296. //-----------------------------------------------------------------------------
  297. // Creates a sinusoid
  298. //-----------------------------------------------------------------------------
  299. // sinePeriod: time that it takes to go through whole sine wave in seconds (default: 1.0f)
  300. // sineMax : the max value for the sine wave (default: 1.0f )
  301. // sineMin: the min value for the sine wave (default: 0.0f )
  302. class CSineProxy : public CResultProxy
  303. {
  304. public:
  305. virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
  306. virtual void OnBind( void *pC_BaseEntity );
  307. private:
  308. CFloatInput m_SinePeriod;
  309. CFloatInput m_SineMax;
  310. CFloatInput m_SineMin;
  311. CFloatInput m_SineTimeOffset;
  312. };
  313. bool CSineProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
  314. {
  315. if (!CResultProxy::Init( pMaterial, pKeyValues ))
  316. return false;
  317. if (!m_SinePeriod.Init( pMaterial, pKeyValues, "sinePeriod", 1.0f ))
  318. return false;
  319. if (!m_SineMax.Init( pMaterial, pKeyValues, "sineMax", 1.0f ))
  320. return false;
  321. if (!m_SineMin.Init( pMaterial, pKeyValues, "sineMin", 0.0f ))
  322. return false;
  323. if (!m_SineTimeOffset.Init( pMaterial, pKeyValues, "timeOffset", 0.0f ))
  324. return false;
  325. return true;
  326. }
  327. void CSineProxy::OnBind( void *pC_BaseEntity )
  328. {
  329. Assert( m_pResult );
  330. float flValue;
  331. float flSineTimeOffset = m_SineTimeOffset.GetFloat();
  332. float flSineMax = m_SineMax.GetFloat();
  333. float flSineMin = m_SineMin.GetFloat();
  334. float flSinePeriod = m_SinePeriod.GetFloat();
  335. if (flSinePeriod == 0)
  336. flSinePeriod = 1;
  337. // get a value in [0,1]
  338. flValue = ( sin( 2.0f * M_PI * (gpGlobals->curtime - flSineTimeOffset) / flSinePeriod ) * 0.5f ) + 0.5f;
  339. // get a value in [min,max]
  340. flValue = ( flSineMax - flSineMin ) * flValue + flSineMin;
  341. SetFloatResult( flValue );
  342. }
  343. EXPOSE_MATERIAL_PROXY( CSineProxy, Sine );
  344. //-----------------------------------------------------------------------------
  345. // copies a var...
  346. //-----------------------------------------------------------------------------
  347. class CEqualsProxy : public CFunctionProxy
  348. {
  349. public:
  350. void OnBind( void *pC_BaseEntity );
  351. };
  352. void CEqualsProxy::OnBind( void *pC_BaseEntity )
  353. {
  354. Assert( m_pSrc1 && m_pResult );
  355. MaterialVarType_t resultType;
  356. int vecSize;
  357. ComputeResultType( resultType, vecSize );
  358. switch( resultType )
  359. {
  360. case MATERIAL_VAR_TYPE_VECTOR:
  361. {
  362. Vector a;
  363. m_pSrc1->GetVecValue( a.Base(), vecSize );
  364. m_pResult->SetVecValue( a.Base(), vecSize );
  365. }
  366. break;
  367. case MATERIAL_VAR_TYPE_FLOAT:
  368. SetFloatResult( m_pSrc1->GetFloatValue() );
  369. break;
  370. case MATERIAL_VAR_TYPE_INT:
  371. m_pResult->SetIntValue( m_pSrc1->GetIntValue() );
  372. break;
  373. }
  374. }
  375. EXPOSE_MATERIAL_PROXY( CEqualsProxy, Equals );
  376. //-----------------------------------------------------------------------------
  377. // Get the fractional part of a var
  378. //-----------------------------------------------------------------------------
  379. class CFracProxy : public CFunctionProxy
  380. {
  381. public:
  382. void OnBind( void *pC_BaseEntity );
  383. };
  384. void CFracProxy::OnBind( void *pC_BaseEntity )
  385. {
  386. Assert( m_pSrc1 && m_pResult );
  387. MaterialVarType_t resultType;
  388. int vecSize;
  389. ComputeResultType( resultType, vecSize );
  390. switch( resultType )
  391. {
  392. case MATERIAL_VAR_TYPE_VECTOR:
  393. {
  394. Vector a;
  395. m_pSrc1->GetVecValue( a.Base(), vecSize );
  396. a[0] -= ( float )( int )a[0];
  397. a[1] -= ( float )( int )a[1];
  398. a[2] -= ( float )( int )a[2];
  399. m_pResult->SetVecValue( a.Base(), vecSize );
  400. }
  401. break;
  402. case MATERIAL_VAR_TYPE_FLOAT:
  403. {
  404. float a = m_pSrc1->GetFloatValue();
  405. a -= ( int )a;
  406. SetFloatResult( a );
  407. }
  408. break;
  409. case MATERIAL_VAR_TYPE_INT:
  410. // don't do anything besides assignment!
  411. m_pResult->SetIntValue( m_pSrc1->GetIntValue() );
  412. break;
  413. }
  414. }
  415. EXPOSE_MATERIAL_PROXY( CFracProxy, Frac );
  416. //-----------------------------------------------------------------------------
  417. // Get the Integer part of a var
  418. //-----------------------------------------------------------------------------
  419. class CIntProxy : public CFunctionProxy
  420. {
  421. public:
  422. void OnBind( void *pC_BaseEntity );
  423. };
  424. void CIntProxy::OnBind( void *pC_BaseEntity )
  425. {
  426. Assert( m_pSrc1 && m_pResult );
  427. MaterialVarType_t resultType;
  428. int vecSize;
  429. ComputeResultType( resultType, vecSize );
  430. switch( resultType )
  431. {
  432. case MATERIAL_VAR_TYPE_VECTOR:
  433. {
  434. Vector a;
  435. m_pSrc1->GetVecValue( a.Base(), vecSize );
  436. a[0] = ( float )( int )a[0];
  437. a[1] = ( float )( int )a[1];
  438. a[2] = ( float )( int )a[2];
  439. m_pResult->SetVecValue( a.Base(), vecSize );
  440. }
  441. break;
  442. case MATERIAL_VAR_TYPE_FLOAT:
  443. {
  444. float a = m_pSrc1->GetFloatValue();
  445. a = ( float )( int )a;
  446. SetFloatResult( a );
  447. }
  448. break;
  449. case MATERIAL_VAR_TYPE_INT:
  450. // don't do anything besides assignment!
  451. m_pResult->SetIntValue( m_pSrc1->GetIntValue() );
  452. break;
  453. }
  454. }
  455. EXPOSE_MATERIAL_PROXY( CIntProxy, Int );
  456. //-----------------------------------------------------------------------------
  457. // Linear ramp proxy
  458. //-----------------------------------------------------------------------------
  459. class CLinearRampProxy : public CResultProxy
  460. {
  461. public:
  462. virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
  463. virtual void OnBind( void *pC_BaseEntity );
  464. private:
  465. CFloatInput m_Rate;
  466. CFloatInput m_InitialValue;
  467. };
  468. bool CLinearRampProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
  469. {
  470. if (!CResultProxy::Init( pMaterial, pKeyValues ))
  471. return false;
  472. if (!m_Rate.Init( pMaterial, pKeyValues, "rate", 1 ))
  473. return false;
  474. if (!m_InitialValue.Init( pMaterial, pKeyValues, "initialValue", 0 ))
  475. return false;
  476. return true;
  477. }
  478. void CLinearRampProxy::OnBind( void *pC_BaseEntity )
  479. {
  480. Assert( m_pResult );
  481. float flValue;
  482. // get a value in [0,1]
  483. flValue = m_Rate.GetFloat() * gpGlobals->curtime + m_InitialValue.GetFloat();
  484. SetFloatResult( flValue );
  485. }
  486. EXPOSE_MATERIAL_PROXY( CLinearRampProxy, LinearRamp );
  487. //-----------------------------------------------------------------------------
  488. // Uniform noise proxy
  489. //-----------------------------------------------------------------------------
  490. class CUniformNoiseProxy : public CResultProxy
  491. {
  492. public:
  493. virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
  494. virtual void OnBind( void *pC_BaseEntity );
  495. private:
  496. CFloatInput m_flMinVal;
  497. CFloatInput m_flMaxVal;
  498. };
  499. bool CUniformNoiseProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
  500. {
  501. if (!CResultProxy::Init( pMaterial, pKeyValues ))
  502. return false;
  503. if (!m_flMinVal.Init( pMaterial, pKeyValues, "minVal", 0 ))
  504. return false;
  505. if (!m_flMaxVal.Init( pMaterial, pKeyValues, "maxVal", 1 ))
  506. return false;
  507. return true;
  508. }
  509. void CUniformNoiseProxy::OnBind( void *pC_BaseEntity )
  510. {
  511. SetFloatResult( random->RandomFloat( m_flMinVal.GetFloat(), m_flMaxVal.GetFloat() ) );
  512. }
  513. EXPOSE_MATERIAL_PROXY( CUniformNoiseProxy, UniformNoise );
  514. //-----------------------------------------------------------------------------
  515. // Gaussian noise proxy
  516. //-----------------------------------------------------------------------------
  517. class CGaussianNoiseProxy : public CResultProxy
  518. {
  519. public:
  520. virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
  521. virtual void OnBind( void *pC_BaseEntity );
  522. private:
  523. CFloatInput m_Mean;
  524. CFloatInput m_StdDev;
  525. CFloatInput m_flMinVal;
  526. CFloatInput m_flMaxVal;
  527. };
  528. bool CGaussianNoiseProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
  529. {
  530. if (!CResultProxy::Init( pMaterial, pKeyValues ))
  531. return false;
  532. if (!m_Mean.Init( pMaterial, pKeyValues, "mean", 0.0f ))
  533. return false;
  534. if (!m_StdDev.Init( pMaterial, pKeyValues, "halfwidth", 1.0f ))
  535. return false;
  536. if (!m_flMinVal.Init( pMaterial, pKeyValues, "minVal", -FLT_MAX ))
  537. return false;
  538. if (!m_flMaxVal.Init( pMaterial, pKeyValues, "maxVal", FLT_MAX ))
  539. return false;
  540. return true;
  541. }
  542. void CGaussianNoiseProxy::OnBind( void *pC_BaseEntity )
  543. {
  544. float flMean = m_Mean.GetFloat();
  545. float flStdDev = m_StdDev.GetFloat();
  546. float flVal = randomgaussian->RandomFloat( flMean, flStdDev );
  547. float flMaxVal = m_flMaxVal.GetFloat();
  548. float flMinVal = m_flMinVal.GetFloat();
  549. if (flMinVal > flMaxVal)
  550. {
  551. float flTemp = flMinVal;
  552. flMinVal = flMaxVal;
  553. flMaxVal = flTemp;
  554. }
  555. // clamp
  556. if (flVal < flMinVal)
  557. flVal = flMinVal;
  558. else if ( flVal > flMaxVal )
  559. flVal = flMaxVal;
  560. SetFloatResult( flVal );
  561. }
  562. EXPOSE_MATERIAL_PROXY( CGaussianNoiseProxy, GaussianNoise );
  563. //-----------------------------------------------------------------------------
  564. // Exponential proxy
  565. //-----------------------------------------------------------------------------
  566. class CExponentialProxy : public CFunctionProxy
  567. {
  568. public:
  569. virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
  570. virtual void OnBind( void *pC_BaseEntity );
  571. private:
  572. CFloatInput m_Scale;
  573. CFloatInput m_Offset;
  574. CFloatInput m_flMinVal;
  575. CFloatInput m_flMaxVal;
  576. };
  577. bool CExponentialProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
  578. {
  579. if (!CFunctionProxy::Init( pMaterial, pKeyValues ))
  580. return false;
  581. if (!m_Scale.Init( pMaterial, pKeyValues, "scale", 1.0f ))
  582. return false;
  583. if (!m_Offset.Init( pMaterial, pKeyValues, "offset", 0.0f ))
  584. return false;
  585. if (!m_flMinVal.Init( pMaterial, pKeyValues, "minVal", -FLT_MAX ))
  586. return false;
  587. if (!m_flMaxVal.Init( pMaterial, pKeyValues, "maxVal", FLT_MAX ))
  588. return false;
  589. return true;
  590. }
  591. void CExponentialProxy::OnBind( void *pC_BaseEntity )
  592. {
  593. float flVal = m_Scale.GetFloat() * exp(m_pSrc1->GetFloatValue( ) + m_Offset.GetFloat());
  594. float flMaxVal = m_flMaxVal.GetFloat();
  595. float flMinVal = m_flMinVal.GetFloat();
  596. if (flMinVal > flMaxVal)
  597. {
  598. float flTemp = flMinVal;
  599. flMinVal = flMaxVal;
  600. flMaxVal = flTemp;
  601. }
  602. // clamp
  603. if (flVal < flMinVal)
  604. flVal = flMinVal;
  605. else if ( flVal > flMaxVal )
  606. flVal = flMaxVal;
  607. SetFloatResult( flVal );
  608. }
  609. EXPOSE_MATERIAL_PROXY( CExponentialProxy, Exponential );
  610. //-----------------------------------------------------------------------------
  611. // Absolute value proxy
  612. //-----------------------------------------------------------------------------
  613. class CAbsProxy : public CFunctionProxy
  614. {
  615. public:
  616. virtual void OnBind( void *pC_BaseEntity );
  617. };
  618. void CAbsProxy::OnBind( void *pC_BaseEntity )
  619. {
  620. SetFloatResult( fabs(m_pSrc1->GetFloatValue( )) );
  621. }
  622. EXPOSE_MATERIAL_PROXY( CAbsProxy, Abs );
  623. //-----------------------------------------------------------------------------
  624. // Empty proxy-- used to comment out large proxy blocks
  625. //-----------------------------------------------------------------------------
  626. class CEmptyProxy : public IMaterialProxy
  627. {
  628. public:
  629. CEmptyProxy() {}
  630. virtual ~CEmptyProxy() {}
  631. virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues ) { return true; }
  632. virtual void OnBind( void *pC_BaseEntity ) {}
  633. virtual void Release( void ) { delete this; }
  634. virtual IMaterial *GetMaterial() { return NULL; }
  635. };
  636. EXPOSE_MATERIAL_PROXY( CEmptyProxy, Empty );
  637. //-----------------------------------------------------------------------------
  638. // Comparison proxy
  639. //-----------------------------------------------------------------------------
  640. class CLessOrEqualProxy : public CFunctionProxy
  641. {
  642. public:
  643. bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
  644. void OnBind( void *pC_BaseEntity );
  645. private:
  646. IMaterialVar *m_pLessVar;
  647. IMaterialVar *m_pGreaterVar;
  648. };
  649. bool CLessOrEqualProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
  650. {
  651. char const* pLessEqualVar = pKeyValues->GetString( "lessEqualVar" );
  652. if( !pLessEqualVar )
  653. return false;
  654. bool foundVar;
  655. m_pLessVar = pMaterial->FindVar( pLessEqualVar, &foundVar, true );
  656. if( !foundVar )
  657. return false;
  658. char const* pGreaterVar = pKeyValues->GetString( "greaterVar" );
  659. if( !pGreaterVar )
  660. return false;
  661. foundVar;
  662. m_pGreaterVar = pMaterial->FindVar( pGreaterVar, &foundVar, true );
  663. if( !foundVar )
  664. return false;
  665. // Compare 2 args..
  666. bool ok = CFunctionProxy::Init( pMaterial, pKeyValues );
  667. ok = ok && m_pSrc2;
  668. return ok;
  669. }
  670. void CLessOrEqualProxy::OnBind( void *pC_BaseEntity )
  671. {
  672. Assert( m_pSrc1 && m_pSrc2 && m_pLessVar && m_pGreaterVar && m_pResult );
  673. IMaterialVar *pSourceVar;
  674. if (m_pSrc1->GetFloatValue() <= m_pSrc2->GetFloatValue())
  675. {
  676. pSourceVar = m_pLessVar;
  677. }
  678. else
  679. {
  680. pSourceVar = m_pGreaterVar;
  681. }
  682. int vecSize = 0;
  683. MaterialVarType_t resultType = m_pResult->GetType();
  684. if (resultType == MATERIAL_VAR_TYPE_VECTOR)
  685. {
  686. if (m_ResultVecComp >= 0)
  687. resultType = MATERIAL_VAR_TYPE_FLOAT;
  688. vecSize = m_pResult->VectorSize();
  689. }
  690. else if (resultType == MATERIAL_VAR_TYPE_UNDEFINED)
  691. {
  692. resultType = pSourceVar->GetType();
  693. if (resultType == MATERIAL_VAR_TYPE_VECTOR)
  694. {
  695. vecSize = pSourceVar->VectorSize();
  696. }
  697. }
  698. switch( resultType )
  699. {
  700. case MATERIAL_VAR_TYPE_VECTOR:
  701. {
  702. Vector src;
  703. pSourceVar->GetVecValue( src.Base(), vecSize );
  704. m_pResult->SetVecValue( src.Base(), vecSize );
  705. }
  706. break;
  707. case MATERIAL_VAR_TYPE_FLOAT:
  708. SetFloatResult( pSourceVar->GetFloatValue() );
  709. break;
  710. case MATERIAL_VAR_TYPE_INT:
  711. m_pResult->SetFloatValue( pSourceVar->GetIntValue() );
  712. break;
  713. }
  714. }
  715. EXPOSE_MATERIAL_PROXY( CLessOrEqualProxy, LessOrEqual );
  716. //-----------------------------------------------------------------------------
  717. // WrapMinMax proxy
  718. //-----------------------------------------------------------------------------
  719. class CWrapMinMaxProxy : public CFunctionProxy
  720. {
  721. public:
  722. virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
  723. virtual void OnBind( void *pC_BaseEntity );
  724. private:
  725. CFloatInput m_flMinVal;
  726. CFloatInput m_flMaxVal;
  727. };
  728. bool CWrapMinMaxProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
  729. {
  730. if (!CFunctionProxy::Init( pMaterial, pKeyValues ))
  731. return false;
  732. if (!m_flMinVal.Init( pMaterial, pKeyValues, "minVal", 0 ))
  733. return false;
  734. if (!m_flMaxVal.Init( pMaterial, pKeyValues, "maxVal", 1 ))
  735. return false;
  736. return true;
  737. }
  738. void CWrapMinMaxProxy::OnBind( void *pC_BaseEntity )
  739. {
  740. Assert( m_pSrc1 && m_pResult );
  741. if ( m_flMaxVal.GetFloat() <= m_flMinVal.GetFloat() ) // Bad input, just return the min
  742. {
  743. SetFloatResult( m_flMinVal.GetFloat() );
  744. }
  745. else
  746. {
  747. float flResult = ( m_pSrc1->GetFloatValue() - m_flMinVal.GetFloat() ) / ( m_flMaxVal.GetFloat() - m_flMinVal.GetFloat() );
  748. if ( flResult >= 0.0f )
  749. {
  750. flResult -= ( float )( int )flResult;
  751. }
  752. else // Negative
  753. {
  754. flResult -= ( float )( ( ( int )flResult ) - 1 );
  755. }
  756. flResult *= ( m_flMaxVal.GetFloat() - m_flMinVal.GetFloat() );
  757. flResult += m_flMinVal.GetFloat();
  758. SetFloatResult( flResult );
  759. }
  760. }
  761. EXPOSE_MATERIAL_PROXY( CWrapMinMaxProxy, WrapMinMax );
  762. //-----------------------------------------------------------------------------
  763. // RemapValClamped
  764. //-----------------------------------------------------------------------------
  765. class CRemapValClampedProxy : public CFunctionProxy
  766. {
  767. public:
  768. bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
  769. void OnBind( void *pC_BaseEntity );
  770. private:
  771. CFloatInput m_RangeInMin;
  772. CFloatInput m_RangeInMax;
  773. CFloatInput m_RangeOutMin;
  774. CFloatInput m_RangeOutMax;
  775. };
  776. bool CRemapValClampedProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
  777. {
  778. if ( !CFunctionProxy::Init( pMaterial, pKeyValues ) )
  779. return false;
  780. if ( !m_RangeInMin.Init( pMaterial, pKeyValues, "range_in_min", 0 ) )
  781. return false;
  782. if ( !m_RangeInMax.Init( pMaterial, pKeyValues, "range_in_max", 1 ) )
  783. return false;
  784. if ( !m_RangeOutMin.Init( pMaterial, pKeyValues, "range_out_min", 0 ) )
  785. return false;
  786. if ( !m_RangeOutMax.Init( pMaterial, pKeyValues, "range_out_max", 1 ) )
  787. return false;
  788. return true;
  789. }
  790. void CRemapValClampedProxy::OnBind( void *pC_BaseEntity )
  791. {
  792. Assert( m_pSrc1 && m_pResult );
  793. MaterialVarType_t resultType;
  794. int vecSize;
  795. ComputeResultType( resultType, vecSize );
  796. float flInMin = m_RangeInMin.GetFloat();
  797. float flInMax = m_RangeInMax.GetFloat();
  798. float flOutMin = m_RangeOutMin.GetFloat();
  799. float flOutMax = m_RangeOutMax.GetFloat();
  800. switch ( resultType )
  801. {
  802. case MATERIAL_VAR_TYPE_FLOAT:
  803. {
  804. SetFloatResult( RemapValClamped( m_pSrc1->GetFloatValue(), flInMin, flInMax, flOutMin, flOutMax ) );
  805. }
  806. break;
  807. case MATERIAL_VAR_TYPE_INT:
  808. {
  809. m_pResult->SetIntValue( (int)RemapValClamped( m_pSrc1->GetIntValue(), flInMin, flInMax, flOutMin, flOutMax ) );
  810. }
  811. break;
  812. }
  813. }
  814. EXPOSE_MATERIAL_PROXY( CRemapValClampedProxy, RemapValClamp );