00001 #ifndef GROW_WITH_AGE_OPERATOR
00002 #define GROW_WITH_AGE_OPERATOR
00003
00004 #include <vector>
00005 #include <gmtl/Vec.h>
00006 #include <gmtl/VecOps.h>
00007
00008 namespace ani
00009 {
00010 // change size as it grows older
00011 template<class __EntityType>
00012 class GrowWithAgeOperator : public ani::Operator<__EntityType>
00013 {
00014 public:
00015 typedef boost::shared_ptr<__EntityType> EntityTypePtr;
00016
00017 public:
00018 GrowWithAgeOperator() : ani::Operator<__EntityType>()
00019 {
00020 mSizeTransitions.push_back( 1.0f );
00021 mSizeTransitions.push_back( 0.75f );
00022 mSizeTransitions.push_back( 0.50f );
00023 mSizeTransitions.push_back( 0.0f );
00024 }
00025 virtual ~GrowWithAgeOperator() {}
00026 void setVolumes( std::vector<float> sizeTransitions ) { mSizeTransitions = sizeTransitions; }
00027 virtual void exec( DynamicSystem<__EntityType>& ps, float timeDelta );
00028
00029 std::vector<float> mSizeTransitions;
00030 };
00031
00032 template <class __EntityType>
00033 void GrowWithAgeOperator<__EntityType>::exec( DynamicSystem<__EntityType>& ps, float timeDelta )
00034 {
00035 std::vector<EntityTypePtr>::iterator it;
00036 for (it = ps.entities().begin(); it != ps.entities().end(); ++it)
00037 {
00038 EntityTypePtr p = *it;
00039 float age__zero_to_one = p->age() / p->ageOfDeath();
00040
00041 // find the range that we'll examine... range = {0...(size-1)} so that we can always check i and i+1
00042 // NOTE: range will at least be 0, since size >= 1
00043 assert( mSizeTransitions.size() > 0 && "to use this operator, you must define some colors" );
00044 float range = (float)mSizeTransitions.size() - 1.0f;
00045
00046 // the indices of the two colors to interpolate between
00047 float indexf = age__zero_to_one * range;
00048 int index = (int)indexf;
00049 int next_index = ((index+1) != (int)mSizeTransitions.size()) ? index+1 : (mSizeTransitions.size() - 1);
00050 assert( index >= 0 && next_index < (int)mSizeTransitions.size() && "out of bounds" );
00051
00052 // find the value to interpolate this color with the next color (should be 0..1)
00053 float val = indexf - (float)index;
00054
00055 float result;
00056 gmtl::Math::lerp( result, val, mSizeTransitions[index], mSizeTransitions[index+1] );
00057
00058 p->setVolume( gmtl::Vec3f( result, result, result ) );
00059 }
00060 }
00061
00062 } // end namespace
00063
00064 #endif
1.2.15