Back to index

supertuxkart  0.5+dfsg1
homing.cpp
Go to the documentation of this file.
00001 //  $Id: homing.cpp 1284 2007-11-08 12:31:54Z hikerstk $
00002 //
00003 //  SuperTuxKart - a fun racing game with go-kart
00004 //  Copyright (C) 2007 Joerg Henrichs
00005 //
00006 //  This program is free software; you can redistribute it and/or
00007 //  modify it under the terms of the GNU General Public License
00008 //  as published by the Free Software Foundation; either version 2
00009 //  of the License, or (at your option) any later version.
00010 //
00011 //  This program is distributed in the hope that it will be useful,
00012 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //  GNU General Public License for more details.
00015 //
00016 //  You should have received a copy of the GNU General Public License
00017 //  along with this program; if not, write to the Free Software
00018 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00019 
00020 #include "homing.hpp"
00021 #include "constants.hpp"
00022 
00023 float Homing::m_st_max_distance;
00024 float Homing::m_st_max_turn_angle;
00025 
00026 // -----------------------------------------------------------------------------
00033 Homing::Homing (Kart *kart) : Flyable(kart, COLLECT_HOMING)
00034 {
00035     // A bit of a hack: the mass of this kinematic object is still 1.0 
00036     // (see flyable), which enables collisions. I tried setting 
00037     // collisionFilterGroup/mask, but still couldn't get this object to 
00038     // collide with the track. By setting the mass to 1, collisions happen.
00039     // (if bullet is compiled with _DEBUG, a warning will be printed the first
00040     // time a homing-track collision happens).
00041     float y_offset=kart->getKartLength()+2.0f*m_extend.getY();
00042     
00043     m_initial_velocity = btVector3(0.0f, m_speed, 0.0f);
00044     createPhysics(y_offset, m_initial_velocity, 
00045                   new btCylinderShape(0.5f*m_extend));
00046     m_body->setCollisionFlags(m_body->getCollisionFlags()           |
00047                               btCollisionObject::CF_KINEMATIC_OBJECT );
00048     m_body->setActivationState(DISABLE_DEACTIVATION);
00049 }   // Homing
00050 
00051 // -----------------------------------------------------------------------------
00052 void Homing::init(const lisp::Lisp* lisp, ssgEntity *homing)
00053 {
00054     Flyable::init(lisp, homing, COLLECT_HOMING);
00055     m_st_max_turn_angle = 15.0f;
00056     m_st_max_distance   = 20.0f;
00057     lisp->get("max-distance",    m_st_max_distance  );
00058     lisp->get("max-turn-angle",  m_st_max_turn_angle);
00059 }   // init
00060 
00061 // -----------------------------------------------------------------------------
00062 void Homing::update(float dt)
00063 {
00064     Flyable::update(dt);
00065 
00066     const Kart *kart=0;
00067     btVector3 direction;
00068     float minDistance;
00069 
00070     getClosestKart(&kart, &minDistance, &direction);
00071     btTransform my_trans=getTrans();
00072     if(minDistance<m_st_max_distance)   // move homing towards kart
00073     {
00074         btTransform target=kart->getTrans();
00075         
00076         float steer=steerTowards(my_trans, target.getOrigin());
00077         if(fabsf(steer)>90.0f) steer=0.0f;
00078         if(steer<-m_st_max_turn_angle)  steer = -m_st_max_turn_angle;
00079         if(steer> m_st_max_turn_angle)  steer =  m_st_max_turn_angle;
00080         // The steering must be interpreted as grad/s (otherwise this would
00081         // depend on the frame rate). But this would usually miss the karts,
00082         // since the angle isn't adjusted quickly enough when coming closer
00083         // So we allow for (much) larger steering angles the closer the
00084         // kart is by multiplying the rotation/sec with max_distance/minDistance
00085         steer *=(dt*m_st_max_distance/minDistance);
00086         btMatrix3x3 steerMatrix(btQuaternion(0.0f,0.0f,DEGREE_TO_RAD(steer)));
00087         my_trans.setBasis(my_trans.getBasis()*steerMatrix);
00088     }   // minDistance<m_st_max_distance
00089     btVector3 v =my_trans.getBasis()*m_initial_velocity;
00090     my_trans.setOrigin(my_trans.getOrigin()+dt*v);
00091     setTrans(my_trans);
00092 }   // update
00093 // -----------------------------------------------------------------------------
00094 float Homing::steerTowards(btTransform& trans, btVector3& target)
00095 {
00096     btMatrix3x3 m(trans.getBasis());
00097     btVector3 forwards(0.f,1.f,0.0f);
00098     btVector3 direction=m*forwards;
00099     float heading = RAD_TO_DEGREE(atan2(direction.getY(),direction.getX()));
00100 
00101     btVector3 pos=trans.getOrigin();
00102     float angle = RAD_TO_DEGREE(atan2(target.getY()-pos.getY(), target.getX()-pos.getX()));
00103     angle -=heading;
00104     if(angle> 180.0f) angle=angle-360.0f;
00105     if(angle<-180.0f) angle=angle+360.0f;
00106     return angle;
00107 }   // steerTowards