sfxCommon.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #ifndef _SFXCOMMON_H_
  23. #define _SFXCOMMON_H_
  24. #ifndef _PLATFORM_H_
  25. #include "platform/platform.h"
  26. #endif
  27. #ifndef _MMATHFN_H_
  28. #include "math/mMathFn.h"
  29. #endif
  30. #ifndef _MRANDOM_H_
  31. #include "math/mRandom.h"
  32. #endif
  33. #ifndef _MMATRIX_H_
  34. #include "math/mMatrix.h"
  35. #endif
  36. #ifndef _MPOINT3_H_
  37. #include "math/mPoint3.h"
  38. #endif
  39. #ifndef _TYPETRAITS_H_
  40. #include "platform/typetraits.h"
  41. #endif
  42. #ifndef _DYNAMIC_CONSOLETYPES_H_
  43. #include "console/dynamicTypes.h"
  44. #endif
  45. class SFXEnvironment;
  46. class SFXPlayList;
  47. //-----------------------------------------------------------------------------
  48. // SFXStatus.
  49. //-----------------------------------------------------------------------------
  50. /// The sound playback state.
  51. enum SFXStatus
  52. {
  53. /// Initial state; no operation yet performed on sound.
  54. SFXStatusNull,
  55. /// Sound is playing.
  56. SFXStatusPlaying,
  57. /// Sound has been stopped.
  58. SFXStatusStopped,
  59. /// Sound is paused.
  60. SFXStatusPaused,
  61. /// Sound stream is starved and playback blocked.
  62. SFXStatusBlocked,
  63. /// Temporary state while transitioning to another state. This is used when multiple
  64. /// threads concurrently maintain a status and need to perform a sequence of actions before
  65. /// being able to fully go from a previous to a new current state. In this case, the
  66. /// transition state marks the status as being under update on another thread.
  67. ///
  68. /// @note Not all places that use SFXStatus actually use this state.
  69. SFXStatusTransition,
  70. };
  71. DefineEnumType( SFXStatus );
  72. inline const char* SFXStatusToString( SFXStatus status )
  73. {
  74. switch ( status )
  75. {
  76. case SFXStatusPlaying: return "playing";
  77. case SFXStatusStopped: return "stopped";
  78. case SFXStatusPaused: return "paused";
  79. case SFXStatusBlocked: return "blocked";
  80. case SFXStatusTransition: return "transition";
  81. case SFXStatusNull:
  82. default: ;
  83. }
  84. return "null";
  85. }
  86. //-----------------------------------------------------------------------------
  87. // SFXChannel.
  88. //-----------------------------------------------------------------------------
  89. /// Animatable channels in the SFX system.
  90. enum SFXChannel
  91. {
  92. SFXChannelVolume,
  93. SFXChannelPitch,
  94. SFXChannelPriority,
  95. SFXChannelPositionX,
  96. SFXChannelPositionY,
  97. SFXChannelPositionZ,
  98. SFXChannelRotationX,
  99. SFXChannelRotationY,
  100. SFXChannelRotationZ,
  101. SFXChannelVelocityX,
  102. SFXChannelVelocityY,
  103. SFXChannelVelocityZ,
  104. SFXChannelMinDistance,
  105. SFXChannelMaxDistance,
  106. SFXChannelConeInsideAngle,
  107. SFXChannelConeOutsideAngle,
  108. SFXChannelConeOutsideVolume,
  109. SFXChannelCursor,
  110. SFXChannelStatus,
  111. SFXChannelUser0,
  112. SFXChannelUser1,
  113. SFXChannelUser2,
  114. SFXChannelUser3,
  115. /// Total number of animatable channels.
  116. SFX_NUM_CHANNELS
  117. };
  118. DefineEnumType( SFXChannel );
  119. //-----------------------------------------------------------------------------
  120. // SFXDistanceModel.
  121. //-----------------------------------------------------------------------------
  122. /// Rolloff curve used for distance volume attenuation of 3D sounds.
  123. enum SFXDistanceModel
  124. {
  125. SFXDistanceModelLinear, ///< Volume decreases linearly from min to max where it reaches zero.
  126. SFXDistanceModelLogarithmic, ///< Volume halves every min distance steps starting from min distance; attenuation stops at max distance.
  127. SFXDistanceModelExponent, /// exponential falloff for distance attenuation.
  128. };
  129. DefineEnumType( SFXDistanceModel );
  130. /// Compute the distance attenuation based on the given distance model.
  131. ///
  132. /// @param minDistance Reference distance; attenuation starts here.
  133. /// @param maxDistance
  134. /// @param distance Actual distance of sound from listener.
  135. /// @param volume Unattenuated volume.
  136. /// @param rolloffFactor Rolloff curve scale factor.
  137. ///
  138. /// @return The attenuated volume.
  139. inline F32 SFXDistanceAttenuation( SFXDistanceModel model, F32 minDistance, F32 maxDistance, F32 distance, F32 volume, F32 rolloffFactor )
  140. {
  141. F32 gain = 1.0f;
  142. switch( model )
  143. {
  144. case SFXDistanceModelLinear:
  145. distance = getMax( distance, minDistance );
  146. distance = getMin( distance, maxDistance );
  147. gain = ( 1 - ( distance - minDistance ) / ( maxDistance - minDistance ) );
  148. break;
  149. case SFXDistanceModelLogarithmic:
  150. distance = getMax( distance, minDistance );
  151. distance = getMin( distance, maxDistance );
  152. gain = minDistance / ( minDistance + rolloffFactor * ( distance - minDistance ) );
  153. break;
  154. ///create exponential distance model
  155. case SFXDistanceModelExponent:
  156. distance = getMax(distance, minDistance);
  157. distance = getMin(distance, maxDistance);
  158. gain = pow((distance / minDistance), (-rolloffFactor));
  159. break;
  160. }
  161. return ( volume * gain );
  162. }
  163. //-----------------------------------------------------------------------------
  164. // SFXFormat.
  165. //-----------------------------------------------------------------------------
  166. /// This class defines the various types of sound data that may be
  167. /// used in the sound system.
  168. ///
  169. /// Unlike with most sound APIs, we consider each sample point to comprise
  170. /// all channels in a sound stream rather than only one value for a single
  171. /// channel.
  172. class SFXFormat
  173. {
  174. protected:
  175. /// The number of sound channels in the data.
  176. U8 mChannels;
  177. /// The number of bits per sound sample.
  178. U8 mBitsPerSample;
  179. /// The frequency in samples per second.
  180. U32 mSamplesPerSecond;
  181. public:
  182. SFXFormat( U8 channels = 0,
  183. U8 bitsPerSample = 0,
  184. U32 samplesPerSecond = 0 )
  185. : mChannels( channels ),
  186. mBitsPerSample( bitsPerSample ),
  187. mSamplesPerSecond( samplesPerSecond )
  188. {}
  189. /// Copy constructor.
  190. SFXFormat( const SFXFormat &format )
  191. : mChannels( format.mChannels ),
  192. mBitsPerSample( format.mBitsPerSample ),
  193. mSamplesPerSecond( format.mSamplesPerSecond )
  194. {}
  195. public:
  196. /// Sets the format.
  197. void set( U8 channels,
  198. U8 bitsPerSample,
  199. U32 samplesPerSecond )
  200. {
  201. mChannels = channels;
  202. mBitsPerSample = bitsPerSample;
  203. mSamplesPerSecond = samplesPerSecond;
  204. }
  205. /// Comparision between formats.
  206. bool operator == ( const SFXFormat& format ) const
  207. {
  208. return mChannels == format.mChannels &&
  209. mBitsPerSample == format.mBitsPerSample &&
  210. mSamplesPerSecond == format.mSamplesPerSecond;
  211. }
  212. /// Returns the number of sound channels.
  213. U8 getChannels() const { return mChannels; }
  214. /// Returns true if there is a single sound channel.
  215. bool isMono() const { return mChannels == 1; }
  216. /// Is true if there are two sound channels.
  217. bool isStereo() const { return mChannels == 2; }
  218. /// Is true if there are more than two sound channels.
  219. bool isMultiChannel() const { return mChannels > 2; }
  220. ///
  221. U32 getSamplesPerSecond() const { return mSamplesPerSecond; }
  222. /// The bits of data per channel.
  223. U8 getBitsPerChannel() const { return mBitsPerSample / mChannels; }
  224. /// The number of bytes of data per channel.
  225. U8 getBytesPerChannel() const { return getBitsPerChannel() / 8; }
  226. /// The number of bits per sound sample.
  227. U8 getBitsPerSample() const { return mBitsPerSample; }
  228. /// The number of bytes of data per sample.
  229. /// @note Be aware that this comprises all channels.
  230. U8 getBytesPerSample() const { return mBitsPerSample / 8; }
  231. /// Returns the duration from the sample count.
  232. U32 getDuration( U32 samples ) const
  233. {
  234. // Use 64bit types to avoid overflow during division.
  235. return ( (U64)samples * (U64)1000 ) / (U64)mSamplesPerSecond;
  236. }
  237. ///
  238. U32 getSampleCount( U32 ms ) const
  239. {
  240. return U64( mSamplesPerSecond ) * U64( ms ) / U64( 1000 );
  241. }
  242. /// Returns the data length in bytes.
  243. U32 getDataLength( U32 ms ) const
  244. {
  245. U32 bytes = ( ( (U64)ms * (U64)mSamplesPerSecond ) * (U64)getBytesPerSample() ) / (U64)1000;
  246. return bytes;
  247. }
  248. };
  249. //-----------------------------------------------------------------------------
  250. // SFXReverb.
  251. //-----------------------------------------------------------------------------
  252. /// Reverb environment properties.
  253. ///
  254. /// @note A given device may not implement all properties.
  255. ///restructure our reverbproperties to match openal
  256. class SFXReverbProperties
  257. {
  258. public:
  259. struct Parent;
  260. float flDensity;
  261. float flDiffusion;
  262. float flGain;
  263. float flGainHF;
  264. float flGainLF;
  265. float flDecayTime;
  266. float flDecayHFRatio;
  267. float flDecayLFRatio;
  268. float flReflectionsGain;
  269. float flReflectionsDelay;
  270. float flReflectionsPan[3];
  271. float flLateReverbGain;
  272. float flLateReverbDelay;
  273. float flLateReverbPan[3];
  274. float flEchoTime;
  275. float flEchoDepth;
  276. float flModulationTime;
  277. float flModulationDepth;
  278. float flAirAbsorptionGainHF;
  279. float flHFReference;
  280. float flLFReference;
  281. float flRoomRolloffFactor;
  282. int iDecayHFLimit;
  283. ///set our defaults to be the same as no reverb otherwise our reverb
  284. ///effects menu sounds
  285. SFXReverbProperties()
  286. {
  287. flDensity = 0.0f;
  288. flDiffusion = 0.0f;
  289. flGain = 0.0f;
  290. flGainHF = 0.0f;
  291. flGainLF = 0.0000f;
  292. flDecayTime = 0.0f;
  293. flDecayHFRatio = 0.0f;
  294. flDecayLFRatio = 0.0f;
  295. flReflectionsGain = 0.0f;
  296. flReflectionsDelay = 0.0f;
  297. dMemset(flReflectionsPan, 0, sizeof(flReflectionsPan));
  298. flLateReverbGain = 0.0f;
  299. flLateReverbDelay = 0.0f;
  300. dMemset(flLateReverbPan, 0, sizeof(flLateReverbPan));
  301. flEchoTime = 0.0f;
  302. flEchoDepth = 0.0f;
  303. flModulationTime = 0.0f;
  304. flModulationDepth = 0.0f;
  305. flAirAbsorptionGainHF = 0.0f;
  306. flHFReference = 0.0f;
  307. flLFReference = 0.0f;
  308. flRoomRolloffFactor = 0.0f;
  309. iDecayHFLimit = 0;
  310. }
  311. void validate()
  312. {
  313. flDensity = mClampF(flDensity, 0.0f, 1.0f);
  314. flDiffusion = mClampF(flDiffusion, 0.0f, 1.0f);
  315. flGain = mClampF(flGain, 0.0f, 1.0f);
  316. flGainHF = mClampF(flGainHF, 0.0f, 1.0f);
  317. flGainLF = mClampF(flGainLF, 0.0f, 1.0f);
  318. flDecayTime = mClampF(flDecayTime, 0.1f, 20.0f);
  319. flDecayHFRatio = mClampF(flDecayHFRatio, 0.1f, 2.0f);
  320. flDecayLFRatio = mClampF(flDecayLFRatio, 0.1f, 2.0f);
  321. flReflectionsGain = mClampF(flReflectionsGain, 0.0f, 3.16f);
  322. flReflectionsDelay = mClampF(flReflectionsDelay, 0.0f, 0.3f);
  323. flReflectionsPan[0] = mClampF(flReflectionsPan[0], -1.0f, 1.0f);
  324. flReflectionsPan[1] = mClampF(flReflectionsPan[1], -1.0f, 1.0f);
  325. flReflectionsPan[2] = mClampF(flReflectionsPan[2], -1.0f, 1.0f);
  326. flLateReverbGain = mClampF(flLateReverbGain, 0.0f, 10.0f);
  327. flLateReverbDelay = mClampF(flLateReverbDelay, 0.0f, 0.1f);
  328. flLateReverbPan[0] = mClampF(flLateReverbPan[0], -1.0f, 1.0f);
  329. flLateReverbPan[1] = mClampF(flLateReverbPan[1], -1.0f, 1.0f);
  330. flLateReverbPan[2] = mClampF(flLateReverbPan[2], -1.0f, 1.0f);
  331. flEchoTime = mClampF(flEchoTime, 0.075f, 0.25f);
  332. flEchoDepth = mClampF(flEchoDepth, 0.0f, 1.0f);
  333. flModulationTime = mClampF(flModulationTime, 0.04f, 4.0f);
  334. flModulationDepth = mClampF(flModulationDepth, 0.0f, 1.0f);
  335. flAirAbsorptionGainHF = mClampF(flAirAbsorptionGainHF, 0.892f, 1.0f);
  336. flHFReference = mClampF(flHFReference, 1000.0f, 20000.0f);
  337. flLFReference = mClampF(flLFReference, 20.0f, 1000.0f);
  338. flRoomRolloffFactor = mClampF(flRoomRolloffFactor, 0.0f, 10.0f);
  339. iDecayHFLimit = mClampF(iDecayHFLimit, 0, 1);
  340. }
  341. };
  342. //-----------------------------------------------------------------------------
  343. // SFXSoundReverbProperties.
  344. //-----------------------------------------------------------------------------
  345. /// Sound reverb properties.
  346. ///
  347. /// @note A given SFX device may not implement all properties.
  348. ///not in use by openal yet if u are going to use ambient reverb zones its
  349. ///probably best to not have reverb on the sound effect itself.
  350. class SFXSoundReverbProperties
  351. {
  352. public:
  353. typedef void Parent;
  354. float flDensity;
  355. float flDiffusion;
  356. float flGain;
  357. float flGainHF;
  358. float flGainLF;
  359. float flDecayTime;
  360. float flDecayHFRatio;
  361. float flDecayLFRatio;
  362. float flReflectionsGain;
  363. float flReflectionsDelay;
  364. float flReflectionsPan[3];
  365. float flLateReverbGain;
  366. float flLateReverbDelay;
  367. float flLateReverbPan[3];
  368. float flEchoTime;
  369. float flEchoDepth;
  370. float flModulationTime;
  371. float flModulationDepth;
  372. float flAirAbsorptionGainHF;
  373. float flHFReference;
  374. float flLFReference;
  375. float flRoomRolloffFactor;
  376. int iDecayHFLimit;
  377. ///Set our defaults to have no reverb
  378. ///if you are going to use zone reverbs its
  379. ///probably best not to use per-voice reverb
  380. SFXSoundReverbProperties()
  381. {
  382. flDensity = 0.0f;
  383. flDiffusion = 0.0f;
  384. flGain = 0.0f;
  385. flGainHF = 0.0f;
  386. flGainLF = 0.0000f;
  387. flDecayTime = 0.0f;
  388. flDecayHFRatio = 0.0f;
  389. flDecayLFRatio = 0.0f;
  390. flReflectionsGain = 0.0f;
  391. flReflectionsDelay = 0.0f;
  392. dMemset(flReflectionsPan, 0, sizeof(flReflectionsPan));
  393. flLateReverbGain = 0.0f;
  394. flLateReverbDelay = 0.0f;
  395. dMemset(flLateReverbPan, 0, sizeof(flLateReverbPan));
  396. flEchoTime = 0.0f;
  397. flEchoDepth = 0.0f;
  398. flModulationTime = 0.0f;
  399. flModulationDepth = 0.0f;
  400. flAirAbsorptionGainHF = 0.0f;
  401. flHFReference = 0.0f;
  402. flLFReference = 0.0f;
  403. flRoomRolloffFactor = 0.0f;
  404. iDecayHFLimit = 0;
  405. }
  406. void validate()
  407. {
  408. flDensity = mClampF(flDensity, 0.0f, 1.0f);
  409. flDiffusion = mClampF(flDiffusion, 0.0f, 1.0f);
  410. flGain = mClampF(flGain, 0.0f, 1.0f);
  411. flGainHF = mClampF(flGainHF, 0.0f, 1.0f);
  412. flGainLF = mClampF(flGainLF, 0.0f, 1.0f);
  413. flDecayTime = mClampF(flDecayTime, 0.1f, 20.0f);
  414. flDecayHFRatio = mClampF(flDecayHFRatio, 0.1f, 2.0f);
  415. flDecayLFRatio = mClampF(flDecayLFRatio, 0.1f, 2.0f);
  416. flReflectionsGain = mClampF(flReflectionsGain, 0.0f, 3.16f);
  417. flReflectionsDelay = mClampF(flReflectionsDelay, 0.0f, 0.3f);
  418. flReflectionsPan[0] = mClampF(flReflectionsPan[0], -1.0f, 1.0f);
  419. flReflectionsPan[1] = mClampF(flReflectionsPan[1], -1.0f, 1.0f);
  420. flReflectionsPan[2] = mClampF(flReflectionsPan[2], -1.0f, 1.0f);
  421. flLateReverbGain = mClampF(flLateReverbGain, 0.0f, 10.0f);
  422. flLateReverbDelay = mClampF(flLateReverbDelay, 0.0f, 0.1f);
  423. flLateReverbPan[0] = mClampF(flLateReverbPan[0], -1.0f, 1.0f);
  424. flLateReverbPan[1] = mClampF(flLateReverbPan[1], -1.0f, 1.0f);
  425. flLateReverbPan[2] = mClampF(flLateReverbPan[2], -1.0f, 1.0f);
  426. flEchoTime = mClampF(flEchoTime, 0.075f, 0.25f);
  427. flEchoDepth = mClampF(flEchoDepth, 0.0f, 1.0f);
  428. flModulationTime = mClampF(flModulationTime, 0.04f, 4.0f);
  429. flModulationDepth = mClampF(flModulationDepth, 0.0f, 1.0f);
  430. flAirAbsorptionGainHF = mClampF(flAirAbsorptionGainHF, 0.892f, 1.0f);
  431. flHFReference = mClampF(flHFReference, 1000.0f, 20000.0f);
  432. flLFReference = mClampF(flLFReference, 20.0f, 1000.0f);
  433. flRoomRolloffFactor = mClampF(flRoomRolloffFactor, 0.0f, 10.0f);
  434. iDecayHFLimit = mClampF(iDecayHFLimit, 0, 1);
  435. }
  436. };
  437. //-----------------------------------------------------------------------------
  438. // SFXListenerProperties.
  439. //-----------------------------------------------------------------------------
  440. ///
  441. class SFXListenerProperties
  442. {
  443. public:
  444. typedef void Parent;
  445. /// Position and orientation of the listener.
  446. MatrixF mTransform;
  447. ///
  448. Point3F mVelocity;
  449. SFXListenerProperties()
  450. : mTransform( true ),
  451. mVelocity( 0.0f, 0.0f, 0.0f ) {}
  452. SFXListenerProperties( const MatrixF& transform, const Point3F& velocity )
  453. : mTransform( transform ),
  454. mVelocity( velocity ) {}
  455. ///
  456. const MatrixF& getTransform() const { return mTransform; }
  457. MatrixF& getTransform() { return mTransform; }
  458. ///
  459. const Point3F& getVelocity() const { return mVelocity; }
  460. Point3F& getVelocity() { return mVelocity; }
  461. };
  462. //-----------------------------------------------------------------------------
  463. // SFXMaterialProperties.
  464. //-----------------------------------------------------------------------------
  465. ///
  466. class SFXMaterialProperties
  467. {
  468. public:
  469. typedef void Parent;
  470. ///
  471. bool mDoubleSided;
  472. ///
  473. F32 mDirectOcclusion;
  474. ///
  475. F32 mReverbOcclusion;
  476. SFXMaterialProperties()
  477. : mDoubleSided( false ),
  478. mDirectOcclusion( 0.5f ),
  479. mReverbOcclusion( 0.5f ) {}
  480. void validate()
  481. {
  482. mDirectOcclusion = mClampF( mDirectOcclusion, 0.0f, 1.0f );
  483. mReverbOcclusion = mClampF( mReverbOcclusion, 0.0f, 1.0f );
  484. }
  485. };
  486. //-----------------------------------------------------------------------------
  487. // SFXVariantFloat.
  488. //-----------------------------------------------------------------------------
  489. /// An array of float values with optional random variances.
  490. template< S32 NUM_VALUES >
  491. struct SFXVariantFloat
  492. {
  493. /// Base value.
  494. F32 mValue[ NUM_VALUES ];
  495. /// Variance of value. Final value will be
  496. ///
  497. /// mClampF( randF( mValue + mVariance[ 0 ], mValue + mVariance[ 1 ] ), min, max )
  498. ///
  499. /// with min and max being dependent on the context of the value.
  500. F32 mVariance[ NUM_VALUES ][ 2 ];
  501. F32 getValue( U32 index = 0, F32 min = TypeTraits< F32 >::MIN, F32 max = TypeTraits< F32 >::MAX ) const
  502. {
  503. AssertFatal( index < NUM_VALUES, "SFXVariantFloat::getValue() - index out of range!" );
  504. return mClampF( gRandGen.randF( mValue[ index ] + mVariance[ index ][ 0 ],
  505. mValue[ index ] + mVariance[ index ][ 1 ] ),
  506. min, max );
  507. }
  508. void validate()
  509. {
  510. for( U32 i = 0; i < NUM_VALUES; ++ i )
  511. mVariance[ i ][ 0 ] = getMin( mVariance[ i ][ 0 ], mVariance[ i ][ 1 ] );
  512. }
  513. };
  514. #endif // _SFXCOMMON_H_