diff --git a/contrib/src/ai/Sources.pp b/contrib/src/ai/Sources.pp index 21e1b8766d..bf4e50e33a 100755 --- a/contrib/src/ai/Sources.pp +++ b/contrib/src/ai/Sources.pp @@ -24,7 +24,7 @@ evade.h \ flee.h \ flock.h \ - globals.h \ + aiGlobals.h \ meshNode.h \ obstacleAvoidance.h \ pathFind.h \ @@ -67,7 +67,7 @@ evade.h \ flee.h \ flock.h \ - globals.h \ + aiGlobals.h \ meshNode.h \ obstacleAvoidance.h \ pathFind.h \ diff --git a/contrib/src/ai/aiBehaviors.cxx b/contrib/src/ai/aiBehaviors.cxx index 20b36a6ef5..190805fc8c 100644 --- a/contrib/src/ai/aiBehaviors.cxx +++ b/contrib/src/ai/aiBehaviors.cxx @@ -1,13 +1,14 @@ -// Filename: aiBehaviors.cxx -// Created by: Deepak, John, Navin (08Sep09) -// +//////////////////////////////////////////////////////////////////////// +// Filename : aiBehaviors.cxx +// Created by : Deepak, John, Navin +// Date : 8 Sep 09 //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) Carnegie Mellon University. All rights reserved. // -// All use of this software is subject to the terms of the revised -// BSD license. You should have received a copy of this license along +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along // with this source code in a file named "LICENSE." // //////////////////////////////////////////////////////////////////// @@ -18,7 +19,7 @@ static const float _PI = 3.14; AIBehaviors::AIBehaviors() { _steering_force = LVecBase3f(0.0, 0.0, 0.0); - _behaviors_flags = _behaviors_flags & BT_none; + _behaviors_flags = _behaviors_flags & _none; _previous_conflict = false; _conflict = false; @@ -47,46 +48,45 @@ AIBehaviors::~AIBehaviors() { } -/////////////////////////////////////////////////////////////////// -// Function: is_conflict -// Description: Checks for conflict between steering forces. -// If there is a conflict it returns 'true' -// and sets _conflict to 'true'. -// If there is no conflict it returns 'false' -// and sets _conflict to 'false'. -/////////////////////////////////////////////////////////////////// -bool AIBehaviors::is_conflict() { - int value = int(is_on(BT_seek)) + int(is_on(BT_flee)) + int(is_on(BT_pursue)) - + int(is_on(BT_evade)) + int(is_on(BT_wander)) + int(is_on(BT_flock)) - + int(is_on(BT_obstacle_avoidance)); +///////////////////////////////////////////////////////////////////////////////// +// +// Function : is_conflict +// Description : Checks for conflict between steering forces. +// If there is a conflict it returns 'true' and sets _conflict to 'true'. +// If there is no conflict it returns 'false' and sets _conflict to 'false'. - if (value > 1) { - if (_previous_conflict == false) { - if (is_on(BT_seek)) { +///////////////////////////////////////////////////////////////////////////////// + +bool AIBehaviors::is_conflict() { + int value = int(is_on(_seek)) + int(is_on(_flee)) + int(is_on(_pursue)) + int(is_on(_evade)) + int(is_on(_wander)) + int(is_on(_flock))+ int(is_on(_obstacle_avoidance)); + + if(value > 1) { + if(_previous_conflict == false) { + if(is_on(_seek)) { _seek_force *= _seek_obj->_seek_weight; } - if (is_on(BT_flee)) { + if(is_on(_flee)) { LVecBase3f dirn = _flee_force; dirn.normalize(); _flee_force = _steering_force.length() * dirn * _flee_obj->_flee_weight; } - if (is_on(BT_pursue)) { + if(is_on(_pursue)) { _pursue_force *= _pursue_obj->_pursue_weight; } - if (is_on(BT_evade)) { + if(is_on(_evade)) { LVecBase3f dirn = _evade_force; dirn.normalize(); _evade_force = _steering_force.length() * dirn * _evade_obj->_evade_weight; } - if (is_on(BT_flock)) { + if(is_on(_flock)) { _flock_force *= _flock_weight; } - if (is_on(BT_wander)) { + if(is_on(_wander)) { _wander_force *= _wander_obj->_wander_weight; } @@ -102,76 +102,78 @@ bool AIBehaviors::is_conflict() { return false; } -//////////////////////////////////////////////////////////////////// -// Function: accumulate_force -// Description: This function updates the individual steering forces -// for each of the ai characters. -// These accumulated forces are eventually what -// comprise the resultant steering force of the -// character. -//////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Function : accumulate_force +// Description : This function updates the individual steering forces for each of the ai characters. +// These accumulated forces are eventually what comprise the resultant +// steering force of the character. + +///////////////////////////////////////////////////////////////////////////////////////////////////// + void AIBehaviors::accumulate_force(string force_type, LVecBase3f force) { LVecBase3f old_force; - if (force_type == "seek") { + if(force_type == "seek") { old_force = _seek_force; _seek_force = old_force + force; } - if (force_type == "flee") { + if(force_type == "flee") { old_force = _flee_force; _flee_force = old_force + force; } - if (force_type == "pursue") { + if(force_type == "pursue") { old_force = _pursue_force; double new_force = old_force.length() + force.length(); _pursue_force = new_force * _pursue_obj->_pursue_direction; } - if (force_type == "evade") { + if(force_type == "evade") { old_force = _evade_force; double new_force = old_force.length() + force.length(); force.normalize(); _evade_force = new_force * force; } - if (force_type == "arrival") { + if(force_type == "arrival") { _arrival_force = force; } - if (force_type == "flock") { + if(force_type == "flock") { old_force = _flock_force; _flock_force = old_force + force; } - if (force_type == "wander") { + if(force_type == "wander") { old_force = _wander_force; _wander_force = old_force + force; } - if (force_type == "obstacle_avoidance") { + if(force_type == "obstacle_avoidance") { old_force = _obstacle_avoidance_force; _obstacle_avoidance_force = old_force +force; } } -//////////////////////////////////////////////////////////////////// -// Function: calculate_prioritized -// Description: This function updates the main steering force -// for the ai character using the accumulate function -// and checks for max force and arrival force. -// It finally returns this steering force which is -// accessed by the update function in the AICharacter -// class. -//////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////// +// +// Function : calculate_prioritized +// Description : This function updates the main steering force for the ai character using +// the accumulate function and checks for max force and arrival force. +// It finally returns this steering force which is accessed by the update +// function in the AICharacter class. + +////////////////////////////////////////////////////////////////////////////////////////////// + LVecBase3f AIBehaviors::calculate_prioritized() { LVecBase3f force; - if (is_on(BT_seek)) { - if (_conflict) { + if(is_on(_seek)) { + if(_conflict) { force = _seek_obj->do_seek() * _seek_obj->_seek_weight; } else { @@ -180,16 +182,16 @@ LVecBase3f AIBehaviors::calculate_prioritized() { accumulate_force("seek",force); } - if (is_on(BT_flee_activate)) { - for (_flee_itr = _flee_list.begin(); _flee_itr != _flee_list.end(); _flee_itr++) { + if(is_on(_flee_activate)) { + for(_flee_itr = _flee_list.begin(); _flee_itr != _flee_list.end(); _flee_itr++) { _flee_itr->flee_activate(); } } - if (is_on(BT_flee)) { - for (_flee_itr = _flee_list.begin(); _flee_itr != _flee_list.end(); _flee_itr++) { - if (_flee_itr->_flee_activate_done) { - if (_conflict) { + if(is_on(_flee)) { + for(_flee_itr = _flee_list.begin(); _flee_itr != _flee_list.end(); _flee_itr++) { + if(_flee_itr->_flee_activate_done) { + if(_conflict) { force = _flee_itr->do_flee() * _flee_itr->_flee_weight; } else { @@ -200,8 +202,8 @@ LVecBase3f AIBehaviors::calculate_prioritized() { } } - if (is_on(BT_pursue)) { - if (_conflict) { + if(is_on(_pursue)) { + if(_conflict) { force = _pursue_obj->do_pursue() * _pursue_obj->_pursue_weight; } else { @@ -210,16 +212,16 @@ LVecBase3f AIBehaviors::calculate_prioritized() { accumulate_force("pursue",force); } - if (is_on(BT_evade_activate)) { - for (_evade_itr = _evade_list.begin(); _evade_itr != _evade_list.end(); _evade_itr++) { + if(is_on(_evade_activate)) { + for(_evade_itr = _evade_list.begin(); _evade_itr != _evade_list.end(); _evade_itr++) { _evade_itr->evade_activate(); } } - if (is_on(BT_evade)) { - for (_evade_itr = _evade_list.begin(); _evade_itr != _evade_list.end(); _evade_itr++) { - if (_evade_itr->_evade_activate_done) { - if (_conflict) { + if(is_on(_evade)) { + for(_evade_itr = _evade_list.begin(); _evade_itr != _evade_list.end(); _evade_itr++) { + if(_evade_itr->_evade_activate_done) { + if(_conflict) { force = (_evade_itr->do_evade()) * (_evade_itr->_evade_weight); } else { @@ -230,21 +232,21 @@ LVecBase3f AIBehaviors::calculate_prioritized() { } } - if (is_on(BT_arrival_activate)) { + if(is_on(_arrival_activate)) { _arrival_obj->arrival_activate(); } - if (is_on(BT_arrival)) { + if(is_on(_arrival)) { force = _arrival_obj->do_arrival(); accumulate_force("arrival",force); } - if (is_on(BT_flock_activate)) { + if(is_on(_flock_activate)) { flock_activate(); } - if (is_on(BT_flock)) { - if (_conflict) { + if(is_on(_flock)) { + if(_conflict) { force = do_flock() * _flock_weight; } else { @@ -253,8 +255,8 @@ LVecBase3f AIBehaviors::calculate_prioritized() { accumulate_force("flock",force); } - if (is_on(BT_wander)) { - if (_conflict) { + if(is_on(_wander)) { + if(_conflict) { force = _wander_obj->do_wander() * _wander_obj->_wander_weight; } else { @@ -263,12 +265,12 @@ LVecBase3f AIBehaviors::calculate_prioritized() { accumulate_force("wander", force); } - if (is_on(BT_obstacle_avoidance_activate)) { + if(is_on(_obstacle_avoidance_activate)) { _obstacle_avoidance_obj->obstacle_avoidance_activate(); } - if (is_on(BT_obstacle_avoidance)) { - if (_conflict) { + if(is_on(_obstacle_avoidance)) { + if(_conflict) { force = _obstacle_avoidance_obj->do_obstacle_avoidance(); } else { @@ -277,32 +279,32 @@ LVecBase3f AIBehaviors::calculate_prioritized() { accumulate_force("obstacle_avoidance", force); } - if (_path_follow_obj!=NULL) { - if (_path_follow_obj->_start) { + if(_path_follow_obj!=NULL) { + if(_path_follow_obj->_start) { _path_follow_obj->do_follow(); } } is_conflict(); - _steering_force += _seek_force * int(is_on(BT_seek)) + _flee_force * int(is_on(BT_flee)) + - _pursue_force * int(is_on(BT_pursue)) + _evade_force * int(is_on(BT_evade)) + - _flock_force * int(is_on(BT_flock)) + _wander_force * int(is_on(BT_wander)) + - _obstacle_avoidance_force * int(is_on(BT_obstacle_avoidance)); + _steering_force += _seek_force * int(is_on(_seek)) + _flee_force * int(is_on(_flee)) + + _pursue_force * int(is_on(_pursue)) + _evade_force * int(is_on(_evade)) + + _flock_force * int(is_on(_flock)) + _wander_force * int(is_on(_wander)) + + _obstacle_avoidance_force * int(is_on(_obstacle_avoidance)); - if (_steering_force.length() > _ai_char->get_max_force()) { + if(_steering_force.length() > _ai_char->get_max_force()) { _steering_force.normalize(); _steering_force = _steering_force * _ai_char->get_max_force(); } - if (is_on(BT_arrival)) { - if (_seek_obj != NULL) { + if(is_on(_arrival)) { + if(_seek_obj != NULL) { LVecBase3f dirn = _steering_force; dirn.normalize(); _steering_force = ((_steering_force.length() - _arrival_force.length()) * dirn); } - if (_pursue_obj != NULL) { + if(_pursue_obj != NULL) { LVecBase3f dirn = _steering_force; dirn.normalize(); _steering_force = ((_steering_force.length() - _arrival_force.length()) * _arrival_obj->_arrival_direction); @@ -311,12 +313,16 @@ LVecBase3f AIBehaviors::calculate_prioritized() { return _steering_force; } -//////////////////////////////////////////////////////////////////// -// Function: remove_ai -// Description: This function removes individual or all the AIs. -//////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +// +// Function : remove_ai +// Description : This function removes individual or all the AIs. + +///////////////////////////////////////////////////////////////////////////////// + +//add for path follow void AIBehaviors::remove_ai(string ai_type) { - switch (char_to_int(ai_type)) { + switch(char_to_int(ai_type)) { case 0: { remove_ai("seek"); remove_ai("flee"); @@ -330,8 +336,8 @@ void AIBehaviors::remove_ai(string ai_type) { break; } - case 1: { - if (_seek_obj != NULL) { + case 1: { + if(_seek_obj != NULL) { turn_off("seek"); delete _seek_obj; _seek_obj = NULL; @@ -349,7 +355,7 @@ void AIBehaviors::remove_ai(string ai_type) { } case 3: { - if (_pursue_obj != NULL) { + if(_pursue_obj != NULL) { turn_off("pursue"); delete _pursue_obj; _pursue_obj = NULL; @@ -367,7 +373,7 @@ void AIBehaviors::remove_ai(string ai_type) { } case 5: { - if (_arrival_obj != NULL) { + if(_arrival_obj != NULL) { turn_off("arrival"); turn_off("arrival_activate"); delete _arrival_obj; @@ -377,7 +383,7 @@ void AIBehaviors::remove_ai(string ai_type) { } case 6: { - if (_flock_group != NULL) { + if(_flock_group != NULL) { turn_off("flock"); turn_off("flock_activate"); _flock_group = NULL; @@ -386,7 +392,7 @@ void AIBehaviors::remove_ai(string ai_type) { } case 7: { - if (_wander_obj != NULL) { + if(_wander_obj != NULL) { turn_off("wander"); delete _wander_obj; _wander_obj = NULL; @@ -395,7 +401,7 @@ void AIBehaviors::remove_ai(string ai_type) { } case 8: { - if (_obstacle_avoidance_obj !=NULL) { + if(_obstacle_avoidance_obj !=NULL) { turn_off("obstacle_avoidance"); delete _obstacle_avoidance_obj; _obstacle_avoidance_obj = NULL; @@ -404,7 +410,7 @@ void AIBehaviors::remove_ai(string ai_type) { } case 9: { - if (_pursue_obj != NULL && _path_follow_obj != NULL) { + if(_pursue_obj != NULL && _path_follow_obj != NULL) { turn_off("pursue"); delete _pursue_obj; _pursue_obj = NULL; @@ -413,9 +419,8 @@ void AIBehaviors::remove_ai(string ai_type) { } break; } - case 16: { - if (_pursue_obj != NULL && _path_follow_obj != NULL) { + if(_pursue_obj != NULL && _path_follow_obj != NULL) { turn_off("pursue"); delete _pursue_obj; _pursue_obj = NULL; @@ -423,18 +428,22 @@ void AIBehaviors::remove_ai(string ai_type) { _path_follow_obj = NULL; } break; - } + } default: - cout << "Invalid option!\n"; + cout<<"Invalid option!"<_start = false; } break; } case 16: { - if (_pursue_obj != NULL && _path_follow_obj != NULL) { + if(_pursue_obj != NULL && _path_follow_obj != NULL) { turn_off("pursue"); _path_follow_obj->_start = false; } break; - } + } default: - cout << "Invalid option!\n"; + cout<<"Invalid option!"<_start = true; } break; } case 16: { - if (_pursue_obj != NULL && _path_follow_obj != NULL) { + if(_pursue_obj != NULL && _path_follow_obj != NULL) { turn_off("pursue"); _path_follow_obj->_start = false; } break; - } + } default: - cout << "Invalid option!\n"; + cout<<"Invalid option!"<_arrival_type = true; turn_on("arrival_activate"); } - else if (_seek_obj) { + else if(_seek_obj) { _arrival_obj = new Arrival(_ai_char, distance); _arrival_obj->_arrival_type = false; turn_on("arrival_activate"); } else { - cout << "Note: A Seek or Pursue behavior is required to use Arrival behavior.\n"; + cout<<"Note: A Seek or Pursue behavior is required to use Arrival behavior."<_ai_char_list.size(); i++) { - if (_flock_group->_ai_char_list[i]->_name != _ai_char->_name) { + //! Loop through all the other AI units in the flock to check if they are neigbours. + for(unsigned int i = 0; i < _flock_group->_ai_char_list.size(); i++) { + if(_flock_group->_ai_char_list[i]->_name != _ai_char->_name) { - // Using visibilty cone to detect neighbors. - LVecBase3f dist_vect = _flock_group->_ai_char_list[i]->_ai_char_np.get_pos() - - _ai_char->_ai_char_np.get_pos(); + //! Using visibilty cone to detect neighbors. + LVecBase3f dist_vect = _flock_group->_ai_char_list[i]->_ai_char_np.get_pos() - _ai_char->_ai_char_np.get_pos(); LVecBase3f ai_char_heading = _ai_char->get_velocity(); ai_char_heading.normalize(); - // Check if the current unit is a neighbor. - if (dist_vect.dot(ai_char_heading) > ((dist_vect.length()) * (ai_char_heading.length()) - * cos(_flock_group->_flock_vcone_angle * (_PI / 180))) + //! Check if the current unit is a neighbor. + if(dist_vect.dot(ai_char_heading) > ((dist_vect.length()) * (ai_char_heading.length()) * cos(_flock_group->_flock_vcone_angle * (_PI / 180))) && (dist_vect.length() < _flock_group->_flock_vcone_radius)) { - // Separation force calculation. - LVecBase3f ai_char_to_units = _ai_char->_ai_char_np.get_pos() - - _flock_group->_ai_char_list[i]->_ai_char_np.get_pos(); + //! Separation force calculation. + LVecBase3f ai_char_to_units = _ai_char->_ai_char_np.get_pos() - _flock_group->_ai_char_list[i]->_ai_char_np.get_pos(); float to_units_dist = ai_char_to_units.length(); ai_char_to_units.normalize(); separation_force += (ai_char_to_units / to_units_dist); - // Calculating the total heading and center of mass of all the neighbors. + //! Calculating the total heading and center of mass of all the neighbors. LVecBase3f neighbor_heading = _flock_group->_ai_char_list[i]->get_velocity(); neighbor_heading.normalize(); total_neighbor_heading += neighbor_heading; total_center_of_mass += _flock_group->_ai_char_list[i]->_ai_char_np.get_pos(); - // Update the neighbor count. + //! Update the neighbor count. ++neighbor_count; } } } - if (neighbor_count > 0) { - // Alignment force calculation + if(neighbor_count > 0) { + //! Alignment force calculation avg_neighbor_heading = total_neighbor_heading / neighbor_count; LVector3f ai_char_heading = _ai_char->get_velocity(); ai_char_heading.normalize(); @@ -805,172 +820,189 @@ LVecBase3f AIBehaviors::do_flock() { avg_neighbor_heading.normalize(); alignment_force = avg_neighbor_heading; - // Cohesion force calculation + //! Cohesion force calculation avg_center_of_mass = total_center_of_mass / neighbor_count; LVecBase3f cohesion_dir = avg_center_of_mass - _ai_char->_ai_char_np.get_pos(); cohesion_dir.normalize(); cohesion_force = cohesion_dir * _ai_char->_movt_force; } - else if (is_on(BT_seek) || is_on(BT_flee) || is_on(BT_pursue) || - is_on(BT_evade) || is_on(BT_wander)) { + else if(is_on(_seek) || is_on(_flee) || is_on(_pursue) || is_on(_evade) || is_on(_wander)) { _flock_done = true; turn_off("flock"); turn_on("flock_activate"); - return (LVecBase3f(0.0, 0.0, 0.0)); + return(LVecBase3f(0.0, 0.0, 0.0)); } - // Calculate the resultant force on the ai character by taking into - // account the separation, alignment and cohesion - // forces along with their corresponding weights. - return (separation_force * _flock_group->_separation_wt + - avg_neighbor_heading * _flock_group->_alignment_wt + //! Calculate the resultant force on the ai character by taking into account the separation, alignment and cohesion + //! forces along with their corresponding weights. + return (separation_force * _flock_group->_separation_wt + avg_neighbor_heading * _flock_group->_alignment_wt + cohesion_force * _flock_group->_cohesion_wt); } -//////////////////////////////////////////////////////////////////// -// Function: wander -// Description: This function activates wander. -// This is the function we want the user to call -// for flock to be done. -//////////////////////////////////////////////////////////////////// -void AIBehaviors::wander(double wander_radius, int flag, double aoe, - float wander_weight) { - _wander_obj = new Wander(_ai_char, wander_radius, flag, aoe, - wander_weight); +///////////////////////////////////////////////////////////////////////////////// +// +// Function : wander +// Description : This function activates wander. +// This is the function we want the user to call for flock to be done. + +///////////////////////////////////////////////////////////////////////////////// + +void AIBehaviors::wander(double wander_radius, int flag, double aoe, float wander_weight) { + _wander_obj = new Wander(_ai_char, wander_radius, flag, aoe, wander_weight); turn_on("wander"); } -//////////////////////////////////////////////////////////////////// -// Function: obstacle avoidance -// Description: This function activates obstacle avoidance for a -// given character. +///////////////////////////////////////////////////////////////////////////////// +// +// Function : obstacle avoidance +// Description : This function activates obstacle avoidance for a given character. // This is the function we want the user to call for // obstacle avoidance to be performed. -//////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////////// + void AIBehaviors::obstacle_avoidance(float obstacle_avoidance_weight) { _obstacle_avoidance_obj = new ObstacleAvoidance(_ai_char, obstacle_avoidance_weight); turn_on("obstacle_avoidance_activate"); } -//////////////////////////////////////////////////////////////////// -// Function: path_follow -// Description: This function activates path following. -// This is the function we want the user to call for -// path following. -//////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +// +// Function : path_follow +// Description : This function activates path following. +// This is the function we want the user to call for path following. + +///////////////////////////////////////////////////////////////////////////////// + void AIBehaviors::path_follow(float follow_wt) { _path_follow_obj = new PathFollow(_ai_char, follow_wt); } -//////////////////////////////////////////////////////////////////// -// Function: add_to_path -// Description: This function adds positions to the path to follow. -//////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +// +// Function : add_to_path +// Description : This function adds positions to the path to follow. + +///////////////////////////////////////////////////////////////////////////////// + void AIBehaviors::add_to_path(LVecBase3f pos) { _path_follow_obj->add_to_path(pos); } -//////////////////////////////////////////////////////////////////// -// Function: start_follow -// Description: This function starts the path follower. -//////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +// +// Function : start_follow +// Description : This function starts the path follower. + +///////////////////////////////////////////////////////////////////////////////// + void AIBehaviors::start_follow(string type) { _path_follow_obj->start(type); } -//////////////////////////////////////////////////////////////////// -// Function: init_path_find -// Description: This function activates path finding in the character. -// This function accepts the meshdata in .csv format. -//////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +// +// Function : init_path_find +// Description : This function activates path finding in the character. +// This function accepts the meshdata in .csv format. +// + +///////////////////////////////////////////////////////////////////////////////// + void AIBehaviors::init_path_find(const char* navmesh_filename) { _path_find_obj = new PathFind(_ai_char); _path_find_obj->set_path_find(navmesh_filename); } -//////////////////////////////////////////////////////////////////// -// Function: path_find_to (for pathfinding towards a -// static position) -// Description: This function checks for the source and target in -// the navigation mesh for its availability and then -// finds the best path via the A* algorithm -// Then it calls the path follower to make the object -// follow the path. -//////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////// +// +// Function : path_find_to (for pathfinding towards a static position) +// Description : This function checks for the source and target in the navigation mesh +// for its availability and then finds the best path via the A* algorithm +// Then it calls the path follower to make the object follow the path. + +/////////////////////////////////////////////////////////////////////////////////////// + void AIBehaviors::path_find_to(LVecBase3f pos, string type) { _path_find_obj->path_find(pos, type); } -//////////////////////////////////////////////////////////////////// -// Function: path_find_to (for pathfinding towards a moving -// target (a NodePath)) -// Description: This function checks for the source and target in -// the navigation mesh for its availability and then -// finds the best path via the A* algorithm -// Then it calls the path follower to make the object -// follow the path. -//////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////// +// +// Function : path_find_to (for pathfinding towards a moving target (a NodePath)) +// Description : This function checks for the source and target in the navigation mesh +// for its availability and then finds the best path via the A* algorithm +// Then it calls the path follower to make the object follow the path. + +/////////////////////////////////////////////////////////////////////////////////////// + void AIBehaviors::path_find_to(NodePath target, string type) { _path_find_obj->path_find(target, type); } -//////////////////////////////////////////////////////////////////// -// Function: add_static_obstacle -// Description: This function allows the user to dynamically add -// obstacles to the -// game environment. The function will update the nodes -// within the bounding volume of the obstacle as non- -// traversable. Hence will not be considered by the -// pathfinding algorithm. -//////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////// +// +// Function : add_static_obstacle +// Description : This function allows the user to dynamically add obstacles to the +// game environment. The function will update the nodes within the +// bounding volume of the obstacle as non-traversable. Hence will not be +// considered by the pathfinding algorithm. + +/////////////////////////////////////////////////////////////////////////////////////// + void AIBehaviors::add_static_obstacle(NodePath obstacle) { _path_find_obj->add_obstacle_to_mesh(obstacle); } -//////////////////////////////////////////////////////////////////// -// Function: add_dynamic_obstacle -// Description: This function starts the pathfinding obstacle -// navigation for the passed in obstacle. -//////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////// +// +// Function : add_dynamic_obstacle +// Description : This function starts the pathfinding obstacle navigation for the +// passed in obstacle. + +/////////////////////////////////////////////////////////////////////////////////////// + void AIBehaviors::add_dynamic_obstacle(NodePath obstacle) { _path_find_obj->dynamic_avoid(obstacle); } -//////////////////////////////////////////////////////////////////// -// Function: behavior_status -// Description: This function returns the status of an AI Type -// whether it is active, paused or disabled. It returns -// -1 if an invalid string is passed. -//////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////// +// +// Function : behavior_status +// Description : This function returns the status of an AI Type whether it is active, +// paused or disabled. It returns -1 if an invalid string is passed. + +/////////////////////////////////////////////////////////////////////////////////////// + string AIBehaviors::behavior_status(string ai_type) { - switch (char_to_int(ai_type)) { + switch(char_to_int(ai_type)) { case 1: - if (_seek_obj) { - if (is_on(BT_seek)) { + if(_seek_obj) { + if(is_on(_seek)) { return "active"; } else { - if (_seek_obj->_seek_done) { + if(_seek_obj->_seek_done) { return "done"; - } + } return "paused"; } } else { - return "disabled"; + return "disabled"; } break; case 2: - if (_flee_obj) { - if (is_on(BT_flee)) { + if(_flee_obj) { + if(is_on(_flee)) { unsigned int i = 0; - for (_flee_itr = _flee_list.begin(); _flee_itr != _flee_list.end(); _flee_itr++) { - if (_flee_itr->_flee_done == true) { + for(_flee_itr = _flee_list.begin(); _flee_itr != _flee_list.end(); _flee_itr++) { + if(_flee_itr->_flee_done == true) { ++i; } } - if (i == _flee_list.size()) { + if(i == _flee_list.size()) { return "done"; } else { @@ -982,14 +1014,14 @@ string AIBehaviors::behavior_status(string ai_type) { } } else { - return "disabled"; + return "disabled"; } break; case 3: - if (_pursue_obj) { - if (is_on(BT_pursue)) { - if (_pursue_obj->_pursue_done) { + if(_pursue_obj) { + if(is_on(_pursue)) { + if(_pursue_obj->_pursue_done) { return "done"; } else { @@ -1006,15 +1038,15 @@ string AIBehaviors::behavior_status(string ai_type) { break; case 4: - if (_evade_obj) { - if (is_on(BT_evade)) { + if(_evade_obj) { + if(is_on(_evade)) { unsigned int i = 0; - for (_evade_itr = _evade_list.begin(); _evade_itr != _evade_list.end(); _evade_itr++) { - if (_evade_itr->_evade_done == true) { + for(_evade_itr = _evade_list.begin(); _evade_itr != _evade_list.end(); _evade_itr++) { + if(_evade_itr->_evade_done == true) { ++i; } } - if (i == _evade_list.size()) { + if(i == _evade_list.size()) { return "done"; } else { @@ -1026,14 +1058,14 @@ string AIBehaviors::behavior_status(string ai_type) { } } else { - return "disabled"; + return "disabled"; } break; case 5: - if (_arrival_obj) { - if (is_on(BT_arrival)) { - if (_arrival_obj->_arrival_done) { + if(_arrival_obj) { + if(is_on(_arrival)) { + if(_arrival_obj->_arrival_done) { return "done"; } else { @@ -1050,9 +1082,9 @@ string AIBehaviors::behavior_status(string ai_type) { break; case 6: - if (_flock_group) { - if (is_on(BT_flock)) { - if (_flock_done) { + if(_flock_group) { + if(is_on(_flock)) { + if(_flock_done) { return "done"; } else { @@ -1065,13 +1097,13 @@ string AIBehaviors::behavior_status(string ai_type) { } } else { - return "disabled"; + return "disabled"; } break; case 7: - if (_wander_obj) { - if (is_on(BT_wander)) { + if(_wander_obj) { + if(is_on(_wander)) { return "active"; } else { @@ -1079,13 +1111,13 @@ string AIBehaviors::behavior_status(string ai_type) { } } else { - return "disabled"; + return "disabled"; } break; case 8: - if (_obstacle_avoidance_obj) { - if (is_on(BT_obstacle_avoidance)) { + if(_obstacle_avoidance_obj) { + if(is_on(_obstacle_avoidance)) { return "active"; } else { @@ -1098,9 +1130,9 @@ string AIBehaviors::behavior_status(string ai_type) { break; case 9: - if (_path_follow_obj) { - if (is_on("pathfollow")) { - if (_pursue_obj->_pursue_done) { + if(_path_follow_obj) { + if(is_on("pathfollow")) { + if(_pursue_obj->_pursue_done) { return "done"; } else { @@ -1117,9 +1149,9 @@ string AIBehaviors::behavior_status(string ai_type) { break; case 16: - if (_path_find_obj) { - if (is_on("pathfind")) { - if (_pursue_obj->_pursue_done) { + if(_path_find_obj) { + if(is_on("pathfind")) { + if(_pursue_obj->_pursue_done) { return "done"; } else { @@ -1136,13 +1168,9 @@ string AIBehaviors::behavior_status(string ai_type) { break; case 10: - if (_seek_obj || _flee_obj || _pursue_obj || _evade_obj || _arrival_obj - || _flock_group || _wander_obj || _obstacle_avoidance_obj || - _path_follow_obj) { - if (is_on(BT_seek) || is_on(BT_flee) || is_on(BT_pursue)|| - is_on(BT_evade) || is_on(BT_arrival) || is_on(BT_flock) - || is_on(BT_wander) || is_on(BT_obstacle_avoidance) || - is_on("pathfollow") || is_on("pathfinding")) { + if(_seek_obj || _flee_obj || _pursue_obj || _evade_obj || _arrival_obj || _flock_group || _wander_obj || _obstacle_avoidance_obj || _path_follow_obj) { + if(is_on(_seek) || is_on(_flee) || is_on(_pursue)|| is_on(_evade) || is_on(_arrival) || is_on(_flock) || is_on(_wander) + || is_on(_obstacle_avoidance) || is_on("pathfollow") || is_on("pathfinding")) { return "active"; } else { @@ -1155,230 +1183,236 @@ string AIBehaviors::behavior_status(string ai_type) { break; default: - cout << "Invalid value!\n"; + cout<<"Invalid value!"<_start); + if(ai_type == "pathfollow") { + if(_path_follow_obj) { + return (is_on(_pursue) && _path_follow_obj->_start); } else { return false; } } - if (ai_type == "pathfinding") { - if (_path_follow_obj && _path_find_obj) { - return (is_on(BT_pursue) && _path_follow_obj->_start); + if(ai_type == "pathfinding") { + if(_path_follow_obj && _path_find_obj) { + return (is_on(_pursue) && _path_follow_obj->_start); } else { return false; @@ -1426,22 +1465,27 @@ bool AIBehaviors::is_on(string ai_type) { return false; } -//////////////////////////////////////////////////////////////////// -// Function: is_off -// Description: This function returns true if an aiBehavior is off -//////////////////////////////////////////////////////////////////// -bool AIBehaviors::is_off(BehaviorType bt) { +/////////////////////////////////////////////////////////////////////////////////////// +// +// Function : is_off +// Description : This function returns true if an aiBehavior is off + +/////////////////////////////////////////////////////////////////////////////////////// + +bool AIBehaviors::is_off(_behavior_type bt) { return ((_behaviors_flags | bt) == bt); } -//////////////////////////////////////////////////////////////////// -// Function: is_off -// Description: This function returns true if pathfollow or -// pathfinding is off -//////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////// +// +// Function : is_off +// Description : This function returns true if pathfollow or pathfinding is off + +/////////////////////////////////////////////////////////////////////////////////////// + bool AIBehaviors::is_off(string ai_type) { - if (ai_type == "pathfollow") { - if (_path_follow_obj && _path_follow_obj->_start) { + if(ai_type == "pathfollow") { + if(_path_follow_obj && _path_follow_obj->_start) { return true; } else { @@ -1449,8 +1493,8 @@ bool AIBehaviors::is_off(string ai_type) { } } - if (ai_type == "pathfinding") { - if (_path_find_obj && _path_follow_obj && _path_follow_obj->_start) { + if(ai_type == "pathfinding") { + if(_path_find_obj && _path_follow_obj && _path_follow_obj->_start) { return true; } else { @@ -1458,6 +1502,6 @@ bool AIBehaviors::is_off(string ai_type) { } } - cout << "You passed an invalid string, defaulting return value to false!\n"; + cout<<"You passed an invalid string, defaulting return value to false!"< > ListFlee; typedef list > ListEvade; -//////////////////////////////////////////////////////////////////// -// Class : AIBehaviors -// Description : This class implements all the steering behaviors -// of the AI framework, such as seek, flee, pursue, -// evade, wander and flock. Each steering behavior -// has a weight which is used when more than one type -// of steering behavior is acting on the same AI -// character. The weight decides the contribution of -// each type of steering behavior. The AICharacter -// class has a handle to an object of this class and -// this allows to invoke the steering behaviors via -// the AICharacter. This class also provides -// functionality such as pausing, resuming and -// removing the AI behaviors of an AI character at -// any time. -/////////////////////////////////////////////////////////////////// -class AIBehaviors { +class EXPCL_PANDAAI AIBehaviors { public: - enum BehaviorType { - BT_none = 0x00000, - BT_seek = 0x00002, - BT_flee = 0x00004, - BT_flee_activate = 0x00100, - BT_arrival = 0x00008, - BT_arrival_activate = 0x01000, - BT_wander = 0x00010, - BT_pursue = 0x00040, - BT_evade = 0x00080, - BT_evade_activate = 0x00800, - BT_flock = 0x00200, - BT_flock_activate = 0x00400, - BT_obstacle_avoidance = 0x02000, - BT_obstacle_avoidance_activate = 0x04000, + enum _behavior_type { + _none = 0x00000, + _seek = 0x00002, + _flee = 0x00004, + _flee_activate = 0x00100, + _arrival = 0x00008, + _arrival_activate = 0x01000, + _wander = 0x00010, + _pursue = 0x00040, + _evade = 0x00080, + _evade_activate = 0x00800, + _flock = 0x00200, + _flock_activate = 0x00400, + _obstacle_avoidance = 0x02000, + _obstacle_avoidance_activate = 0x04000 }; AICharacter *_ai_char; @@ -92,8 +81,7 @@ public: Flee *_flee_obj; LVecBase3f _flee_force; - // This list is used if the ai character needs to flee from - // multiple onjects. + //! This list is used if the ai character needs to flee from multiple onjects. ListFlee _flee_list; ListFlee::iterator _flee_itr; @@ -103,16 +91,14 @@ public: Evade *_evade_obj; LVecBase3f _evade_force; - // This list is used if the ai character needs to evade from - // multiple onjects. + //! This list is used if the ai character needs to evade from multiple onjects. ListEvade _evade_list; ListEvade::iterator _evade_itr; Arrival *_arrival_obj; LVecBase3f _arrival_force; - // Since Flock is a collective behavior the variables are - // declared within the AIBehaviors class. + //! Since Flock is a collective behavior the variables are declared within the AIBehaviors class. float _flock_weight; LVecBase3f _flock_force; bool _flock_done; @@ -132,11 +118,10 @@ public: AIBehaviors(); ~AIBehaviors(); - bool is_on(BehaviorType bt); - bool is_off(BehaviorType bt); - // special cases for pathfollow and pathfinding - bool is_on(string ai_type); - bool is_off(string ai_type); + bool is_on(_behavior_type bt); + bool is_on(string ai_type); // special cases for pathfollow and pathfinding + bool is_off(_behavior_type bt); + bool is_off(string ai_type); // special cases for pathfollow and pathfinding void turn_on(string ai_type); void turn_off(string ai_type); @@ -154,34 +139,32 @@ PUBLISHED: void seek(NodePath target_object, float seek_wt = 1.0); void seek(LVecBase3f pos, float seek_wt = 1.0); - void flee(NodePath target_object, double panic_distance = 10.0, - double relax_distance = 10.0, float flee_wt = 1.0); - void flee(LVecBase3f pos, double panic_distance = 10.0, - double relax_distance = 10.0, float flee_wt = 1.0); + void flee(NodePath target_object, double panic_distance = 10.0, double relax_distance = 10.0, float flee_wt = 1.0); + void flee(LVecBase3f pos, double panic_distance = 10.0, double relax_distance = 10.0, float flee_wt = 1.0); void pursue(NodePath target_object, float pursue_wt = 1.0); - void evade(NodePath target_object, double panic_distance = 10.0, - double relax_distance = 10.0, float evade_wt = 1.0); + void evade(NodePath target_object, double panic_distance = 10.0, double relax_distance = 10.0, float evade_wt = 1.0); void arrival(double distance = 10.0); void flock(float flock_wt); - void wander(double wander_radius = 5.0, int flag =0, - double aoe = 0.0, float wander_weight = 1.0); + void wander(double wander_radius = 5.0, int flag =0, double aoe = 0.0, float wander_weight = 1.0); void obstacle_avoidance(float feeler_length = 1.0); - void path_follow(float follow_wt = 1.0); + void path_follow(float follow_wt); void add_to_path(LVecBase3f pos); void start_follow(string type = "normal"); + // should have different function names. void init_path_find(const char* navmesh_filename); void path_find_to(LVecBase3f pos, string type = "normal"); void path_find_to(NodePath target, string type = "normal"); void add_static_obstacle(NodePath obstacle); void add_dynamic_obstacle(NodePath obstacle); + // void remove_ai(string ai_type); void pause_ai(string ai_type); @@ -191,3 +174,14 @@ PUBLISHED: }; #endif + + + + + + + + + + + diff --git a/contrib/src/ai/aiCharacter.cxx b/contrib/src/ai/aiCharacter.cxx index fecb869196..e5a95005aa 100644 --- a/contrib/src/ai/aiCharacter.cxx +++ b/contrib/src/ai/aiCharacter.cxx @@ -1,21 +1,21 @@ -// Filename: aiCharacter.cxx -// Created by: Deepak, John, Navin (08Sep09) -// +//////////////////////////////////////////////////////////////////////// +// Filename : aiCharacter.cxx +// Created by : Deepak, John, Navin +// Date : 8 Sep 09 //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) Carnegie Mellon University. All rights reserved. // -// All use of this software is subject to the terms of the revised -// BSD license. You should have received a copy of this license -// along with this source code in a file named "LICENSE." +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." // //////////////////////////////////////////////////////////////////// #include "aiCharacter.h" -AICharacter::AICharacter(string model_name, NodePath model_np, double mass, - double movt_force, double max_force) { +AICharacter::AICharacter(string model_name, NodePath model_np, double mass, double movt_force, double max_force) { _name = model_name; _ai_char_np = model_np; @@ -35,16 +35,18 @@ AICharacter::AICharacter(string model_name, NodePath model_np, double mass, AICharacter::~AICharacter() { } -//////////////////////////////////////////////////////////////////// -// Function: update -// Description: Each character's update will update its ai and -// physics based on his resultant steering force. -// This also makes the character look in the -// direction of the force. -//////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +// +// Function : update +// Description : Each character's update will update its ai and physics +// based on his resultant steering force. +// This also makes the character look at the direction of the force. + +///////////////////////////////////////////////////////////////////////////////////////// + void AICharacter::update() { -if (!_steering->is_off(_steering->BT_none)) { + if(!_steering->is_off(_steering->_none)) { LVecBase3f old_pos = _ai_char_np.get_pos(); @@ -59,7 +61,7 @@ if (!_steering->is_off(_steering->BT_none)) { _ai_char_np.set_pos(old_pos + _velocity) ; - if (steering_force.length() > 0) { + if(steering_force.length() > 0) { _ai_char_np.look_at(old_pos + (direction * 5)); _ai_char_np.set_h(_ai_char_np.get_h() + 180); _ai_char_np.set_p(-_ai_char_np.get_p()); diff --git a/contrib/src/ai/aiCharacter.h b/contrib/src/ai/aiCharacter.h index d628a21818..87a7925dda 100644 --- a/contrib/src/ai/aiCharacter.h +++ b/contrib/src/ai/aiCharacter.h @@ -1,34 +1,42 @@ -// Filename: aiCharacter.h -// Created by: Deepak, John, Navin (08Sep09) -// +//////////////////////////////////////////////////////////////////////// +// Filename : aiCharacter.h +// Created by : Deepak, John, Navin +// Date : 8 Sep 09 //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) Carnegie Mellon University. All rights reserved. // -// All use of this software is subject to the terms of the revised -// BSD license. You should have received a copy of this license along +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along // with this source code in a file named "LICENSE." // //////////////////////////////////////////////////////////////////// -#ifndef AICHARACTER_H -#define AICHARACTER_H +#pragma warning (disable:4996) +#pragma warning (disable:4005) +#pragma warning(disable:4275) + + +#ifndef _AICHARACTER_H +#define _AICHARACTER_H + +#include "aiBehaviors.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Class : AICharacter +// Description : This class is used for creating the ai characters. It assigns both physics and ai +// attributes to the character. It also has an update function which updates the physics and ai +// of the character. This update function is called by the AIWorld update. + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////// class AIBehaviors; class AIWorld; -//////////////////////////////////////////////////////////////////// -// Class : AICharacter -// Description : This class is used for creating the ai characters. -// It assigns both physics and ai attributes to the -// character. It also has an update function which -// updates the physics and ai of the character. -// This update function is called by the AIWorld -// update. -//////////////////////////////////////////////////////////////////// -class AICharacter { -public: +class EXPCL_PANDAAI AICharacter { + public: double _mass; double _max_force; LVecBase3f _velocity; @@ -61,12 +69,10 @@ PUBLISHED: AIBehaviors * get_ai_behaviors(); - // This function is used to enable or disable the guides - // for path finding. + // This function is used to enable or disable the guides for path finding. void set_pf_guide(bool pf_guide); - AICharacter(string model_name, NodePath model_np, double mass, - double movt_force, double max_force); + AICharacter(string model_name, NodePath model_np, double mass, double movt_force, double max_force); ~AICharacter(); }; diff --git a/contrib/src/ai/aiGlobals.h b/contrib/src/ai/aiGlobals.h index 83d01ccde5..0732537ca2 100644 --- a/contrib/src/ai/aiGlobals.h +++ b/contrib/src/ai/aiGlobals.h @@ -1,20 +1,27 @@ -// Filename: aiGlobals.h -// Created by: Deepak, John, Navin (08Sep09) +//////////////////////////////////////////////////////////////////////// +// Filename : aiGlobals.h +// Created by : Deepak, John, Navin +// Date: 8 Sep 09 // //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) Carnegie Mellon University. All rights reserved. // -// All use of this software is subject to the terms of the revised -// BSD license. You should have received a copy of this license -// along with this source code in a file named "LICENSE." +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." // //////////////////////////////////////////////////////////////////// -#ifndef AIGLOBALS_H -#define AIGLOBALS_H +#pragma warning (disable:4996) +#pragma warning (disable:4005) +#pragma warning(disable:4275) +#ifndef _AI_GLOBALS_H +#define _AI_GLOBALS_H + +#include "config_ai.h" #include "pandaFramework.h" #include "textNode.h" #include "pandaSystem.h" diff --git a/contrib/src/ai/aiNode.cxx b/contrib/src/ai/aiNode.cxx index 9696c1f32a..00c1fa57a3 100644 --- a/contrib/src/ai/aiNode.cxx +++ b/contrib/src/ai/aiNode.cxx @@ -6,9 +6,9 @@ // PANDA 3D SOFTWARE // Copyright (c) Carnegie Mellon University. All rights reserved. // -// All use of this software is subject to the terms of the revised -// BSD license. You should have received a copy of this license -// along with this source code in a file named "LICENSE." +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." // //////////////////////////////////////////////////////////////////// diff --git a/contrib/src/ai/aiNode.h b/contrib/src/ai/aiNode.h index e84947c865..b84fe56c0f 100644 --- a/contrib/src/ai/aiNode.h +++ b/contrib/src/ai/aiNode.h @@ -6,9 +6,9 @@ // PANDA 3D SOFTWARE // Copyright (c) Carnegie Mellon University. All rights reserved. // -// All use of this software is subject to the terms of the revised -// BSD license. You should have received a copy of this license -// along with this source code in a file named "LICENSE." +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." // //////////////////////////////////////////////////////////////////// @@ -28,7 +28,7 @@ // tool makes use of this class to generate the nodes // on the mesh. //////////////////////////////////////////////////////////////////// -class AINode { +class EXPCL_PANDAAI AINode { PUBLISHED: // This variable specifies whether the node is an obtacle or not. // Used for dynamic obstacle addition to the environment. diff --git a/contrib/src/ai/aiPathFinder.cxx b/contrib/src/ai/aiPathFinder.cxx index 18c90e88a3..2857b21062 100644 --- a/contrib/src/ai/aiPathFinder.cxx +++ b/contrib/src/ai/aiPathFinder.cxx @@ -1,13 +1,14 @@ -// Filename: aiPathfinder.cxx -// Created by: Deepak, John, Navin (08Sep09) -// +//////////////////////////////////////////////////////////////////////// +// Filename : aiPathFinder.cxx +// Created by : Deepak, John, Navin +// Date : 10 Nov 09 //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) Carnegie Mellon University. All rights reserved. // -// All use of this software is subject to the terms of the revised -// BSD license. You should have received a copy of this license along +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along // with this source code in a file named "LICENSE." // //////////////////////////////////////////////////////////////////// @@ -21,22 +22,22 @@ PathFinder::PathFinder(NavMesh nav_mesh) { PathFinder::~PathFinder() { } -//////////////////////////////////////////////////////////////////// -// Function: find_path -// Description: This function initializes the pathfinding process -// by accepting the source and destination nodes. -// It then calls the generate_path(). -//////////////////////////////////////////////////////////////////// -void PathFinder::find_path(AINode *src_node, AINode *dest_node) { +///////////////////////////////////////////////////////////////////////////////////////// +// +// Function : find_path +// Description : This function initializes the pathfinding process by accepting the +// source and destination nodes. It then calls the generate_path(). + +///////////////////////////////////////////////////////////////////////////////////////// + +void PathFinder::find_path(Node *src_node, Node *dest_node) { _src_node = src_node; _dest_node = dest_node; - // Add a dummy node as the first element of the open list with score - // = -1. - // Inorder to implement a binary heap the index of the elements - // should never be 0. - AINode *_dummy_node = new AINode(-1, -1, LVecBase3f(0.0, 0.0, 0.0), 0, 0, 0); - _dummy_node->_status = _dummy_node->ST_open; + // Add a dummy node as the first element of the open list with score = -1. + // Inorder to implement a binary heap the index of the elements should never be 0. + Node *_dummy_node = new Node(-1, -1, LVecBase3f(0.0, 0.0, 0.0), 0, 0, 0); + _dummy_node->_status = _dummy_node->open; _dummy_node->_score = -1; _open_list.push_back(_dummy_node); @@ -47,23 +48,24 @@ void PathFinder::find_path(AINode *src_node, AINode *dest_node) { generate_path(); } -//////////////////////////////////////////////////////////////////// -// Function: generate_path -// Description: This function performs the pathfinding process -// using the A* algorithm. +///////////////////////////////////////////////////////////////////////////////////////// +// +// Function : generate_path +// Description : This function performs the pathfinding process using the A* algorithm. // It updates the openlist and closelist. -//////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////////////////// + void PathFinder::generate_path() { // All the A* algorithm is implemented here. // The check is > 1 due to the existence of the dummy node. - while (_open_list.size() > 1) { - // The first element of the open list will always be the optimal - // node. - // This is because the open list is a binary heap with element - // having the smallest score at the top of the heap. - AINode* nxt_node = _open_list[1]; + while(_open_list.size() > 1) { + // The first element of the open list will always be the optimal node. + // This is because the open list is a binary heap with element having the + // smallest score at the top of the heap. + Node* nxt_node = _open_list[1]; - if (nxt_node->_grid_x == _dest_node->_grid_x && + if(nxt_node->_grid_x == _dest_node->_grid_x && nxt_node->_grid_y == _dest_node->_grid_y) { // Remove the optimal node from the top of the heap. remove_from_olist(); @@ -81,23 +83,25 @@ void PathFinder::generate_path() { add_to_clist(nxt_node); } } - cout << "DESTINATION NOT REACHABLE MATE!\n"; + cout<<"DESTINATION NOT REACHABLE MATE!"<_neighbours[i] != NULL) { - if (parent_node->_neighbours[i]->_status == parent_node->_neighbours[i]->ST_neutral + for(int i = 0; i < 8; ++i) { + if(parent_node->_neighbours[i] != NULL) { + if(parent_node->_neighbours[i]->_status == parent_node->_neighbours[i]->neutral && parent_node->_neighbours[i]->_type == true) { // Link the neighbor to the parent node. parent_node->_neighbours[i]->_prv_node = parent_node; @@ -110,30 +114,35 @@ void PathFinder::identify_neighbors(AINode *parent_node) { } } -//////////////////////////////////////////////////////////////////// -// Function: calc_node_score -// Description: This function calculates the score of each node. +///////////////////////////////////////////////////////////////////////////////////////// +// +// Function : calc_node_score +// Description : This function calculates the score of each node. // Score = Cost + Heuristics. -//////////////////////////////////////////////////////////////////// -void PathFinder::calc_node_score(AINode *nd) { + +///////////////////////////////////////////////////////////////////////////////////////// + +void PathFinder::calc_node_score(Node *nd) { nd->_cost = calc_cost_frm_src(nd); nd->_heuristic = calc_heuristic(nd); nd->_score = nd->_cost + nd->_heuristic; } -//////////////////////////////////////////////////////////////////// -// Function: calc_cost_frm_src -// Description: This function calculates the cost of each node by -// finding out the number of node traversals required -// to reach the source node. -// Diagonal traversals have have cost = 14. -// Horizontal / Vertical traversals have cost = 10. -//////////////////////////////////////////////////////////////////// -int PathFinder::calc_cost_frm_src(AINode *nd) { +///////////////////////////////////////////////////////////////////////////////////////// +// +// Function : calc_cost_frm_src +// Description : This function calculates the cost of each node by finding out +// the number of node traversals required to reach the source node. +// Diagonal traversals have cost = 14. +// Horizontal / Vertical traversals have cost = 10. + +///////////////////////////////////////////////////////////////////////////////////////// + +int PathFinder::calc_cost_frm_src(Node *nd) { int cost = 0; - AINode *start_node = nd; - while (start_node->_prv_node != _src_node) { - if (is_diagonal_node(start_node)) { + Node *start_node = nd; + while(start_node->_prv_node != _src_node) { + if(is_diagonal_node(start_node)) { cost += 14; } else { @@ -142,7 +151,7 @@ int PathFinder::calc_cost_frm_src(AINode *nd) { start_node = start_node->_prv_node; } // Add the cost of traversal to the source node also. - if (is_diagonal_node(start_node)) { + if(is_diagonal_node(start_node)) { cost += 14; } else { @@ -151,15 +160,16 @@ int PathFinder::calc_cost_frm_src(AINode *nd) { return cost; } -//////////////////////////////////////////////////////////////////// -// Function: calc_heuristic -// Description: This function calculates the heuristic of the nodes -// using Manhattan method. All it does is predict the -// number of node traversals required to reach the -// target node. No diagonal traversals are allowed -// in this technique. -//////////////////////////////////////////////////////////////////// -int PathFinder::calc_heuristic(AINode *nd) { +///////////////////////////////////////////////////////////////////////////////////////// +// +// Function : calc_heuristic +// Description : This function calculates the heuristic of the nodes using Manhattan method. +// All it does is predict the number of node traversals required to reach the target node. +// No diagonal traversals are allowed in this technique. + +///////////////////////////////////////////////////////////////////////////////////////// + +int PathFinder::calc_heuristic(Node *nd) { int row_diff = abs(_dest_node->_grid_x - nd->_grid_x); int col_diff = abs(_dest_node->_grid_y - nd->_grid_y); @@ -167,20 +177,20 @@ int PathFinder::calc_heuristic(AINode *nd) { return heuristic; } -//////////////////////////////////////////////////////////////////// -// Function: is_diagonal_node -// Description: This function checks if the traversal from a -// node is diagonal. -//////////////////////////////////////////////////////////////////// -bool PathFinder::is_diagonal_node(AINode *nd) { - // Calculate the row and column differences between child and parent - // nodes. +///////////////////////////////////////////////////////////////////////////////////////// +// +// Function : is_diagonal_node +// Description : This function checks if the traversal from a node is diagonal. + +///////////////////////////////////////////////////////////////////////////////////////// + +bool PathFinder::is_diagonal_node(Node *nd) { + // Calculate the row and column differences between child and parent nodes. float row_diff = nd->_grid_x - nd->_prv_node->_grid_x; float col_diff = nd->_grid_y - nd->_prv_node->_grid_y; - // Check if the relationship between child and parent node is - // diagonal. - if (row_diff == 0 || col_diff == 0) { + // Check if the relationship between child and parent node is diagonal. + if(row_diff == 0 || col_diff == 0) { return false; } else { @@ -188,35 +198,37 @@ bool PathFinder::is_diagonal_node(AINode *nd) { } } -//////////////////////////////////////////////////////////////////// -// Function: add_to_olist -// Description: This function adds a node to the open list heap. +///////////////////////////////////////////////////////////////////////////////////////// +// +// Function : add_to_olist +// Description : This function adds a node to the open list heap. // A binay heap is maintained to improve the search. -//////////////////////////////////////////////////////////////////// -void PathFinder::add_to_olist(AINode *nd) { + +///////////////////////////////////////////////////////////////////////////////////////// + + +void PathFinder::add_to_olist(Node *nd) { // Variables required to search the binary heap. - AINode *child_node, *parent_node; + Node *child_node, *parent_node; int child_idx, parent_idx; // Set the status as open. - nd->_status = nd->ST_open; + nd->_status = nd->open; // Add the node to the open list. _open_list.push_back(nd); - // Find the parent and child nodes and create temporary nodes out - // of them. In a binary heap the children of a parent node are - // always i*2 and i*2 + 1, where i is the index of the parent node - // in the heap. And hence, the parent of a node can be easily found - // out by dividing by 2 and rounding it. + // Find the parent and child nodes and create temporary nodes out of them. + // In a binary heap the children of a parent node are always i*2 and i*2 + 1, + // where i is the index of the parent node in the heap. And hence, the parent + // of a node can be easily found out by dividing by 2 and rounding it. child_idx = _open_list.size() - 1; parent_idx = child_idx / 2; child_node = _open_list[child_idx]; parent_node = _open_list[parent_idx]; - // Keep traversing the heap until the lowest element in the list is - // bubbled + // Keep traversing the heap until the lowest element in the list is bubbled // to the top of the heap. - while (_open_list[child_idx]->_score <= _open_list[parent_idx]->_score) { + while(_open_list[child_idx]->_score <= _open_list[parent_idx]->_score) { // Swap the parent node and the child node. _open_list[parent_idx] = child_node; _open_list[child_idx] = parent_node; @@ -230,53 +242,52 @@ void PathFinder::add_to_olist(AINode *nd) { parent_node = _open_list[parent_idx]; } - // At this point the AINode with the smallest score will be at the - // top of the heap. + // At this point the Node with the smallest score will be at the top of the heap. } -//////////////////////////////////////////////////////////////////// -// Function: remove_from_olist -// Description: This function removes a node from the open list. +///////////////////////////////////////////////////////////////////////////////////////// +// +// Function : remove_from_olist +// Description : This function removes a node from the open list. // During the removal the binary heap is maintained. -//////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////////////////// + void PathFinder::remove_from_olist() { // Variables for maintaining the binary heap. - AINode *child_node, *child_node_1, *child_node_2; + Node *child_node, *child_node_1, *child_node_2; int child_idx, child_idx_1, child_idx_2; - // Remove the AINode at index 1 from the open list binary heap. - // Note: AINode at index 0 of open list is a dummy node. + // Remove the Node at index 1 from the open list binary heap. + // Note: Node at index 0 of open list is a dummy node. _open_list.erase(_open_list.begin() + 1); - if (_open_list.size() > 1) { + if(_open_list.size() > 1) { // Store the last element in the open list to a temp_node. - AINode *temp_node = _open_list[_open_list.size() - 1]; + Node *temp_node = _open_list[_open_list.size() - 1]; - // Shift the elements of the open list to the right by 1 element - // circularly, excluding element at 0 index. - for (int i = _open_list.size() - 1; i > 1; --i) { + // Shift the elements of the open list to the right by 1 element circularly, excluding element at 0 index. + for(int i = _open_list.size() - 1; i > 1; --i) { _open_list[i] = _open_list[i - 1]; } // Assign the temp_node to 1st element in the open list. _open_list[1] = temp_node; - // Set the iterator for traversing the node from index 1 in - // the heap. + // Set the iterator for traversing the node from index 1 in the heap. unsigned int k = 1; - // This loop traverses down the open list till the node reaches - // the correct position in the binary heap. - while (true) { - if ((k * 2 + 1) < _open_list.size()) { + // This loop traverses down the open list till the node reaches the correct position in the binary heap. + while(true) { + if((k * 2 + 1) < _open_list.size()) { // Two children exists for the parent node. child_idx_1 = k * 2; child_idx_2 = k * 2 + 1; child_node_1 = _open_list[child_idx_1]; child_node_2 = _open_list[child_idx_2]; - if (_open_list[child_idx_1]->_score < _open_list[child_idx_2]->_score) { - if (_open_list[k]->_score > _open_list[child_idx_1]->_score) { + if(_open_list[child_idx_1]->_score < _open_list[child_idx_2]->_score) { + if(_open_list[k]->_score > _open_list[child_idx_1]->_score) { // Swap the parent node and the child node. _open_list[child_idx_1] = _open_list[k]; _open_list[k] = child_node_1; @@ -289,7 +300,7 @@ void PathFinder::remove_from_olist() { } } else { - if (_open_list[k]->_score > _open_list[child_idx_2]->_score) { + if(_open_list[k]->_score > _open_list[child_idx_2]->_score) { // Swap the parent node and the child node. _open_list[child_idx_2] = _open_list[k]; _open_list[k] = child_node_2; @@ -302,12 +313,12 @@ void PathFinder::remove_from_olist() { } } } - else if ((k * 2) < _open_list.size()) { + else if((k * 2) < _open_list.size()) { // Only one child exists for the parent node. child_idx = k * 2; child_node = _open_list[child_idx]; - if (_open_list[k]->_score > _open_list[child_idx]->_score) { + if(_open_list[k]->_score > _open_list[child_idx]->_score) { // Swap the parent node and the child node. _open_list[child_idx] = _open_list[k]; _open_list[k] = child_node; @@ -326,50 +337,57 @@ void PathFinder::remove_from_olist() { } } - // At this point the AINode was successfully removed and the binary - // heap re-arranged. + // At this point the Node was succesfully removed and the binary heap re-arranged. } -//////////////////////////////////////////////////////////////////// -// Function: add_to_clist -// Description: This function adds a node to the closed list. -//////////////////////////////////////////////////////////////////// -void PathFinder::add_to_clist(AINode *nd) { +///////////////////////////////////////////////////////////////////////////////////////// +// +// Function : add_to_clist +// Description : This function adds a node to the closed list. + +///////////////////////////////////////////////////////////////////////////////////////// + +void PathFinder::add_to_clist(Node *nd) { // Set the status as closed. - nd->_status = nd->ST_close; + nd->_status = nd->close; // Add the node to the close list. _closed_list.push_back(nd); } -//////////////////////////////////////////////////////////////////// -// Function: remove_from_clist -// Description: This function removes a node from the closed list. -//////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +// +// Function : remove_from_clist +// Description : This function removes a node from the closed list. + +///////////////////////////////////////////////////////////////////////////////////////// + void PathFinder::remove_from_clist(int r, int c) { - for (unsigned int i = 0; i < _closed_list.size(); ++i) { - if (_closed_list[i]->_grid_x == r && _closed_list[i]->_grid_y == c) { + for(unsigned int i = 0; i < _closed_list.size(); ++i) { + if(_closed_list[i]->_grid_x == r && _closed_list[i]->_grid_y == c) { _closed_list.erase(_closed_list.begin() + i); break; } } } -//////////////////////////////////////////////////////////////////// -// Function: find_in_mesh -// Description: This function allows the user to pass a position -// and it returns the corresponding node on the -// navigation mesh. A very useful function as it allows -// for dynamic updation of the mesh based on position. -//////////////////////////////////////////////////////////////////// -AINode* find_in_mesh(NavMesh nav_mesh, LVecBase3f pos, int grid_size) { +///////////////////////////////////////////////////////////////////////////////////////// +// +// Function : find_in_mesh +// Description : This function allows the user to pass a position and it returns the +// corresponding node on the navigation mesh. A very useful function as +// it allows for dynamic updation of the mesh based on position. + +///////////////////////////////////////////////////////////////////////////////////////// + +Node* find_in_mesh(NavMesh nav_mesh, LVecBase3f pos, int grid_size) { int size = grid_size; float x = pos[0]; float y = pos[1]; - for (int i = 0; i < size; ++i) { - for (int j = 0; j < size; ++j) { - if (nav_mesh[i][j] != NULL && nav_mesh[i][j]->contains(x, y)) { - return (nav_mesh[i][j]); + for(int i = 0; i < size; ++i) { + for(int j = 0; j < size; ++j) { + if(nav_mesh[i][j] != NULL && nav_mesh[i][j]->contains(x, y)) { + return(nav_mesh[i][j]); } } } diff --git a/contrib/src/ai/aiPathFinder.h b/contrib/src/ai/aiPathFinder.h index 8e71314b89..c1c167ad54 100644 --- a/contrib/src/ai/aiPathFinder.h +++ b/contrib/src/ai/aiPathFinder.h @@ -1,61 +1,64 @@ -// Filename: aiPathfinder.h -// Created by: Deepak, John, Navin (08Sep09) -// +//////////////////////////////////////////////////////////////////////// +// Filename : aiPathFinder.h +// Created by : Deepak, John, Navin +// Date : 10 Nov 09 //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) Carnegie Mellon University. All rights reserved. // -// All use of this software is subject to the terms of the revised -// BSD license. You should have received a copy of this license along +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along // with this source code in a file named "LICENSE." // //////////////////////////////////////////////////////////////////// -#ifndef PATHFINDER_H -#define PATHFINDER_H +#ifndef _PATHFINDER_H +#define _PATHFINDER_H -#include "aiNode.h" +#include "meshNode.h" #include "cmath.h" #include "lineSegs.h" -typedef vector NodeArray; +typedef vector NodeArray; typedef vector NavMesh; -AINode* find_in_mesh(NavMesh nav_mesh, LVecBase3f pos, int grid_size); +Node* find_in_mesh(NavMesh nav_mesh, LVecBase3f pos, int grid_size); -//////////////////////////////////////////////////////////////////// -// Class : PathFinder -// Description : This class implements pathfinding using the A* -// algorithm. It also uses a Binary Heap search to -// search the open list. The heuristics are -// calculated using the manhattan method. -//////////////////////////////////////////////////////////////////// -class PathFinder { -PUBLISHED: - AINode *_src_node; - AINode *_dest_node; - vector _open_list; - vector _closed_list; +//////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Class : PathFinder +// Description : This class implements pathfinding using A* algorithm. It also uses a Binary Heap search to +// search the open list. The heuristics are calculated using the manhattan method. + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class EXPCL_PANDAAI PathFinder { +public: + Node *_src_node; + Node *_dest_node; + vector _open_list; + vector _closed_list; NavMesh _grid; - void identify_neighbors(AINode *nd); - int calc_cost_frm_src(AINode *nd); - int calc_heuristic(AINode *nd); - void calc_node_score(AINode *nd); - bool is_diagonal_node(AINode *nd); + void identify_neighbors(Node *nd); + int calc_cost_frm_src(Node *nd); + int calc_heuristic(Node *nd); + void calc_node_score(Node *nd); + bool is_diagonal_node(Node *nd); - void add_to_olist(AINode *nd); + void add_to_olist(Node *nd); void remove_from_olist(); - void add_to_clist(AINode *nd); + void add_to_clist(Node *nd); void remove_from_clist(int r, int c); void generate_path(); - void find_path(AINode *src_node, AINode *dest_node); + void find_path(Node *src_node, Node *dest_node); PathFinder(NavMesh nav_mesh); ~PathFinder(); }; #endif + diff --git a/contrib/src/ai/aiWorld.cxx b/contrib/src/ai/aiWorld.cxx index bb6fa90804..418a4f99aa 100644 --- a/contrib/src/ai/aiWorld.cxx +++ b/contrib/src/ai/aiWorld.cxx @@ -1,14 +1,15 @@ -// Filename: aiWorld.cxx -// Created by: Deepak, John, Navin (08Sep09) -// +//////////////////////////////////////////////////////////////////////// +// Filename : aiWorld.cxx +// Created by : Deepak, John, Navin +// Date : 8 Sep 09 //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) Carnegie Mellon University. All rights reserved. // -// All use of this software is subject to the terms of the revised -// BSD license. You should have received a copy of this license -// along with this source code in a file named "LICENSE." +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." // //////////////////////////////////////////////////////////////////// @@ -36,11 +37,11 @@ void AIWorld::remove_ai_char(string name) { void AIWorld::remove_ai_char_from_flock(string name) { AICharPool::node *ai_pool; ai_pool = _ai_char_pool->_head; - while ((ai_pool) != NULL) { - for (unsigned int i = 0; i < _flock_pool.size(); ++i) { - if (ai_pool->_ai_char->_ai_char_flock_id == _flock_pool[i]->get_id()) { - for (unsigned int j = 0; j<_flock_pool[i]->_ai_char_list.size(); ++j) { - if (_flock_pool[i]->_ai_char_list[j]->_name == name) { + while((ai_pool) != NULL) { + for(unsigned int i = 0; i < _flock_pool.size(); ++i) { + if(ai_pool->_ai_char->_ai_char_flock_id == _flock_pool[i]->get_id()) { + for(unsigned int j = 0; j<_flock_pool[i]->_ai_char_list.size(); ++j) { + if(_flock_pool[i]->_ai_char_list[j]->_name == name) { _flock_pool[i]->_ai_char_list.erase(_flock_pool[i]->_ai_char_list.begin() + j); return; } @@ -55,47 +56,51 @@ void AIWorld::print_list() { _ai_char_pool->print_list(); } -//////////////////////////////////////////////////////////////////// -// Function: update -// Description: The AIWorld update function calls the update -// function of all the AI characters which have been -// added to the AIWorld. -//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +// Function : update +// Description : The AIWorld update function calls the update function of all the +// AI characters which have been added to the AIWorld. + +///////////////////////////////////////////////////////////////////////////////// + void AIWorld::update() { AICharPool::node *ai_pool; ai_pool = _ai_char_pool->_head; - while ((ai_pool)!=NULL) { + while((ai_pool)!=NULL) { ai_pool->_ai_char->update(); ai_pool = ai_pool->_next; } } -//////////////////////////////////////////////////////////////////// -// Function: add_flock -// Description: This function adds all the AI characters in the -// Flock object to the AICharPool. This function -// allows adding the AI characetrs as part of a flock. -//////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +// +// Function : add_flock +// Description : This function adds all the AI characters in the Flock object to +// the AICharPool. This function allows adding the AI characetrs as +// part of a flock. + +///////////////////////////////////////////////////////////////////////////////// + void AIWorld::add_flock(Flock *flock) { // Add all the ai_characters in the flock to the AIWorld. - for (unsigned int i = 0; i < flock->_ai_char_list.size(); ++i) { + for(unsigned int i = 0; i < flock->_ai_char_list.size(); ++i) { this->add_ai_char(flock->_ai_char_list[i]); } // Add the flock to the flock pool. _flock_pool.push_back(flock); } -//////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// // -// Function: get_flock -// Description: This function returns a handle to the Flock whose -// id is passed. -//////////////////////////////////////////////////////////////////// +// Function : get_flock +// Description : This function returns a handle to the Flock whose id is passed. + +///////////////////////////////////////////////////////////////////////////////// Flock AIWorld::get_flock(unsigned int flock_id) { - for (unsigned int i=0; i < _flock_pool.size(); ++i) { - if (_flock_pool[i]->get_id() == flock_id) { + for(unsigned int i=0; i < _flock_pool.size(); ++i) { + if(_flock_pool[i]->get_id() == flock_id) { return *_flock_pool[i]; } } @@ -103,52 +108,61 @@ Flock AIWorld::get_flock(unsigned int flock_id) { return *null_flock; } -//////////////////////////////////////////////////////////////////// -// Function: remove_flock -// Description: This function removes the flock behavior completely. -//////////////////////////////////////////////////////////////////// -void AIWorld::remove_flock(unsigned int flock_id) { - for (unsigned int i = 0; i < _flock_pool.size(); ++i) { - if (_flock_pool[i]->get_id() == flock_id) { - for (unsigned int j = 0; j < _flock_pool[i]->_ai_char_list.size(); ++j) { - _flock_pool[i]->_ai_char_list[j]->get_ai_behaviors()->turn_off("flock_activate"); - _flock_pool[i]->_ai_char_list[j]->get_ai_behaviors()->turn_off("flock"); - _flock_pool[i]->_ai_char_list[j]->get_ai_behaviors()->_flock_group = NULL; - } - _flock_pool.erase(_flock_pool.begin() + i); - break; - } - } -} +///////////////////////////////////////////////////////////////////////////////// +// +// Function : remove_flock +// Description : This function removes the flock behavior completely. -//////////////////////////////////////////////////////////////////// -// Function: flock_off -// Description: This function turns off the flock behavior -// temporarily. Similar to pausing the behavior. -//////////////////////////////////////////////////////////////////// -void AIWorld::flock_off(unsigned int flock_id) { - for (unsigned int i = 0; i < _flock_pool.size(); ++i) { - if (_flock_pool[i]->get_id() == flock_id) { - for (unsigned int j = 0; j < _flock_pool[i]->_ai_char_list.size(); ++j) { +///////////////////////////////////////////////////////////////////////////////// + +void AIWorld::remove_flock(unsigned int flock_id) { + for(unsigned int i = 0; i < _flock_pool.size(); ++i) { + if(_flock_pool[i]->get_id() == flock_id) { + for(unsigned int j = 0; j < _flock_pool[i]->_ai_char_list.size(); ++j) { _flock_pool[i]->_ai_char_list[j]->get_ai_behaviors()->turn_off("flock_activate"); _flock_pool[i]->_ai_char_list[j]->get_ai_behaviors()->turn_off("flock"); - } - break; + _flock_pool[i]->_ai_char_list[j]->get_ai_behaviors()->_flock_group = NULL; + } + _flock_pool.erase(_flock_pool.begin() + i); + break; } } } -//////////////////////////////////////////////////////////////////// -// Function: flock_on -// Description: This function turns on the flock behavior. -//////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +// +// Function : flock_off +// Description : This function turns off the flock behavior temporarily. Similar to +// pausing the behavior. + +///////////////////////////////////////////////////////////////////////////////// + +void AIWorld::flock_off(unsigned int flock_id) { + for(unsigned int i = 0; i < _flock_pool.size(); ++i) { + if(_flock_pool[i]->get_id() == flock_id) { + for(unsigned int j = 0; j < _flock_pool[i]->_ai_char_list.size(); ++j) { + _flock_pool[i]->_ai_char_list[j]->get_ai_behaviors()->turn_off("flock_activate"); + _flock_pool[i]->_ai_char_list[j]->get_ai_behaviors()->turn_off("flock"); + } + break; + } + } +} + +///////////////////////////////////////////////////////////////////////////////// +// +// Function : flock_on +// Description : This function turns on the flock behavior. + +///////////////////////////////////////////////////////////////////////////////// + void AIWorld::flock_on(unsigned int flock_id) { - for (unsigned int i = 0; i < _flock_pool.size(); ++i) { - if (_flock_pool[i]->get_id() == flock_id) { - for (unsigned int j = 0; j < _flock_pool[i]->_ai_char_list.size(); ++j) { - _flock_pool[i]->_ai_char_list[j]->get_ai_behaviors()->turn_on("flock_activate"); - } - break; + for(unsigned int i = 0; i < _flock_pool.size(); ++i) { + if(_flock_pool[i]->get_id() == flock_id) { + for(unsigned int j = 0; j < _flock_pool[i]->_ai_char_list.size(); ++j) { + _flock_pool[i]->_ai_char_list[j]->get_ai_behaviors()->turn_on("flock_activate"); + } + break; } } } @@ -164,7 +178,7 @@ void AICharPool::append(AICharacter *ai_ch) { node *q; node *t; - if (_head == NULL) { + if(_head == NULL) { q = new node(); q->_ai_char = ai_ch; q->_next = NULL; @@ -172,7 +186,7 @@ void AICharPool::append(AICharacter *ai_ch) { } else { q = _head; - while ( q->_next != NULL) { + while( q->_next != NULL) { q = q->_next; } @@ -188,13 +202,13 @@ void AICharPool::del(string name) { node *r; q = _head; - if (_head == NULL) { + if(_head==NULL) { return; } // Only one node in the linked list - if (q->_next == NULL) { - if (q->_ai_char->_name == name) { + if(q->_next == NULL) { + if(q->_ai_char->_name == name) { _head = NULL; delete q; } @@ -202,10 +216,10 @@ void AICharPool::del(string name) { } r = q; - while ( q != NULL) { - if ( q->_ai_char->_name == name) { + while( q != NULL) { + if( q->_ai_char->_name == name) { // Special case - if (q == _head) { + if(q == _head) { _head = q->_next; delete q; return; @@ -220,38 +234,46 @@ void AICharPool::del(string name) { } } -//////////////////////////////////////////////////////////////////// -// Function: print_list -// Description: This function prints the ai characters in the -// AICharPool. Used for debugging purposes. -//////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +// +// Function : print_list +// Description : This function prints the ai characters in the AICharPool. Used for +// debugging purposes. + +///////////////////////////////////////////////////////////////////////////////// + void AICharPool::print_list() { node* q; q = _head; - while (q != NULL) { - cout << q->_ai_char->_name << "\n"; + while(q != NULL) { + cout<_ai_char->_name<_next; } } -//////////////////////////////////////////////////////////////////// -// Function: add_obstacle -// Description: This function adds the nodepath as an obstacle that -// is needed by the obstacle avoidance behavior. -//////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +// +// Function : add_obstacle +// Description : This function adds the nodepath as an obstacle that is needed +// by the obstacle avoidance behavior. + +///////////////////////////////////////////////////////////////////////////////// + void AIWorld::add_obstacle(NodePath obstacle) { _obstacles.push_back(obstacle); } -//////////////////////////////////////////////////////////////////// -// Function: remove_obstacle -// Description: This function removes the nodepath from the -// obstacles list that is needed by the obstacle -// avoidance behavior. -//////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +// +// Function : remove_obstacle +// Description : This function removes the nodepath from the obstacles list that is needed +// by the obstacle avoidance behavior. + +///////////////////////////////////////////////////////////////////////////////// + void AIWorld::remove_obstacle(NodePath obstacle) { - for (unsigned int i = 0; i <= _obstacles.size(); ++i) { - if (_obstacles[i] == obstacle) { + for(unsigned int i = 0; i <= _obstacles.size(); ++i) { + if(_obstacles[i] == obstacle) { _obstacles.erase(_obstacles.begin() + i); } } diff --git a/contrib/src/ai/aiWorld.h b/contrib/src/ai/aiWorld.h index 2bb1838321..bd6f0be3a6 100644 --- a/contrib/src/ai/aiWorld.h +++ b/contrib/src/ai/aiWorld.h @@ -1,19 +1,25 @@ -// Filename: aiWorld.h -// Created by: Deepak, John, Navin (08Sep09) -// +//////////////////////////////////////////////////////////////////////// +// Filename : aiWorld.h +// Created by : Deepak, John, Navin +// Date : 8 Sep 09 //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) Carnegie Mellon University. All rights reserved. // -// All use of this software is subject to the terms of the revised -// BSD license. You should have received a copy of this license along +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along // with this source code in a file named "LICENSE." // //////////////////////////////////////////////////////////////////// -#ifndef AIWORLD_H -#define AIWORLD_H +#pragma warning (disable:4996) +#pragma warning (disable:4005) +#pragma warning(disable:4275) + + +#ifndef _AIWORLD_H +#define _AIWORLD_H #include "aiGlobals.h" #include "aiCharacter.h" @@ -22,66 +28,81 @@ class AICharacter; class Flock; -//////////////////////////////////////////////////////////////////// -// Class : AICharPool -// Description : This class implements a linked list of AI -// Characters allowing the user to add and delete -// characters from the linked list. -// This will be used in the AIWorld class. -//////////////////////////////////////////////////////////////////// -class AICharPool { -public: - struct node { - AICharacter * _ai_char; - node * _next; - }; +/////////////////////////////////////////////////////////////////////// +// +// Class : AICharPool +// Description : This class implements a linked list of AI Characters allowing +// the user to add and delete characters from the linked list. +// This will be used in the AIWorld class. - node* _head; - AICharPool(); - ~AICharPool(); - void append(AICharacter *ai_ch); - void del(string name); - void print_list(); +//////////////////////////////////////////////////////////////////////// + + +class EXPCL_PANDAAI AICharPool { + public: + struct node { + AICharacter * _ai_char; + node * _next; + } ; + + node* _head; + AICharPool(); + ~AICharPool(); + void append(AICharacter *ai_ch); + void del(string name); + void print_list(); }; -//////////////////////////////////////////////////////////////////// -// Class : AIWorld -// Description : A class that implements the virtual AI world which -// keeps track of the AI characters active at any -// given time. It contains a linked list of AI -// characters, obstactle data and unique name for each -// character. It also updates each characters state. -// The AI characters can also be added to the world -// as flocks. -//////////////////////////////////////////////////////////////////// -class AIWorld { -private: + +/////////////////////////////////////////////////////////////////////// +// +// Class : AIWorld +// Description : A class that implements the virtual AI world which keeps track +// of the AI characters active at any given time. It contains a linked +// list of AI characters, obstactle data and unique name for each +// character. It also updates each characters state. The AI characters +// can also be added to the world as flocks. + +//////////////////////////////////////////////////////////////////////// + + +class EXPCL_PANDAAI AIWorld { + private: AICharPool * _ai_char_pool; NodePath _render; -public: - vector _obstacles; - typedef std::vector FlockPool; - FlockPool _flock_pool; - void remove_ai_char_from_flock(string name); + public: + vector _obstacles; + typedef std::vector FlockPool; + FlockPool _flock_pool; + void remove_ai_char_from_flock(string name); PUBLISHED: - AIWorld(NodePath render); - ~AIWorld(); + AIWorld(NodePath render); + ~AIWorld(); - void add_ai_char(AICharacter *ai_ch); - void remove_ai_char(string name); + void add_ai_char(AICharacter *ai_ch); + void remove_ai_char(string name); - void add_flock(Flock *flock); - void flock_off(unsigned int flock_id); - void flock_on(unsigned int flock_id); - void remove_flock(unsigned int flock_id); - Flock get_flock(unsigned int flock_id); + void add_flock(Flock *flock); + void flock_off(unsigned int flock_id); + void flock_on(unsigned int flock_id); + void remove_flock(unsigned int flock_id); + Flock get_flock(unsigned int flock_id); - void add_obstacle(NodePath obstacle); - void remove_obstacle(NodePath obstacle); + void add_obstacle(NodePath obstacle); + void remove_obstacle(NodePath obstacle); - void print_list(); - void update(); + void print_list(); + void update(); }; #endif + + + + + + + + + diff --git a/contrib/src/ai/ai_composite1.cxx b/contrib/src/ai/ai_composite1.cxx index 25a0755143..959215f925 100644 --- a/contrib/src/ai/ai_composite1.cxx +++ b/contrib/src/ai/ai_composite1.cxx @@ -18,3 +18,4 @@ #include "aiNode.cxx" #include "aiPathFinder.cxx" +#include "meshNode.cxx" diff --git a/contrib/src/ai/arrival.cxx b/contrib/src/ai/arrival.cxx index ee2d2827bb..329955aba1 100644 --- a/contrib/src/ai/arrival.cxx +++ b/contrib/src/ai/arrival.cxx @@ -1,14 +1,15 @@ -// Filename: arrival.cxx -// Created by: Deepak, John, Navin (24Oct09) -// +//////////////////////////////////////////////////////////////////////// +// Filename : arrival.cxx +// Created by : Deepak, John, Navin +// Date : 24 Oct 09 //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) Carnegie Mellon University. All rights reserved. // -// All use of this software is subject to the terms of the revised -// BSD license. You should have received a copy of this license -// along with this source code in a file named "LICENSE." +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." // //////////////////////////////////////////////////////////////////// @@ -24,42 +25,42 @@ Arrival::Arrival(AICharacter *ai_ch, double distance) { Arrival::~Arrival() { } -//////////////////////////////////////////////////////////////////// -// Function: do_arrival -// Description: This function performs the arrival and returns an -// arrival force which is used in the -// calculate_prioritized function. In case the steering -// force is zero, it resets to arrival_activate. The -// arrival behavior works only when seek or pursue is -// active. This function is not to be used by the user. -//////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +// +// Function : do_arrival +// Description : This function performs the arrival and returns an arrival force which is used +// in the calculate_prioritized function. +// In case the steering force = 0, it resets to arrival_activate. +// The arrival behavior works only when seek or pursue is active. +// This function is not to be used by the user. + +///////////////////////////////////////////////////////////////////////////////// + LVecBase3f Arrival::do_arrival() { LVecBase3f direction_to_target; double distance; - if (_arrival_type) { - direction_to_target = _ai_char->get_ai_behaviors()->_pursue_obj->_pursue_target.get_pos(_ai_char->_window_render) - - _ai_char->_ai_char_np.get_pos(_ai_char->_window_render); + if(_arrival_type) { + direction_to_target = _ai_char->get_ai_behaviors()->_pursue_obj->_pursue_target.get_pos(_ai_char->_window_render) - _ai_char->_ai_char_np.get_pos(_ai_char->_window_render); } else { - direction_to_target = _ai_char->get_ai_behaviors()->_seek_obj->_seek_position - - _ai_char->_ai_char_np.get_pos(_ai_char->_window_render); + direction_to_target = _ai_char->get_ai_behaviors()->_seek_obj->_seek_position - _ai_char->_ai_char_np.get_pos(_ai_char->_window_render); } distance = direction_to_target.length(); _arrival_direction = direction_to_target; _arrival_direction.normalize(); - if (int(distance) == 0) { + if(int(distance) == 0) { _ai_char->_steering->_steering_force = LVecBase3f(0.0, 0.0, 0.0); _ai_char->_steering->_arrival_force = LVecBase3f(0.0, 0.0, 0.0); - if (_ai_char->_steering->_seek_obj != NULL) { + if(_ai_char->_steering->_seek_obj != NULL) { _ai_char->_steering->turn_off("arrival"); _ai_char->_steering->turn_on("arrival_activate"); } _arrival_done = true; - return (LVecBase3f(0.0, 0.0, 0.0)); + return(LVecBase3f(0.0, 0.0, 0.0)); } else { _arrival_done = false; @@ -68,36 +69,37 @@ LVecBase3f Arrival::do_arrival() { double u = _ai_char->get_velocity().length(); LVecBase3f desired_force = ((u * u) / (2 * distance)) * _ai_char->get_mass(); - if (_ai_char->_steering->_seek_obj != NULL) { - return (desired_force); + if(_ai_char->_steering->_seek_obj != NULL) { + return(desired_force); } - if (_ai_char->_steering->_pursue_obj != NULL) { + if(_ai_char->_steering->_pursue_obj != NULL) { - if (distance > _arrival_distance) { + if(distance > _arrival_distance) { _ai_char->_steering->turn_off("arrival"); _ai_char->_steering->turn_on("arrival_activate"); _ai_char->_steering->resume_ai("pursue"); } - return (desired_force); + return(desired_force); } - cout << "Arrival works only with seek and pursue\n"; - return (LVecBase3f(0.0, 0.0, 0.0)); + cout<<"Arrival works only with seek and pursue"<_ai_char_np.get_pos(_ai_char->_window_render) - _ai_char->get_ai_behaviors()->_pursue_obj->_pursue_target.get_pos(_ai_char->_window_render)); } else { @@ -105,15 +107,15 @@ void Arrival::arrival_activate() { } double distance = dirn.length(); - if (distance < _arrival_distance && _ai_char->_steering->_steering_force.length() > 0) { + if(distance < _arrival_distance && _ai_char->_steering->_steering_force.length() > 0) { _ai_char->_steering->turn_off("arrival_activate"); _ai_char->_steering->turn_on("arrival"); - if (_ai_char->_steering->is_on(_ai_char->_steering->BT_seek)) { + if(_ai_char->_steering->is_on(_ai_char->_steering->_seek)) { _ai_char->_steering->turn_off("seek"); } - if (_ai_char->_steering->is_on(_ai_char->_steering->BT_pursue)) { + if(_ai_char->_steering->is_on(_ai_char->_steering->_pursue)) { _ai_char->_steering->pause_ai("pursue"); } } diff --git a/contrib/src/ai/arrival.h b/contrib/src/ai/arrival.h index b66c286026..69c0709e7a 100644 --- a/contrib/src/ai/arrival.h +++ b/contrib/src/ai/arrival.h @@ -1,29 +1,27 @@ -// Filename: arrival.h -// Created by: Deepak, John, Navin (24Oct09) -// +//////////////////////////////////////////////////////////////////////// +// Filename : arrival.h +// Created by : Deepak, John, Navin +// Date : 24 Oct 09 //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) Carnegie Mellon University. All rights reserved. // -// All use of this software is subject to the terms of the revised -// BSD license. You should have received a copy of this license -// along with this source code in a file named "LICENSE." +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." // //////////////////////////////////////////////////////////////////// -#ifndef ARRIVAL_H -#define ARRIVAL_H + +#ifndef _ARRIVAL_H +#define _ARRIVAL_H #include "aiGlobals.h" #include "aiCharacter.h" class AICharacter; -//////////////////////////////////////////////////////////////////// -// Class : Arrival -// Description : This class handles all calls to the arrival behavior -//////////////////////////////////////////////////////////////////// -class Arrival { +class EXPCL_PANDAAI Arrival { public: AICharacter *_ai_char; @@ -34,8 +32,7 @@ public: LVecBase3f _arrival_direction; bool _arrival_done; - // This flag specifies if the arrival behavior is being used with - // seek or pursue behavior. + // This flag specifies if the arrival behavior is being used with seek or pursue behavior. // True = used with pursue. // False = used with seek. bool _arrival_type; diff --git a/contrib/src/ai/evade.cxx b/contrib/src/ai/evade.cxx index 61cbaf4d12..149ab4fbf4 100644 --- a/contrib/src/ai/evade.cxx +++ b/contrib/src/ai/evade.cxx @@ -1,22 +1,22 @@ -// Filename: evade.cxx -// Created by: Deepak, John, Navin (24Oct09) -// +//////////////////////////////////////////////////////////////////////// +// Filename : evade.cxx +// Created by : Deepak, John, Navin +// Date : 24 Oct 09 //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) Carnegie Mellon University. All rights reserved. // -// All use of this software is subject to the terms of the revised -// BSD license. You should have received a copy of this license -// along with this source code in a file named "LICENSE." +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." // //////////////////////////////////////////////////////////////////// #include "evade.h" -Evade:: -Evade(AICharacter *ai_ch, NodePath target_object, - double panic_distance, double relax_distance, float evade_wt) { +Evade::Evade(AICharacter *ai_ch, NodePath target_object, double panic_distance, + double relax_distance, float evade_wt) { _ai_char = ai_ch; _evade_target = target_object; @@ -31,56 +31,58 @@ Evade(AICharacter *ai_ch, NodePath target_object, Evade::~Evade() { } -//////////////////////////////////////////////////////////////////// -// Function: do_evade -// Description: This function performs the evade and returns an -// evade force which is used in the -// calculate_prioritized function. In case the -// AICharacter is past the (panic + relax) distance, -// it resets to evade_activate. This function is not -// to be used by the user. -//////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +// +// Function : do_evade +// Description : This function performs the evade and returns an evade force which is used +// in the calculate_prioritized function. +// In case the AICharacter is past the (panic + relax) distance, +// it resets to evade_activate. +// This function is not to be used by the user. + +///////////////////////////////////////////////////////////////////////////////// + LVecBase3f Evade::do_evade() { assert(_evade_target && "evade target not assigned"); - _evade_direction = _ai_char->_ai_char_np.get_pos(_ai_char->_window_render) - - _evade_target.get_pos(_ai_char->_window_render); + _evade_direction = _ai_char->_ai_char_np.get_pos(_ai_char->_window_render) - _evade_target.get_pos(_ai_char->_window_render); double distance = _evade_direction.length(); _evade_direction.normalize(); LVecBase3f desired_force = _evade_direction * _ai_char->_movt_force; - if (distance > (_evade_distance + _evade_relax_distance)) { - if ((_ai_char->_steering->_behaviors_flags | - _ai_char->_steering->BT_evade) == _ai_char->_steering->BT_evade) { + if(distance > (_evade_distance + _evade_relax_distance)) { + if((_ai_char->_steering->_behaviors_flags | _ai_char->_steering->_evade) == _ai_char->_steering->_evade) { _ai_char->_steering->_steering_force = LVecBase3f(0.0, 0.0, 0.0); } _ai_char->_steering->turn_off("evade"); _ai_char->_steering->turn_on("evade_activate"); _evade_done = true; - return (LVecBase3f(0.0, 0.0, 0.0)); - } else { - _evade_done = false; - return (desired_force); + return(LVecBase3f(0.0, 0.0, 0.0)); + } + else { + _evade_done = false; + return(desired_force); } } -//////////////////////////////////////////////////////////////////// -// Function: evade_activate -// Description: This function checks for whether the target is -// within the panic distance. -// When this is true, it calls the do_evade function -// and sets the evade direction. -// This function is not to be used by the user. -//////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +// +// Function : evade_activate +// Description : This function checks for whether the target is within the panic distance. +// When this is true, it calls the do_evade function and sets the evade direction. +// This function is not to be used by the user. + +///////////////////////////////////////////////////////////////////////////////// + void Evade::evade_activate() { - _evade_direction = (_ai_char->_ai_char_np.get_pos(_ai_char->_window_render) - _evade_target.get_pos(_ai_char->_window_render)); + _evade_direction = (_ai_char->_ai_char_np.get_pos(_ai_char->_window_render) - _evade_target.get_pos(_ai_char->_window_render)); double distance = _evade_direction.length(); _evade_activate_done = false; - if (distance < _evade_distance) { - _ai_char->_steering->turn_off("evade_activate"); - _ai_char->_steering->turn_on("evade"); - _evade_activate_done = true; + if(distance < _evade_distance) { + _ai_char->_steering->turn_off("evade_activate"); + _ai_char->_steering->turn_on("evade"); + _evade_activate_done = true; } } diff --git a/contrib/src/ai/evade.h b/contrib/src/ai/evade.h index b1d7c4396d..088548ea28 100644 --- a/contrib/src/ai/evade.h +++ b/contrib/src/ai/evade.h @@ -1,30 +1,27 @@ -// Filename: evade.h -// Created by: Deepak, John, Navin (24Oct09) -// +//////////////////////////////////////////////////////////////////////// +// Filename : evade.h +// Created by : Deepak, John, Navin +// Date : 24 Oct 09 //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) Carnegie Mellon University. All rights reserved. // -// All use of this software is subject to the terms of the revised -// BSD license. You should have received a copy of this license -// along with this source code in a file named "LICENSE." +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." // //////////////////////////////////////////////////////////////////// -#ifndef EVADE_H -#define EVADE_H +#ifndef _EVADE_H +#define _EVADE_H #include "aiGlobals.h" #include "aiCharacter.h" class AICharacter; -//////////////////////////////////////////////////////////////////// -// Class : Evade -// Description : This class handles all calls to the evade behavior -//////////////////////////////////////////////////////////////////// -class Evade { +class EXPCL_PANDAAI Evade { public: AICharacter *_ai_char; diff --git a/contrib/src/ai/flee.cxx b/contrib/src/ai/flee.cxx index 9245d0e039..af0b2a0548 100644 --- a/contrib/src/ai/flee.cxx +++ b/contrib/src/ai/flee.cxx @@ -1,14 +1,15 @@ -// Filename: flee.cxx -// Created by: Deepak, John, Navin (24Oct09) -// +//////////////////////////////////////////////////////////////////////// +// Filename : flee.cxx +// Created by : Deepak, John, Navin +// Date : 24 Oct 09 //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) Carnegie Mellon University. All rights reserved. // -// All use of this software is subject to the terms of the revised -// BSD license. You should have received a copy of this license -// along with this source code in a file named "LICENSE." +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." // //////////////////////////////////////////////////////////////////// @@ -31,7 +32,7 @@ Flee::Flee(AICharacter *ai_ch, NodePath target_object, double panic_distance, Flee::Flee(AICharacter *ai_ch, LVecBase3f pos, double panic_distance, double relax_distance, float flee_wt){ - _ai_char = ai_ch; + _ai_char = ai_ch; _flee_position = pos; _flee_distance = panic_distance; @@ -45,14 +46,17 @@ Flee::Flee(AICharacter *ai_ch, LVecBase3f pos, double panic_distance, Flee::~Flee() { } -//////////////////////////////////////////////////////////////////// -// Function: do_flee -// Description: This function performs the flee and returns a flee -// force which is used in the calculate_prioritized -// function. In case the AICharacter is past the -// (panic + relax) distance, it resets to flee_activate. -// This function is not to be used by the user. -//////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +// +// Function : do_flee +// Description : This function performs the flee and returns a flee force which is used +// in the calculate_prioritized function. +// In case the AICharacter is past the (panic + relax) distance, +// it resets to flee_activate. +// This function is not to be used by the user. + +///////////////////////////////////////////////////////////////////////////////// + LVecBase3f Flee::do_flee() { LVecBase3f dirn; double distance; @@ -62,28 +66,29 @@ LVecBase3f Flee::do_flee() { distance = dirn.length(); desired_force = _flee_direction * _ai_char->_movt_force; - if (distance > (_flee_distance + _flee_relax_distance)) { - if ((_ai_char->_steering->_behaviors_flags | _ai_char->_steering->BT_flee) == _ai_char->_steering->BT_flee) { - _ai_char->_steering->_steering_force = LVecBase3f(0.0, 0.0, 0.0); + if(distance > (_flee_distance + _flee_relax_distance)) { + if((_ai_char->_steering->_behaviors_flags | _ai_char->_steering->_flee) == _ai_char->_steering->_flee) { + _ai_char->_steering->_steering_force = LVecBase3f(0.0, 0.0, 0.0); } _flee_done = true; _ai_char->_steering->turn_off("flee"); _ai_char->_steering->turn_on("flee_activate"); - return (LVecBase3f(0.0, 0.0, 0.0)); + return(LVecBase3f(0.0, 0.0, 0.0)); } else { - return (desired_force); + return(desired_force); } } -//////////////////////////////////////////////////////////////////// -// Function: flee_activate -// Description: This function checks for whether the target is -// within the panic distance. When this is true, -// it calls the do_flee function and sets the flee -// direction. -// This function is not to be used by the user. -//////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +// +// Function : flee_activate +// Description : This function checks for whether the target is within the panic distance. +// When this is true, it calls the do_flee function and sets the flee direction. +// This function is not to be used by the user. + +///////////////////////////////////////////////////////////////////////////////// + void Flee::flee_activate() { LVecBase3f dirn; double distance; @@ -93,12 +98,12 @@ void Flee::flee_activate() { dirn = (_ai_char->_ai_char_np.get_pos(_ai_char->_window_render) - _flee_position); distance = dirn.length(); - if (distance < _flee_distance) { - _flee_direction = _ai_char->_ai_char_np.get_pos(_ai_char->_window_render) - _flee_position; - _flee_direction.normalize(); - _flee_present_pos = _ai_char->_ai_char_np.get_pos(_ai_char->_window_render); - _ai_char->_steering->turn_off("flee_activate"); - _ai_char->_steering->turn_on("flee"); - _flee_activate_done = true; + if(distance < _flee_distance) { + _flee_direction = _ai_char->_ai_char_np.get_pos(_ai_char->_window_render) - _flee_position; + _flee_direction.normalize(); + _flee_present_pos = _ai_char->_ai_char_np.get_pos(_ai_char->_window_render); + _ai_char->_steering->turn_off("flee_activate"); + _ai_char->_steering->turn_on("flee"); + _flee_activate_done = true; } } diff --git a/contrib/src/ai/flee.h b/contrib/src/ai/flee.h index a6b2efee6e..fc3e86c931 100644 --- a/contrib/src/ai/flee.h +++ b/contrib/src/ai/flee.h @@ -1,30 +1,27 @@ -// Filename: flee.h -// Created by: Deepak, John, Navin (24Oct09) -// +//////////////////////////////////////////////////////////////////////// +// Filename : flee.h +// Created by : Deepak, John, Navin +// Date : 24 Oct 09 //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) Carnegie Mellon University. All rights reserved. // -// All use of this software is subject to the terms of the revised -// BSD license. You should have received a copy of this license -// along with this source code in a file named "LICENSE." +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." // //////////////////////////////////////////////////////////////////// -#ifndef FLEE_H -#define FLEE_H +#ifndef _FLEE_H +#define _FLEE_H #include "aiGlobals.h" #include "aiCharacter.h" class AICharacter; -//////////////////////////////////////////////////////////////////// -// Class : Flee -// Description : This class handles all calls to the flee behavior -//////////////////////////////////////////////////////////////////// -class Flee { +class EXPCL_PANDAAI Flee { public: AICharacter *_ai_char; diff --git a/contrib/src/ai/flock.cxx b/contrib/src/ai/flock.cxx index 36445b208f..b2b039947d 100644 --- a/contrib/src/ai/flock.cxx +++ b/contrib/src/ai/flock.cxx @@ -1,6 +1,7 @@ -// Filename: flock.cxx -// Created by: Deepak, John, Navin (12Oct09) -// +//////////////////////////////////////////////////////////////////////// +// Filename : flock.cxx +// Created by : Deepak, John, Navin +// Date : 12 Oct 09 //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE @@ -27,10 +28,13 @@ Flock::Flock(unsigned int flock_id, double vcone_angle, double vcone_radius, uns Flock::~Flock() { } -//////////////////////////////////////////////////////////////////// -// Function: add_ai_char -// Description: This function adds AI characters to the flock. -//////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +// +// Function : add_ai_char +// Description : This function adds AI characters to the flock. + +///////////////////////////////////////////////////////////////////////////////////////// + void Flock::add_ai_char(AICharacter *ai_char) { ai_char->_ai_char_flock_id = _flock_id; ai_char->_steering->_flock_group = this; diff --git a/contrib/src/ai/flock.h b/contrib/src/ai/flock.h index 18bf13cbac..66a10c57b3 100644 --- a/contrib/src/ai/flock.h +++ b/contrib/src/ai/flock.h @@ -1,55 +1,56 @@ -// Filename: flock.h -// Created by: Deepak, John, Navin (12Oct09) -// +//////////////////////////////////////////////////////////////////////// +// Filename : flock.h +// Created by : Deepak, John, Navin +// Date : 12 Oct 09 //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) Carnegie Mellon University. All rights reserved. // -// All use of this software is subject to the terms of the revised -// BSD license. You should have received a copy of this license -// along with this source code in a file named "LICENSE." +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." // //////////////////////////////////////////////////////////////////// -#ifndef FLOCK_H -#define FLOCK_H +#ifndef _FLOCK_H +#define _FLOCK_H #include "aiGlobals.h" #include "aiCharacter.h" class AICharacter; -//////////////////////////////////////////////////////////////////// -// Class : Flock -// Description : This class is used to define the flock attributes -// and the AI characters which are part of the flock. -//////////////////////////////////////////////////////////////////// -class Flock { +/////////////////////////////////////////////////////////////////////////////////////// +// +// Class : Flock +// Description : This class is used to define the flock attributes and the AI characters +// which are part of the flock. + +/////////////////////////////////////////////////////////////////////////////////////// + +class EXPCL_PANDAAI Flock { private: unsigned int _flock_id; public: - // Variables which will hold the parameters of the ai character's - // visibility cone. + // Variables which will hold the parameters of the ai character's visibilty cone. double _flock_vcone_angle; double _flock_vcone_radius; - // Variables to specify weights of separation, cohesion and - // alignment behaviors and thus create variable flock behavior. + // Variables to specify weights of separation, cohesion and alignment behaviors and thus + // create variable flock behavior. unsigned int _separation_wt; unsigned int _cohesion_wt; unsigned int _alignment_wt; - // This vector will hold all the ai characters which belong to - // this flock. + // This vector will hold all the ai characters which belong to this flock. typedef std::vector AICharList; AICharList _ai_char_list; PUBLISHED: - Flock(unsigned int flock_id, double vcone_angle, double vcone_radius, - unsigned int separation_wt = 2, unsigned int cohesion_wt = 4, - unsigned int alignment_wt = 1); + Flock(unsigned int flock_id, double vcone_angle, double vcone_radius, unsigned int separation_wt = 2, + unsigned int cohesion_wt = 4, unsigned int alignment_wt = 1); ~Flock(); // Function to add the ai characters to _ai_char_list. diff --git a/contrib/src/ai/globals.h b/contrib/src/ai/globals.h deleted file mode 100644 index 9ff7b89a6a..0000000000 --- a/contrib/src/ai/globals.h +++ /dev/null @@ -1,32 +0,0 @@ -// Filename: globals.h -// Created by: Deepak, John, Navin (26Apr10) -// -//////////////////////////////////////////////////////////////////// -// -// PANDA 3D SOFTWARE -// Copyright (c) Carnegie Mellon University. All rights reserved. -// -// All use of this software is subject to the terms of the revised BSD -// license. You should have received a copy of this license along -// with this source code in a file named "LICENSE." -// -//////////////////////////////////////////////////////////////////// - -#pragma warning (disable:4996) -#pragma warning (disable:4005) -#pragma warning (disable:4275) - -#ifndef _GLOBALS_H -#define _GLOBALS_H - -#include "pandaFramework.h" -#include "textNode.h" -#include "pandaSystem.h" - -#include "lvecBase3.h" -#include "nodePath.h" - -#include "genericAsyncTask.h" -#include "asyncTaskManager.h" - -#endif diff --git a/contrib/src/ai/meshNode.cxx b/contrib/src/ai/meshNode.cxx index 7fc0711f69..0dfdf49ac6 100644 --- a/contrib/src/ai/meshNode.cxx +++ b/contrib/src/ai/meshNode.cxx @@ -2,42 +2,42 @@ #include "meshNode.h" Node::Node(int grid_x, int grid_y, LVecBase3f pos, float w, float l, float h) { - for(int i = 0; i < 8; ++i) { - _neighbours[i] = NULL; - } + for(int i = 0; i < 8; ++i) { + _neighbours[i] = NULL; + } - _position = pos; - _width = w; - _length = l; - _height = h; - _grid_x = grid_x; - _grid_y = grid_y; + _position = pos; + _width = w; + _length = l; + _height = h; + _grid_x = grid_x; + _grid_y = grid_y; _status = neutral; - _type = true; - _score = 0; - _cost = 0; - _heuristic = 0; + _type = true; + _score = 0; + _cost = 0; + _heuristic = 0; _next = NULL; - _prv_node = NULL; + _prv_node = NULL; } Node::~Node() { } ///////////////////////////////////////////////////////////////////////////////////////// -//! -//! Function : contains -//! Description : This is a handy function which returns true if the passed position is -//! within the node's dimensions. +// +// Function : contains +// Description : This is a handy function which returns true if the passed position is +// within the node's dimensions. ///////////////////////////////////////////////////////////////////////////////////////// bool Node::contains(float x, float y) { if(_position.get_x() - _width / 2 <= x && _position.get_x() + _width / 2 >= x && _position.get_y() - _length / 2 <= y && _position.get_y() + _length / 2 >= y) { - return true; + return true; } else { - return false; + return false; } } \ No newline at end of file diff --git a/contrib/src/ai/meshNode.h b/contrib/src/ai/meshNode.h index 3f559284c3..bf2db9680f 100644 --- a/contrib/src/ai/meshNode.h +++ b/contrib/src/ai/meshNode.h @@ -2,66 +2,66 @@ #ifndef _MESHNODE_H #define _MESHNODE_H -#include "globals.h" +#include "aiGlobals.h" -//////////////////////////////////////////////////////////////////// -// Class : Node -// Description : This class is used to assign the nodes on the mesh. -// It holds all the data necessary to compute A* -// algorithm. It also maintains a lot of vital -// information such as the neighbor nodes of each -// node and also its position on the mesh. -// Note: the Mesh Generator which is a stand alone -// tool makes use of this class to generate the nodes -// on the mesh. -/////////////////////////////////////////////////////////////////// -class Node { +//////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Class : Node +// Description : This class is used to assign the nodes on the mesh. It holds all the data necessary to +// compute A* algorithm. It also maintains a lot of vital information such as the neighbor +// nodes of each node and also its position on the mesh. +// Note: The Mesh Generator which is a stand alone tool makes use of this class to generate the nodes on the +// mesh. + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class EXPCL_PANDAAI Node { public: - // This variable specifies whether the node is an obtacle or not. - // Used for dynamic obstacle addition to the environment. - // obstacle = false - // navigational = true - bool _type; + // This variable specifies whether the node is an obtacle or not. + // Used for dynamic obstacle addition to the environment. + // obstacle = false + // navigational = true + bool _type; - // This variable specifies the node status whether open, close or neutral. - // open = belongs to _open_list. - // close = belongs to _closed_list. - // neutral = unexamined node. - enum Status { - open, - close, - neutral - }; - Status _status; + // This variable specifies the node status whether open, close or neutral. + // open = belongs to _open_list. + // close = belongs to _closed_list. + // neutral = unexamined node. + enum Status { + open, + close, + neutral + }; + Status _status; - // The score is used to compute the traversal expense to nodes when using A*. - // _score = _cost + heuristic - int _score; - int _cost; - int _heuristic; + // The score is used to compute the traversal expense to nodes when using A*. + // _score = _cost + heuristic + int _score; + int _cost; + int _heuristic; - // Used to trace back the path after it is generated using A*. - Node *_prv_node; + // Used to trace back the path after it is generated using A*. + Node *_prv_node; - // Position of the node in the 2d grid. - int _grid_x, _grid_y; + // Position of the node in the 2d grid. + int _grid_x, _grid_y; - // Position of the node in 3D space. - LVecBase3f _position; + // Position of the node in 3D space. + LVecBase3f _position; - // Dimensions of each face / cell on the mesh. - // Height is given in case of expansion to a 3d mesh. Currently not used. - float _width, _length ,_height; - Node *_neighbours[8]; // anti-clockwise from top left corner. + // Dimensions of each face / cell on the mesh. + // Height is given in case of expansion to a 3d mesh. Currently not used. + float _width, _length ,_height; + Node *_neighbours[8]; // anti-clockwise from top left corner. - // The _next pointer is used for traversal during mesh generation from the model. - // Note: The data in this member is discarded when mesh data is written into navmesh.csv file. - Node *_next; + // The _next pointer is used for traversal during mesh generation from the model. + // Note: The data in this member is discarded when mesh data is written into navmesh.csv file. + Node *_next; - Node(int grid_x, int grid_y, LVecBase3f pos, float w, float l, float h); - ~Node(); + Node(int grid_x, int grid_y, LVecBase3f pos, float w, float l, float h); + ~Node(); - bool contains(float x, float y); + bool contains(float x, float y); }; #endif diff --git a/contrib/src/ai/obstacleAvoidance.cxx b/contrib/src/ai/obstacleAvoidance.cxx index 98632fd575..7354636194 100644 --- a/contrib/src/ai/obstacleAvoidance.cxx +++ b/contrib/src/ai/obstacleAvoidance.cxx @@ -1,14 +1,15 @@ -// Filename: obstacleAvoidance.cxx -// Created by: Deepak, John, Navin (10Nov09) -// +//////////////////////////////////////////////////////////////////////// +// Filename : obstacleAvoidance.cxx +// Created by : Deepak, John, Navin +// Date : 10 Nov 09 //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) Carnegie Mellon University. All rights reserved. // -// All use of this software is subject to the terms of the revised -// BSD license. You should have received a copy of this license -// along with this source code in a file named "LICENSE." +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." // //////////////////////////////////////////////////////////////////// @@ -22,12 +23,14 @@ ObstacleAvoidance::ObstacleAvoidance(AICharacter *ai_char, float feeler_length) ObstacleAvoidance::~ObstacleAvoidance() { } -//////////////////////////////////////////////////////////////////// -// Function: obstacle_detection -// Description: This function checks if an obstacle is near to the -// AICharacter and if an obstacle is detected returns -// true. -//////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +// +// Function : obstacle_detection +// Description : This function checks if an obstacle is near to the AICharacter and +// if an obstacle is detected returns true + +///////////////////////////////////////////////////////////////////////////////// + bool ObstacleAvoidance::obstacle_detection() { // Calculate the volume of the AICharacter with respect to render PT(BoundingVolume) np_bounds = _ai_char->get_node_path().get_bounds(); @@ -37,15 +40,12 @@ bool ObstacleAvoidance::obstacle_detection() { double expanded_radius; LVecBase3f to_obstacle; LVecBase3f prev_avoidance; - for (unsigned int i = 0; i < _ai_char->_world->_obstacles.size(); ++i) { + for(unsigned int i = 0; i < _ai_char->_world->_obstacles.size(); ++i) { PT(BoundingVolume) bounds = _ai_char->_world->_obstacles[i].get_bounds(); CPT(BoundingSphere) bsphere = bounds->as_bounding_sphere(); - LVecBase3f near_obstacle = _ai_char->_world->_obstacles[i].get_pos() - - _ai_char->get_node_path().get_pos(); - // Check if it's the nearest obstacle, If so initialize as the nearest - // obstacle - if ((near_obstacle.length() < distance) && - (_ai_char->_world->_obstacles[i].get_pos() != _ai_char->get_node_path().get_pos())) { + LVecBase3f near_obstacle = _ai_char->_world->_obstacles[i].get_pos() - _ai_char->get_node_path().get_pos(); + // Check if it's the nearest obstacle, If so initialize as the nearest obstacle + if((near_obstacle.length() < distance) && (_ai_char->_world->_obstacles[i].get_pos() != _ai_char->get_node_path().get_pos())) { _nearest_obstacle = _ai_char->_world->_obstacles[i]; distance = near_obstacle.length(); expanded_radius = bsphere->get_radius() + np_sphere->get_radius(); @@ -58,59 +58,56 @@ bool ObstacleAvoidance::obstacle_detection() { LVector3f line_vector = _ai_char->get_char_render().get_relative_vector(_ai_char->get_node_path(), LVector3f::forward()); LVecBase3f project = (to_obstacle.dot(line_vector) * line_vector) / line_vector.length_squared(); LVecBase3f perp = project - to_obstacle; - // If the nearest obstacle will collide with our AICharacter then - // send obstacle detection as true - if ((_nearest_obstacle) && - (perp.length() < expanded_radius - np_sphere->get_radius()) && - (project.length() < feeler.length())) { + // If the nearest obstacle will collide with our AICharacter then send obstacle detection as true + if((_nearest_obstacle) && (perp.length() < expanded_radius - np_sphere->get_radius()) && (project.length() < feeler.length())) { return true; } return false; } -//////////////////////////////////////////////////////////////////// -// Function: obstacle_avoidance_activate -// Description: This function activates obstacle_avoidance if an -// obstacle is detected -//////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +// +// Function : obstacle_avoidance_activate +// Description : This function activates obstacle_avoidance if a obstacle +// is detected + +///////////////////////////////////////////////////////////////////////////////// + void ObstacleAvoidance::obstacle_avoidance_activate() { - if (obstacle_detection()) { + if(obstacle_detection()) { _ai_char->_steering->turn_off("obstacle_avoidance_activate"); _ai_char->_steering->turn_on("obstacle_avoidance"); } } -//////////////////////////////////////////////////////////////////// -// Function: do_obstacle_avoidance -// Description: This function returns the force necessary by the -// AICharacter to avoid the nearest obstacle detected -// by obstacle_detection function -// NOTE : This assumes the obstacles are spherical -//////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +// +// Function : do_obstacle_avoidance +// Description : This function returns the force necessary by the AICharacter to +// avoid the nearest obstacle detected by obstacle_detection +// function +// NOTE : This assumes the obstacles are spherical + +///////////////////////////////////////////////////////////////////////////////// + LVecBase3f ObstacleAvoidance::do_obstacle_avoidance() { - LVecBase3f offset = _ai_char->get_node_path().get_pos() - - _nearest_obstacle.get_pos(); + LVecBase3f offset = _ai_char->get_node_path().get_pos() - _nearest_obstacle.get_pos(); PT(BoundingVolume) bounds =_nearest_obstacle.get_bounds(); CPT(BoundingSphere) bsphere = bounds->as_bounding_sphere(); PT(BoundingVolume) np_bounds = _ai_char->get_node_path().get_bounds(); CPT(BoundingSphere) np_sphere = np_bounds->as_bounding_sphere(); - double distance_needed = offset.length() - bsphere->get_radius() - - np_sphere->get_radius(); - - if (obstacle_detection()) { - LVecBase3f direction = _ai_char->get_char_render().get_relative_vector( - _ai_char->get_node_path(), LVector3f::forward()); + double distance_needed = offset.length() - bsphere->get_radius() - np_sphere->get_radius(); + if((obstacle_detection())) { + LVecBase3f direction = _ai_char->get_char_render().get_relative_vector(_ai_char->get_node_path(), LVector3f::forward()); direction.normalize(); float forward_component = offset.dot(direction); LVecBase3f projection = forward_component * direction; LVecBase3f perpendicular_component = offset - projection; double p = perpendicular_component.length(); perpendicular_component.normalize(); - LVecBase3f avoidance = perpendicular_component; - - // The closer the obstacle, the more force it generates - avoidance = (avoidance * _ai_char->get_max_force() * - _ai_char->_movt_force) / (p + 0.01); + LVecBase3f avoidance = perpendicular_component; + // The more closer the obstacle, the more force it generates + avoidance = (avoidance * _ai_char->get_max_force() * _ai_char->_movt_force) / (p + 0.01); return avoidance; } _ai_char->_steering->turn_on("obstacle_avoidance_activate"); diff --git a/contrib/src/ai/obstacleAvoidance.h b/contrib/src/ai/obstacleAvoidance.h index 790db0b191..9df1c2bde1 100644 --- a/contrib/src/ai/obstacleAvoidance.h +++ b/contrib/src/ai/obstacleAvoidance.h @@ -1,30 +1,27 @@ -// Filename: obstacleAvoidance.h -// Created by: Deepak, John, Navin (10Nov2009) -// +#ifndef OBSTACLE_AVOIDANCE_H +#define OBSTACLE_AVOIDANCE_H + +//////////////////////////////////////////////////////////////////////// +// Filename : obstacleAvoidance.h +// Created by : Deepak, John, Navin +// Date : 10 Nov 2009 //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) Carnegie Mellon University. All rights reserved. // -// All use of this software is subject to the terms of the revised -// BSD license. You should have received a copy of this license -// along with this source code in a file named "LICENSE." +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." // //////////////////////////////////////////////////////////////////// -#ifndef OBSTACLE_AVOIDANCE_H -#define OBSTACLE_AVOIDANCE_H #include "aiCharacter.h" #include "boundingSphere.h" class AICharacter; -//////////////////////////////////////////////////////////////////// -// Class : ObstacleAvoidance -// Description : This class handles all calls to the obstacle -// avoidance behavior -//////////////////////////////////////////////////////////////////// -class ObstacleAvoidance { +class EXPCL_PANDAAI ObstacleAvoidance { public : AICharacter *_ai_char; float _obstacle_avoidance_weight; diff --git a/contrib/src/ai/pathFind.cxx b/contrib/src/ai/pathFind.cxx index 4534759827..65fa6f57d6 100644 --- a/contrib/src/ai/pathFind.cxx +++ b/contrib/src/ai/pathFind.cxx @@ -1,19 +1,5 @@ -// Filename: pathFind.cxx -// Created by: Deepak, John, Navin (12Oct09) -// -//////////////////////////////////////////////////////////////////// -// -// PANDA 3D SOFTWARE -// Copyright (c) Carnegie Mellon University. All rights reserved. -// -// All use of this software is subject to the terms of the revised -// BSD license. You should have received a copy of this license -// along with this source code in a file named "LICENSE." -// -//////////////////////////////////////////////////////////////////// #include "pathFind.h" -#include "pstrtod.h" PathFind::PathFind(AICharacter *ai_ch) { _ai_char = ai_ch; @@ -21,7 +7,7 @@ PathFind::PathFind(AICharacter *ai_ch) { _parent = new GeomNode("parent"); _ai_char->_window_render.attach_new_node(_parent); - _pen = new LineSegs("pen"); + _pen = new LineSegs("pen"); _pen->set_color(1.0, 0.0, 0.0); _pen->set_thickness(2.0); @@ -32,11 +18,13 @@ PathFind::PathFind(AICharacter *ai_ch) { PathFind::~PathFind() { } -//////////////////////////////////////////////////////////////////// -// Function: create_nav_mesh -// Description: This function recreates the navigation mesh from -// the .csv file. -//////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +// +// Function : create_nav_mesh +// Description : This function recreates the navigation mesh from the .csv file + +///////////////////////////////////////////////////////////////////////////////// + void PathFind::create_nav_mesh(const char* navmesh_filename) { // Stage variables. int grid_x, grid_y; @@ -46,23 +34,22 @@ void PathFind::create_nav_mesh(const char* navmesh_filename) { // Variable to hold line data read from file. string line; - // Array for storing data members obtained from each line of the - // file. + // Array for storing data members obtained from each line of the file. string fields[10]; // Open data file for reading. ifstream nav_mesh_file (navmesh_filename); - if (nav_mesh_file.is_open()) { + if(nav_mesh_file.is_open()) { // Capture the grid size from the file. getline(nav_mesh_file, line); int pos = line.find(","); _grid_size = atoi((line.substr(pos + 1)).c_str()); // Initialize the stage mesh with NULL nodes. - for (int r = 0; r < _grid_size; ++r) { - _nav_mesh.push_back(vector()); - for (int c = 0; c < _grid_size; ++c) { + for(int r = 0; r < _grid_size; ++r) { + _nav_mesh.push_back(vector()); + for(int c = 0; c < _grid_size; ++c) { _nav_mesh[r].push_back(NULL); } } @@ -71,51 +58,52 @@ void PathFind::create_nav_mesh(const char* navmesh_filename) { getline(nav_mesh_file, line); // Begin reading data from the file. - while (!nav_mesh_file.eof()) { + while(!nav_mesh_file.eof()) { getline(nav_mesh_file, line); stringstream linestream (line); // Stores all the data members in the line to the array. - // Data structure: NULL,NodeType,GridX,GridY,Length,Width, - // Height,PosX,PosY,PosZ - for (int i = 0; i < 10; ++i) { + // Data structure: NULL,NodeType,GridX,GridY,Length,Width,Height,PosX,PosY,PosZ + for(int i = 0; i < 10; ++i) { getline(linestream, fields[i], ','); } // Populate the main nodes into stage mesh. - if (fields[0] == "0" && fields[1] == "0") { + if(fields[0] == "0" && fields[1] == "0") { grid_x = atoi(fields[2].c_str()); grid_y = atoi(fields[3].c_str()); - l = patof(fields[4].c_str()); - w = patof(fields[5].c_str()); - h = patof(fields[6].c_str()); - position = LVecBase3f(patof(fields[7].c_str()), - patof(fields[8].c_str()), patof(fields[9].c_str())); + l = atof(fields[4].c_str()); + w = atof(fields[5].c_str()); + h = atof(fields[6].c_str()); + position = LVecBase3f(atof(fields[7].c_str()), atof(fields[8].c_str()), atof(fields[9].c_str())); + + Node *stage_node = new Node(grid_x, grid_y, position, w, l, h); - AINode *stage_node = new AINode(grid_x, grid_y, position, w, l, h); _nav_mesh[grid_y][grid_x] = stage_node; } - else if (fields[0] == "") { + else if(fields[0] == "") { // End of file reached at this point. nav_mesh_file.close(); - // Assign the neighbor nodes for each of the main nodes - // that just got populated into the stage mesh. + // Assign the neighbor nodes for each of the main nodes that just got populated into the stage mesh. assign_neighbor_nodes(navmesh_filename); } } } else { - cout << "error opening navmesh.csv file!\n"; + cout<<"error opening navmesh.csv file!"<_neighbours[i] = _nav_mesh[gd_yn][gd_xn]; } - else if (fields_n[0] == "1" && fields_n[1] == "1") { + else if(fields_n[0] == "1" && fields_n[1] == "1") { // NULL neighbor. _nav_mesh[gd_y][gd_x]->_neighbours[i] = NULL; } else { - cout << "Warning: Corrupt data!\n"; + cout<<"Warning: Corrupt data!"<_steering->_path_follow_obj) { + if(_ai_char->_steering->_path_follow_obj) { _ai_char->_steering->remove_ai("pathfollow"); } _ai_char->_steering->path_follow(1.0f); - if (_path_finder_obj) { + if(_path_finder_obj) { delete _path_finder_obj; _path_finder_obj = NULL; } @@ -196,17 +187,19 @@ void PathFind::set_path_find(const char* navmesh_filename) { _path_finder_obj = new PathFinder(_nav_mesh); } -//////////////////////////////////////////////////////////////////// -// Function: path_find (for pathfinding towards a static position) -// Description: This function checks for the source and target in -// the navigation mesh for its availability and then -// finds the best path via the A* algorithm Then it -// calls the path follower to make the object follow -// the path. -//////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////// +// +// Function : path_find (for pathfinding towards a static position) +// Description : This function checks for the source and target in the navigation mesh +// for its availability and then finds the best path via the A* algorithm +// Then it calls the path follower to make the object follow the path. + +/////////////////////////////////////////////////////////////////////////////////////// + + void PathFind::path_find(LVecBase3f pos, string type) { - if (type == "addPath") { - if (_ai_char->_steering->_path_follow_obj) { + if(type == "addPath") { + if(_ai_char->_steering->_path_follow_obj) { _ai_char->_steering->remove_ai("pathfollow"); } @@ -215,41 +208,40 @@ void PathFind::path_find(LVecBase3f pos, string type) { clear_path(); - AINode* src = find_in_mesh(_nav_mesh, - _ai_char->_ai_char_np.get_pos(_ai_char->_window_render), _grid_size); + Node* src = find_in_mesh(_nav_mesh, _ai_char->_ai_char_np.get_pos(_ai_char->_window_render), _grid_size); - if (src == NULL) { - cout << "couldnt find source\n"; + if(src == NULL) { + cout<<"couldnt find source"<find_path(src, dst); trace_path(src); } - if (!_ai_char->_steering->_path_follow_obj->_start) { + if(!_ai_char->_steering->_path_follow_obj->_start) { _ai_char->_steering->start_follow(); } } -//////////////////////////////////////////////////////////////////// -// Function: path_find (for pathfinding towards a moving target -// (a NodePath)) -// Description: This function checks for the source and target in -// the navigation mesh for its availability and then -// finds the best path via the A* algorithm -// Then it calls the path follower to make the object -// follow the path. -//////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////// +// +// Function : path_find (for pathfinding towards a moving target (a NodePath)) +// Description : This function checks for the source and target in the navigation mesh +// for its availability and then finds the best path via the A* algorithm +// Then it calls the path follower to make the object follow the path. + +/////////////////////////////////////////////////////////////////////////////////////// + void PathFind::path_find(NodePath target, string type) { - if (type == "addPath") { - if (_ai_char->_steering->_path_follow_obj) { + if(type == "addPath") { + if(_ai_char->_steering->_path_follow_obj) { _ai_char->_steering->remove_ai("pathfollow"); } @@ -261,42 +253,43 @@ void PathFind::path_find(NodePath target, string type) { _path_find_target = target; _prev_position = target.get_pos(_ai_char->_window_render); - AINode* src = find_in_mesh(_nav_mesh, - _ai_char->_ai_char_np.get_pos(_ai_char->_window_render), _grid_size); + Node* src = find_in_mesh(_nav_mesh, _ai_char->_ai_char_np.get_pos(_ai_char->_window_render), _grid_size); - if (src == NULL) { - cout << "couldnt find source\n"; + if(src == NULL) { + cout<<"couldnt find source"<find_path(src, dst); trace_path(src); } - if (_ai_char->_steering->_path_follow_obj!=NULL) { - if (!_ai_char->_steering->_path_follow_obj->_start) { + if(_ai_char->_steering->_path_follow_obj!=NULL) { + if(!_ai_char->_steering->_path_follow_obj->_start) { _ai_char->_steering->start_follow("pathfind"); } } } -//////////////////////////////////////////////////////////////////// -// Function: clear_path -// Description: Helper function to restore the path and mesh -// to its initial state -//////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////// +// +// Function : clear_path +// Description : Helper function to restore the path and mesh to its initial state + +/////////////////////////////////////////////////////////////////////////////////////// + void PathFind::clear_path() { // Initialize to zero - for (int i = 0; i < _grid_size; ++i) { - for (int j = 0; j < _grid_size; ++j) { - if (_nav_mesh[i][j] != NULL) { - _nav_mesh[i][j]->_status = _nav_mesh[i][j]->ST_neutral; + for(int i = 0; i < _grid_size; ++i) { + for(int j = 0; j < _grid_size; ++j) { + if(_nav_mesh[i][j] != NULL) { + _nav_mesh[i][j]->_status = _nav_mesh[i][j]->neutral; _nav_mesh[i][j]->_cost = 0; _nav_mesh[i][j]->_heuristic = 0; _nav_mesh[i][j]->_score = 0; @@ -305,34 +298,35 @@ void PathFind::clear_path() { } } - if (_path_finder_obj) { + if(_path_finder_obj) { _path_finder_obj->_open_list.clear(); _path_finder_obj->_closed_list.clear(); } } -//////////////////////////////////////////////////////////////////// -// Function: trace_path -// Description: This function is the function which sends the path -// information one by one to the path follower so that -// it can store the path needed to be -// traversed by the pathfinding object -//////////////////////////////////////////////////////////////////// -void PathFind::trace_path(AINode* src) { - if (_ai_char->_pf_guide) { +/////////////////////////////////////////////////////////////////////////////////////// +// +// Function : trace_path +// Description : This function is the function which sends the path information one by +// one to the path follower so that it can store the path needed to be +// traversed by the pathfinding object + +/////////////////////////////////////////////////////////////////////////////////////// + +void PathFind::trace_path(Node* src) { + if(_ai_char->_pf_guide) { _parent->remove_all_children(); } else { _parent->remove_all_children(); } - if (_path_finder_obj->_closed_list.size() > 0) { - AINode *traversor = _path_finder_obj->_closed_list[_path_finder_obj->_closed_list.size() - 0.5]; - while (traversor != src) { - if (_ai_char->_pf_guide) { + if(_path_finder_obj->_closed_list.size() > 0) { + Node *traversor = _path_finder_obj->_closed_list[_path_finder_obj->_closed_list.size() - 0.5]; + while(traversor != src) { + if(_ai_char->_pf_guide) { _pen->move_to(traversor->_position.get_x(), traversor->_position.get_y(), 1); - _pen->draw_to(traversor->_prv_node->_position.get_x(), - traversor->_prv_node->_position.get_y(), 0.5); + _pen->draw_to(traversor->_prv_node->_position.get_x(), traversor->_prv_node->_position.get_y(), 0.5); PT(GeomNode) gnode = _pen->create(); _parent->add_child(gnode); } @@ -342,32 +336,33 @@ void PathFind::trace_path(AINode* src) { } } -//////////////////////////////////////////////////////////////////// -// Function: add_obstacle_to_mesh -// Description: This function allows the user to dynamically add -// obstacles to the game environment. The function -// will update the nodes within the -// bounding volume of the obstacle as non-traversable. -// Hence will not be considered by the pathfinding -// algorithm. -//////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////// +// +// Function : add_obstacle_to_mesh +// Description : This function allows the user to dynamically add obstacles to the +// game environment. The function will update the nodes within the +// bounding volume of the obstacle as non-traversable. Hence will not be +// considered by the pathfinding algorithm. + +/////////////////////////////////////////////////////////////////////////////////////// + void PathFind::add_obstacle_to_mesh(NodePath obstacle) { PT(BoundingVolume) np_bounds = obstacle.get_bounds(); CPT(BoundingSphere) np_sphere = np_bounds->as_bounding_sphere(); - AINode* temp = find_in_mesh(_nav_mesh, obstacle.get_pos(), _grid_size); + Node* temp = find_in_mesh(_nav_mesh, obstacle.get_pos(), _grid_size); - if (temp != NULL) { + if(temp != NULL) { float left = temp->_position.get_x() - np_sphere->get_radius(); float right = temp->_position.get_x() + np_sphere->get_radius(); float top = temp->_position.get_y() + np_sphere->get_radius(); float down = temp->_position.get_y() - np_sphere->get_radius(); - for (int i = 0; i < _grid_size; ++i) { - for (int j = 0; j < _grid_size; ++j) { - if (_nav_mesh[i][j] != NULL && _nav_mesh[i][j]->_type == true) { - if (_nav_mesh[i][j]->_position.get_x() >= left && _nav_mesh[i][j]->_position.get_x() <= right && - _nav_mesh[i][j]->_position.get_y() >= down && _nav_mesh[i][j]->_position.get_y() <= top) { + for(int i = 0; i < _grid_size; ++i) { + for(int j = 0; j < _grid_size; ++j) { + if(_nav_mesh[i][j] != NULL && _nav_mesh[i][j]->_type == true) { + if(_nav_mesh[i][j]->_position.get_x() >= left && _nav_mesh[i][j]->_position.get_x() <= right && + _nav_mesh[i][j]->_position.get_y() >= down && _nav_mesh[i][j]->_position.get_y() <= top) { _nav_mesh[i][j]->_type = false; _previous_obstacles.insert(_previous_obstacles.end(), i); _previous_obstacles.insert(_previous_obstacles.end(), j); @@ -378,35 +373,44 @@ void PathFind::add_obstacle_to_mesh(NodePath obstacle) { } } -//////////////////////////////////////////////////////////////////// -// Function: do_dynamic_avoid() -// Description: This function does the updation of the collisions to -// the mesh based on the new positions of the obstacles. -//////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////// +// +// Function : do_dynamic_avoid() +// Description : This function does the updation of the collisions to the mesh based +// on the new positions of the obstacles. + +/////////////////////////////////////////////////////////////////////////////////////// + void PathFind::do_dynamic_avoid() { clear_previous_obstacles(); _previous_obstacles.clear(); - for (unsigned int i = 0; i < _dynamic_obstacle.size(); ++i) { + for(unsigned int i = 0; i < _dynamic_obstacle.size(); ++i) { add_obstacle_to_mesh(_dynamic_obstacle[i]); } } -//////////////////////////////////////////////////////////////////// -// Function: clear_previous_obstacles() -// Description: Helper function to reset the collisions if the -// obstacle is not on the node anymore. -//////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////// +// +// Function : clear_previous_obstacles() +// Description : Helper function to reset the collisions if the obstacle is not on the +// node anymore + +/////////////////////////////////////////////////////////////////////////////////////// + void PathFind::clear_previous_obstacles(){ - for (unsigned int i = 0; i < _previous_obstacles.size(); i = i + 2) { + for(unsigned int i = 0; i < _previous_obstacles.size(); i = i + 2) { _nav_mesh[_previous_obstacles[i]][_previous_obstacles[i + 1]]->_type = true; } } -//////////////////////////////////////////////////////////////////// -// Function: dynamic_avoid -// Description: This function starts the pathfinding obstacle -// navigation for the passed in obstacle. -//////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////// +// +// Function : dynamic_avoid +// Description : This function starts the pathfinding obstacle navigation for the +// passed in obstacle. + +/////////////////////////////////////////////////////////////////////////////////////// + void PathFind::dynamic_avoid(NodePath obstacle) { _dynamic_avoid = true; _dynamic_obstacle.insert(_dynamic_obstacle.end(), obstacle); diff --git a/contrib/src/ai/pathFind.h b/contrib/src/ai/pathFind.h index 9584bbd234..a82142947b 100644 --- a/contrib/src/ai/pathFind.h +++ b/contrib/src/ai/pathFind.h @@ -1,19 +1,21 @@ -// Filename: pathFind.h -// Created by: Deepak, John, Navin (12Oct09) -// + +//////////////////////////////////////////////////////////////////////// +// Filename : pathFind.h +// Created by : Deepak, John, Navin +// Date : 12 Oct 09 //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) Carnegie Mellon University. All rights reserved. // -// All use of this software is subject to the terms of the revised -// BSD license. You should have received a copy of this license -// along with this source code in a file named "LICENSE." +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." // //////////////////////////////////////////////////////////////////// -#ifndef PATHFIND_H -#define PATHFIND_H +#ifndef _PATHFIND_H +#define _PATHFIND_H #include "aiGlobals.h" #include "aiCharacter.h" @@ -22,16 +24,16 @@ class AICharacter; -//////////////////////////////////////////////////////////////////// -// Class : PathFind -// Description : This class contains all the members and functions -// that are required to form an interface between -// the AIBehaviors class and the PathFinder class. -// An object (pointer) of this class is provided in -// the AIBehaviors class. It is only via this object -// that the user can activate pathfinding. -//////////////////////////////////////////////////////////////////// -class PathFind { +//////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Class : PathFind +// Description : This class contains all the members and functions that are required to form an interface between +// the AIBehaviors class and the PathFinder class. An object (pointer) of this class is provided in the +// AIBehaviors class. It is only via this object that the user can activate pathfinding. + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class EXPCL_PANDAAI PathFind { public: AICharacter *_ai_char; PathFinder *_path_finder_obj; @@ -52,7 +54,7 @@ public: ~PathFind(); void clear_path(); - void trace_path(AINode* src); + void trace_path(Node* src); void create_nav_mesh(const char* navmesh_filename); void assign_neighbor_nodes(const char* navmesh_filename); diff --git a/contrib/src/ai/pathFollow.cxx b/contrib/src/ai/pathFollow.cxx index de2e79b99f..0e276eb5c4 100644 --- a/contrib/src/ai/pathFollow.cxx +++ b/contrib/src/ai/pathFollow.cxx @@ -1,16 +1,3 @@ -// Filename: pathFollow.cxx -// Created by: Deepak, John, Navin (24Oct09) -// -//////////////////////////////////////////////////////////////////// -// -// PANDA 3D SOFTWARE -// Copyright (c) Carnegie Mellon University. All rights reserved. -// -// All use of this software is subject to the terms of the revised -// BSD license. You should have received a copy of this license -// along with this source code in a file named "LICENSE." -// -//////////////////////////////////////////////////////////////////// #include "pathFollow.h" @@ -25,24 +12,29 @@ PathFollow::PathFollow(AICharacter *ai_ch, float follow_wt) { PathFollow::~PathFollow() { } -//////////////////////////////////////////////////////////////////// -// Function: add_to_path -// Description: This function adds the positions generated from a -// pathfind or a simple path follow behavior to the -// _path list. -//////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +// +// Function : add_to_path +// Description : This function adds the positions generated from a pathfind or a simple +// path follow behavior to the _path list. + +///////////////////////////////////////////////////////////////////////////////////////// + void PathFollow::add_to_path(LVecBase3f pos) { _path.push_back(pos); } -//////////////////////////////////////////////////////////////////// -// Function: start -// Description: This function initiates the path follow behavior. -//////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +// +// Function : start +// Description : This function initiates the path follow behavior. + +///////////////////////////////////////////////////////////////////////////////////////// + void PathFollow::start(string type) { _type = type; _start = true; - if (_path.size() > 0) { + if(_path.size() > 0) { _curr_path_waypoint = _path.size() - 1; _dummy = _ai_char->_window_render.attach_new_node("dummy"); _dummy.set_pos(_path[_curr_path_waypoint]); @@ -51,32 +43,31 @@ void PathFollow::start(string type) { } } -//////////////////////////////////////////////////////////////////// -// Function: do_follow -// Description: This function allows continuous path finding by AI -// chars. There are 2 ways in which this is implemented. -// 1. The character re-calculates the optimal path -// everytime the target changes its position. -// Less computationally expensive. -// 2. The character continuosly re-calculates its -// optimal path to the target. This is used in a -// scenario where the ai chars have to avoid other AI -// chars. More computationally expensive. -//////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +// +// Function : do_follow +// Description : This function allows continuous path finding by ai chars. There are 2 +// ways in which this is implemented. +// 1. The character re-calculates the optimal path everytime the target +// changes its position. Less computationally expensive. +// 2. The character continuosly re-calculates its optimal path to the +// target. This is used in a scenario where the ai chars have to avoid +// other ai chars. More computationally expensive. + +///////////////////////////////////////////////////////////////////////////////////////// + void PathFollow::do_follow() { - if ((_myClock->get_real_time() - _time) > 0.5) { - if (_type == "pathfind") { - // This 'if' statement when 'true' causes the path to be - // re-calculated irrespective of target position. - // This is done when _dynamice_avoid is active. More - // computationally expensive. - if (_ai_char->_steering->_path_find_obj->_dynamic_avoid) { + if((_myClock->get_real_time() - _time) > 0.5) { + if(_type=="pathfind") { + // This 'if' statement when 'true' causes the path to be re-calculated irrespective of target position. + // This is done when _dynamice_avoid is active. More computationally expensive. + if(_ai_char->_steering->_path_find_obj->_dynamic_avoid) { _ai_char->_steering->_path_find_obj->do_dynamic_avoid(); - if (check_if_possible()) { + if(check_if_possible()) { _path.clear(); _ai_char->_steering->_path_find_obj->path_find(_ai_char->_steering->_path_find_obj->_path_find_target); // Ensure that the path size is not 0. - if (_path.size() > 0) { + if(_path.size() > 0) { _curr_path_waypoint = _path.size() - 1; _dummy.set_pos(_path[_curr_path_waypoint]); } @@ -86,16 +77,15 @@ void PathFollow::do_follow() { } } } - // This 'if' statement causes the path to be re-calculated only - // when there is a change in target position. + // This 'if' statement causes the path to be re-calculated only when there is a change in target position. // Less computationally expensive. - else if (_ai_char->_steering->_path_find_obj->_path_find_target.get_pos(_ai_char->_window_render) + else if(_ai_char->_steering->_path_find_obj->_path_find_target.get_pos(_ai_char->_window_render) != _ai_char->_steering->_path_find_obj->_prev_position) { - if (check_if_possible()) { + if(check_if_possible()) { _path.clear(); _ai_char->_steering->_path_find_obj->path_find(_ai_char->_steering->_path_find_obj->_path_find_target); // Ensure that the path size is not 0. - if (_path.size() > 0) { + if(_path.size() > 0) { _curr_path_waypoint = _path.size() - 1; _dummy.set_pos(_path[_curr_path_waypoint]); } @@ -107,32 +97,35 @@ void PathFollow::do_follow() { } _time = _myClock->get_real_time(); } - } + } - if (_curr_path_waypoint > 0) { - double distance = (_path[_curr_path_waypoint] - - _ai_char->_ai_char_np.get_pos(_ai_char->_window_render)).length(); + if(_curr_path_waypoint > 0) { + double distance = (_path[_curr_path_waypoint] - _ai_char->_ai_char_np.get_pos(_ai_char->_window_render)).length(); - if (distance < 5) { + if(distance < 5) { _curr_path_waypoint--; _dummy.set_pos(_path[_curr_path_waypoint]); } } } -//////////////////////////////////////////////////////////////////// -// Function: check_if_possible -// Description: This function checks if the current positions of -// the ai char and the target char can be used to -// generate an optimal path. -//////////////////////////////////////////////////////////////////// -bool PathFollow::check_if_possible() { - AINode* src = find_in_mesh(_ai_char->_steering->_path_find_obj->_nav_mesh, - _ai_char->_ai_char_np.get_pos(_ai_char->_window_render), - _ai_char->_steering->_path_find_obj->_grid_size); - LVecBase3f _prev_position = _ai_char->_steering->_path_find_obj->_path_find_target.get_pos(_ai_char->_window_render); - AINode* dst = find_in_mesh(_ai_char->_steering->_path_find_obj->_nav_mesh, - _prev_position, _ai_char->_steering->_path_find_obj->_grid_size); +///////////////////////////////////////////////////////////////////////////////////////// +// +// Function : check_if_possible +// Description : This function checks if the current positions of the ai char and the +// target char can be used to generate an optimal path. - return (src && dst); +///////////////////////////////////////////////////////////////////////////////////////// + +bool PathFollow::check_if_possible() { + Node* src = find_in_mesh(_ai_char->_steering->_path_find_obj->_nav_mesh, _ai_char->_ai_char_np.get_pos(_ai_char->_window_render), _ai_char->_steering->_path_find_obj->_grid_size); + LVecBase3f _prev_position = _ai_char->_steering->_path_find_obj->_path_find_target.get_pos(_ai_char->_window_render); + Node* dst = find_in_mesh(_ai_char->_steering->_path_find_obj->_nav_mesh, _prev_position, _ai_char->_steering->_path_find_obj->_grid_size); + + if(src && dst) { + return true; + } + else { + return false; + } } diff --git a/contrib/src/ai/pathFollow.h b/contrib/src/ai/pathFollow.h index a92520503b..125ef98784 100644 --- a/contrib/src/ai/pathFollow.h +++ b/contrib/src/ai/pathFollow.h @@ -1,32 +1,14 @@ -// Filename: pathFollow.h -// Created by: Deepak, John, Navin (24Oct09) -// -//////////////////////////////////////////////////////////////////// -// -// PANDA 3D SOFTWARE -// Copyright (c) Carnegie Mellon University. All rights reserved. -// -// All use of this software is subject to the terms of the revised -// BSD license. You should have received a copy of this license -// along with this source code in a file named "LICENSE." -// -//////////////////////////////////////////////////////////////////// -#ifndef PATHFOLLOW_H -#define PATHFOLLOW_H +#ifndef _PATHFOLLOW_H +#define _PATHFOLLOW_H #include "aiGlobals.h" #include "aiCharacter.h" -#include "aiNode.h" +#include "meshNode.h" class AICharacter; -//////////////////////////////////////////////////////////////////// -// Class : PathFollow -// Description : This class handles all calls to the path follow -// behavior and has functions to handle pathfinding -//////////////////////////////////////////////////////////////////// -class PathFollow { +class EXPCL_PANDAAI PathFollow { public: AICharacter *_ai_char; diff --git a/contrib/src/ai/pursue.cxx b/contrib/src/ai/pursue.cxx index 5ff8be0d29..259f5b340e 100644 --- a/contrib/src/ai/pursue.cxx +++ b/contrib/src/ai/pursue.cxx @@ -1,14 +1,15 @@ -// Filename: pursue.cxx -// Created by: Deepak, John, Navin (24Oct09) -// +//////////////////////////////////////////////////////////////////////// +// Filename : pursue.cxx +// Created by : Deepak, John, Navin +// Date : 24 Oct 09 //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) Carnegie Mellon University. All rights reserved. // -// All use of this software is subject to the terms of the revised -// BSD license. You should have received a copy of this license -// along with this source code in a file named "LICENSE." +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." // //////////////////////////////////////////////////////////////////// @@ -26,27 +27,27 @@ Pursue::Pursue(AICharacter *ai_ch, NodePath target_object, float pursue_wt) { Pursue::~Pursue() { } -//////////////////////////////////////////////////////////////////// -// Function: do_pursue -// Description: This function performs the pursue and returns a -// pursue force which is used -// in the calculate_prioritized function. -// In case the target has been reached it resets the -// forces to 0 so that the character stops. -// This function is not to be used by the user. -//////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +// +// Function : do_pursue +// Description : This function performs the pursue and returns a pursue force which is used +// in the calculate_prioritized function. +// In case the target has been reached it resets the forces to 0 so that the character stops. +// This function is not to be used by the user. + +///////////////////////////////////////////////////////////////////////////////// + LVecBase3f Pursue::do_pursue() { assert(_pursue_target && "pursue target not assigned"); LVecBase3f present_pos = _ai_char->_ai_char_np.get_pos(_ai_char->_window_render); - double target_distance = (_pursue_target.get_pos(_ai_char->_window_render) - - present_pos).length(); + double target_distance = (_pursue_target.get_pos(_ai_char->_window_render) - present_pos).length(); - if (int(target_distance) == 0) { + if(int(target_distance) == 0) { _pursue_done = true; _ai_char->_steering->_steering_force = LVecBase3f(0.0, 0.0, 0.0); _ai_char->_steering->_pursue_force = LVecBase3f(0.0, 0.0, 0.0); - return (LVecBase3f(0.0, 0.0, 0.0)); + return(LVecBase3f(0.0, 0.0, 0.0)); } else { _pursue_done = false; @@ -56,5 +57,5 @@ LVecBase3f Pursue::do_pursue() { _pursue_direction.normalize(); LVecBase3f desired_force = _pursue_direction * _ai_char->_movt_force; - return (desired_force); + return(desired_force); } diff --git a/contrib/src/ai/pursue.h b/contrib/src/ai/pursue.h index 55dab8d847..cf8893cef3 100644 --- a/contrib/src/ai/pursue.h +++ b/contrib/src/ai/pursue.h @@ -1,31 +1,27 @@ -// Filename: pursue.h -// Created by: Deepak, John, Navin (24Oct09) -// +//////////////////////////////////////////////////////////////////////// +// Filename : pursue.h +// Created by : Deepak, John, Navin +// Date : 24 Oct 09 //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) Carnegie Mellon University. All rights reserved. // -// All use of this software is subject to the terms of the revised -// BSD license. You should have received a copy of this license -// along with this source code in a file named "LICENSE." +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." // //////////////////////////////////////////////////////////////////// -#ifndef PURSUE_H -#define PURSUE_H +#ifndef _PURSUE_H +#define _PURSUE_H #include "aiGlobals.h" #include "aiCharacter.h" class AICharacter; -//////////////////////////////////////////////////////////////////// -// Class : Pursue -// Description : This class handles all calls to the pursue -// behavior -//////////////////////////////////////////////////////////////////// -class Pursue { +class EXPCL_PANDAAI Pursue { public: AICharacter *_ai_char; @@ -39,4 +35,5 @@ public: ~Pursue(); LVecBase3f do_pursue(); }; + #endif diff --git a/contrib/src/ai/seek.cxx b/contrib/src/ai/seek.cxx index 9afaf91058..6139c08398 100644 --- a/contrib/src/ai/seek.cxx +++ b/contrib/src/ai/seek.cxx @@ -1,14 +1,15 @@ -// Filename: seek.cxx -// Created by: Deepak, John, Navin (24Oct09) -// +//////////////////////////////////////////////////////////////////////// +// Filename : seek.cxx +// Created by : Deepak, John, Navin +// Date : 24 Oct 09 //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) Carnegie Mellon University. All rights reserved. // -// All use of this software is subject to the terms of the revised -// BSD license. You should have received a copy of this license -// along with this source code in a file named "LICENSE." +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." // //////////////////////////////////////////////////////////////////// @@ -20,21 +21,19 @@ Seek::Seek(AICharacter *ai_ch, NodePath target_object, float seek_wt) { _seek_position = target_object.get_pos(_ai_char->_window_render); _seek_weight = seek_wt; - _seek_direction = _seek_position - - _ai_char->_ai_char_np.get_pos(_ai_char->_window_render); + _seek_direction = _seek_position - _ai_char->_ai_char_np.get_pos(_ai_char->_window_render); _seek_direction.normalize(); _seek_done = false; } Seek::Seek(AICharacter *ai_ch, LVecBase3f pos, float seek_wt) { - _ai_char = ai_ch; + _ai_char = ai_ch; _seek_position = pos; _seek_weight = seek_wt; - _seek_direction = _seek_position - - _ai_char->_ai_char_np.get_pos(_ai_char->_window_render); + _seek_direction = _seek_position - _ai_char->_ai_char_np.get_pos(_ai_char->_window_render); _seek_direction.normalize(); _seek_done = false; @@ -43,24 +42,25 @@ Seek::Seek(AICharacter *ai_ch, LVecBase3f pos, float seek_wt) { Seek::~Seek() { } -//////////////////////////////////////////////////////////////////// -// Function: do_seek -// Description: This function performs the seek and returns a seek -// force which is used -// in the calculate_prioritized function. -// This function is not to be used by the user. -//////////////////////////////////////////////////////////////////// -LVecBase3f Seek::do_seek() { - double target_distance = (_seek_position - - _ai_char->_ai_char_np.get_pos(_ai_char->_window_render)).length(); +///////////////////////////////////////////////////////////////////////////////// +// +// Function : do_seek +// Description : This function performs the seek and returns a seek force which is used +// in the calculate_prioritized function. +// This function is not to be used by the user. - if (int(target_distance) == 0) { +///////////////////////////////////////////////////////////////////////////////// + +LVecBase3f Seek::do_seek() { + double target_distance = (_seek_position - _ai_char->_ai_char_np.get_pos(_ai_char->_window_render)).length(); + + if(int(target_distance) == 0) { _seek_done = true; - _ai_char->_steering->_steering_force = LVecBase3f(0.0, 0.0, 0.0); - _ai_char->_steering->turn_off("seek"); - return (LVecBase3f(0.0, 0.0, 0.0)); + _ai_char->_steering->_steering_force = LVecBase3f(0.0, 0.0, 0.0); + _ai_char->_steering->turn_off("seek"); + return(LVecBase3f(0.0, 0.0, 0.0)); } LVecBase3f desired_force = _seek_direction * _ai_char->_movt_force; - return (desired_force); + return(desired_force); } diff --git a/contrib/src/ai/seek.h b/contrib/src/ai/seek.h index e5e5dc0fa2..c3f3ddc4a4 100644 --- a/contrib/src/ai/seek.h +++ b/contrib/src/ai/seek.h @@ -1,30 +1,27 @@ -// Filename: seek.h -// Created by: Deepak, John, Navin (24Oct09) -// +//////////////////////////////////////////////////////////////////////// +// Filename : seek.h +// Created by : Deepak, John, Navin +// Date : 24 Oct 09 //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) Carnegie Mellon University. All rights reserved. // -// All use of this software is subject to the terms of the revised -// BSD license. You should have received a copy of this license -// along with this source code in a file named "LICENSE." +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." // //////////////////////////////////////////////////////////////////// -#ifndef SEEK_H -#define SEEK_H +#ifndef _SEEK_H +#define _SEEK_H #include "aiGlobals.h" #include "aiCharacter.h" class AICharacter; -//////////////////////////////////////////////////////////////////// -// Class : Seek -// Description : This class handles all calls to the seek behavior -//////////////////////////////////////////////////////////////////// -class Seek { +class EXPCL_PANDAAI Seek { public: AICharacter *_ai_char; diff --git a/contrib/src/ai/wander.cxx b/contrib/src/ai/wander.cxx index e1bc7154ba..804eb50105 100644 --- a/contrib/src/ai/wander.cxx +++ b/contrib/src/ai/wander.cxx @@ -1,39 +1,45 @@ -// Filename: wander.cxx -// Created by: Deepak, John, Navin (24Oct09) -// +//////////////////////////////////////////////////////////////////////// +// Filename : wander.cxx +// Created by : Deepak, John, Navin +// Date : 24 Oct 09 //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) Carnegie Mellon University. All rights reserved. // -// All use of this software is subject to the terms of the revised -// BSD license. You should have received a copy of this license -// along with this source code in a file named "LICENSE." +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." // //////////////////////////////////////////////////////////////////// #include "wander.h" -//////////////////////////////////////////////////////////////////// -// Function: rand_float -// Description: This function creates a random float point number -//////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +// +// Function : rand_float +// Description : This function creates a random float point number + +///////////////////////////////////////////////////////////////////////////////// + double rand_float() { const static double rand_max = 0x7fff; return ((rand()) / (rand_max + 1.0)); } -//////////////////////////////////////////////////////////////////// -// Function: random_clamped -// Description: This function returns a random floating point number -// in the range -1 to 1. -//////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +// +// Function : random_clamped +// Description : This function returns a random floating point number in the range +// -1 to 1. + +///////////////////////////////////////////////////////////////////////////////// + double random_clamped() { - return (rand_float() - rand_float()); + return (rand_float() - rand_float()); } -Wander::Wander(AICharacter *ai_ch, double wander_radius,int flag, - double aoe, float wander_weight) { +Wander::Wander(AICharacter *ai_ch, double wander_radius,int flag, double aoe, float wander_weight) { _ai_char = ai_ch; _wander_radius = wander_radius ; _wander_weight = wander_weight; @@ -49,30 +55,25 @@ Wander::Wander(AICharacter *ai_ch, double wander_radius,int flag, // Value 2 - XZ axes wander // Value 3 - XYZ axes wander // default is XY axes - switch (_flag) { + switch(_flag) { case 0: { - _wander_target = LVecBase3f(_wander_radius * cos(theta), - _wander_radius * sin(theta),0); + _wander_target = LVecBase3f(_wander_radius * cos(theta), _wander_radius * sin(theta),0); break; } case 1: { - _wander_target = LVecBase3f(0, _wander_radius * cos(theta), - _wander_radius * sin(theta)); + _wander_target = LVecBase3f(0, _wander_radius * cos(theta), _wander_radius * sin(theta)); break; } case 2: { - _wander_target = LVecBase3f(_wander_radius * cos(theta), 0, - _wander_radius * sin(theta)); + _wander_target = LVecBase3f(_wander_radius * cos(theta), 0, _wander_radius * sin(theta)); break; } case 3: { - _wander_target = LVecBase3f(_wander_radius * sin(theta) * cos(si), - _wander_radius * sin(theta) * sin(si), _wander_radius * cos(theta)); + _wander_target = LVecBase3f(_wander_radius * sin(theta) * cos(si), _wander_radius * sin(theta) * sin(si), _wander_radius * cos(theta)); break; } default: { - _wander_target = LVecBase3f(_wander_radius * cos(theta), - _wander_radius * sin(theta),0); + _wander_target = LVecBase3f(_wander_radius * cos(theta), _wander_radius * sin(theta),0); break; } } @@ -81,21 +82,22 @@ Wander::Wander(AICharacter *ai_ch, double wander_radius,int flag, Wander::~Wander() { } -//////////////////////////////////////////////////////////////////// -// Function: do_wander -// Description: This function performs the wander and returns the -// wander force which is used +///////////////////////////////////////////////////////////////////////////////// +// +// Function : do_wander +// Description : This function performs the wander and returns the wander force which is used // in the calculate_prioritized function. // This function is not to be used by the user. -//////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////////// + LVecBase3f Wander::do_wander() { LVecBase3f present_pos = _ai_char->get_node_path().get_pos(_ai_char->get_char_render()); - // Create the random slices to enable random movement of wander - // for x,y,z respectively + // Create the random slices to enable random movement of wander for x,y,z respectively double time_slice_1 = random_clamped() * 1.5; double time_slice_2 = random_clamped() * 1.5; double time_slice_3 = random_clamped() * 1.5; - switch (_flag) { + switch(_flag) { case 0: { _wander_target += LVecBase3f(time_slice_1, time_slice_2, 0); break; @@ -128,13 +130,13 @@ LVecBase3f Wander::do_wander() { desired_force.normalize(); desired_force *= _ai_char->_movt_force; double distance = (present_pos - _init_pos).length(); - if (_area_of_effect > 0 && distance > _area_of_effect) { - LVecBase3f direction = present_pos - _init_pos; - direction.normalize(); - desired_force = - direction * _ai_char->_movt_force; - LVecBase3f dirn = _ai_char->_steering->_steering_force; - dirn.normalize(); - _ai_char->_steering->_steering_force = LVecBase3f(0.0, 0.0, 0.0); + if(_area_of_effect > 0 && distance > _area_of_effect) { + LVecBase3f direction = present_pos - _init_pos; + direction.normalize(); + desired_force = - direction * _ai_char->_movt_force; + LVecBase3f dirn = _ai_char->_steering->_steering_force; + dirn.normalize(); + _ai_char->_steering->_steering_force = LVecBase3f(0.0, 0.0, 0.0); } return desired_force; } diff --git a/contrib/src/ai/wander.h b/contrib/src/ai/wander.h index 106973a32f..2ea89606eb 100644 --- a/contrib/src/ai/wander.h +++ b/contrib/src/ai/wander.h @@ -1,40 +1,38 @@ -// Filename: wander.h -// Created by: Deepak, John, Navin (24Oct09) -// +//////////////////////////////////////////////////////////////////////// +// Filename : wander.h +// Created by : Deepak, John, Navin +// Date : 24 Oct 09 //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) Carnegie Mellon University. All rights reserved. // -// All use of this software is subject to the terms of the revised -// BSD license. You should have received a copy of this license -// along with this source code in a file named "LICENSE." +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." // //////////////////////////////////////////////////////////////////// -#ifndef WANDER_H -#define WANDER_H + +#ifndef _WANDER_H +#define _WANDER_H #include "aiCharacter.h" class AICharacter; -//////////////////////////////////////////////////////////////////// -// Class : Wander -// Description : This class handles all calls to the wander behavior -//////////////////////////////////////////////////////////////////// -class Wander { -public: - AICharacter *_ai_char; - double _wander_radius; - LVecBase3f _wander_target; - float _wander_weight; - int _flag; - LVecBase3f _init_pos; - double _area_of_effect; +class EXPCL_PANDAAI Wander { + public: + AICharacter *_ai_char; + double _wander_radius; + LVecBase3f _wander_target; + float _wander_weight; + int _flag; + LVecBase3f _init_pos; + double _area_of_effect; - Wander(AICharacter *ai_ch, double wander_radius, int flag, double aoe, float wander_weight); - LVecBase3f do_wander(); - ~Wander(); + Wander(AICharacter *ai_ch, double wander_radius, int flag, double aoe, float wander_weight); + LVecBase3f do_wander(); + ~Wander(); }; #endif