Panda3D

wander.cxx

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 }
 All Classes Functions Variables Enumerations