Panda3D
wander.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file wander.cxx
10  * @author Deepak, John, Navin
11  * @date 2009-10-24
12  */
13 
14 #include "wander.h"
15 
16 /**
17  * This function creates a random float point number
18  */
19 double rand_float() {
20  const static double rand_max = 0x7fff;
21  return ((rand()) / (rand_max + 1.0));
22 }
23 
24 /**
25  * This function returns a random floating point number in the range -1 to 1.
26  */
27 double random_clamped() {
28  return (rand_float() - rand_float());
29 }
30 
31 Wander::Wander(AICharacter *ai_ch, double wander_radius,int flag, double aoe, float wander_weight) {
32  _ai_char = ai_ch;
33  _wander_radius = wander_radius ;
34  _wander_weight = wander_weight;
35  double theta = rand_float() * 2 * 3.14159;
36  double si = rand_float() * 3.14159;
37  _flag = flag;
38  // Area around which the character should wander
39  _area_of_effect = aoe;
40  _init_pos = _ai_char->get_node_path().get_pos(_ai_char->get_char_render());
41  // _flag is used by Wander to wander in a given axis Value 0 - XY axes
42  // wander Value 1 - YZ axes wander Value 2 - XZ axes wander Value 3 - XYZ
43  // axes wander default is XY axes
44  switch(_flag) {
45  case 0: {
46  _wander_target = LVecBase3(_wander_radius * cos(theta), _wander_radius * sin(theta),0);
47  break;
48  }
49  case 1: {
50  _wander_target = LVecBase3(0, _wander_radius * cos(theta), _wander_radius * sin(theta));
51  break;
52  }
53  case 2: {
54  _wander_target = LVecBase3(_wander_radius * cos(theta), 0, _wander_radius * sin(theta));
55  break;
56  }
57  case 3: {
58  _wander_target = LVecBase3(_wander_radius * sin(theta) * cos(si), _wander_radius * sin(theta) * sin(si), _wander_radius * cos(theta));
59  break;
60  }
61  default: {
62  _wander_target = LVecBase3(_wander_radius * cos(theta), _wander_radius * sin(theta),0);
63  break;
64  }
65  }
66 }
67 
68 Wander::~Wander() {
69 }
70 
71 /**
72  * This function performs the wander and returns the wander force which is
73  * used in the calculate_prioritized function. This function is not to be
74  * used by the user.
75  */
76 LVecBase3 Wander::do_wander() {
77  LVecBase3 present_pos = _ai_char->get_node_path().get_pos(_ai_char->get_char_render());
78  // Create the random slices to enable random movement of wander for x,y,z
79  // respectively
80  double time_slice_1 = random_clamped() * 1.5;
81  double time_slice_2 = random_clamped() * 1.5;
82  double time_slice_3 = random_clamped() * 1.5;
83  switch(_flag) {
84  case 0: {
85  _wander_target += LVecBase3(time_slice_1, time_slice_2, 0);
86  break;
87  }
88  case 1: {
89  _wander_target += LVecBase3(0, time_slice_1, time_slice_2);
90  break;
91  }
92  case 2: {
93  _wander_target += LVecBase3(time_slice_1, 0, time_slice_2);
94  break;
95  }
96  case 3: {
97  _wander_target += LVecBase3(time_slice_1, time_slice_2, time_slice_3);
98  break;
99  }
100 
101  default: {
102  _wander_target = LVecBase3(time_slice_1, time_slice_2, 0);
103  }
104  }
105  _wander_target.normalize();
106  _wander_target *= _wander_radius;
107  LVecBase3 target = _ai_char->get_char_render().get_relative_vector(_ai_char->get_node_path(), LVector3::forward());
108  target.normalize();
109 
110  // Project wander target onto global space
111  target = _wander_target + target;
112  LVecBase3 desired_target = present_pos + target;
113  LVecBase3 desired_force = desired_target - _ai_char->get_node_path().get_pos() ;
114  desired_force.normalize();
115  desired_force *= _ai_char->_movt_force;
116  double distance = (present_pos - _init_pos).length();
117  if(_area_of_effect > 0 && distance > _area_of_effect) {
118  LVecBase3 direction = present_pos - _init_pos;
119  direction.normalize();
120  desired_force = - direction * _ai_char->_movt_force;
121  LVecBase3 dirn = _ai_char->_steering->_steering_force;
122  dirn.normalize();
123  _ai_char->_steering->_steering_force = LVecBase3(0.0, 0.0, 0.0);
124  }
125  return desired_force;
126 }
LVector3 get_relative_vector(const NodePath &other, const LVecBase3 &vec) const
Given that the indicated vector is in the coordinate system of the other node, returns the same vecto...
Definition: nodePath.cxx:1903
double rand_float()
This function creates a random float point number.
Definition: wander.cxx:19
double random_clamped()
This function returns a random floating point number in the range -1 to 1.
Definition: wander.cxx:27
LPoint3 get_pos() const
Retrieves the translation component of the transform.
Definition: nodePath.cxx:992
LVecBase3 do_wander()
This function performs the wander and returns the wander force which is used in the calculate_priorit...
Definition: wander.cxx:76
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.