Panda3D
|
00001 //////////////////////////////////////////////////////////////////////// 00002 // Filename : arrival.cxx 00003 // Created by : Deepak, John, Navin 00004 // Date : 24 Oct 09 00005 //////////////////////////////////////////////////////////////////// 00006 // 00007 // PANDA 3D SOFTWARE 00008 // Copyright (c) Carnegie Mellon University. All rights reserved. 00009 // 00010 // All use of this software is subject to the terms of the revised BSD 00011 // license. You should have received a copy of this license along 00012 // with this source code in a file named "LICENSE." 00013 // 00014 //////////////////////////////////////////////////////////////////// 00015 00016 #include "arrival.h" 00017 00018 Arrival::Arrival(AICharacter *ai_ch, double distance) { 00019 _ai_char = ai_ch; 00020 00021 _arrival_distance = distance; 00022 _arrival_done = false; 00023 } 00024 00025 Arrival::~Arrival() { 00026 } 00027 00028 ///////////////////////////////////////////////////////////////////////////////// 00029 // 00030 // Function : do_arrival 00031 // Description : This function performs the arrival and returns an arrival force which is used 00032 // in the calculate_prioritized function. 00033 // In case the steering force = 0, it resets to arrival_activate. 00034 // The arrival behavior works only when seek or pursue is active. 00035 // This function is not to be used by the user. 00036 00037 ///////////////////////////////////////////////////////////////////////////////// 00038 00039 LVecBase3f Arrival::do_arrival() { 00040 LVecBase3f direction_to_target; 00041 double distance; 00042 00043 if(_arrival_type) { 00044 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); 00045 } 00046 else { 00047 direction_to_target = _ai_char->get_ai_behaviors()->_seek_obj->_seek_position - _ai_char->_ai_char_np.get_pos(_ai_char->_window_render); 00048 } 00049 distance = direction_to_target.length(); 00050 00051 _arrival_direction = direction_to_target; 00052 _arrival_direction.normalize(); 00053 00054 if(int(distance) == 0) { 00055 _ai_char->_steering->_steering_force = LVecBase3f(0.0, 0.0, 0.0); 00056 _ai_char->_steering->_arrival_force = LVecBase3f(0.0, 0.0, 0.0); 00057 00058 if(_ai_char->_steering->_seek_obj != NULL) { 00059 _ai_char->_steering->turn_off("arrival"); 00060 _ai_char->_steering->turn_on("arrival_activate"); 00061 } 00062 _arrival_done = true; 00063 return(LVecBase3f(0.0, 0.0, 0.0)); 00064 } 00065 else { 00066 _arrival_done = false; 00067 } 00068 00069 double u = _ai_char->get_velocity().length(); 00070 LVecBase3f desired_force = ((u * u) / (2 * distance)) * _ai_char->get_mass(); 00071 00072 if(_ai_char->_steering->_seek_obj != NULL) { 00073 return(desired_force); 00074 } 00075 00076 if(_ai_char->_steering->_pursue_obj != NULL) { 00077 00078 if(distance > _arrival_distance) { 00079 _ai_char->_steering->turn_off("arrival"); 00080 _ai_char->_steering->turn_on("arrival_activate"); 00081 _ai_char->_steering->resume_ai("pursue"); 00082 } 00083 00084 return(desired_force); 00085 } 00086 00087 cout<<"Arrival works only with seek and pursue"<<endl; 00088 return(LVecBase3f(0.0, 0.0, 0.0)); 00089 } 00090 00091 ///////////////////////////////////////////////////////////////////////////////// 00092 // 00093 // Function : arrival_activate 00094 // Description : This function checks for whether the target is within the arrival distance. 00095 // When this is true, it calls the do_arrival function and sets the arrival direction. 00096 // This function is not to be used by the user. 00097 00098 ///////////////////////////////////////////////////////////////////////////////// 00099 00100 void Arrival::arrival_activate() { 00101 LVecBase3f dirn; 00102 if(_arrival_type) { 00103 dirn = (_ai_char->_ai_char_np.get_pos(_ai_char->_window_render) - _ai_char->get_ai_behaviors()->_pursue_obj->_pursue_target.get_pos(_ai_char->_window_render)); 00104 } 00105 else { 00106 dirn = (_ai_char->_ai_char_np.get_pos(_ai_char->_window_render) - _ai_char->get_ai_behaviors()->_seek_obj->_seek_position); 00107 } 00108 double distance = dirn.length(); 00109 00110 if(distance < _arrival_distance && _ai_char->_steering->_steering_force.length() > 0) { 00111 _ai_char->_steering->turn_off("arrival_activate"); 00112 _ai_char->_steering->turn_on("arrival"); 00113 00114 if(_ai_char->_steering->is_on(_ai_char->_steering->_seek)) { 00115 _ai_char->_steering->turn_off("seek"); 00116 } 00117 00118 if(_ai_char->_steering->is_on(_ai_char->_steering->_pursue)) { 00119 _ai_char->_steering->pause_ai("pursue"); 00120 } 00121 } 00122 }