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