Torque3D Documentation / _generateds / tResponseCurve.h

tResponseCurve.h

Engine/source/math/util/tResponseCurve.h

More...

Classes:

Detailed Description

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24// Notice:
 25// Some of this code originates from an article in AI Game Programming Wisdom 
 26// by Dave Mark.
 27
 28#ifndef _TRESPONSECURVE_H_
 29#define _TRESPONSECURVE_H_
 30
 31#ifndef _TVECTOR_H_
 32#include "core/util/tVector.h"
 33#endif
 34
 35#ifndef _MMATHFN_H_
 36#include "math/mMathFn.h"
 37#endif
 38
 39#ifndef _SIMOBJECT_H_
 40#include "console/simObject.h"
 41#endif
 42
 43
 44// -------------------------------
 45// Represents a sigmoid function
 46// Note: not used by ResponseCurve
 47// -------------------------------
 48
 49class Sigmoid
 50{
 51public:
 52   Sigmoid( F32 s, F32 m) { _s = s; _m = m; }
 53   ~Sigmoid() {};
 54   
 55   inline F32 get( F32 x )
 56   {
 57      F32 pow = -2.0f * ( ( x - _m ) / _s );
 58      F32 y = 1.0f / mPow( 1 + M_CONST_E_F, pow );
 59      return y;
 60   }
 61
 62   F32 _s;
 63   F32 _m;
 64};
 65
 66// -----------------------------------------------------------------------------
 67// Represents a response curve, can query values
 68// -----------------------------------------------------------------------------
 69
 70template< class T >
 71class ResponseCurve
 72{
 73public:
 74
 75   struct Sample
 76   {
 77      Sample() :mF(0) { dMemset(&mVal, 0, sizeof(mVal)); }
 78      Sample( F32 f, const T &val ) : mF(f), mVal(val) {}
 79
 80      F32 mF;
 81      T mVal;
 82   };
 83
 84   typedef Vector< Sample> SampleList;
 85   SampleList mSamples;
 86
 87   const SampleList& getSamples() { return mSamples; }
 88
 89   ResponseCurve() {}
 90   ResponseCurve( U32 numSamples ) { mSamples.reserve(numSamples); }
 91
 92   void clear() { mSamples.clear(); }
 93   void addPoint( F32 f, const T &val );
 94   //void addPoints( U32 count, F32 f[], const T &val[] );
 95   T getVal( F32 f ) const;
 96   S32 setPoint( S32 idx, F32 f, const T &val ); 
 97   void removePoint( S32 idx );
 98   S32 getSampleCount() const { return mSamples.size(); }
 99};
100
101//-----------------------------------------------------------------------------
102// Adds a new value to the Response Curve, at the position f
103//-----------------------------------------------------------------------------
104template< class T > 
105inline void ResponseCurve<T>::addPoint( F32 f, const T &val )
106{
107   typename SampleList::iterator iter = mSamples.begin();
108   for ( ; iter != mSamples.end(); iter++ )
109   {
110      if ( iter->mF == f )
111      {
112         Con::warnf( "Warn: ResponseCurve<T>::AddPoint, Duplicate values are not allowed." );
113         return;
114      }
115
116   if ( iter->mF > f )
117      break;
118   }
119
120   mSamples.insert( iter, Sample( f, val ) );
121}
122
123//-----------------------------------------------------------------------------
124// Finds the right value at position f, interpolating between the previous
125// and the following values
126//-----------------------------------------------------------------------------
127template< class T > 
128inline T ResponseCurve<T>::getVal( F32 f ) const
129{
130   T retVal;
131
132   if ( mSamples.empty() )
133   {
134      retVal = T();
135   }
136   else
137   {
138      U32 nSamples = mSamples.size();
139      if ( nSamples == 1 || f <= mSamples[0].mF )
140      {
141         retVal = mSamples[0].mVal;
142      }
143      else if ( f >= mSamples[nSamples-1].mF )
144      {
145         retVal = mSamples[nSamples-1].mVal;
146      }
147      else
148      {
149         U32 i = 1;
150         while ( i < (nSamples-1) && mSamples[i].mF < f )
151            ++i;
152
153         // Interpolate between m_Samples[i-1] and m_Samples[i]
154         F32 fSampleMin = mSamples[i-1].mF;
155         F32 fSampleMax = mSamples[i].mF;
156         AssertWarn(fSampleMin != fSampleMax, "fSampleMin should not equal fSampleMax" );
157
158         F32 t = (f - fSampleMin) / (fSampleMax - fSampleMin);
159         retVal = mSamples[i-1].mVal + ( mSamples[i].mVal - mSamples[i-1].mVal) * t;
160      }
161   }
162
163   return retVal;
164}
165
166template< class T > 
167inline S32 ResponseCurve< T >::setPoint( S32 idx, F32 f, const T &val )
168{   
169   mSamples.erase( idx );
170   
171   typename SampleList::iterator iter = mSamples.begin();
172   for ( ; iter != mSamples.end(); iter++ )
173   {
174      if ( iter->mF == f )
175      {
176         Con::warnf( "Warn: ResponseCurve<T>::AddPoint, Duplicate values are not allowed." );
177         return -1;
178      }
179
180   if ( iter->mF > f )
181      break;
182   }
183
184   mSamples.insert( iter, Sample( f, val ) );
185
186   return (S32)( iter - mSamples.begin() );
187}
188
189
190class FloatCurve : public ResponseCurve<F32>
191{
192public:
193   FloatCurve() {}   
194};
195
196
197// -----------------------------------------------
198// A ResponseCurve<F32> wrapped as a SimObject
199// -----------------------------------------------
200
201class SimResponseCurve : public SimObject
202{
203   typedef SimObject Parent;
204
205public:
206
207   SimResponseCurve();
208   //~SimResponseCurve();
209
210   DECLARE_CONOBJECT( SimResponseCurve );
211
212   virtual bool onAdd();
213   virtual void onRemove();
214
215   void addPoint( F32 value, F32 time );
216   F32 getValue( F32 time );
217   void clear();
218
219   ResponseCurve<F32> mCurve;
220};
221
222
223// A networked-datablock version of ResponseCurve
224/*
225class ResponseCurveData : public SimDataBlock
226{
227   typedef SimDataBlock Parent;
228
229public:
230
231   ResponseCurveData();
232   //~ResponseCurveData();
233
234   DECLARE_CONOBJECT( ResponseCurveData );
235
236   virtual bool onAdd();
237   virtual void onRemove();
238
239
240   void addPoint( F32 value, F32 time );
241   F32 getValue( F32 time );
242   void clear();
243
244   ResponseCurve<F32> mCurve;
245};
246*/
247
248#endif
249