00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 00014 00015 #include "wander.h" 00016 00021 00023 00024 double rand_float() { 00025 const static double rand_max = 0x7fff; 00026 return ((rand()) / (rand_max + 1.0)); 00027 } 00028 00034 00036 00037 double random_clamped() { 00038 return (rand_float() - rand_float()); 00039 } 00040 00041 Wander::Wander(AICharacter *ai_ch, double wander_radius, bool flag_3D, double aoe, float wander_weight) { 00042 _ai_char = ai_ch; 00043 _wander_radius = wander_radius ; 00044 _wander_weight = wander_weight; 00045 double theta = rand_float() * 2 * 3.14159; 00046 double si = rand_float() * 3.14159; 00047 _flag_3D = flag_3D; 00048 00049 _area_of_effect = aoe; 00050 _init_pos = _ai_char->get_node_path().get_pos(_ai_char->get_char_render()); 00051 00052 if(_flag_3D) { 00053 _wander_target = LVecBase3f(_wander_radius * sin(theta) * cos(si), _wander_radius * sin(theta) * sin(si), _wander_radius * cos(theta)); 00054 } 00055 else { 00056 _wander_target = LVecBase3f(_wander_radius * cos(theta), _wander_radius * sin(theta),0); 00057 } 00058 } 00059 00060 Wander::~Wander() { 00061 } 00062 00069 00071 00072 LVecBase3f Wander::do_wander() { 00073 LVecBase3f present_pos = _ai_char->get_node_path().get_pos(_ai_char->get_char_render()); 00074 00075 double time_slice_1 = random_clamped() * 1.5; 00076 double time_slice_2 = random_clamped() * 1.5; 00077 double time_slice_3 = random_clamped() * 1.5; 00078 switch(_flag_3D) { 00079 case 1: 00080 _wander_target = LVecBase3f(time_slice_1, time_slice_2, time_slice_3); 00081 break; 00082 00083 default : 00084 _wander_target = LVecBase3f(time_slice_1, time_slice_2, 0); 00085 } 00086 _wander_target.normalize(); 00087 _wander_target *= _wander_radius; 00088 LVecBase3f target = _ai_char->get_char_render().get_relative_vector(_ai_char->get_node_path(), LVector3f::forward()); 00089 target.normalize(); 00090 target = _wander_target + target; 00091 LVecBase3f desired_target = present_pos + target; 00092 LVecBase3f desired_force = desired_target -_ai_char->get_node_path().get_pos() ; 00093 desired_force.normalize(); 00094 00095 desired_force *= _ai_char->_movt_force; 00096 00097 double distance = (present_pos - _init_pos).length(); 00098 00099 if(_area_of_effect > 0 && distance > _area_of_effect) { 00100 LVecBase3f direction = present_pos - _init_pos; 00101 direction.normalize(); 00102 desired_force = -direction * _ai_char->_movt_force; 00103 LVecBase3f dirn = _ai_char->_steering->_steering_force; 00104 dirn.normalize(); 00105 _ai_char->_steering->_steering_force = LVecBase3f(0.0, 0.0, 0.0); 00106 } 00107 00108 return desired_force; 00109 } 00110