Panda3D

arrival.cxx

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 }
 All Classes Functions Variables Enumerations