1) Removed more windows warnings.

2) Cleanup of old unused, and non-bullet code
3) Fixed wheelies, though they are currently still
   disabled in the stk_config.data file since the
   AI crashes with the new wheelie implementation.



git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@1365 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2007-12-20 04:37:35 +00:00
parent 1b95764c6a
commit 6daa2ef2d0
35 changed files with 161 additions and 812 deletions

View File

@ -25,9 +25,9 @@
#include "track.hpp"
#include "camera.hpp"
#include "user_config.hpp"
#include "constants.hpp"
void
Camera::setScreenPosition ( int numPlayers, int pos )
void Camera::setScreenPosition ( int numPlayers, int pos )
{
assert(pos >= 0 && pos <= 3);
@ -77,7 +77,7 @@ Camera::setScreenPosition ( int numPlayers, int pos )
}
}
m_LastPitch = 0.0f;
}
} // setScreenPosition
//-----------------------------------------------------------------------------
Camera::Camera ( int numPlayers, int which_ )
@ -96,21 +96,19 @@ Camera::Camera ( int numPlayers, int which_ )
setScreenPosition ( numPlayers, m_which_kart ) ;
m_last_steer_offset = 0;
}
} // Camera
//-----------------------------------------------------------------------------
void
Camera::setMode(Mode mode_)
void Camera::setMode(Mode mode_)
{
m_mode = mode_;
}
} // setMode
//-----------------------------------------------------------------------------
void
Camera::setReverseHeading(bool b)
void Camera::setReverseHeading(bool b)
{
m_reverse = b;
}
} // setReverseHeading
//-----------------------------------------------------------------------------
void Camera::update (float dt)
@ -119,11 +117,13 @@ void Camera::update (float dt)
if ( m_which_kart >= int(world->getNumKarts()) || m_which_kart < 0 ) m_which_kart = 0 ;
sgCoord kartcoord;
const Kart *kart=world->getPlayerKart(m_which_kart);
sgCopyCoord(&kartcoord, world->getPlayerKart(m_which_kart)->getCoord());
// Use the terrain pitch to avoid the camera following a wheelie the kart is doing
kartcoord.hpr[1]=RAD_TO_DEGREE( kart->getTerrainPitch(DEGREE_TO_RAD(kartcoord.hpr[0])) );
kartcoord.hpr[2] = 0;
// If the car angle is 'significantly' different from the camera angle,
// If the terrain pitch is 'significantly' different from the camera angle,
// start adjusting the camera. This helps with steep declines, where
// otherwise the track is not visible anymore.
if(fabsf(kartcoord.hpr[1]-m_LastPitch)>1.0f) {
@ -194,7 +194,7 @@ void Camera::update (float dt)
sgSetCoord(&cam, result);
m_context -> setCamera (&cam) ;
}
} // update
//-----------------------------------------------------------------------------
void Camera::apply ()
@ -208,5 +208,5 @@ void Camera::apply ()
(int)((float)height * m_h) ) ;
m_context -> makeCurrent () ;
}
} // apply

View File

@ -29,9 +29,6 @@
*/
/* Handy constants */
#define GRAVITY (4.0f * 9.80665f)
#define MILE 1609.344f
#define KILOMETER 1000.000f
#define HOUR (60.0f * 60.0f)
@ -41,7 +38,6 @@
eg 30 * MILES_PER_HOUR is 30mph expressed in m/sec
*/
#define MILES_PER_HOUR (MILE/HOUR)
#define KILOMETERS_PER_HOUR (KILOMETER/HOUR)
// Zipper related constants:
@ -54,18 +50,6 @@
// ===============================
#define TRAFFIC_VELOCITY ( 20.0f * KILOMETERS_PER_HOUR )
#define MAX_TURN_RATE 22.5f /* Degrees per second. */
// Projectile related constants
// ============================
#define HOMING_MISSILE_TURN_RATE (MAX_TURN_RATE*6.0f)
#define HOMING_MISSILE_PITCH_RATE (MAX_TURN_RATE*0.125f)
#define MAX_HOME_DIST 50.0f
#define MAX_HOME_DIST_SQD (MAX_HOME_DIST * MAX_HOME_DIST)
#define DEFAULT_NUM_LAPS_IN_RACE 5
/* M$ compilers don't define M_PI... */
#ifndef M_PI

View File

@ -20,7 +20,6 @@
#include <math.h>
#include "flyable.hpp"
#include "constants.hpp"
#include "world.hpp"
#include "kart.hpp"
#include "projectile_manager.hpp"
@ -66,32 +65,17 @@ void Flyable::createPhysics(const btVector3& offset, const btVector3 velocity)
// 2) Compute the pitch of the terrain. This avoids the problem of the
// rocket hitting the floor (e.g. if the kart is braking and therefore
// pointing downwards).
btTransform trans;
m_owner->getTrans(&trans);
btTransform trans = m_owner->getTrans();
// Compute heading so that straight forward (direction=(0,1,0)) is 0:
btVector3 forwards(0.0f, 1.0f, 0.0f);
btVector3 direction=trans.getBasis()*forwards;
// get heading=trans.getBasis*(0,1,0) ... so save the multiplication:
btVector3 direction(trans.getBasis()[0][1],
trans.getBasis()[1][1],
trans.getBasis()[2][1]);
float heading=atan2(-direction.getX(), direction.getY());
float pitch=0.0f;
TerrainInfo::update(trans.getOrigin());
float pitch = getTerrainPitch(heading);
if(getHoT()!=Track::NOHIT)
{
const btVector3 normal=getNormal();
const float X =-sin(heading);
const float Y = cos(heading);
// Compute the angle between the normal of the plane and the line to
// (x,y,0). (x,y,0) is normalised, so are the coordinates of the plane,
// simplifying the computation of the scalar product.
pitch = ( normal.getX()*X + normal.getY()*Y )/normal.length(); // use ( x,y,0)
// The actual angle computed above is between the normal and the (x,y,0)
// line, so to compute the actual angles 90 degrees must be subtracted.
pitch = acosf(pitch) - NINETY_DEGREE_RAD;
}
btMatrix3x3 m;
m.setEulerZYX(pitch, 0.0f, heading);
trans.setBasis(m);
@ -159,15 +143,13 @@ Flyable::~Flyable()
//-----------------------------------------------------------------------------
void Flyable::getClosestKart(const Kart **minKart, float *minDist, btVector3 *minDelta) const
{
btTransform tProjectile;
getTrans(&tProjectile);
btTransform tProjectile=getTrans();
*minDist = 99999.9f;
for(unsigned int i=0 ; i<world->getNumKarts(); i++ )
{
Kart *kart = world -> getKart(i);
if(kart == m_owner) continue;
btTransform t;
kart->getTrans(&t);
btTransform t=kart->getTrans();
btVector3 delta = t.getOrigin()-tProjectile.getOrigin();
float distance2 = delta.length2();
@ -207,15 +189,13 @@ void Flyable::update (float dt)
// -----------------------------------------------------------------------------
void Flyable::placeModel()
{
btTransform t;
getTrans(&t);
btTransform t=getTrans();
float m[4][4];
t.getOpenGLMatrix((float*)&m);
sgSetCoord(&m_curr_pos, m);
const btVector3 &v=m_body->getLinearVelocity();
sgSetVec3(m_velocity.xyz, v.x(), v.y(), v.z());
m_model_transform->setTransform(&m_curr_pos);
Moveable::placeModel();
} // placeModel
// -----------------------------------------------------------------------------

View File

@ -80,7 +80,6 @@ public:
bool hasHit () { return m_has_hit_something; }
void reset () { Moveable::reset();
sgCopyCoord(&m_last_pos,&m_reset_pos ); }
void OutsideTrack (int isReset) { explode(NULL); }
}; // Flyable
#endif

View File

@ -23,7 +23,6 @@
#include "widget_manager.hpp"
#include "world.hpp"
#include "menu_manager.hpp"
void
BaseGUI::animateWidget(const int PREV_SELECTED_WGT, const int SELECTED_WGT)
{

View File

@ -21,8 +21,7 @@
#define HEADER_BASEGUI_H
#include <SDL/SDL.h>
#include "player.hpp"
#include "input.hpp"
class BaseGUI
{

View File

@ -17,8 +17,8 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "difficulty.hpp"
#include "race_manager.hpp"
#include "difficulty.hpp"
#include "widget_manager.hpp"
#include "menu_manager.hpp"
#include "translation.hpp"

View File

@ -79,7 +79,7 @@ void Font::Print(const char *text, int size,
int sz = (int)(size*std::max(scale_x,scale_y)*fontScaling);
float l,r,t,b;
m_fnt->getBBox(text, sz, 0, &l, &r, &b, &t);
m_fnt->getBBox(text, (float)sz, 0, &l, &r, &b, &t);
const int W = (int)((r-l+0.99));
const int H = (int)((t-b+0.99));
@ -104,7 +104,7 @@ void Font::Print(const char *text, int size,
}
m_text_out->begin();
m_text_out->setPointSize(sz);
m_text_out->setPointSize((float)sz);
if(doShadow)
{
m_text_out->start2f((GLfloat)x-2, (GLfloat)y-2);

View File

@ -17,8 +17,8 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "num_laps.hpp"
#include "race_manager.hpp"
#include "num_laps.hpp"
#include "widget_manager.hpp"
#include "menu_manager.hpp"
#if defined(WIN32) && !defined(__CYGWIN__)

View File

@ -17,8 +17,8 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "num_players.hpp"
#include "race_manager.hpp"
#include "num_players.hpp"
#include "widget_manager.hpp"
#include "menu_manager.hpp"
#include "translation.hpp"

View File

@ -19,15 +19,13 @@
#include <SDL/SDL.h>
#include "player_controls.hpp"
#include "widget_manager.hpp"
#include "player_controls.hpp"
#include "user_config.hpp"
#include "menu_manager.hpp"
#include "translation.hpp"
#include "sdldrv.hpp"
#include <string>
enum WidgetTokens
{
WTOK_TITLE,

View File

@ -20,11 +20,10 @@
#ifndef HEADER_PLAYERCONTROLS_H
#define HEADER_PLAYERCONTROLS_H
#include "base_gui.hpp"
#include "player.hpp"
#include <string>
#include <SDL/SDL.h>
#include "base_gui.hpp"
#include "player.hpp"
class PlayerControls: public BaseGUI
{

View File

@ -19,10 +19,10 @@
#include <SDL/SDL.h>
#include "race_menu.hpp"
#include "user_config.hpp"
#include "world.hpp"
#include "widget_manager.hpp"
#include "user_config.hpp"
#include "race_menu.hpp"
#include "world.hpp"
#include "menu_manager.hpp"
#include "race_manager.hpp"

View File

@ -81,7 +81,7 @@ RaceResultsGUI::RaceResultsGUI()
Kart *k = world->getKart(i);
order[k->getPosition()-1] = i;
const std::string& s = k->getName();
unsigned int l = s.size();
unsigned int l = (unsigned int)s.size();
if(l>max_name_len) max_name_len = l;
} // for i

View File

@ -64,13 +64,10 @@ void Homing::update(float dt)
float minDistance;
getClosestKart(&kart, &minDistance, &direction);
btTransform my_trans;
getTrans(&my_trans);
btTransform my_trans=getTrans();
if(minDistance<m_st_max_distance) // move homing towards kart
{
btTransform target;
kart->getTrans(&target);
getTrans(&my_trans);
btTransform target=kart->getTrans();
float steer=steerTowards(my_trans, target.getOrigin());
if(fabsf(steer)>90.0f) steer=0.0f;

View File

@ -523,6 +523,7 @@
WholeProgramOptimization="false"
AdditionalIncludeDirectories="./../../../src;&quot;$(PLIB_PATH)&quot;;&quot;$(SDL_PATH)\include&quot;;&quot;$(ALUT_PATH)\include&quot;;&quot;$(OGG_PATH)\include&quot;;&quot;$(VORBIS_PATH)\include&quot;;&quot;$(OPENAL_PATH)\include&quot;;&quot;$(OPENAL_PATH)\include\AL&quot;;../../../src/bullet/src;&quot;$(GLUT_PATH)\include&quot;"
PreprocessorDefinitions="BULLET;HAVE_OPENAL;HAVE_OGGVORBIS;_DEBUG;_CONSOLE;WIN32;NOMINMAX;VERSION=\&quot;0.4alpha\&quot;;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;DEBUG"
GeneratePreprocessedFile="0"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"

View File

@ -1,8 +1,6 @@
#ifndef TUXKART_INPUT_H
#define TUXKART_INPUT_H
#include <string>
enum AxisDirection {
AD_NEGATIVE,
AD_POSITIVE,

View File

@ -377,18 +377,16 @@ void Kart::reset()
world->m_track->spatialToTrack( m_curr_track_coords, m_curr_pos.xyz,
m_track_sector );
btTransform trans;
trans.setIdentity();
// Set heading:
trans.setRotation(btQuaternion(btVector3(0.0f, 0.0f, 1.0f),
DEGREE_TO_RAD(m_reset_pos.hpr[0])) );
m_transform.setRotation(btQuaternion(btVector3(0.0f, 0.0f, 1.0f),
DEGREE_TO_RAD(m_reset_pos.hpr[0])) );
// Set position
trans.setOrigin(btVector3(m_reset_pos.xyz[0],
m_reset_pos.xyz[1],
m_reset_pos.xyz[2]+0.5f*m_kart_height));
m_transform.setOrigin(btVector3(m_reset_pos.xyz[0],
m_reset_pos.xyz[1],
m_reset_pos.xyz[2]+0.5f*m_kart_height));
m_vehicle->applyEngineForce (0.0f, 2);
m_vehicle->applyEngineForce (0.0f, 3);
m_body->setCenterOfMassTransform(trans);
m_body->setCenterOfMassTransform(m_transform);
m_body->setLinearVelocity (btVector3(0.0f,0.0f,0.0f));
m_body->setAngularVelocity(btVector3(0.0f,0.0f,0.0f));
for(int j=0; j<m_vehicle->getNumWheels(); j++)
@ -487,6 +485,7 @@ void Kart::doLapCounting ()
void Kart::doObjectInteractions ()
{
int i;
// FIXME: a lot of work for the 'traffic jam' sound - perhaps just remove it?
for ( i = 0 ; i < m_grid_position ; i++ )
{
sgVec3 xyz ;
@ -503,31 +502,9 @@ void Kart::doObjectInteractions ()
world->addCollisions(m_grid_position, 1);
world->addCollisions(i, 1);
if ( m_velocity.xyz[1] > other_kart->getVelocity()->xyz[1] )
{
forceCrash () ;
sgSubVec2 ( other_kart->getCoord()->xyz, xyz ) ;
}
else
{
other_kart->forceCrash () ;
sgAddVec2 ( getCoord()->xyz, xyz ) ;
}
if(m_attachment.getType()==ATTACH_BOMB &&
m_attachment.getPreviousOwner()!=other_kart)
{
m_attachment.moveBombFromTo(this, other_kart);
}
if(other_kart->m_attachment.getType()==ATTACH_BOMB &&
other_kart->m_attachment.getPreviousOwner()!=this)
{
m_attachment.moveBombFromTo(other_kart, this);
}
} // if sgLengthSquaredVec2(xy)<1.0
} // for i
// Check if any herring was hit.
herring_manager->hitHerring(this);
} // doObjectInteractions
//-----------------------------------------------------------------------------
@ -554,11 +531,11 @@ void Kart::collectedHerring(Herring* herring)
} // hitHerring
//-----------------------------------------------------------------------------
void Kart::doZipperProcessing (float delta)
void Kart::doZipperProcessing (float dt)
{
if ( m_zipper_time_left > delta )
if ( m_zipper_time_left > dt )
{
m_zipper_time_left -= delta ;
m_zipper_time_left -= dt ;
if ( m_velocity.xyz[1] < ZIPPER_VELOCITY )
m_velocity.xyz[1] = ZIPPER_VELOCITY ;
}
@ -566,6 +543,7 @@ void Kart::doZipperProcessing (float delta)
} // doZipperProcessing
//-----------------------------------------------------------------------------
// Simulates gears
float Kart::getActualWheelForce()
{
const std::vector<float>& gear_ratio=m_kart_properties->getGearSwitchRatio();
@ -618,51 +596,6 @@ void Kart::handleExplosion(const sgVec3& pos, bool direct_hit)
}
} // handleExplosion
//-----------------------------------------------------------------------------
void Kart::forceCrash ()
{
m_wheelie_angle = CRASH_PITCH ;
btVector3 velocity = m_body->getLinearVelocity();
velocity.setY( 0.0f );
velocity.setX( 0.0f );
getVehicle()->getRigidBody()->setLinearVelocity( velocity );
} // forceCrash
//-----------------------------------------------------------------------------
#ifndef BULLET
void Kart::doCollisionAnalysis ( float delta, float hot )
{
if ( m_collided )
{
if ( m_velocity.xyz[1] > MIN_COLLIDE_VELOCITY )
{
m_velocity.xyz[1] -= COLLIDE_BRAKING_RATE * delta ;
}
else if ( m_velocity.xyz[1] < -MIN_COLLIDE_VELOCITY )
{
m_velocity.xyz[1] += COLLIDE_BRAKING_RATE * delta ;
}
} // if collided
if ( m_crashed && m_velocity.xyz[1] > MIN_CRASH_VELOCITY )
{
forceCrash () ;
}
else if ( m_wheelie_angle < 0.0f )
{
m_wheelie_angle += getWheelieRestoreRate() * delta;
if ( m_wheelie_angle >= 0.0f ) m_wheelie_angle = 0.0f ;
}
/* Make sure that the car doesn't go through the floor */
if ( isOnGround() )
{
m_velocity.xyz[2] = 0.0f ;
} // isOnGround
} // doCollisionAnalysis
#endif
//-----------------------------------------------------------------------------
void Kart::update (float dt)
{
@ -696,15 +629,14 @@ void Kart::update (float dt)
}
m_curr_pos.xyz[2] += rescue_height*dt/rescue_time;
btTransform pos=m_body->getCenterOfMassTransform();
pos.setOrigin(btVector3(m_curr_pos.xyz[0],m_curr_pos.xyz[1],m_curr_pos.xyz[2]));
m_transform.setOrigin(btVector3(m_curr_pos.xyz[0],m_curr_pos.xyz[1],m_curr_pos.xyz[2]));
btQuaternion q_roll (btVector3(0.f, 1.f, 0.f),
-m_rescue_roll*dt/rescue_time*M_PI/180.0f);
btQuaternion q_pitch(btVector3(1.f, 0.f, 0.f),
-m_rescue_pitch*dt/rescue_time*M_PI/180.0f);
pos.setRotation(pos.getRotation()*q_roll*q_pitch);
m_body->setCenterOfMassTransform(pos);
setTrans(pos);
m_transform.setRotation(m_transform.getRotation()*q_roll*q_pitch);
m_body->setCenterOfMassTransform(m_transform);
//printf("Set %f %f %f\n",pos.getOrigin().x(),pos.getOrigin().y(),pos.getOrigin().z());
} // if m_rescue
m_attachment.update(dt, &m_velocity);
@ -741,6 +673,9 @@ void Kart::update (float dt)
} // if there is terrain and it's not a reset material
doObjectInteractions();
// Check if any herring was hit.
herring_manager->hitHerring(this);
// Save the last valid sector for forced rescue on shortcuts
if(m_track_sector != Track::UNKNOWN_SECTOR &&
!m_rescue )
@ -877,7 +812,7 @@ float Kart::handleWheelie(float dt)
}
if(m_wheelie_angle <=0.0f) return 0.0f;
const btTransform& chassisTrans = m_body->getCenterOfMassTransform();
const btTransform& chassisTrans = getTrans();
btVector3 targetUp(0.0f, 0.0f, 1.0f);
btVector3 forwardW (chassisTrans.getBasis()[0][1],
chassisTrans.getBasis()[1][1],
@ -898,6 +833,7 @@ float Kart::handleWheelie(float dt)
angvel += deltaangvel;
m_body->setAngularVelocity(angvel);
return m_kart_properties->getWheeliePowerBoost() * getMaxPower()
* m_wheelie_angle/getWheelieMaxPitch();
} // handleWheelie
@ -919,8 +855,8 @@ void Kart::updatePhysics (float dt)
{ // braking or moving backwards
if(m_speed > 0.f)
{ // going forward, apply brake force
m_vehicle->applyEngineForce(-1.0f*getBrakeFactor()*engine_power, 2);
m_vehicle->applyEngineForce(-1.0f*getBrakeFactor()*engine_power, 3);
m_vehicle->applyEngineForce(-getBrakeFactor()*engine_power, 2);
m_vehicle->applyEngineForce(-getBrakeFactor()*engine_power, 3);
}
else
{ // going backward, apply reverse gear ratio
@ -1281,19 +1217,8 @@ void Kart::placeModel ()
// replayed.
if(!user_config->m_replay_history)
{
btTransform t;
if(m_rescue)
{
// FIXME: can we use motion_state/getTrans as below here?
// FIXME: e.g. by setting motion_state appropriately during rescue?
t=m_body->getCenterOfMassTransform();
}
else
{
getTrans(&t);
}
float m[4][4];
t.getOpenGLMatrix((float*)&m);
getTrans().getOpenGLMatrix((float*)&m);
//printf(" is %f %f %f\n",t.getOrigin().x(),t.getOrigin().y(),t.getOrigin().z());
// Transfer the new position and hpr to m_curr_pos
@ -1308,6 +1233,7 @@ void Kart::placeModel ()
const float CENTER_SHIFT = getGravityCenterShift();
c.xyz[2] -= (0.5f-CENTER_SHIFT)*m_kart_height; // adjust for center of gravity
m_model_transform->setTransform(&c);
Moveable::placeModel();
// Check if a kart needs to be rescued.
if((fabs(m_curr_pos.hpr[2])>60 &&
@ -1316,16 +1242,6 @@ void Kart::placeModel ()
m_rescue=true;
m_time_since_stuck=0.0f;
}
#ifndef BULLET
sgCoord c ;
sgCopyCoord ( &c, &m_curr_pos ) ;
c.hpr[1] += m_wheelie_angle ;
c.xyz[2] += 0.3f*fabs(sin(m_wheelie_angle
*SG_DEGREES_TO_RADIANS));
m_model -> setTransform ( & c ) ;
#endif
} // placeModel

View File

@ -226,7 +226,8 @@ public:
float getTimeAtLap () const {return m_time_at_last_lap; }
float getKartLength () const {return m_kart_length; }
void createPhysics (ssgEntity *obj);
float getKartHeight () const {return m_kart_height; }
float getKartHeight () const {return m_kart_height; }
float getWheelieAngle () const {return m_wheelie_angle; }
btRaycastVehicle *getVehicle () const {return m_vehicle; }
void updateBulletPhysics(float dt);
void draw ();
@ -246,14 +247,10 @@ public:
virtual void collectedHerring (Herring* herring);
virtual void reset ();
virtual void handleZipper ();
virtual void forceCrash ();
virtual void crashed () {};
virtual void doLapCounting ();
virtual void update (float dt );
#ifndef BULLET
virtual void doCollisionAnalysis(float dt, float hot );
#endif
virtual void doObjectInteractions();
virtual void OutsideTrack (int isReset) {m_rescue=true;}
};
class TrafficDriver : public Kart

View File

@ -24,6 +24,7 @@
#include "translation.hpp"
#if defined(WIN32) && !defined(__CYGWIN__)
# define snprintf _snprintf
# define strdup _strdup
#endif
ssgState *fuzzy_gst;

View File

@ -84,6 +84,7 @@ void Moveable::createBody(float mass, btTransform& trans,
btCollisionShape *shape, MoveableType m) {
btVector3 inertia;
m_transform = trans;
shape->calculateLocalInertia(mass, inertia);
m_motion_state = new btDefaultMotionState(trans);
@ -169,11 +170,17 @@ void Moveable::update (float dt)
}
} // if m_history_position
placeModel () ;
placeModel();
m_first_time = false ;
} // update
//-----------------------------------------------------------------------------
void Moveable::placeModel()
{
m_motion_state->getWorldTransform(m_transform);
m_model_transform->setTransform(&m_curr_pos);
} // placeModel
//-----------------------------------------------------------------------------
/**
* Computes the new position and hpr of the kart after a single time step.
@ -233,143 +240,3 @@ void Moveable::ReadHistory(char* s, int kartNumber, int indx)
exit(-2);
}
} // ReadHistory
//-----------------------------------------------------------------------------
#define ISECT_STEP_SIZE 0.4f
#define COLLISION_SPHERE_RADIUS 0.6f
#define max(m,n) ((m)>(n) ? (m) : (n)) /* return highest number */
#ifndef BULLET
//-----------------------------------------------------------------------------
float Moveable::collectIsectData ( sgVec3 start, sgVec3 end )
{
sgVec3 vel ;
m_collided = m_crashed = false ; /* Initial assumption */
sgSubVec3 ( vel, end, start ) ;
const float SPEED = sgLengthVec3 ( vel ) ;
/*
At higher speeds, we must test frequently so we can't
pass through something thin by mistake.
At very high speeds, this is getting costly...so beware!
*/
int nsteps = (int) ceil ( SPEED / ISECT_STEP_SIZE ) ;
if ( nsteps == 0 ) nsteps = 1 ;
if ( nsteps > 100 )
{
fprintf(stderr, "WARNING: Speed too high for collision detection!\n"
"WARNING: Nsteps=%d, Speed=%f!\n"
"moveable %p, vel=%f,%f,%f\n",
nsteps, SPEED, this, vel[0], vel[1], vel[2]);
nsteps = 100 ;
}
sgScaleVec3 ( vel, vel, 1.0f / (float) nsteps ) ;
sgVec3 pos1, pos2 ;
sgCopyVec3 ( pos1, start ) ;
float hot = -9999.0 ;
for ( int i = 0 ; i < nsteps ; i++ )
{
sgAddVec3 ( pos2, pos1, vel ) ;
float hot1 = getIsectData ( pos1, pos2 ) ;
hot = max(hot, hot1);
sgCopyVec3 ( pos1, pos2 ) ;
if(m_collided) break;
}
sgCopyVec3 ( end, pos2 ) ;
return hot ;
} // collectIsectData
//-----------------------------------------------------------------------------
float Moveable::getIsectData ( sgVec3 start, sgVec3 end )
{
int num_hits;
sgSphere sphere;
/*
It's necessary to lift the center of the bounding sphere
somewhat so that Player can stand on a slope.
*/
sphere.setRadius ( COLLISION_SPHERE_RADIUS ) ;
sphere.setCenter ( 0.0f, 0.0f, COLLISION_SPHERE_RADIUS + 0.3f) ;
/* Do a bounding-sphere test for Player. */
sgSetVec3 ( m_surface_avoidance_vector, 0.0f, 0.0f, 0.0f );
// new collision algorithm
AllHits a;
sphere.setCenter ( end[0],end[1],end[2]+ COLLISION_SPHERE_RADIUS + 0.3f) ;
num_hits = world->Collision(&sphere, &a);
for(AllHits::iterator i=a.begin(); i!=a.end(); i++)
{
if ( (*i)->m_plane[2]>0.4 ) continue;
const float DIST = sphere.getRadius()-(*i)->m_dist;
sgVec3 nrm ;
sgCopyVec3 ( nrm, (*i)->m_plane ) ;
sgScaleVec3 ( nrm, nrm, DIST ) ;
sgAddVec3 ( m_surface_avoidance_vector, nrm ) ;
sgVec3 tmp ;
sgCopyVec3 ( tmp, sphere.getCenter() ) ;
sgAddVec3 ( tmp, nrm ) ;
sphere.setCenter ( tmp ) ;
m_collided = true ;
Material* m = material_manager->getMaterial( (*i)->m_leaf);
if (m->isZipper () ) m_collided = false ;
if (m->isCrashable() ) m_crashed = true ;
if (m->isReset () ) OutsideTrack(1);
} // for i in a
sgAddVec3(end, m_surface_avoidance_vector);
// H.O.T == Height Of Terrain
// ==========================
const float TOP = COLLISION_SPHERE_RADIUS + max(start[2],end[2]);
sgVec3 dstart; sgCopyVec3(dstart, end);
sgVec3 dummy; sgCopyVec3(dummy, end);
dummy[2]=TOP;
ssgLeaf* m_leaf;
const float HOT = world->GetHOT(dummy, dummy, &m_leaf, &m_normal_hot);
if(m_leaf)
{
m_material_hot = material_manager->getMaterial(m_leaf);
// Only rescue the kart if it (nearly) touches the reset-material,
// not only when it is above it. The condition for touching
// a material is somewha coars, since the kart might have been falling
// for quite some time, it might be really fast, so I guess a somewhat
// coarser test is better for that case.
if(m_material_hot->isReset() &&
fabs(TOP-COLLISION_SPHERE_RADIUS - HOT)<0.2) OutsideTrack(1);
if(m_material_hot->isZipper()) handleZipper();
}
else
{
OutsideTrack(0);
}
if (end[2] < HOT )
{
end[2] = HOT ;
} // end[2]<HOT
return HOT ;
} // getIsectData
#endif

View File

@ -30,11 +30,6 @@
/* Limits of Kart performance */
#define CRASH_PITCH -45.0f
#define MAX_NATURAL_VELOCITY ( 60.0f * KILOMETERS_PER_HOUR )
#define MIN_CRASH_VELOCITY (MAX_NATURAL_VELOCITY * 0.2f)
#define MIN_COLLIDE_VELOCITY (MAX_NATURAL_VELOCITY * 0.1f)
#define COLLIDE_BRAKING_RATE (MAX_NATURAL_VELOCITY * 1.0f)
#define MAX_HERRING_EATEN 20
@ -50,7 +45,7 @@ protected:
sgVec3 m_abs_velocity; /* world coordinates' velocity vector */
sgVec4* m_normal_hot; /* plane on which HOT was computed */
Material* m_material_hot; /* Material at HOT */
ssgTransform* m_model_transform; // The transform where the model is under
ssgTransform* m_model_transform; // The transform where the model is under
ssgTransform* m_shadow;
int m_collided;
int m_crashed;
@ -63,6 +58,7 @@ protected:
sgCoord* m_history_position;
btRigidBody* m_body;
btDefaultMotionState* m_motion_state;
btTransform m_transform;
public:
@ -80,29 +76,18 @@ public:
const sgCoord* getCoord () const {return &m_curr_pos; }
const sgVec4* getNormalHOT () const {return m_normal_hot; }
void setCoord (sgCoord* pos) {sgCopyCoord ( &m_curr_pos,pos); }
virtual void placeModel () {m_model_transform->setTransform(&m_curr_pos); }
virtual void placeModel ();
virtual void handleZipper () {};
virtual void reset ();
virtual void update (float dt) ;
virtual void updatePosition(float dt, sgMat4 result);
#ifndef BULLET
virtual void doCollisionAnalysis(float dt, float hot);
#endif
// Gets called when no high of terrain can be determined (isReset=0), or
// there is a 'reset' material under the moveable --> karts need to be
// rescued, missiles should explode.
virtual void OutsideTrack (int isReset) {}
#ifndef BULLET
float getIsectData (sgVec3 start, sgVec3 end );
#endif
void WriteHistory (char* s, int kartNumber, int indx);
void ReadHistory (char* s, int kartNumber, int indx);
btRigidBody* getBody () const {return m_body; }
void createBody(float mass, btTransform& trans,
btCollisionShape *shape, MoveableType m);
void getTrans (btTransform* t) const
{m_motion_state->getWorldTransform(*t);}
void getTrans (btTransform* t) const {*t=m_transform;}
const btTransform& getTrans () const {return m_transform;}
void setTrans (btTransform& t){m_motion_state->setWorldTransform(t);}
}
; // class Moveable

View File

@ -134,6 +134,8 @@ void Physics::update(float dt)
*/
void Physics::KartKartCollision(Kart *kartA, Kart *kartB)
{
kartA->crashed();
kartB->crashed();
Attachment *attachmentA=kartA->getAttachment();
Attachment *attachmentB=kartB->getAttachment();
@ -200,8 +202,6 @@ btScalar Physics::solveGroup(btCollisionObject** bodies, int numBodies,
Moveable *movA = static_cast<Moveable*>(objA->getUserPointer());
Moveable *movB = static_cast<Moveable*>(objB->getUserPointer());
if(!numContacts) continue; // no real collision
// 1) object A is a track
// =======================
if(!movA)
@ -210,14 +210,22 @@ btScalar Physics::solveGroup(btCollisionObject** bodies, int numBodies,
{ // 1.1 projectile hits track
// -------------------------
m_all_collisions.push_back(CollisionPair(movB, Moveable::MOV_PROJECTILE,
NULL, Moveable::MOV_TRACK ));
NULL, Moveable::MOV_TRACK ));
}
else if(movB && movB->getMoveableType()==Moveable::MOV_KART)
{
((Kart*)movB)->crashed();
}
}
// 2) object a is a kart
// =====================
else if(movA->getMoveableType()==Moveable::MOV_KART)
{
if(movB && movB->getMoveableType()==Moveable::MOV_PROJECTILE)
if(!movB)
{
((Kart*)movA)->crashed();
}
else if(movB && movB->getMoveableType()==Moveable::MOV_PROJECTILE)
{ // 2.1 projectile hits kart
// -------------------------
m_all_collisions.push_back(CollisionPair(movB, Moveable::MOV_PROJECTILE,
@ -239,19 +247,19 @@ btScalar Physics::solveGroup(btCollisionObject** bodies, int numBodies,
{ // 3.1) projectile hits track
// --------------------------
m_all_collisions.push_back(CollisionPair(movA, Moveable::MOV_PROJECTILE,
NULL, Moveable::MOV_TRACK ));
NULL, Moveable::MOV_TRACK ));
}
else if(movB->getMoveableType()==Moveable::MOV_PROJECTILE)
{ // 3.2 projectile hits projectile
// ------------------------------
m_all_collisions.push_back(CollisionPair(movA, Moveable::MOV_PROJECTILE,
movB, Moveable::MOV_PROJECTILE));
movB, Moveable::MOV_PROJECTILE));
}
else if(movB->getMoveableType()==Moveable::MOV_KART)
{ // 3.3 projectile hits kart
// ------------------------
m_all_collisions.push_back(CollisionPair(movA, Moveable::MOV_PROJECTILE,
movB, Moveable::MOV_KART ));
movB, Moveable::MOV_KART ));
}
}
// 4) Nothing else should happen

View File

@ -164,9 +164,9 @@ void PlayerKart::update(float dt)
} // update
//-----------------------------------------------------------------------------
void PlayerKart::forceCrash()
void PlayerKart::crashed()
{
Kart::forceCrash();
Kart::crashed();
sound_manager->playSfx( SOUND_CRASH );
}

View File

@ -52,7 +52,7 @@ public:
void update (float);
void addMessages ();
void action (KartAction action, int value);
void forceCrash ();
void crashed ();
void handleZipper ();
void collectedHerring (Herring* herring);
int isPlayerKart () const {return 1;}

View File

@ -1,343 +0,0 @@
// $Id$
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2004-2005 Steve Baker <sjbaker1@airmail.net>
// Copyright (C) 2006 Joerg Henrichs, Steve Baker
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "constants.hpp"
#include "projectile.hpp"
#include "world.hpp"
#include "kart.hpp"
#include "projectile_manager.hpp"
#include "sound_manager.hpp"
#include "scene.hpp"
#include "ssg_help.hpp"
Projectile::Projectile(Kart *kart, int collectable) : Moveable(false)
{
init(kart, collectable);
} // Projectile
//-----------------------------------------------------------------------------
void Projectile::init(Kart *kart, int collectable_)
{
m_owner = kart;
m_type = collectable_;
m_has_hit_something = false;
m_last_radar_beep = -1;
m_speed = collectable_manager->getSpeed(m_type);
ssgTransform *m = getModel();
m->addKid(collectable_manager->getModel(m_type));
scene->add(m);
#ifdef BULLET
m_exploded = false;
float x_min, x_max, y_min, y_max, z_min, z_max;
// getModel returns the transform node, so get the actual model node
MinMax(getModel()->getKid(0), &x_min, &x_max, &y_min, &y_max, &z_min, &z_max);
float half_length = 0.5f*(y_max-y_min);
btCylinderShape* shape = new btCylinderShapeX(btVector3(half_length,
0.5f*(z_max-z_min),
0.5f*(x_max-x_min)));
// The rocket has to start ahead of the kart (not in), so it has to
// be moved forward by (at least) half a kart lengt .. we use one length here
btTransform trans;
kart->getTrans(&trans);
// We should get heading from the kart, and pitch/roll from the terrain here
btVector3 normal=getNormal();
if(getHoT()!=Track::NOHIT)
{
float m[4][4];
trans.getOpenGLMatrix((float*)&m);
sgCoord pos;
sgSetCoord(&pos, m);
btQuaternion q=trans.getRotation();
const float angle_terrain = DEGREE_TO_RAD(pos.hpr[0]);
// The projectile should have the pitch of the terrain on which the kart
// is - while this is not really realistic, it plays much better this way
const float X = -sin(angle_terrain);
const float Y = cos(angle_terrain);
// Compute the angle between the normal of the plane and the line to
// (x,y,0). (x,y,0) is normalised, so are the coordinates of the plane,
// simplifying the computation of the scalar product.
float pitch = ( normal.getX()*X + normal.getY()*Y ); // use ( x,y,0)
// The actual angle computed above is between the normal and the (x,y,0)
// line, so to compute the actual angles 90 degrees must be subtracted.
pos.hpr[1] = acosf(pitch)/M_PI*180.0f-90.0f;
btQuaternion r=trans.getRotation();
r.setEuler(DEGREE_TO_RAD(pos.hpr[1]),DEGREE_TO_RAD(pos.hpr[2]),DEGREE_TO_RAD(pos.hpr[0]));
trans.setRotation(r);
} // if a normal exist
m_initial_velocity = trans.getBasis()*btVector3(0.0f, m_speed, 0.0f);
btTransform offset;
offset.setOrigin(btVector3(0.0f, 2.0f*kart->getKartLength()+2.0f*half_length,
kart->getKartHeight()));
// The cylinder needs to be rotated by 90 degrees to face in the right direction:
btQuaternion r90(0.0f, 0.0f, -NINETY_DEGREE_RAD);
offset.setRotation(r90);
// Apply rotation and offste
trans *= offset;
float mass=1.0f;
createBody(mass, trans, shape, Moveable::MOV_PROJECTILE);
// Simplified rockets: no gravity
world->getPhysics()->addBody(getBody());
m_body->setGravity(btVector3(0.0f, 0.0f, 0.0f));
m_body->setLinearVelocity(m_initial_velocity);
// FIXME: for now it is necessary to synch the graphical position with the
// physical position, since 'hot' computation is done using the
// graphical position (and hot can trigger an explosion when no
// terrain is under the rocket). Once hot is done with bullet as
// well, this shouldn't be necessary anymore.
placeModel();
m_current_HAT = world->getHAT(offset.getOrigin());
m_HAT_counter = 0;
#else
sgCoord c;
sgCopyCoord(&c, kart->getCoord());
const float angle_terrain = c.hpr[0]*M_PI/180.0f;
// The projectile should have the pitch of the terrain on which the kart
const sgVec4* normal = kart->getNormalHOT();
if(normal)
{
const float X = -sin(angle_terrain);
const float Y = cos(angle_terrain);
// Compute the angle between the normal of the plane and the line to
// (x,y,0). (x,y,0) is normalised, so are the coordinates of the plane,
// simplifying the computation of the scalar product.
float pitch = ( (*normal)[0]*X + (*normal)[1]*Y ); // use ( x,y,0)
// The actual angle computed above is between the normal and the (x,y,0)
// line, so to compute the actual angles 90 degrees must be subtracted.
c.hpr[1] = acosf(pitch)/M_PI*180.0f-90.0f;
}
setCoord(&c);
#endif
} // init
//-----------------------------------------------------------------------------
Projectile::~Projectile()
{
#ifdef BULLET
world->getPhysics()->removeBody(getBody());
#endif
} // ~Projectile
//-----------------------------------------------------------------------------
void Projectile::update (float dt)
{
#ifdef BULLET
if(m_exploded) return;
m_body->setLinearVelocity(m_initial_velocity);
m_HAT_counter++;
if(m_HAT_counter==10)
{
m_current_HAT = world->getHAT(getBody()->getCenterOfMassPosition());
m_HAT_counter = 0;
}
#else
// we don't even do any physics here - just set the
// velocity, and ignore everything else for projectiles.
m_velocity.xyz[1] = m_speed;
sgCopyCoord ( &m_last_pos, &m_curr_pos);
#endif
Moveable::update(dt);
doObjectInteractions();
} // update
// -----------------------------------------------------------------------------
#ifdef BULLET
void Projectile::placeModel()
{
btTransform t;
getTrans(&t);
// FIXME: this 90 degrees rotation can be removed
// if the 3d model is rotated instead
btQuaternion r90(0.0f, 0.0f, NINETY_DEGREE_RAD);
t.setRotation(t.getRotation()*r90);
float m[4][4];
t.getOpenGLMatrix((float*)&m);
sgSetCoord(&m_curr_pos, m);
const btVector3 &v=m_body->getLinearVelocity();
sgSetVec3(m_velocity.xyz, v.x(), v.y(), v.z());
m_model->setTransform(&m_curr_pos);
} // placeModel
#endif
// -----------------------------------------------------------------------------
/** Returns true if this missile has hit something, otherwise false. */
void Projectile::doObjectInteractions ()
{
float ndist = SG_MAX ;
int nearest = -1 ;
for ( unsigned int i = 0 ; i < world->getNumKarts() ; i++ )
{
sgCoord *pos ;
Kart *kart = world -> getKart(i);
pos = kart -> getCoord();
if ( m_type != COLLECT_NOTHING && kart != m_owner )
{
const float D = sgDistanceSquaredVec3 ( pos->xyz, getCoord()->xyz ) ;
#ifndef BULLET
if ( D < 2.0f )
{
explode(kart);
return;
}
else
#endif
if ( D < ndist )
{
ndist = D ;
nearest = i ;
} // if !D<2.0f
} // if m_type!=NOTHING &&kart!=m_owner
} // for i<getNumKarts
if ( m_type == COLLECT_HOMING_MISSILE && nearest != -1 &&
ndist < MAX_HOME_DIST_SQD )
{
sgVec3 delta;
sgVec3 hpr;
Kart * kart=world->getKart(nearest);
if(m_last_radar_beep!=nearest && kart->isPlayerKart())
{
sound_manager->playSfx(SOUND_MISSILE_LOCK);
m_last_radar_beep=nearest;
}
sgCoord *k = kart->getCoord() ;
sgSubVec3 ( delta, k->xyz, m_curr_pos.xyz ) ;
#ifdef BULLET
sgHPRfromVec3 ( hpr, delta ) ;
m_curr_pos.hpr[1] = -hpr[1];
sgSubVec3 ( hpr, m_curr_pos.hpr ) ;
if ( hpr[0] > 180.0f ) hpr[0] -= 360.0f ;
if ( hpr[0] < -180.0f ) hpr[0] += 360.0f ;
if ( hpr[0] > 80.0f || hpr[0] < -80.0f )
m_velocity.hpr[0] = 0.0f ;
else
{
if ( hpr[0] > 3.0f ) m_velocity.hpr[0] = HOMING_MISSILE_TURN_RATE ;
else if ( hpr[0] < -3.0f ) m_velocity.hpr[0] = -HOMING_MISSILE_TURN_RATE ;
else m_velocity.hpr[0] = 0.0f ;
}
#else
delta[2] = 0.0f ;
sgHPRfromVec3 ( hpr, delta ) ;
sgSubVec3 ( hpr, m_curr_pos.hpr ) ;
if ( hpr[0] > 180.0f ) hpr[0] -= 360.0f ;
if ( hpr[0] < -180.0f ) hpr[0] += 360.0f ;
if ( hpr[1] > 180.0f ) hpr[1] -= 360.0f ;
if ( hpr[1] < -180.0f ) hpr[1] += 360.0f ;
if ( hpr[0] > 80.0f || hpr[0] < -80.0f )
m_velocity.hpr[0] = 0.0f ;
else
{
if ( hpr[0] > 3.0f ) m_velocity.hpr[0] = HOMING_MISSILE_TURN_RATE ;
else if ( hpr[0] < -3.0f ) m_velocity.hpr[0] = -HOMING_MISSILE_TURN_RATE ;
else m_velocity.hpr[0] = 0.0f ;
if ( hpr[2] > 1.0f ) m_velocity.hpr[1] = -HOMING_MISSILE_PITCH_RATE ;
else if ( hpr[2] < -1.0f ) m_velocity.hpr[1] = HOMING_MISSILE_PITCH_RATE ;
else m_velocity.hpr[1] = 0.0f ;
}
#endif
}
else // m_type!=HOMING||nearest==-1||ndist>MAX_HOME_DIST_SQD
m_velocity.hpr[0] = m_velocity.hpr[1] = 0.0f ;
} // doObjectInteractions
//-----------------------------------------------------------------------------
#ifndef BULLET
void Projectile::doCollisionAnalysis ( float dt, float hot )
{
if ( m_collided || m_crashed )
{
if ( m_type == COLLECT_SPARK )
{
sgVec3 bouncevec ;
sgVec3 direction ;
sgNormalizeVec3 ( bouncevec, m_surface_avoidance_vector ) ;
sgSubVec3 ( direction, m_curr_pos.xyz, m_last_pos.xyz ) ;
sgReflectInPlaneVec3 ( direction, bouncevec ) ;
sgHPRfromVec3 ( m_curr_pos.hpr, direction ) ;
}
else if ( m_type != COLLECT_NOTHING )
{
explode(NULL); // no kart was hit directly
}
} // if m_collided||m_crashed
} // doCollisionAnalysis
#endif
//-----------------------------------------------------------------------------
void Projectile::explode(Kart *kart_hit)
{
#ifdef BULLET
if(m_exploded) return;
#endif
m_has_hit_something=true;
m_curr_pos.xyz[2] += 1.2f ;
// Notify the projectile manager that this rocket has hit something.
// The manager will create the appropriate explosion object, and
// place this projectile into a list so that it can be reused later,
// without the additional cost of creating the object again
projectile_manager->explode();
// Now remove this projectile from the graph:
ssgTransform *m = getModel();
m->removeAllKids();
scene->remove(m);
#ifdef BULLET
world->getPhysics()->removeBody(getBody());
m_exploded=true;
#endif
for ( unsigned int i = 0 ; i < world->getNumKarts() ; i++ )
{
Kart *kart = world -> getKart(i);
// handle the actual explosion. Set a flag it if was a direct hit.
kart->handleExplosion(m_curr_pos.xyz, kart==kart_hit);
}
} // explode
/* EOF */

View File

@ -1,69 +0,0 @@
// $Id$
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2004-2005 Steve Baker <sjbaker1@airmail.net>
// Copyright (C) 2006 Joerg Henrichs, Steve Baker
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_PROJECTILE_H
#define HEADER_PROJECTILE_H
#include "moveable.hpp"
class Kart;
class Projectile : public Moveable
{
sgCoord m_last_pos;
const Kart* m_owner;
float m_speed; // Speed of the projectile
int m_type ;
bool m_has_hit_something;
int m_last_radar_beep;
#ifdef BULLET
bool m_exploded;
btVector3 m_initial_velocity;
float m_current_HAT; // height above terrain
int m_HAT_counter; // compute HAT only every N timesteps
#endif
public:
Projectile (Kart* kart_, int type);
virtual ~Projectile();
void init (Kart* kart_, int type);
void update (float);
#ifdef BULLET
void placeModel ();
#endif
#ifndef BULLET
void doCollisionAnalysis (float dt, float hot);
#endif
void doObjectInteractions();
void explode (Kart* kart);
bool hasHit () {return m_has_hit_something;}
void reset ()
{
Moveable::reset();
sgCopyCoord(&m_last_pos,&m_reset_pos );
}
void OutsideTrack (int isReset) {explode(NULL);}
} ;
#endif

View File

@ -21,9 +21,9 @@
#define HEADER_RACEMANAGER_H
#include <vector>
#include <string>
#include <algorithm>
#include <string>
#include "race_setup.hpp"
#include "cup_data.hpp"

View File

@ -82,8 +82,7 @@ void Spark::update(float dt)
// speed, which causes the speed to increase, which in turn causes
// the spark to fly higher and higher.
btVector3 v=m_body->getLinearVelocity();
btTransform trans;
getTrans(&trans);
btTransform trans=getTrans();
float hat = trans.getOrigin().getZ();
if (hat<= m_max_height)
{

View File

@ -21,7 +21,7 @@
#include "terrain_info.hpp"
#include "world.hpp"
#include "constants.hpp"
TerrainInfo::TerrainInfo(btVector3 &pos, int frequency)
{
@ -38,9 +38,30 @@ void TerrainInfo::update( btVector3& pos)
{
world->getTrack()->getTerrainInfo(pos, &m_HoT,
&m_normal, &m_material);
m_normal.normalize();
m_HoT_counter = 0;
}
} // update
// -----------------------------------------------------------------------------
/** Returns the pitch of the terrain depending on the heading
*/
float TerrainInfo::getTerrainPitch(float heading) const {
if(m_HoT==Track::NOHIT) return 0.0f;
const float X =-sin(heading);
const float Y = cos(heading);
// Compute the angle between the normal of the plane and the line to
// (x,y,0). (x,y,0) is normalised, so are the coordinates of the plane,
// simplifying the computation of the scalar product.
float pitch = ( m_normal.getX()*X + m_normal.getY()*Y ); // use ( x,y,0)
// The actual angle computed above is between the normal and the (x,y,0)
// line, so to compute the actual angles 90 degrees must be subtracted.
pitch = acosf(pitch) - NINETY_DEGREE_RAD;
return pitch;
} // getTerrainPitch
// -----------------------------------------------------------------------------
/* EOF */

View File

@ -36,14 +36,15 @@ private:
float m_HoT; // height of terrain
public:
TerrainInfo(int frequency=1) {m_HoT_frequency=frequency;
m_HoT_counter=frequency; }
TerrainInfo(btVector3 &pos, int frequency=1);
virtual ~TerrainInfo() {};
virtual void update(btVector3 &pos);
float getHoT() const { return m_HoT; }
const Material* getMaterial() const { return m_material; }
const btVector3& getNormal() const { return m_normal; }
TerrainInfo(int frequency=1) {m_HoT_frequency=frequency;
m_HoT_counter=frequency; }
TerrainInfo(btVector3 &pos, int frequency=1);
virtual ~TerrainInfo() {};
virtual void update(btVector3 &pos);
float getHoT() const { return m_HoT; }
const Material* getMaterial() const { return m_material; }
const btVector3& getNormal() const { return m_normal; }
float getTerrainPitch(float heading) const;
}; // TerrainInfo

View File

@ -19,6 +19,7 @@
#include "kart.hpp"
#include "constants.hpp"
#include "world.hpp"
inline float sgnsq ( float x ) { return ( x < 0 ) ? -(x * x) : (x * x) ; }
@ -40,7 +41,7 @@ void TrafficDriver::update (float dt)
m_velocity.hpr[0] = sgnsq(m_curr_track_coords[0])*12.0f ;
m_velocity.xyz[1] = TRAFFIC_VELOCITY ;
m_velocity.xyz[2] -= GRAVITY * dt ;
m_velocity.xyz[2] -= world->getGravity()* dt ;
if ( m_wheelie_angle != 0.0f )
m_wheelie_angle = 0.0f ;

View File

@ -24,6 +24,19 @@
#ifndef HEADER_WIDGET_H
#define HEADER_WIDGET_H
// This include strings causes very many warning in the gui subdir:
// xlocnum(590) : warning C4312: 'type cast' : conversion from 'uintptr_t' to 'void *' of greater size
// These can apparently be removed by removing 64 bit compatibility warnings, or
// just disable the warning during the include:
#if defined(WIN32) && !defined(__CYGWIN__)
# pragma warning(disable:4312)
#endif
#include <string>
#if defined(WIN32) && !defined(__CYGWIN__)
# pragma warning(default:4312)
#endif
#include "gui/font.hpp"
#ifdef __APPLE__
# include <OpenGL/gl.h>
#else
@ -34,8 +47,6 @@
# include <GL/gl.h>
#endif
#include <string>
#include "gui/font.hpp"
enum WidgetFontSize { WGT_FNT_SML = 18, WGT_FNT_MED = 24, WGT_FNT_LRG = 30};

View File

@ -340,10 +340,10 @@ bool WidgetManager::layout()
for( int i = 0; i < NUM_WIDGETS; ++i )
{
m_widgets[i].widget->m_scroll_pos_x =
m_widgets[i].last_preset_scroll_x;
(float)m_widgets[i].last_preset_scroll_x;
m_widgets[i].widget->m_scroll_pos_y =
m_widgets[i].last_preset_scroll_y;
(float)m_widgets[i].last_preset_scroll_y;
}
const int PREV_SELECTED_WGT_TOKEN = m_selected_wgt_token;
@ -730,7 +730,7 @@ void WidgetManager::setInitialRectState
)
{
m_default_show_rect = SHOW;
m_default_rect_round_corners = ROUND_CORNERS;
m_default_rect_round_corners = (ROUND_CORNERS!= WGT_AREA_NONE);
m_default_rect_color = COLOR;
}
@ -911,8 +911,8 @@ void WidgetManager::setWgtText( const int TOKEN, const char* TEXT )
//Reset the scroll position, because it will be the wrong value if
//new text has a different size
m_widgets[ID].widget->m_scroll_pos_x = m_widgets[ID].last_preset_scroll_x;
m_widgets[ID].widget->m_scroll_pos_y = m_widgets[ID].last_preset_scroll_y;
m_widgets[ID].widget->m_scroll_pos_x = (float)m_widgets[ID].last_preset_scroll_x;
m_widgets[ID].widget->m_scroll_pos_y = (float)m_widgets[ID].last_preset_scroll_y;
}
else
{
@ -1006,7 +1006,7 @@ void WidgetManager::setWgtXScrollPos
const int ID = findId(TOKEN);
if( ID != WGT_NONE )
{
m_widgets[ID].widget->m_scroll_pos_x = POS;
m_widgets[ID].widget->m_scroll_pos_x = (float)POS;
m_widgets[ID].last_preset_scroll_x = POS;
}
else
@ -1035,7 +1035,7 @@ void WidgetManager::setWgtYScrollPos
const int ID = findId(TOKEN);
if( ID != WGT_NONE )
{
m_widgets[ID].widget->m_scroll_pos_y = POS;
m_widgets[ID].widget->m_scroll_pos_y = (float)POS;
m_widgets[ID].last_preset_scroll_y = POS;
}
else
@ -1118,7 +1118,7 @@ int WidgetManager::handlePointer(const int X, const int Y )
//The search starts with the current selected widget(since it's most
//probable that the mouse is on top of it )
const int NUM_WIDGETS = m_widgets.size();
const int NUM_WIDGETS = (int)m_widgets.size();
if( m_selected_wgt_token != WGT_NONE )
{
@ -1231,7 +1231,7 @@ WidgetManager::decreaseScrollSpeed(const bool fast)
*/
int WidgetManager::findLeftWidget(const int START_WGT) const
{
const int NUM_WIDGETS = m_widgets.size();
const int NUM_WIDGETS = (int)m_widgets.size();
int closest_wgt = WGT_NONE;
int closest_x_dist = user_config->m_width;
int closest_y_dist = user_config->m_height;
@ -1284,7 +1284,7 @@ int WidgetManager::findLeftWidget(const int START_WGT) const
*/
int WidgetManager::findRightWidget(const int START_WGT) const
{
const int NUM_WIDGETS = m_widgets.size();
const int NUM_WIDGETS = (int)m_widgets.size();
int closest_wgt = WGT_NONE;
int closest_x_dist = user_config->m_width;
int closest_y_dist = user_config->m_height;
@ -1334,7 +1334,7 @@ int WidgetManager::findRightWidget(const int START_WGT) const
*/
int WidgetManager::findTopWidget(const int START_WGT) const
{
const int NUM_WIDGETS = m_widgets.size();
const int NUM_WIDGETS = (int)m_widgets.size();
int closest_wgt = WGT_NONE;
int closest_x_dist = user_config->m_width;
int closest_y_dist = user_config->m_height;
@ -1389,7 +1389,7 @@ int WidgetManager::findTopWidget(const int START_WGT) const
*/
int WidgetManager::findBottomWidget(const int START_WGT) const
{
const int NUM_WIDGETS = m_widgets.size();
const int NUM_WIDGETS = (int)m_widgets.size();
int closest_wgt = WGT_NONE;
int closest_x_dist = user_config->m_width;
int closest_y_dist = user_config->m_height;

View File

@ -20,9 +20,9 @@
#define HEADER_WIDGET_MANAGER_H
#include "widget.hpp"
#include <vector>
/* Here are some big-picture instructions about how to use this widget
* manager: the extern widget_manager is a global interface to the class. Call
* addWgt() to specify the widgets you want, and for each widget specify the