17 ObstacleAvoidance(
AICharacter *ai_char,
float feeler_length) {
19 _feeler = feeler_length;
23 ~ObstacleAvoidance() {
33 PT(
BoundingVolume) np_bounds = _ai_char->get_node_path().get_bounds();
35 LVecBase3 avoidance(0.0, 0.0, 0.0);
36 double distance = 0x7fff ;
37 double expanded_radius = 0;
38 LVecBase3 to_obstacle;
39 for(
unsigned int i = 0; i < _ai_char->_world->_obstacles.size(); ++i) {
40 PT(
BoundingVolume) bounds = _ai_char->_world->_obstacles[i].get_bounds();
42 LVecBase3 near_obstacle = _ai_char->_world->_obstacles[i].get_pos() - _ai_char->get_node_path().
get_pos();
45 if((near_obstacle.length() < distance) && (_ai_char->_world->_obstacles[i].get_pos() != _ai_char->get_node_path().
get_pos())) {
46 _nearest_obstacle = _ai_char->_world->_obstacles[i];
47 distance = near_obstacle.length();
48 expanded_radius = bsphere->get_radius() + np_sphere->get_radius();
52 LVecBase3 feeler = _feeler * _ai_char->get_char_render().
get_relative_vector(_ai_char->get_node_path(), LVector3::forward());
54 feeler *= (expanded_radius + np_sphere->get_radius()) ;
55 to_obstacle = _nearest_obstacle.
get_pos() - _ai_char->get_node_path().
get_pos();
56 LVector3 line_vector = _ai_char->get_char_render().
get_relative_vector(_ai_char->get_node_path(), LVector3::forward());
57 LVecBase3 project = (to_obstacle.dot(line_vector) * line_vector) / line_vector.length_squared();
58 LVecBase3 perp = project - to_obstacle;
62 if (_nearest_obstacle && (perp.length() < expanded_radius - np_sphere->get_radius()) && (project.length() < feeler.length())) {
74 _ai_char->_steering->
turn_off(
"obstacle_avoidance_activate");
75 _ai_char->_steering->
turn_on(
"obstacle_avoidance");
86 LVecBase3 offset = _ai_char->get_node_path().
get_pos() - _nearest_obstacle.
get_pos();
89 PT(
BoundingVolume) np_bounds = _ai_char->get_node_path().get_bounds();
93 LVecBase3 direction = _ai_char->get_char_render().
get_relative_vector(_ai_char->get_node_path(), LVector3::forward());
94 direction.normalize();
95 float forward_component = offset.dot(direction);
96 LVecBase3 projection = forward_component * direction;
97 LVecBase3 perpendicular_component = offset - projection;
98 double p = perpendicular_component.length();
99 perpendicular_component.normalize();
100 LVecBase3 avoidance = perpendicular_component;
102 avoidance = (avoidance * _ai_char->get_max_force() * _ai_char->_movt_force) / (p + 0.01);
105 _ai_char->_steering->
turn_on(
"obstacle_avoidance_activate");
106 _ai_char->_steering->
turn_off(
"obstacle_avoidance");
107 return LVecBase3(0, 0, 0);
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...
This defines a bounding sphere, consisting of a center and a radius.
void turn_on(std::string ai_type)
This function turns on any aiBehavior which is passed as a string.
bool obstacle_detection()
This function checks if an obstacle is near to the AICharacter and if an obstacle is detected returns...
void turn_off(std::string ai_type)
This function turns off any aiBehavior which is passed as a string.
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
LPoint3 get_pos() const
Retrieves the translation component of the transform.
void obstacle_avoidance_activate()
This function activates obstacle_avoidance if a obstacle is detected.
LVecBase3 do_obstacle_avoidance()
This function returns the force necessary by the AICharacter to avoid the nearest obstacle detected b...