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