1) Fixed zipper (settings for further tuning in stk_config.data).

2) Fixed bug in collision detection (a kart-kart crash could cause
   a sigsegv).
3) Fixed bug in track loader, which caused somer track objects (e.g.
   zipper in bsod castle) not to get the correct pitch/roll, causing
   them to 'stick out')
4) Fixed wheelie handling for AI (though wheelies are still disabled
   by default, change wheelie-max-speed-ratio to 0.5 to test).
5) Some cleanup of non-bullet code.



git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@1370 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2008-01-01 14:30:39 +00:00
parent 56e24ec8a6
commit a5e2ef24d5
23 changed files with 358 additions and 226 deletions

View File

@ -22,6 +22,8 @@
(bomb-time 30.0 ) ;; time till a bomb explodes (bomb-time 30.0 ) ;; time till a bomb explodes
(bomb-time-increase -5.0 ) ;; time added to timer when bomb is passed on (bomb-time-increase -5.0 ) ;; time added to timer when bomb is passed on
(anvil-time 2.0 ) ;; time an anvil is active (anvil-time 2.0 ) ;; time an anvil is active
(zipper-time 5.0 ) ;; time a zipper is active
(zipper-force 800.0 ) ;; additional zipper force
(shortcut-road-distance 23.0 ) ;; max. distance from side of road to be still (shortcut-road-distance 23.0 ) ;; max. distance from side of road to be still
;; considered on the road (otherwise shortcut) ;; considered on the road (otherwise shortcut)
;; usually 5 is a good value, but for the math class ;; usually 5 is a good value, but for the math class

View File

@ -77,6 +77,8 @@ supertuxkart_SOURCES = main.cpp \
auto_kart.hpp \ auto_kart.hpp \
player_kart.cpp player_kart.hpp \ player_kart.cpp player_kart.hpp \
terrain_info.cpp terrain_info.hpp \ terrain_info.cpp terrain_info.hpp \
triangle_mesh.cpp triangle_mesh.hpp \
user_pointer.hpp \
flyable.cpp flyable.hpp \ flyable.cpp flyable.hpp \
missile.cpp missile.hpp \ missile.cpp missile.hpp \
homing.cpp homing.hpp \ homing.cpp homing.hpp \

View File

@ -122,7 +122,7 @@ void Attachment::moveBombFromTo(Kart *from, Kart *to)
} // moveBombFromTo } // moveBombFromTo
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Attachment::update(float dt, sgCoord *velocity) void Attachment::update(float dt)
{ {
if(m_type==ATTACH_NOTHING) return; if(m_type==ATTACH_NOTHING) return;
m_time_left -=dt; m_time_left -=dt;

View File

@ -74,7 +74,7 @@ public:
?stk_config->m_anvil_speed_factor:1.0f; ?stk_config->m_anvil_speed_factor:1.0f;
} }
void hitGreenHerring(); void hitGreenHerring();
void update (float dt, sgCoord *velocity); void update (float dt);
void moveBombFromTo(Kart *from, Kart *to); void moveBombFromTo(Kart *from, Kart *to);
}; };

View File

@ -52,6 +52,7 @@ Flyable::Flyable(Kart *kart, CollectableType type) : Moveable(false)
m_shape = NULL; m_shape = NULL;
m_mass = 1.0f; m_mass = 1.0f;
setUserPointerType(UP_PROJECTILE);
// Add the graphical model // Add the graphical model
ssgTransform *m = getModelTransform(); ssgTransform *m = getModelTransform();
m->addKid(m_st_model[type]); m->addKid(m_st_model[type]);
@ -88,7 +89,7 @@ void Flyable::createPhysics(const btVector3& offset, const btVector3 velocity)
trans *= offset_transform; trans *= offset_transform;
m_shape = createShape(); // get shape m_shape = createShape(); // get shape
createBody(m_mass, trans, m_shape, Moveable::MOV_PROJECTILE); createBody(m_mass, trans, m_shape, UserPointer::UP_PROJECTILE);
world->getPhysics()->addBody(getBody()); world->getPhysics()->addBody(getBody());
// Simplified rockets: no gravity // Simplified rockets: no gravity
@ -193,8 +194,6 @@ void Flyable::placeModel()
float m[4][4]; float m[4][4];
t.getOpenGLMatrix((float*)&m); t.getOpenGLMatrix((float*)&m);
sgSetCoord(&m_curr_pos, m); sgSetCoord(&m_curr_pos, m);
const btVector3 &v=m_body->getLinearVelocity();
sgSetVec3(m_velocity.xyz, v.x(), v.y(), v.z());
Moveable::placeModel(); Moveable::placeModel();
} // placeModel } // placeModel

View File

@ -893,6 +893,10 @@
RelativePath="../../../src\traffic.cpp" RelativePath="../../../src\traffic.cpp"
> >
</File> </File>
<File
RelativePath="..\..\triangle_mesh.cpp"
>
</File>
<File <File
RelativePath="../../../src\user_config.cpp" RelativePath="../../../src\user_config.cpp"
> >
@ -1307,10 +1311,18 @@
RelativePath="../../../src\translation.hpp" RelativePath="../../../src\translation.hpp"
> >
</File> </File>
<File
RelativePath="..\..\triangle_mesh.hpp"
>
</File>
<File <File
RelativePath="../../../src\user_config.hpp" RelativePath="../../../src\user_config.hpp"
> >
</File> </File>
<File
RelativePath="..\..\user_pointer.hpp"
>
</File>
<File <File
RelativePath="..\..\widget.hpp" RelativePath="..\..\widget.hpp"
> >

View File

@ -79,7 +79,7 @@ void KartParticleSystem::particle_create(int, Particle *p)
p -> m_time_to_live = 0.5 ; /* Droplets evaporate after 5 seconds */ p -> m_time_to_live = 0.5 ; /* Droplets evaporate after 5 seconds */
const sgCoord* POS = m_kart->getCoord(); const sgCoord* POS = m_kart->getCoord();
const sgCoord* VEL = m_kart->getVelocity(); const btVector3 VEL = m_kart->getVelocity();
const float X_DIRECTION = sgCos (POS->hpr[0] - 90.0f); // Point at the rear const float X_DIRECTION = sgCos (POS->hpr[0] - 90.0f); // Point at the rear
const float Y_DIRECTION = sgSin (POS->hpr[0] - 90.0f); // Point at the rear const float Y_DIRECTION = sgSin (POS->hpr[0] - 90.0f); // Point at the rear
@ -89,7 +89,7 @@ void KartParticleSystem::particle_create(int, Particle *p)
p->m_pos[0] += X_DIRECTION * 0.7f; p->m_pos[0] += X_DIRECTION * 0.7f;
p->m_pos[1] += Y_DIRECTION * 0.7f; p->m_pos[1] += Y_DIRECTION * 0.7f;
const float ABS_VEL = sqrt((VEL->xyz[0] * VEL->xyz[0]) + (VEL->xyz[1] * VEL->xyz[1])); const float ABS_VEL = sqrt((VEL.getX() * VEL.getX()) + (VEL.getY() * VEL.getY()));
p->m_vel[0] = X_DIRECTION * -ABS_VEL/2; p->m_vel[0] = X_DIRECTION * -ABS_VEL/2;
p->m_vel[1] = Y_DIRECTION * -ABS_VEL/2; p->m_vel[1] = Y_DIRECTION * -ABS_VEL/2;
@ -200,7 +200,7 @@ void Kart::createPhysics(ssgEntity *obj)
// -------------------- // --------------------
btTransform trans; btTransform trans;
trans.setIdentity(); trans.setIdentity();
createBody(mass, trans, &m_kart_chassis, Moveable::MOV_KART); createBody(mass, trans, &m_kart_chassis, UserPointer::UP_KART);
m_body->setDamping(m_kart_properties->getChassisLinearDamping(), m_body->setDamping(m_kart_properties->getChassisLinearDamping(),
m_kart_properties->getChassisAngularDamping() ); m_kart_properties->getChassisAngularDamping() );
@ -397,13 +397,6 @@ void Kart::reset()
placeModel(); placeModel();
} // reset } // reset
//-----------------------------------------------------------------------------
void Kart::handleZipper()
{
m_wheelie_angle = ZIPPER_ANGLE;
m_zipper_time_left = ZIPPER_TIME;
} // handleZipper
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Kart::doLapCounting () void Kart::doLapCounting ()
{ {
@ -530,29 +523,18 @@ void Kart::collectedHerring(Herring* herring)
sound_manager->playSfx(SOUND_FULL); sound_manager->playSfx(SOUND_FULL);
} // hitHerring } // hitHerring
//-----------------------------------------------------------------------------
void Kart::doZipperProcessing (float dt)
{
if ( m_zipper_time_left > dt )
{
m_zipper_time_left -= dt ;
if ( m_velocity.xyz[1] < ZIPPER_VELOCITY )
m_velocity.xyz[1] = ZIPPER_VELOCITY ;
}
else m_zipper_time_left = 0.0f ;
} // doZipperProcessing
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Simulates gears // Simulates gears
float Kart::getActualWheelForce() float Kart::getActualWheelForce()
{ {
float zipperF=(m_zipper_time_left>0.0f) ? stk_config->m_zipper_force : 0.0f;
const std::vector<float>& gear_ratio=m_kart_properties->getGearSwitchRatio(); const std::vector<float>& gear_ratio=m_kart_properties->getGearSwitchRatio();
for(unsigned int i=0; i<gear_ratio.size(); i++) for(unsigned int i=0; i<gear_ratio.size(); i++)
{ {
if(m_speed <= m_max_speed*gear_ratio[i]) if(m_speed <= m_max_speed*gear_ratio[i])
return getMaxPower()*m_kart_properties->getGearPowerIncrease()[i]; return getMaxPower()*m_kart_properties->getGearPowerIncrease()[i]+zipperF;
} }
return getMaxPower(); return getMaxPower()+zipperF;
} // getActualWheelForce } // getActualWheelForce
@ -610,9 +592,11 @@ void Kart::update (float dt)
m_time_since_stuck = 0.0f; m_time_since_stuck = 0.0f;
} }
m_zipper_time_left = m_zipper_time_left>0.0f ? m_zipper_time_left-dt : 0.0f;
//m_wheel_position gives the rotation around the X-axis, and since velocity's //m_wheel_position gives the rotation around the X-axis, and since velocity's
//timeframe is the delta time, we don't have to multiply it with dt. //timeframe is the delta time, we don't have to multiply it with dt.
m_wheel_position += m_velocity.xyz[1]; m_wheel_position += getVelocity().getY();
if ( m_rescue ) if ( m_rescue )
{ {
@ -639,7 +623,7 @@ void Kart::update (float dt)
//printf("Set %f %f %f\n",pos.getOrigin().x(),pos.getOrigin().y(),pos.getOrigin().z()); //printf("Set %f %f %f\n",pos.getOrigin().x(),pos.getOrigin().y(),pos.getOrigin().z());
} // if m_rescue } // if m_rescue
m_attachment.update(dt, &m_velocity); m_attachment.update(dt);
/*smoke drawing control point*/ /*smoke drawing control point*/
if ( user_config->m_smoke ) if ( user_config->m_smoke )
@ -647,20 +631,22 @@ void Kart::update (float dt)
if (m_smoke_system != NULL) if (m_smoke_system != NULL)
m_smoke_system->update (dt); m_smoke_system->update (dt);
} // user_config->smoke } // user_config->smoke
doZipperProcessing (dt) ;
updatePhysics(dt); updatePhysics(dt);
sgCopyVec2 ( m_last_track_coords, m_curr_track_coords ); sgCopyVec2 ( m_last_track_coords, m_curr_track_coords );
Moveable::update(dt); Moveable::update(dt);
btTransform trans; btTransform trans=getTrans();
getTrans(&trans);
TerrainInfo::update(trans.getOrigin()); TerrainInfo::update(trans.getOrigin());
if (getHoT()==Track::NOHIT || if (getHoT()==Track::NOHIT ||
(getMaterial()->isReset() && isOnGround()) ) (getMaterial()->isReset() && isOnGround()) )
{ {
forceRescue(); forceRescue();
} }
else if(getMaterial()->isZipper())
{
handleZipper();
}
else else
{ {
for(int i=0; i<m_vehicle->getNumWheels(); i++) for(int i=0; i<m_vehicle->getNumWheels(); i++)
@ -762,6 +748,11 @@ void Kart::update (float dt)
processSkidMarks(); processSkidMarks();
} // update } // update
//-----------------------------------------------------------------------------
void Kart::handleZipper()
{
m_zipper_time_left = stk_config->m_zipper_time;
} // handleZipper
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#define sgn(x) ((x<0)?-1.0f:((x>0)?1.0f:0.0f)) #define sgn(x) ((x<0)?-1.0f:((x>0)?1.0f:0.0f))
@ -769,8 +760,7 @@ void Kart::update (float dt)
void Kart::draw() void Kart::draw()
{ {
float m[16]; float m[16];
btTransform t; btTransform t=getTrans();
getTrans(&t);
t.getOpenGLMatrix(m); t.getOpenGLMatrix(m);
btVector3 wire_color(0.5f, 0.5f, 0.5f); btVector3 wire_color(0.5f, 0.5f, 0.5f);
@ -1223,8 +1213,6 @@ void Kart::placeModel ()
//printf(" is %f %f %f\n",t.getOrigin().x(),t.getOrigin().y(),t.getOrigin().z()); //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 // Transfer the new position and hpr to m_curr_pos
sgSetCoord(&m_curr_pos, m); sgSetCoord(&m_curr_pos, m);
const btVector3 &v=m_body->getLinearVelocity();
sgSetVec3(m_velocity.xyz, v.x(), v.y(), v.z());
} }
sgCoord c ; sgCoord c ;
sgCopyCoord ( &c, &m_curr_pos ) ; sgCopyCoord ( &c, &m_curr_pos ) ;
@ -1236,8 +1224,8 @@ void Kart::placeModel ()
Moveable::placeModel(); Moveable::placeModel();
// Check if a kart needs to be rescued. // Check if a kart needs to be rescued.
if((fabs(m_curr_pos.hpr[2])>60 && if((fabs(m_curr_pos.hpr[2])>60 && getSpeed()<3.0f) ||
sgLengthVec3(m_velocity.xyz)<3.0f) || m_time_since_stuck > 2.0f) m_time_since_stuck > 2.0f)
{ {
m_rescue=true; m_rescue=true;
m_time_since_stuck=0.0f; m_time_since_stuck=0.0f;
@ -1278,17 +1266,17 @@ void Kart::handleMagnet(float cdist, int closest)
sgHPRfromVec3 ( getCoord()->hpr, vec ) ; sgHPRfromVec3 ( getCoord()->hpr, vec ) ;
float tgt_velocity = world->getKart(closest)->getVelocity()->xyz[1] ; float tgt_velocity = world->getKart(closest)->getVelocity().getY();
//JH FIXME: that should probably be changed, e.g. by increasing the throttle //JH FIXME: that should probably be changed, e.g. by increasing the throttle
// to something larger than 1??? // to something larger than 1???
if (cdist > stk_config->m_magnet_min_range_sq) if (cdist > stk_config->m_magnet_min_range_sq)
{ {
if ( m_velocity.xyz[1] < tgt_velocity ) if ( getSpeed ()< tgt_velocity )
m_velocity.xyz[1] = tgt_velocity * 1.4f; ;//FIXME m_velocity.xyz[1] = tgt_velocity * 1.4f;
} }
else else
m_velocity.xyz[1] = tgt_velocity ; ;//FIXME m_velocity.xyz[1] = tgt_velocity ;
} // handleMagnet } // handleMagnet
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -78,7 +78,6 @@ protected:
KartControl m_controls; // The position of the karts controls KartControl m_controls; // The position of the karts controls
int m_track_sector; // index in driveline, special values int m_track_sector; // index in driveline, special values
// e.g. UNKNOWN_SECTOR can be negative! // e.g. UNKNOWN_SECTOR can be negative!
float m_zipper_time_left;
sgVec2 m_last_track_coords; sgVec2 m_last_track_coords;
sgVec3 m_curr_track_coords; sgVec3 m_curr_track_coords;
sgVec3 m_velocity_wc; // velocity in world coordinates sgVec3 m_velocity_wc; // velocity in world coordinates
@ -87,7 +86,8 @@ protected:
bool m_skid_rear; // true if rear tires are skidding bool m_skid_rear; // true if rear tires are skidding
float m_max_speed; // maximum speed of the kart, computed from float m_max_speed; // maximum speed of the kart, computed from
float m_max_speed_reverse_ratio; float m_max_speed_reverse_ratio;
float m_wheelie_angle ; float m_wheelie_angle;
float m_zipper_time_left; // zipper time left
float m_lap_start_time; // Time at start of a new lap float m_lap_start_time; // Time at start of a new lap
float m_kart_length; // length of kart float m_kart_length; // length of kart
char m_fastest_lap_message[255]; char m_fastest_lap_message[255];
@ -139,34 +139,29 @@ protected:
void load_wheels (ssgBranch* obj); void load_wheels (ssgBranch* obj);
public: public:
Kart(const KartProperties* kartProperties_, int position_, sgCoord init_pos); Kart(const KartProperties* kartProperties_, int position_,
virtual ~Kart(); sgCoord init_pos);
virtual ~Kart();
void loadData(); void loadData();
void placeModel ();
void placeModel (); const KartProperties*
const KartProperties* getKartProperties() const getKartProperties () const { return m_kart_properties; }
{ return m_kart_properties; }
void setKartProperties (const KartProperties *kp) void setKartProperties (const KartProperties *kp)
{ m_kart_properties=kp;} { m_kart_properties=kp; }
void attach (attachmentType attachment_, float time) void attach (attachmentType attachment_, float time)
{ m_attachment.set(attachment_, time);} { m_attachment.set(attachment_, time); }
void gotZipper (float angle, float time)
{
m_wheelie_angle=angle;
m_zipper_time_left=time;
}
void setCollectable (CollectableType t, int n) void setCollectable (CollectableType t, int n)
{ m_collectable.set(t, n); } { m_collectable.set(t, n); }
void setPosition (int p) {m_race_position = p; } void setPosition (int p)
int getSector () { return m_track_sector; } { m_race_position = p; }
float getDistanceDownTrack() { return m_curr_track_coords[1]; } int getSector () const { return m_track_sector; }
float getDistanceToCenter () { return m_curr_track_coords[0]; } float getDistanceDownTrack() const { return m_curr_track_coords[1]; }
Attachment *getAttachment () { return &m_attachment; } float getDistanceToCenter () const { return m_curr_track_coords[0]; }
Attachment *getAttachment () { return &m_attachment; }
void setAttachmentType (attachmentType t, float time_left=0.0f, void setAttachmentType (attachmentType t, float time_left=0.0f,
Kart*k=NULL) Kart*k=NULL)
{ m_attachment.set(t, time_left, k); } { m_attachment.set(t, time_left, k); }
Collectable *getCollectable () { return &m_collectable; } Collectable *getCollectable () { return &m_collectable; }
int getNumCollectables () const { return m_collectable.getNum();} int getNumCollectables () const { return m_collectable.getNum();}
int getNumHerring () const { return m_num_herrings_gobbled;} int getNumHerring () const { return m_num_herrings_gobbled;}
int getLap () const { return m_race_lap; } int getLap () const { return m_race_lap; }
@ -179,7 +174,6 @@ public:
void processSkidMarks (); void processSkidMarks ();
void getClosestKart (float *cdist, int *closest); void getClosestKart (float *cdist, int *closest);
void handleMagnet (float cdist, int closest); void handleMagnet (float cdist, int closest);
void doZipperProcessing (float dt);
void updatePhysics (float dt); void updatePhysics (float dt);
float NormalizedLateralForce(float alpha, float corner) const; float NormalizedLateralForce(float alpha, float corner) const;

View File

@ -71,17 +71,15 @@ void Moveable::reset ()
m_crashed = false; m_crashed = false;
m_material_hot = NULL; m_material_hot = NULL;
m_normal_hot = NULL; m_normal_hot = NULL;
if(m_body) m_body->setLinearVelocity(btVector3(0.0, 0.0, 0.0));
sgZeroVec3 ( m_velocity.xyz ) ;
sgZeroVec3 ( m_velocity.hpr ) ;
sgCopyCoord ( &m_curr_pos, &m_reset_pos ) ; sgCopyCoord ( &m_curr_pos, &m_reset_pos ) ;
sgZeroVec3 ( m_abs_velocity ) ;
} // reset } // reset
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Moveable::createBody(float mass, btTransform& trans, void Moveable::createBody(float mass, btTransform& trans,
btCollisionShape *shape, MoveableType m) { btCollisionShape *shape,
UserPointer::UserPointerType t) {
btVector3 inertia; btVector3 inertia;
m_transform = trans; m_transform = trans;
@ -93,7 +91,7 @@ void Moveable::createBody(float mass, btTransform& trans,
m_body = new btRigidBody(mass, m_motion_state, m_body = new btRigidBody(mass, m_motion_state,
shape, inertia); shape, inertia);
m_body->setUserPointer(this); m_body->setUserPointer(this);
setMoveableType(m); setUserPointerType(t);
} // createBody } // createBody
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -118,29 +116,17 @@ void Moveable::update (float dt)
sgCopyCoord(&m_velocity, &tmp); sgCopyCoord(&m_velocity, &tmp);
m_velocity.xyz[2]=DUMMY; m_velocity.xyz[2]=DUMMY;
#else #else
sgCopyCoord(&m_velocity, &tmp); m_velocityLC.setValue(tmp.xyz[0],tmp.xyz[1],tmp.xyz[2]);
#endif #endif
} }
else else
{ {
sgCopyCoord(&(m_history_velocity[history->GetCurrentIndex()]), &m_velocity); m_history_velocity[history->GetCurrentIndex()].xyz[0]=m_velocityLC.getX();
m_history_velocity[history->GetCurrentIndex()].xyz[1]=m_velocityLC.getY();
m_history_velocity[history->GetCurrentIndex()].xyz[2]=m_velocityLC.getZ();
} }
} // if m_history_velocity } // if m_history_velocity
sgMat4 result;
updatePosition(dt,result);
sgVec3 start ; sgCopyVec3 (start, m_curr_pos.xyz );
sgVec3 end ; sgCopyVec3 (end , result[3] );
sgCopyVec3 (result[3], end) ;
sgVec3 prev_pos;
sgCopyVec3(prev_pos, m_curr_pos.xyz);
sgSetCoord (&m_curr_pos, result);
sgSubVec3 (m_abs_velocity, m_curr_pos.xyz, prev_pos);
if(m_history_position) if(m_history_position)
{ {
if(user_config->m_replay_history) if(user_config->m_replay_history)
@ -170,6 +156,7 @@ void Moveable::update (float dt)
} }
} // if m_history_position } // if m_history_position
m_velocityLC = getVelocity()*getTrans().getBasis();
placeModel(); placeModel();
m_first_time = false ; m_first_time = false ;
} // update } // update
@ -181,22 +168,6 @@ void Moveable::placeModel()
m_model_transform->setTransform(&m_curr_pos); m_model_transform->setTransform(&m_curr_pos);
} // placeModel } // placeModel
//-----------------------------------------------------------------------------
/**
* Computes the new position and hpr of the kart after a single time step.
*/
void Moveable::updatePosition(float dt, sgMat4 result)
{
sgCoord scaled_velocity ;
sgMat4 delta, mat;
/* Scale velocities to current time step. */
sgScaleVec3 (scaled_velocity.xyz, m_velocity.xyz, dt);
sgScaleVec3 (scaled_velocity.hpr, m_velocity.hpr, dt);
sgMakeCoordMat4(delta, & scaled_velocity );
sgMakeCoordMat4(mat , & m_curr_pos );
sgMultMat4 (result, mat, delta );
} // updatePosition
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Moveable::WriteHistory(char* s, int kartNumber, int indx) void Moveable::WriteHistory(char* s, int kartNumber, int indx)
{ {

View File

@ -23,9 +23,8 @@
#include <plib/ssg.h> #include <plib/ssg.h>
#include "material.hpp" #include "material.hpp"
#ifdef BULLET
#include "btBulletDynamicsCommon.h" #include "btBulletDynamicsCommon.h"
#endif #include "user_pointer.hpp"
/* Limits of Kart performance */ /* Limits of Kart performance */
#define CRASH_PITCH -45.0f #define CRASH_PITCH -45.0f
@ -33,16 +32,13 @@
#define MAX_HERRING_EATEN 20 #define MAX_HERRING_EATEN 20
class Moveable class Moveable : public UserPointer
{ {
public: private:
enum MoveableType {MOV_KART, MOV_PROJECTILE, MOV_TRACK} ; btVector3 m_velocityLC; /* velocity in kart coordinates */
protected: protected:
MoveableType m_moveable_type; /* used when upcasting bullet user pointers */ sgCoord m_reset_pos; /* Where to start in case of a reset */
sgCoord m_reset_pos; /* Where to start in case of a reset */ sgCoord m_curr_pos; /* current position */
sgCoord m_curr_pos; /* current position */
sgCoord m_velocity; /* current velocity in local coordinates */
sgVec3 m_abs_velocity; /* world coordinates' velocity vector */
sgVec4* m_normal_hot; /* plane on which HOT was computed */ sgVec4* m_normal_hot; /* plane on which HOT was computed */
Material* m_material_hot; /* Material at HOT */ 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
@ -68,25 +64,23 @@ public:
Moveable (bool bHasHistory=false); Moveable (bool bHasHistory=false);
virtual ~Moveable(); virtual ~Moveable();
ssgTransform* getModelTransform() {return m_model_transform; } ssgTransform* getModelTransform() {return m_model_transform; }
MoveableType getMoveableType() const {return m_moveable_type; } const btVector3 &getVelocity() const {return m_body->getLinearVelocity();}
void setMoveableType(MoveableType m){m_moveable_type=m; } const btVector3 &getVelocityLC() const {return m_velocityLC; }
sgCoord* getVelocity () {return & m_velocity; } sgCoord* getCoord () {return &m_curr_pos; }
sgCoord* getCoord () {return &m_curr_pos; } const sgCoord* getCoord () const {return &m_curr_pos; }
const sgCoord* getCoord () const {return &m_curr_pos; } const sgVec4* getNormalHOT () const {return m_normal_hot; }
const sgVec4* getNormalHOT () const {return m_normal_hot; } void setCoord (sgCoord* pos) {sgCopyCoord ( &m_curr_pos,pos); }
void setCoord (sgCoord* pos) {sgCopyCoord ( &m_curr_pos,pos); }
virtual void placeModel (); virtual void placeModel ();
virtual void handleZipper () {}; virtual void handleZipper () {};
virtual void reset (); virtual void reset ();
virtual void update (float dt) ; virtual void update (float dt) ;
virtual void updatePosition(float dt, sgMat4 result);
void WriteHistory (char* s, int kartNumber, int indx); void WriteHistory (char* s, int kartNumber, int indx);
void ReadHistory (char* s, int kartNumber, int indx); void ReadHistory (char* s, int kartNumber, int indx);
btRigidBody* getBody () const {return m_body; } btRigidBody* getBody () const {return m_body; }
void createBody(float mass, btTransform& trans, void createBody(float mass, btTransform& trans,
btCollisionShape *shape, MoveableType m); btCollisionShape *shape,
void getTrans (btTransform* t) const {*t=m_transform;} UserPointer::UserPointerType t);
const btTransform& getTrans () const {return m_transform;} const btTransform& getTrans () const {return m_transform;}
void setTrans (btTransform& t){m_motion_state->setWorldTransform(t);} void setTrans (btTransform& t){m_motion_state->setWorldTransform(t);}
} }

View File

@ -103,18 +103,18 @@ void Physics::update(float dt)
std::vector<CollisionPair>::iterator p; std::vector<CollisionPair>::iterator p;
for(p=m_all_collisions.begin(); p!=m_all_collisions.end(); ++p) for(p=m_all_collisions.begin(); p!=m_all_collisions.end(); ++p)
{ {
if(p->type_a==Moveable::MOV_KART) { // kart-kart collision if(p->type_a==UserPointer::UP_KART) { // kart-kart collision
Kart *kartA = (Kart*)(p->a); Kart *kartA = (Kart*)(p->a);
Kart *kartB = (Kart*)(p->b); Kart *kartB = (Kart*)(p->b);
KartKartCollision(kartA, kartB); KartKartCollision(kartA, kartB);
} // if kart-kart collision } // if kart-kart collision
else // now the first object must be a projectile else // now the first object must be a projectile
{ {
if(p->type_b==Moveable::MOV_TRACK) // must be projectile hit track if(p->type_b==UserPointer::UP_TRACK) // must be projectile hit track
{ {
((Flyable*)(p->a))->hitTrack(); ((Flyable*)(p->a))->hitTrack();
} }
else if(p->type_b==Moveable::MOV_KART) // projectile hit kart else if(p->type_b==UserPointer::UP_KART) // projectile hit kart
{ {
Flyable *f=(Flyable*)(p->a); Flyable *f=(Flyable*)(p->a);
f->explode((Kart*)(p->b)); f->explode((Kart*)(p->b));
@ -206,60 +206,61 @@ btScalar Physics::solveGroup(btCollisionObject** bodies, int numBodies,
// ======================= // =======================
if(!movA) if(!movA)
{ {
if(movB && movB->getMoveableType()==Moveable::MOV_PROJECTILE) if(movB && movB->getUserPointerType()==UserPointer::UP_PROJECTILE)
{ // 1.1 projectile hits track { // 1.1 projectile hits track
// ------------------------- // -------------------------
m_all_collisions.push_back(CollisionPair(movB, Moveable::MOV_PROJECTILE, m_all_collisions.push_back(CollisionPair(movB, UserPointer::UP_PROJECTILE,
NULL, Moveable::MOV_TRACK )); NULL, UserPointer::UP_TRACK ));
} }
else if(movB && movB->getMoveableType()==Moveable::MOV_KART) else if(movB && movB->getUserPointerType()==UserPointer::UP_KART)
{ {
((Kart*)movB)->crashed(); ((Kart*)movB)->crashed();
} }
} }
// 2) object a is a kart // 2) object a is a kart
// ===================== // =====================
else if(movA->getMoveableType()==Moveable::MOV_KART) else if(movA->getUserPointerType()==UserPointer::UP_KART)
{ {
if(!movB) if(!movB)
{ { // The casts here are important, otherwise re-casting the
// pointers later in kart-kart does not work as expected.
((Kart*)movA)->crashed(); ((Kart*)movA)->crashed();
} }
else if(movB && movB->getMoveableType()==Moveable::MOV_PROJECTILE) else if(movB && movB->getUserPointerType()==UserPointer::UP_PROJECTILE)
{ // 2.1 projectile hits kart { // 2.1 projectile hits kart
// ------------------------- // -------------------------
m_all_collisions.push_back(CollisionPair(movB, Moveable::MOV_PROJECTILE, m_all_collisions.push_back(CollisionPair(movB, UserPointer::UP_PROJECTILE,
movA, Moveable::MOV_KART )); (Kart*)movA, UserPointer::UP_KART ));
} }
else if(movB && movB->getMoveableType()==Moveable::MOV_KART) else if(movB && movB->getUserPointerType()==UserPointer::UP_KART)
{ // 2.2 kart hits kart { // 2.2 kart hits kart
// ------------------ // ------------------
m_all_collisions.push_back(CollisionPair(movA, Moveable::MOV_KART, m_all_collisions.push_back(CollisionPair((Kart*)movA, UserPointer::UP_KART,
movB, Moveable::MOV_KART )); (Kart*)movB, UserPointer::UP_KART ));
} }
} }
// 3) object is a projectile // 3) object is a projectile
// ======================== // ========================
else if(movA->getMoveableType()==Moveable::MOV_PROJECTILE) else if(movA->getUserPointerType()==UserPointer::UP_PROJECTILE)
{ {
if(!movB) if(!movB)
{ // 3.1) projectile hits track { // 3.1) projectile hits track
// -------------------------- // --------------------------
m_all_collisions.push_back(CollisionPair(movA, Moveable::MOV_PROJECTILE, m_all_collisions.push_back(CollisionPair(movA, UserPointer::UP_PROJECTILE,
NULL, Moveable::MOV_TRACK )); NULL, UserPointer::UP_TRACK ));
} }
else if(movB->getMoveableType()==Moveable::MOV_PROJECTILE) else if(movB->getUserPointerType()==UserPointer::UP_PROJECTILE)
{ // 3.2 projectile hits projectile { // 3.2 projectile hits projectile
// ------------------------------ // ------------------------------
m_all_collisions.push_back(CollisionPair(movA, Moveable::MOV_PROJECTILE, m_all_collisions.push_back(CollisionPair(movA, UserPointer::UP_PROJECTILE,
movB, Moveable::MOV_PROJECTILE)); movB, UserPointer::UP_PROJECTILE));
} }
else if(movB->getMoveableType()==Moveable::MOV_KART) else if(movB->getUserPointerType()==UserPointer::UP_KART)
{ // 3.3 projectile hits kart { // 3.3 projectile hits kart
// ------------------------ // ------------------------
m_all_collisions.push_back(CollisionPair(movA, Moveable::MOV_PROJECTILE, m_all_collisions.push_back(CollisionPair(movA, UserPointer::UP_PROJECTILE,
movB, Moveable::MOV_KART )); (Kart*)movB, UserPointer::UP_KART ));
} }
} }
// 4) Nothing else should happen // 4) Nothing else should happen

View File

@ -51,13 +51,13 @@ private:
class CollisionPair { class CollisionPair {
public: public:
void *a, *b; void *a, *b;
Moveable::MoveableType type_a, type_b; UserPointer::UserPointerType type_a, type_b;
// The entries in Collision Pairs are sorted: if a projectile // The entries in Collision Pairs are sorted: if a projectile
// is included, it's always 'a'. If only two karts are reported // is included, it's always 'a'. If only two karts are reported
// the first kart pointer is the smaller one // the first kart pointer is the smaller one
CollisionPair(void *a1, Moveable::MoveableType atype, CollisionPair(void *a1, UserPointer::UserPointerType atype,
void *b1, Moveable::MoveableType btype) { void *b1, UserPointer::UserPointerType btype) {
if(atype==Moveable::MOV_KART && btype==Moveable::MOV_KART && a1>b1) { if(atype==Moveable::UP_KART && btype==Moveable::UP_KART && a1>b1) {
a=b1;b=a1; type_a=btype; type_b=atype; a=b1;b=a1; type_a=btype; type_b=atype;
} else { } else {
a=a1; b=b1; type_a=atype; type_b=btype; a=a1; b=b1; type_a=atype; type_b=btype;

View File

@ -223,7 +223,7 @@ void PlayerKart::addMessages()
// Display a warning message if the kart is going back way (unless // Display a warning message if the kart is going back way (unless
// the kart has already finished the race). // the kart has already finished the race).
if ((angle_diff > 120.0f || angle_diff < -120.0f) && if ((angle_diff > 120.0f || angle_diff < -120.0f) &&
getVelocity () -> xyz [ 1 ] > 0.0 && !raceIsFinished() ) getVelocity().getY() > 0.0f && !raceIsFinished() )
{ {
m->addMessage(_("WRONG WAY!"), this, -1.0f, 60); m->addMessage(_("WRONG WAY!"), this, -1.0f, 60);
} // if angle is too big } // if angle is too big

View File

@ -133,7 +133,7 @@ void DefaultRobot::handle_braking()
//We may brake if we are about to get out of the road, but only if the //We may brake if we are about to get out of the road, but only if the
//kart is on top of the road, and if we won't slow down below a certain //kart is on top of the road, and if we won't slow down below a certain
//limit. //limit.
if ( m_crashes.m_road && m_on_road && m_velocity.xyz[1] > MIN_SPEED) if ( m_crashes.m_road && m_on_road && getVelocityLC().getY() > MIN_SPEED)
{ {
float kart_ang_diff = world->m_track->m_angle[m_track_sector] - float kart_ang_diff = world->m_track->m_angle[m_track_sector] -
m_curr_pos.hpr[0]; m_curr_pos.hpr[0];
@ -172,7 +172,7 @@ void DefaultRobot::handle_braking()
//Brake if the kart's speed is bigger than the speed we need //Brake if the kart's speed is bigger than the speed we need
//to go through the curve at the widest angle, or if the kart //to go through the curve at the widest angle, or if the kart
//is not going straight in relation to the road. //is not going straight in relation to the road.
if(m_velocity.xyz[1] > m_curve_target_speed || if(getVelocityLC().getY() > m_curve_target_speed ||
kart_ang_diff > MIN_TRACK_ANGLE ) kart_ang_diff > MIN_TRACK_ANGLE )
{ {
#ifdef AI_DEBUG #ifdef AI_DEBUG
@ -407,14 +407,16 @@ bool DefaultRobot::do_wheelie ( const int STEPS )
if( m_crashes.m_road ) return false; if( m_crashes.m_road ) return false;
if( m_crashes.m_kart != -1 ) return false; if( m_crashes.m_kart != -1 ) return false;
sgVec2 vel_normal, step_coord; sgVec2 step_coord;
sgVec3 step_track_coord; sgVec3 step_track_coord;
float distance; float distance;
//We have to be careful with normalizing, because if the source argument //We have to be careful with normalizing, because if the source argument
//has both the X and Y axis set to 0, it returns nan to the destiny. //has both the X and Y axis set to 0, it returns nan to the destiny.
if( m_abs_velocity[0] == 0.0 && m_abs_velocity[1] == 0.0 ) return false; const btVector3 &VEL=getVelocity();
sgNormalizeVec2( vel_normal, m_abs_velocity ); if( VEL.getX() == 0.0 && VEL.getY() == 0.0 ) return false;
btVector3 vel_normal(VEL.getX(), VEL.getY(), 0.0);
vel_normal.normalize();
//FIXME: instead of using 1.5, it should find out how much time it //FIXME: instead of using 1.5, it should find out how much time it
//will pass to stop doing the wheelie completely from the current state. //will pass to stop doing the wheelie completely from the current state.
@ -423,7 +425,7 @@ bool DefaultRobot::do_wheelie ( const int STEPS )
/* The following method of finding if a position is outside of the track /* The following method of finding if a position is outside of the track
is less accurate than calling findRoadSector(), but a lot faster. is less accurate than calling findRoadSector(), but a lot faster.
*/ */
const int WHEELIE_STEPS = int(( m_velocity.xyz[1] * CHECK_DIST )/ const int WHEELIE_STEPS = int(( getVelocityLC().getY() * CHECK_DIST )/
m_kart_properties->getKartLength() ); m_kart_properties->getKartLength() );
for( int i = WHEELIE_STEPS; i > STEPS - 1; --i ) for( int i = WHEELIE_STEPS; i > STEPS - 1; --i )
@ -527,7 +529,7 @@ void DefaultRobot::check_crashes( const int STEPS, sgVec3 const pos )
//having karts too close in any direction. The crash with the track can //having karts too close in any direction. The crash with the track can
//tell when a kart is going to get out of the track so it steers. //tell when a kart is going to get out of the track so it steers.
sgVec2 vel_normal; btVector3 vel_normal;
//in this func we use it as a 2d-vector, but later on it is passed //in this func we use it as a 2d-vector, but later on it is passed
//to world->m_track->findRoadSector, there it is used as a 3d-vector //to world->m_track->findRoadSector, there it is used as a 3d-vector
//to find distance to plane, so z must be initialized to zero //to find distance to plane, so z must be initialized to zero
@ -541,11 +543,16 @@ void DefaultRobot::check_crashes( const int STEPS, sgVec3 const pos )
const size_t NUM_KARTS = world->getNumKarts(); const size_t NUM_KARTS = world->getNumKarts();
//Protection against having vel_normal with nan values //Protection against having vel_normal with nan values
if( m_abs_velocity[0] == 0.0 && m_abs_velocity[1] == 0.0 ) const btVector3 &VEL = getVelocity();
if( VEL.getX() == 0.0 && VEL.getY() == 0.0 )
{ {
vel_normal[0] = vel_normal[1] = 0.0; vel_normal.setValue(0.0, 0.0, 0.0);
}
else
{
vel_normal.setValue(VEL.getX(), VEL.getY(), 0.0);
vel_normal.normalize();
} }
else sgNormalizeVec2( vel_normal, m_abs_velocity );
for(int i = 1; STEPS > i; ++i) for(int i = 1; STEPS > i; ++i)
{ {
@ -564,8 +571,8 @@ void DefaultRobot::check_crashes( const int STEPS, sgVec3 const pos )
world->getKart(j)->getCoord()->xyz ); world->getKart(j)->getCoord()->xyz );
if( kart_distance < m_kart_properties->getKartLength() + 0.125f * i ) if( kart_distance < m_kart_properties->getKartLength() + 0.125f * i )
if( m_velocity.xyz[1] > world->getKart(j)-> if( getVelocityLC().getY() > world->getKart(j)->
getVelocity()->xyz[1] * 0.75f ) m_crashes.m_kart = j; getVelocityLC().getY() * 0.75f ) m_crashes.m_kart = j;
} }
} }
@ -751,7 +758,7 @@ inline float DefaultRobot::normalize_angle( float angle )
*/ */
int DefaultRobot::calc_steps() int DefaultRobot::calc_steps()
{ {
int steps = int( m_velocity.xyz[1] / m_kart_properties->getKartLength() ); int steps = int( getVelocityLC().getY() / m_kart_properties->getKartLength() );
if( steps < m_min_steps ) steps = m_min_steps; if( steps < m_min_steps ) steps = m_min_steps;
//Increase the steps depending on the width, if we steering hard, //Increase the steps depending on the width, if we steering hard,
@ -869,7 +876,7 @@ void DefaultRobot::find_curve()
int next_hint = m_track_sector; int next_hint = m_track_sector;
int i; int i;
for(i = m_track_sector; total_dist < m_velocity.xyz[1]; i = next_hint) for(i = m_track_sector; total_dist < getVelocityLC().getY(); i = next_hint)
{ {
next_hint = i + 1 < DRIVELINE_SIZE ? i + 1 : 0; next_hint = i + 1 < DRIVELINE_SIZE ? i + 1 : 0;
total_dist += sgDistanceVec2(world->m_track->m_driveline[i], world->m_track->m_driveline[next_hint]); total_dist += sgDistanceVec2(world->m_track->m_driveline[i], world->m_track->m_driveline[next_hint]);

View File

@ -66,13 +66,14 @@ SoundManager::SoundManager()
else else
m_initialized = true; m_initialized = true;
#else #else
if(alutInit(0, NULL) == AL_TRUE) // init OpenAL sound system // if(alutInit(0, NULL) == AL_TRUE) // init OpenAL sound system
m_initialized = true; alutInit(0, NULL);
else // m_initialized = true;
{ // else
fprintf(stderr, _("WARNING: Could not initialize the ALUT based sound.\n")); // {
m_initialized = false; // fprintf(stderr, _("WARNING: Could not initialize the ALUT based sound.\n"));
} // m_initialized = false;
// }
alGetError(); //Called here to clear any non-important errors found alGetError(); //Called here to clear any non-important errors found
#endif #endif
@ -187,7 +188,7 @@ void SoundManager::playMusic(const char* filename)
if((m_current_music->load(filename)) == false) if((m_current_music->load(filename)) == false)
{ {
delete m_current_music; delete m_current_music;
m_current_music=0; m_current_music=0;
fprintf(stderr, "WARNING: Unabled to load music %s, not supported or not found.\n", filename); fprintf(stderr, "WARNING: Unabled to load music %s, not supported or not found.\n", filename);
} }
else else

View File

@ -34,7 +34,6 @@ void STKConfig::load(const std::string filename)
fprintf(stderr,"Missing default value for '%s' in '%s'.\n", \ fprintf(stderr,"Missing default value for '%s' in '%s'.\n", \
strA,filename.c_str());exit(-1); \ strA,filename.c_str());exit(-1); \
} }
#ifdef BULLET
if(m_gear_switch_ratio.size()==0) if(m_gear_switch_ratio.size()==0)
{ {
fprintf(stderr,"Missing default value for 'gear-switch-ratio' in '%s'.\n", fprintf(stderr,"Missing default value for 'gear-switch-ratio' in '%s'.\n",
@ -52,7 +51,7 @@ void STKConfig::load(const std::string filename)
fprintf(stderr,"in '%s' must be equal.\n", filename.c_str()); fprintf(stderr,"in '%s' must be equal.\n", filename.c_str());
exit(-1); exit(-1);
} }
#endif
CHECK_NEG(m_max_karts, "max-karts" ); CHECK_NEG(m_max_karts, "max-karts" );
CHECK_NEG(m_grid_order, "grid-order" ); CHECK_NEG(m_grid_order, "grid-order" );
@ -109,6 +108,8 @@ void STKConfig::load(const std::string filename)
CHECK_NEG(m_bomb_time, "bomb-time" ); CHECK_NEG(m_bomb_time, "bomb-time" );
CHECK_NEG(m_bomb_time_increase, "bomb-time-increase" ); CHECK_NEG(m_bomb_time_increase, "bomb-time-increase" );
CHECK_NEG(m_anvil_time, "anvil-time" ); CHECK_NEG(m_anvil_time, "anvil-time" );
CHECK_NEG(m_zipper_time, "zipper-time" );
CHECK_NEG(m_zipper_force, "zipper-force" );
CHECK_NEG(m_max_road_distance, "shortcut-road-distance" ); CHECK_NEG(m_max_road_distance, "shortcut-road-distance" );
CHECK_NEG(m_shortcut_segments, "shortcut-skipped-segments" ); CHECK_NEG(m_shortcut_segments, "shortcut-skipped-segments" );
CHECK_NEG(m_suspension_rest, "suspension-rest" ); CHECK_NEG(m_suspension_rest, "suspension-rest" );
@ -134,6 +135,7 @@ void STKConfig::init_defaults()
m_wheelie_max_speed_ratio = m_wheelie_pitch_rate = m_wheelie_restore_rate = m_wheelie_max_speed_ratio = m_wheelie_pitch_rate = m_wheelie_restore_rate =
m_wheelie_speed_boost = m_air_res_reduce[2] = m_air_res_reduce[1] = m_wheelie_speed_boost = m_air_res_reduce[2] = m_air_res_reduce[1] =
m_parachute_time = m_bomb_time = m_bomb_time_increase= m_anvil_time = m_parachute_time = m_bomb_time = m_bomb_time_increase= m_anvil_time =
m_zipper_time = m_zipper_force =
m_parachute_time_other = m_magnet_time = m_max_road_distance = m_shortcut_segments = m_parachute_time_other = m_magnet_time = m_max_road_distance = m_shortcut_segments =
//bullet physics data //bullet physics data
m_suspension_stiffness = m_wheel_damping_relaxation = m_wheel_damping_compression = m_suspension_stiffness = m_wheel_damping_relaxation = m_wheel_damping_compression =
@ -170,6 +172,8 @@ void STKConfig::getAllData(const lisp::Lisp* lisp)
lisp->get("bomb-time", m_bomb_time ); lisp->get("bomb-time", m_bomb_time );
lisp->get("bomb-time-increase", m_bomb_time_increase ); lisp->get("bomb-time-increase", m_bomb_time_increase );
lisp->get("anvil-time", m_anvil_time ); lisp->get("anvil-time", m_anvil_time );
lisp->get("zipper-time", m_zipper_time );
lisp->get("zipper-force", m_zipper_force );
lisp->get("explosion-impulse", m_explosion_impulse ); lisp->get("explosion-impulse", m_explosion_impulse );
lisp->get("max-karts", m_max_karts ); lisp->get("max-karts", m_max_karts );
lisp->get("grid-order", m_grid_order ); lisp->get("grid-order", m_grid_order );

View File

@ -39,6 +39,8 @@ public:
float m_bomb_time; // time before a bomb explodes float m_bomb_time; // time before a bomb explodes
float m_bomb_time_increase; // time added to bomb timer when it's passed on float m_bomb_time_increase; // time added to bomb timer when it's passed on
float m_anvil_time; // time an anvil is active float m_anvil_time; // time an anvil is active
float m_zipper_time; // duration a zipper is active
float m_zipper_force; // additional force added to the acceleration
float m_max_road_distance; // max distance from road to be still ON road float m_max_road_distance; // max distance from road to be still ON road
float m_shortcut_segments; // skipping more than this number of segments is float m_shortcut_segments; // skipping more than this number of segments is
// considered to be a shortcut // considered to be a shortcut

View File

@ -41,7 +41,6 @@
#if defined(WIN32) && !defined(__CYGWIN__) #if defined(WIN32) && !defined(__CYGWIN__)
# define snprintf _snprintf # define snprintf _snprintf
#endif #endif
std::vector<const Material*>Track::m_triangleIndex2Material;
float const Track::NOHIT=-99999.9f; float const Track::NOHIT=-99999.9f;
@ -72,8 +71,8 @@ Track::~Track()
*/ */
void Track::cleanup() void Track::cleanup()
{ {
world->getPhysics()->removeBody(m_body); delete m_non_collision_mesh;
delete m_body; delete m_track_mesh;
} // ~Track } // ~Track
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -1007,29 +1006,22 @@ Track::readDrivelineFromFile(std::vector<sgVec3Wrapper>& line, const std::string
void Track::createPhysicsModel() void Track::createPhysicsModel()
{ {
if(!m_model) return; if(!m_model) return;
m_track_mesh = new TriangleMesh();
m_non_collision_mesh = new TriangleMesh();
// Collect all triangles in the track_mesh
sgMat4 mat; sgMat4 mat;
sgMakeIdentMat4(mat); sgMakeIdentMat4(mat);
btTriangleMesh *track_mesh = new btTriangleMesh(); convertTrackToBullet(m_model, mat);
m_triangleIndex2Material.clear(); m_track_mesh->createBody();
// Collect all triangles in the track_mesh m_non_collision_mesh->createBody(btCollisionObject::CF_NO_CONTACT_RESPONSE);
convertTrackToBullet(m_model, mat, track_mesh);
// Now convert the triangle mesh into a static rigid body
btCollisionShape *mesh_shape = new btBvhTriangleMeshShape(track_mesh, true);
btTransform startTransform;
startTransform.setIdentity();
btDefaultMotionState *myMotionState = new btDefaultMotionState(startTransform);
m_body=new btRigidBody(0.0f, myMotionState, mesh_shape);
// FIXME: can the mesh_shape and or track_mesh be deleted now?
world->getPhysics()->addBody(m_body);
m_body->setUserPointer(0);
m_body->setCollisionFlags(m_body->getCollisionFlags() |
btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
} // createPhysicsModel } // createPhysicsModel
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
//* Convert the ssg track tree into its physics equivalents. //* Convert the ssg track tree into its physics equivalents.
void Track::convertTrackToBullet(ssgEntity *track, sgMat4 m, btTriangleMesh* track_mesh) void Track::convertTrackToBullet(ssgEntity *track, sgMat4 m)
{ {
if(!track) return; if(!track) return;
MovingPhysics *mp = dynamic_cast<MovingPhysics*>(track); MovingPhysics *mp = dynamic_cast<MovingPhysics*>(track);
@ -1042,10 +1034,10 @@ void Track::convertTrackToBullet(ssgEntity *track, sgMat4 m, btTriangleMesh* tra
} }
else if(track->isAKindOf(ssgTypeLeaf())) else if(track->isAKindOf(ssgTypeLeaf()))
{ {
ssgLeaf *leaf = (ssgLeaf*)(track); ssgLeaf *leaf = (ssgLeaf*)(track);
Material *mat = material_manager->getMaterial(leaf); Material *material = material_manager->getMaterial(leaf);
// Don't convert triangles with material that is ignored (e.g. fuzzy_sand) // Don't convert triangles with material that is ignored (e.g. fuzzy_sand)
if(!mat || mat->isIgnore()) return; if(!material || material->isIgnore()) return;
for(int i=0; i<leaf->getNumTriangles(); i++) for(int i=0; i<leaf->getNumTriangles(); i++)
{ {
@ -1059,8 +1051,14 @@ void Track::convertTrackToBullet(ssgEntity *track, sgMat4 m, btTriangleMesh* tra
btVector3 vb1(vv1[0],vv1[1],vv1[2]); btVector3 vb1(vv1[0],vv1[1],vv1[2]);
btVector3 vb2(vv2[0],vv2[1],vv2[2]); btVector3 vb2(vv2[0],vv2[1],vv2[2]);
btVector3 vb3(vv3[0],vv3[1],vv3[2]); btVector3 vb3(vv3[0],vv3[1],vv3[2]);
track_mesh->addTriangle(vb1, vb2, vb3); if(material->isZipper())
m_triangleIndex2Material.push_back(mat); {
m_non_collision_mesh->addTriangle(vb1, vb2, vb3, material);
}
else
{
m_track_mesh->addTriangle(vb1, vb2, vb3, material);
}
} }
} // if(track isAKindOf leaf) } // if(track isAKindOf leaf)
@ -1073,14 +1071,14 @@ void Track::convertTrackToBullet(ssgEntity *track, sgMat4 m, btTriangleMesh* tra
sgPreMultMat4(tmpM,tmpT); sgPreMultMat4(tmpM,tmpT);
for(ssgEntity *e = t->getKid(0); e!=NULL; e=t->getNextKid()) for(ssgEntity *e = t->getKid(0); e!=NULL; e=t->getNextKid())
{ {
convertTrackToBullet(e, tmpM, track_mesh); convertTrackToBullet(e, tmpM);
} // for i } // for i
} }
else if (track->isAKindOf(ssgTypeBranch())) else if (track->isAKindOf(ssgTypeBranch()))
{ {
ssgBranch *b =(ssgBranch*)track; ssgBranch *b =(ssgBranch*)track;
for(ssgEntity* e=b->getKid(0); e!=NULL; e=b->getNextKid()) { for(ssgEntity* e=b->getKid(0); e!=NULL; e=b->getNextKid()) {
convertTrackToBullet(e, m, track_mesh); convertTrackToBullet(e, m);
} // for i<getNumKids } // for i<getNumKids
} }
else else
@ -1161,7 +1159,7 @@ void Track::loadTrackModel()
} }
else if ( sscanf ( s, "\"%[^\"]\",%f,%f,{},%f,{},{}", else if ( sscanf ( s, "\"%[^\"]\",%f,%f,{},%f,{},{}",
fname, &(loc.xyz[0]), &(loc.xyz[1]), fname, &(loc.xyz[0]), &(loc.xyz[1]),
&(loc.hpr[0]) ) == 3 ) &(loc.hpr[0]) ) == 4 )
{ {
/* All 6 DOF specified - but need height, roll, pitch */ /* All 6 DOF specified - but need height, roll, pitch */
need_hat = true ; need_hat = true ;
@ -1291,7 +1289,7 @@ void Track::getTerrainInfo(btVector3 &pos, float *hot, btVector3* normal,
bool normalInWorldSpace) { bool normalInWorldSpace) {
if(rayResult.m_localShapeInfo && rayResult.m_localShapeInfo->m_shapePart>=0 ) if(rayResult.m_localShapeInfo && rayResult.m_localShapeInfo->m_shapePart>=0 )
{ {
m_material=m_triangleIndex2Material[rayResult.m_localShapeInfo->m_triangleIndex]; m_material = ((TriangleMesh*)rayResult.m_collisionObject->getUserPointer())->getMaterial(rayResult.m_localShapeInfo->m_triangleIndex);
} }
return btCollisionWorld::ClosestRayResultCallback::AddSingleResult(rayResult, return btCollisionWorld::ClosestRayResultCallback::AddSingleResult(rayResult,
normalInWorldSpace); normalInWorldSpace);

View File

@ -35,6 +35,7 @@
#include <vector> #include <vector>
#include "btBulletDynamicsCommon.h" #include "btBulletDynamicsCommon.h"
#include "material.hpp" #include "material.hpp"
#include "triangle_mesh.hpp"
class Track class Track
{ {
@ -49,8 +50,8 @@ private:
std::string m_description; std::string m_description;
std::string m_filename; std::string m_filename;
ssgBranch* m_model; ssgBranch* m_model;
btRigidBody* m_body; TriangleMesh* m_track_mesh;
static std::vector<const Material*> m_triangleIndex2Material; TriangleMesh* m_non_collision_mesh;
public: public:
enum RoadSide{ RS_DONT_KNOW = -1, RS_LEFT = 0, RS_RIGHT = 1 }; enum RoadSide{ RS_DONT_KNOW = -1, RS_LEFT = 0, RS_RIGHT = 1 };
@ -182,7 +183,7 @@ public:
const std::vector<SGfloat>& getWidth() const {return m_path_width; } const std::vector<SGfloat>& getWidth() const {return m_path_width; }
const std::string& getHerringStyle () const {return m_herring_style; } const std::string& getHerringStyle () const {return m_herring_style; }
void getStartCoords (unsigned int pos, sgCoord* coords) const; void getStartCoords (unsigned int pos, sgCoord* coords) const;
static const Material* getMaterial (unsigned int n) {return m_triangleIndex2Material[n];} // static const Material* getMaterial (unsigned int n) {return m_triangleIndex2Material[n];}
void getTerrainInfo(btVector3 &pos, float *hot, btVector3* normal, void getTerrainInfo(btVector3 &pos, float *hot, btVector3* normal,
const Material **material) const; const Material **material) const;
void createPhysicsModel (); void createPhysicsModel ();
@ -194,18 +195,17 @@ public:
} }
private: private:
void loadTrack (std::string filename); void loadTrack (std::string filename);
void herring_command (sgVec3 *xyz, char htype, int bNeedHeight); void herring_command (sgVec3 *xyz, char htype, int bNeedHeight);
void loadDriveline (); void loadDriveline ();
void readDrivelineFromFile (std::vector<sgVec3Wrapper>& line, void readDrivelineFromFile (std::vector<sgVec3Wrapper>& line,
const std::string& file_ext ); const std::string& file_ext );
void convertTrackToBullet (ssgEntity *track, sgMat4 m, void convertTrackToBullet (ssgEntity *track, sgMat4 m);
btTriangleMesh* track_mesh);
float pointSideToLine( const sgVec2 L1, const sgVec2 L2, float pointSideToLine(const sgVec2 L1, const sgVec2 L2,
const sgVec2 P ) const; const sgVec2 P ) const;
int pointInQuad( const sgVec2 A, const sgVec2 B, int pointInQuad(const sgVec2 A, const sgVec2 B,
const sgVec2 C, const sgVec2 D, const sgVec2 POINT ) const; const sgVec2 C, const sgVec2 D, const sgVec2 POINT ) const;
} }
; // class Track ; // class Track

View File

@ -36,12 +36,12 @@ void TrafficDriver::update (float dt)
if ( ( track_velocity [ 0 ] < 0.0f && m_curr_track_coords [ 0 ] > 0.0f ) || if ( ( track_velocity [ 0 ] < 0.0f && m_curr_track_coords [ 0 ] > 0.0f ) ||
( track_velocity [ 0 ] > 0.0f && m_curr_track_coords [ 0 ] < 0.0f ) ) ( track_velocity [ 0 ] > 0.0f && m_curr_track_coords [ 0 ] < 0.0f ) )
m_velocity.hpr[0] = sgnsq(m_curr_track_coords[0])*3.0f ; ;//FIXME m_velocity.hpr[0] = sgnsq(m_curr_track_coords[0])*3.0f ;
else else
m_velocity.hpr[0] = sgnsq(m_curr_track_coords[0])*12.0f ; //FIXME m_velocity.hpr[0] = sgnsq(m_curr_track_coords[0])*12.0f ;
m_velocity.xyz[1] = TRAFFIC_VELOCITY ; //FIXME m_velocity.xyz[1] = TRAFFIC_VELOCITY ;
m_velocity.xyz[2] -= world->getGravity()* dt ; //FIXME m_velocity.xyz[2] -= world->getGravity()* dt ;
if ( m_wheelie_angle != 0.0f ) if ( m_wheelie_angle != 0.0f )
m_wheelie_angle = 0.0f ; m_wheelie_angle = 0.0f ;

67
src/triangle_mesh.cpp Normal file
View File

@ -0,0 +1,67 @@
// $Id: triangle_mesh.cpp 839 2006-10-24 00:01:56Z hiker $
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2006 Joerg Henrichs
//
// 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 ofati
// 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 "triangle_mesh.hpp"
#include "world.hpp"
// -----------------------------------------------------------------------------
TriangleMesh::~TriangleMesh()
{
if(m_body)
{
world->getPhysics()->removeBody(m_body);
delete m_body;
delete m_motion_state;
delete m_collision_shape;
}
} // ~TriangleMesh
// -----------------------------------------------------------------------------
void TriangleMesh::addTriangle(btVector3 t1, btVector3 t2, btVector3 t3,
const Material* m)
{
m_triangleIndex2Material.push_back(m);
m_mesh.addTriangle(t1, t2, t3);
} // addTriangle
// -----------------------------------------------------------------------------
void TriangleMesh::createBody(btCollisionObject::CollisionFlags flags)
{
if(m_triangleIndex2Material.size()==0)
{
m_collision_shape = NULL;
m_motion_state = NULL;
m_body = NULL;
return;
}
// Now convert the triangle mesh into a static rigid body
m_collision_shape = new btBvhTriangleMeshShape(&m_mesh, true);
btTransform startTransform;
startTransform.setIdentity();
m_motion_state = new btDefaultMotionState(startTransform);
m_body=new btRigidBody(0.0f, m_motion_state, m_collision_shape);
world->getPhysics()->addBody(m_body);
m_body->setUserPointer(this);
m_body->setCollisionFlags(m_body->getCollisionFlags() |
flags |
btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
} // createBody
// -----------------------------------------------------------------------------

49
src/triangle_mesh.hpp Normal file
View File

@ -0,0 +1,49 @@
// $Id: triangle_mesh.hpp 839 2006-10-24 00:01:56Z hiker $
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2006 Joerg Henrichs
//
// 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_TRIANGLE_MESH_H
#define HEADER_TRIANGLE_MESH_H
#include <vector>
#include "user_pointer.hpp"
#include "btBulletDynamicsCommon.h"
#include "material.hpp"
/** A special class to store a triangle mesh with a separate material
* per triangle.
*/
class TriangleMesh : public UserPointer
{
std::vector<const Material*> m_triangleIndex2Material;
btRigidBody *m_body;
btTriangleMesh m_mesh;
btDefaultMotionState *m_motion_state;
btCollisionShape *m_collision_shape;
public:
TriangleMesh(): UserPointer(UserPointer::UP_TRACK), m_mesh() {};
~TriangleMesh();
void addTriangle(btVector3 t1, btVector3 t2, btVector3 t3,
const Material* m);
void createBody(btCollisionObject::CollisionFlags flags=
(btCollisionObject::CollisionFlags)0);
const Material* getMaterial(int n) const {return m_triangleIndex2Material[n];}
};
#endif
/* EOF */

41
src/user_pointer.hpp Normal file
View File

@ -0,0 +1,41 @@
// $Id: user_pointer.hpp 839 2006-10-24 00:01:56Z hiker $
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2007 Joerg Henrichs
//
// 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_USER_POINTER_H
#define HEADER_USER_POINTER_H
/** Some bullet objects store 'user pointers'. This is a base class
* that allows to easily determine the type of the user pointer.
*/
class UserPointer
{
public:
enum UserPointerType {UP_UNDEF, UP_KART, UP_PROJECTILE, UP_TRACK} ;
protected:
UserPointerType m_user_pointer_type;
public:
UserPointerType getUserPointerType() const {return m_user_pointer_type;}
void setUserPointerType(UserPointerType t)
{ m_user_pointer_type=t; }
UserPointer(): m_user_pointer_type(UP_UNDEF) {};
UserPointer(UserPointerType t): m_user_pointer_type(t) {};
};
#endif
/* EOF */