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 }
AICharacter
Definition: aiCharacter.h:29
NodePath::get_pos
LPoint3 get_pos() const
Retrieves the translation component of the transform.
Definition: nodePath.cxx:1040
NodePath::get_relative_vector
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:1966
Wander::do_wander
LVecBase3 do_wander()
This function performs the wander and returns the wander force which is used in the calculate_priorit...
Definition: wander.cxx:76
random_clamped
double random_clamped()
This function returns a random floating point number in the range -1 to 1.
Definition: wander.cxx:27
rand_float
double rand_float()
This function creates a random float point number.
Definition: wander.cxx:19
wander.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.