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