Panda3D
|
00001 //////////////////////////////////////////////////////////////////////// 00002 // Filename : wander.cxx 00003 // Created by : Deepak, John, Navin 00004 // Date : 24 Oct 09 00005 //////////////////////////////////////////////////////////////////// 00006 // 00007 // PANDA 3D SOFTWARE 00008 // Copyright (c) Carnegie Mellon University. All rights reserved. 00009 // 00010 // All use of this software is subject to the terms of the revised BSD 00011 // license. You should have received a copy of this license along 00012 // with this source code in a file named "LICENSE." 00013 // 00014 //////////////////////////////////////////////////////////////////// 00015 00016 #include "wander.h" 00017 00018 ///////////////////////////////////////////////////////////////////////////////// 00019 // 00020 // Function : rand_float 00021 // Description : This function creates a random float point number 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 // Function : random_clamped 00033 // Description : This function returns a random floating point number in the range 00034 // -1 to 1. 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 // Area around which the character should wander 00050 _area_of_effect = aoe; 00051 _init_pos = _ai_char->get_node_path().get_pos(_ai_char->get_char_render()); 00052 // _flag is used by Wander to wander in a given axis 00053 // Value 0 - XY axes wander 00054 // Value 1 - YZ axes wander 00055 // Value 2 - XZ axes wander 00056 // Value 3 - XYZ axes wander 00057 // default is XY axes 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 // Function : do_wander 00088 // Description : This function performs the wander and returns the wander force which is used 00089 // in the calculate_prioritized function. 00090 // This function is not to be used by the user. 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 // Create the random slices to enable random movement of wander for x,y,z respectively 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 // Project wander target onto global space 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 }