xsi_random.h
Go to the documentation of this file.
00001 //*****************************************************************************
00011 //*****************************************************************************
00012 
00013 #if (_MSC_VER > 1000) || defined(SGI_COMPILER)
00014 #pragma once
00015 #endif
00016 
00017 #ifndef __XSIRANDOM_H__
00018 #define __XSIRANDOM_H__
00019 
00020 #include "sicppsdk.h"
00021 #include <math.h>
00022 
00023 namespace XSI {
00024 
00025 namespace MATH {
00026 
00027 //*****************************************************************************
00036 //*****************************************************************************
00037 class SICPPSDKDECL CRandom
00038 {
00039     public:
00042     SICPPSDK_INLINE CRandom();
00043 
00047     SICPPSDK_INLINE CRandom( LONG in_nSeed );
00048 
00053     SICPPSDK_INLINE CRandom( const CRandom& in_random );
00054 
00056     ~CRandom() {}
00057 
00061     SICPPSDK_INLINE void PutSeed( LONG in_nSeed );
00062 
00066     SICPPSDK_INLINE LONG GetValue() const;
00067 
00071     SICPPSDK_INLINE float GetNormalizedValue() const;
00072 
00076     SICPPSDK_INLINE operator LONG () const;
00077 
00081     void PutIndex( ULONG in_nIndex );
00082 
00086     SICPPSDK_INLINE LONG operator++();
00087 
00091     SICPPSDK_INLINE LONG operator++(int);
00092 
00096     SICPPSDK_INLINE LONG operator--();
00097 
00101     SICPPSDK_INLINE LONG operator--(int);
00102 
00106     SICPPSDK_INLINE void Skip( ULONG in_nOffset );
00107 
00108     private:
00109     void Init( LONG in_nSeed, short in_nState, ULONG in_nStartIndex );
00110     LONG GetValue( LONG in_nIndex ) const;
00111     LONG GetNext( LONG in_nPrev );
00112     LONG GetPrevious( LONG in_nNext );
00113     static LONG Skip( LONG in_nValue, ULONG in_nOffset );
00114 
00115     static ULONG Map( LONG in_nUnmapped );
00116     static LONG Unmap( ULONG in_nMapped );
00117 
00118     mutable enum State
00119     {
00120         HAVE_NONE,
00121         HAVE_INDEX,
00122         HAVE_INDEX_AND_RND
00123     } m_eState;
00124 
00125     LONG m_nSeed;
00126     ULONG m_nIndex;
00127     mutable LONG m_nRnd;
00128 };
00129 
00130 SICPPSDK_INLINE CRandom::CRandom()
00131 {
00132     Init( 0, HAVE_NONE, 0 );
00133 }
00134 
00135 SICPPSDK_INLINE CRandom::CRandom( LONG in_nSeed )
00136 {
00137     Init( in_nSeed, HAVE_NONE, 0 );
00138 }
00139 
00140 SICPPSDK_INLINE CRandom::CRandom( const CRandom& in_random )
00141 {
00142     m_nSeed = in_random.m_nSeed;
00143     m_eState = in_random.m_eState;
00144     m_nIndex = in_random.m_nIndex;
00145     m_nRnd = in_random.m_nRnd;
00146 }
00147 
00148 SICPPSDK_INLINE void CRandom::PutSeed( LONG in_nSeed )
00149 {
00150     m_nSeed = Map( 0 );
00151     PutIndex( in_nSeed + 12345 );
00152     m_nSeed = Map( GetValue() );
00153 }
00154 
00155 SICPPSDK_INLINE LONG CRandom::GetValue() const
00156 {
00157     if ( m_eState < HAVE_INDEX_AND_RND )
00158     {
00159         m_nRnd = GetValue( m_nIndex );
00160         m_eState = HAVE_INDEX_AND_RND;
00161     }
00162     return m_nRnd;
00163 }
00164 
00165 SICPPSDK_INLINE float CRandom::GetNormalizedValue() const
00166 {
00167     return (GetValue()/(float)(1<<30));
00168 }
00169 
00170 SICPPSDK_INLINE CRandom::operator LONG () const
00171 {
00172     return GetValue();
00173 }
00174 
00175 SICPPSDK_INLINE LONG CRandom::operator++()
00176 {
00177     ++m_nIndex;
00178     if ( m_eState >= HAVE_INDEX_AND_RND )
00179     {
00180         return m_nRnd = GetNext( m_nRnd );
00181     }
00182     return GetValue();
00183 }
00184 
00185 SICPPSDK_INLINE LONG CRandom::operator++(int)
00186 {
00187     ++m_nIndex;
00188     int nTmp = GetValue();
00189     m_nRnd = GetNext( m_nRnd );
00190     return nTmp;
00191 }
00192 
00193 SICPPSDK_INLINE LONG CRandom::operator--()
00194 {
00195     --m_nIndex;
00196     if ( m_eState >= HAVE_INDEX_AND_RND )
00197     {
00198         return m_nRnd = GetPrevious( m_nRnd );
00199     }
00200 
00201     return GetValue();
00202 }
00203 
00204 SICPPSDK_INLINE LONG CRandom::operator--(int)
00205 {
00206     --m_nIndex;
00207     LONG nTmp = GetValue();
00208     m_nRnd = GetPrevious( m_nRnd );
00209     return nTmp;
00210 }
00211 
00212 SICPPSDK_INLINE void CRandom::Skip( ULONG in_nOffset )
00213 {
00214     PutIndex( m_nIndex + in_nOffset );
00215 }
00216 
00217 };
00218 };
00219 
00220 #endif // __XSIRANDOM_H__