00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "wander.h"
00017
00018
00019
00020
00021
00022
00023
00024
00025 double rand_float() {
00026 const static double rand_max = 0x7fff;
00027 return ((rand()) / (rand_max + 1.0));
00028 }
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 double random_clamped() {
00039 return (rand_float() - rand_float());
00040 }
00041
00042 Wander::Wander(AICharacter *ai_ch, double wander_radius,int flag, double aoe, float wander_weight) {
00043 _ai_char = ai_ch;
00044 _wander_radius = wander_radius ;
00045 _wander_weight = wander_weight;
00046 double theta = rand_float() * 2 * 3.14159;
00047 double si = rand_float() * 3.14159;
00048 _flag = flag;
00049
00050 _area_of_effect = aoe;
00051 _init_pos = _ai_char->get_node_path().get_pos(_ai_char->get_char_render());
00052
00053
00054
00055
00056
00057
00058 switch(_flag) {
00059 case 0: {
00060 _wander_target = LVecBase3f(_wander_radius * cos(theta), _wander_radius * sin(theta),0);
00061 break;
00062 }
00063 case 1: {
00064 _wander_target = LVecBase3f(0, _wander_radius * cos(theta), _wander_radius * sin(theta));
00065 break;
00066 }
00067 case 2: {
00068 _wander_target = LVecBase3f(_wander_radius * cos(theta), 0, _wander_radius * sin(theta));
00069 break;
00070 }
00071 case 3: {
00072 _wander_target = LVecBase3f(_wander_radius * sin(theta) * cos(si), _wander_radius * sin(theta) * sin(si), _wander_radius * cos(theta));
00073 break;
00074 }
00075 default: {
00076 _wander_target = LVecBase3f(_wander_radius * cos(theta), _wander_radius * sin(theta),0);
00077 break;
00078 }
00079 }
00080 }
00081
00082 Wander::~Wander() {
00083 }
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 LVecBase3f Wander::do_wander() {
00095 LVecBase3f present_pos = _ai_char->get_node_path().get_pos(_ai_char->get_char_render());
00096
00097 double time_slice_1 = random_clamped() * 1.5;
00098 double time_slice_2 = random_clamped() * 1.5;
00099 double time_slice_3 = random_clamped() * 1.5;
00100 switch(_flag) {
00101 case 0: {
00102 _wander_target += LVecBase3f(time_slice_1, time_slice_2, 0);
00103 break;
00104 }
00105 case 1: {
00106 _wander_target += LVecBase3f(0, time_slice_1, time_slice_2);
00107 break;
00108 }
00109 case 2: {
00110 _wander_target += LVecBase3f(time_slice_1, 0, time_slice_2);
00111 break;
00112 }
00113 case 3: {
00114 _wander_target += LVecBase3f(time_slice_1, time_slice_2, time_slice_3);
00115 break;
00116 }
00117
00118 default: {
00119 _wander_target = LVecBase3f(time_slice_1, time_slice_2, 0);
00120 }
00121 }
00122 _wander_target.normalize();
00123 _wander_target *= _wander_radius;
00124 LVecBase3f target = _ai_char->get_char_render().get_relative_vector(_ai_char->get_node_path(), LVector3f::forward());
00125 target.normalize();
00126
00127 target = _wander_target + target;
00128 LVecBase3f desired_target = present_pos + target;
00129 LVecBase3f desired_force = desired_target - _ai_char->get_node_path().get_pos() ;
00130 desired_force.normalize();
00131 desired_force *= _ai_char->_movt_force;
00132 double distance = (present_pos - _init_pos).length();
00133 if(_area_of_effect > 0 && distance > _area_of_effect) {
00134 LVecBase3f direction = present_pos - _init_pos;
00135 direction.normalize();
00136 desired_force = - direction * _ai_char->_movt_force;
00137 LVecBase3f dirn = _ai_char->_steering->_steering_force;
00138 dirn.normalize();
00139 _ai_char->_steering->_steering_force = LVecBase3f(0.0, 0.0, 0.0);
00140 }
00141 return desired_force;
00142 }