1) Fixed 'rescue bug', i.e. karts have now a proper
heading after being rescued 2) Partly fixed 'automatic rescue' bug: karts get rescued when touching a reset material (though it currently can take a bit before it happens). 3) Restructured code: track loading and converting is now done in the track object. 4) Fixed several warnings for windows. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@1345 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
d8dac4e85b
commit
d0c1aa9e8c
22
src/kart.cpp
22
src/kart.cpp
@ -394,7 +394,6 @@ void Kart::reset()
|
|||||||
world->m_track->spatialToTrack( m_curr_track_coords, m_curr_pos.xyz,
|
world->m_track->spatialToTrack( m_curr_track_coords, m_curr_pos.xyz,
|
||||||
m_track_sector );
|
m_track_sector );
|
||||||
|
|
||||||
#ifdef BULLET
|
|
||||||
btTransform trans;
|
btTransform trans;
|
||||||
trans.setIdentity();
|
trans.setIdentity();
|
||||||
// Set heading:
|
// Set heading:
|
||||||
@ -414,7 +413,6 @@ void Kart::reset()
|
|||||||
m_vehicle->updateWheelTransform(j, true);
|
m_vehicle->updateWheelTransform(j, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
placeModel();
|
placeModel();
|
||||||
} // reset
|
} // reset
|
||||||
|
|
||||||
@ -711,20 +709,15 @@ void Kart::update (float dt)
|
|||||||
{
|
{
|
||||||
// Let the kart raise 2m in the 2 seconds of the rescue
|
// Let the kart raise 2m in the 2 seconds of the rescue
|
||||||
const float rescue_time = 2.0f;
|
const float rescue_time = 2.0f;
|
||||||
#ifdef BULLET
|
|
||||||
const float rescue_height = 2.0f;
|
const float rescue_height = 2.0f;
|
||||||
#endif
|
|
||||||
if(m_attachment.getType() != ATTACH_TINYTUX)
|
if(m_attachment.getType() != ATTACH_TINYTUX)
|
||||||
{
|
{
|
||||||
if(isPlayerKart()) sound_manager -> playSfx ( SOUND_BZZT );
|
if(isPlayerKart()) sound_manager -> playSfx ( SOUND_BZZT );
|
||||||
m_attachment.set( ATTACH_TINYTUX, rescue_time ) ;
|
m_attachment.set( ATTACH_TINYTUX, rescue_time ) ;
|
||||||
#ifdef BULLET
|
|
||||||
m_rescue_pitch = m_curr_pos.hpr[1];
|
m_rescue_pitch = m_curr_pos.hpr[1];
|
||||||
m_rescue_roll = m_curr_pos.hpr[2];
|
m_rescue_roll = m_curr_pos.hpr[2];
|
||||||
world->getPhysics()->removeKart(this);
|
world->getPhysics()->removeKart(this);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#ifdef BULLET
|
|
||||||
m_curr_pos.xyz[2] += rescue_height*dt/rescue_time;
|
m_curr_pos.xyz[2] += rescue_height*dt/rescue_time;
|
||||||
|
|
||||||
btTransform pos=m_body->getCenterOfMassTransform();
|
btTransform pos=m_body->getCenterOfMassTransform();
|
||||||
@ -735,13 +728,8 @@ void Kart::update (float dt)
|
|||||||
-m_rescue_pitch*dt/rescue_time*M_PI/180.0f);
|
-m_rescue_pitch*dt/rescue_time*M_PI/180.0f);
|
||||||
pos.setRotation(pos.getRotation()*q_roll*q_pitch);
|
pos.setRotation(pos.getRotation()*q_roll*q_pitch);
|
||||||
m_body->setCenterOfMassTransform(pos);
|
m_body->setCenterOfMassTransform(pos);
|
||||||
setTrans(pos);
|
setTrans(pos);
|
||||||
//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());
|
||||||
#else
|
|
||||||
sgZeroVec3 ( m_velocity.xyz ) ;
|
|
||||||
sgZeroVec3 ( m_velocity.hpr ) ;
|
|
||||||
m_velocity.xyz[2] = 1.1f * GRAVITY * dt *10.0f;
|
|
||||||
#endif
|
|
||||||
} // if m_rescue
|
} // if m_rescue
|
||||||
m_attachment.update(dt, &m_velocity);
|
m_attachment.update(dt, &m_velocity);
|
||||||
|
|
||||||
@ -1058,7 +1046,7 @@ void Kart::endRescue()
|
|||||||
world ->m_track -> trackToSpatial ( m_curr_pos.xyz, m_track_sector ) ;
|
world ->m_track -> trackToSpatial ( m_curr_pos.xyz, m_track_sector ) ;
|
||||||
m_curr_pos.hpr[0] = world->m_track->m_angle[m_track_sector] ;
|
m_curr_pos.hpr[0] = world->m_track->m_angle[m_track_sector] ;
|
||||||
m_rescue = false ;
|
m_rescue = false ;
|
||||||
#ifdef BULLET
|
|
||||||
world->getPhysics()->addKart(this, m_vehicle);
|
world->getPhysics()->addKart(this, m_vehicle);
|
||||||
m_body->setLinearVelocity (btVector3(0.0f,0.0f,0.0f));
|
m_body->setLinearVelocity (btVector3(0.0f,0.0f,0.0f));
|
||||||
m_body->setAngularVelocity(btVector3(0.0f,0.0f,0.0f));
|
m_body->setAngularVelocity(btVector3(0.0f,0.0f,0.0f));
|
||||||
@ -1070,10 +1058,10 @@ void Kart::endRescue()
|
|||||||
btTransform pos=m_body->getCenterOfMassTransform();
|
btTransform pos=m_body->getCenterOfMassTransform();
|
||||||
pos.setOrigin(btVector3(m_curr_pos.xyz[0],m_curr_pos.xyz[1],
|
pos.setOrigin(btVector3(m_curr_pos.xyz[0],m_curr_pos.xyz[1],
|
||||||
m_curr_pos.xyz[2]+0.5f*m_kart_height));
|
m_curr_pos.xyz[2]+0.5f*m_kart_height));
|
||||||
|
pos.setRotation(btQuaternion(btVector3(0.0f, 0.0f, 1.0f),
|
||||||
|
DEGREE_TO_RAD(world->m_track->m_angle[m_track_sector])));
|
||||||
m_body->setCenterOfMassTransform(pos);
|
m_body->setCenterOfMassTransform(pos);
|
||||||
setTrans(pos);
|
setTrans(pos);
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // endRescue
|
} // endRescue
|
||||||
|
|
||||||
|
@ -60,20 +60,20 @@ public:
|
|||||||
|
|
||||||
int matches ( char *tx ) ;
|
int matches ( char *tx ) ;
|
||||||
|
|
||||||
bool isIgnore () { return m_ignore ; }
|
ssgSimpleState
|
||||||
bool isZipper () { return m_zipper ; }
|
*getState () const { return m_state ; }
|
||||||
bool isSphereMap () { return m_sphere_map ; }
|
bool isIgnore () const { return m_ignore; }
|
||||||
bool isCrashable () { return m_collideable ; }
|
bool isZipper () const { return m_zipper; }
|
||||||
bool isReset () { return m_resetter ; }
|
bool isSphereMap () const { return m_sphere_map; }
|
||||||
float getFriction() { return m_friction ; }
|
bool isCrashable () const { return m_collideable; }
|
||||||
|
bool isReset () const { return m_resetter; }
|
||||||
|
float getFriction () const { return m_friction; }
|
||||||
|
char *getTexFname () const { return m_texname; }
|
||||||
|
int getIndex () const { return m_index; }
|
||||||
|
void apply () { m_state -> apply (); }
|
||||||
|
|
||||||
void applyToLeaf ( ssgLeaf *l ) ;
|
void applyToLeaf ( ssgLeaf *l ) ;
|
||||||
|
|
||||||
ssgSimpleState *getState () { return m_state ; }
|
|
||||||
int getIndex () { return m_index ; }
|
|
||||||
void apply () { m_state -> apply () ; }
|
|
||||||
|
|
||||||
char *getTexFname () const { return m_texname ; }
|
|
||||||
|
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
@ -240,6 +240,7 @@ void Moveable::ReadHistory(char* s, int kartNumber, int indx)
|
|||||||
|
|
||||||
#define max(m,n) ((m)>(n) ? (m) : (n)) /* return highest number */
|
#define max(m,n) ((m)>(n) ? (m) : (n)) /* return highest number */
|
||||||
|
|
||||||
|
#ifndef BULLET
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
float Moveable::collectIsectData ( sgVec3 start, sgVec3 end )
|
float Moveable::collectIsectData ( sgVec3 start, sgVec3 end )
|
||||||
{
|
{
|
||||||
@ -371,3 +372,4 @@ float Moveable::getIsectData ( sgVec3 start, sgVec3 end )
|
|||||||
return HOT ;
|
return HOT ;
|
||||||
} // getIsectData
|
} // getIsectData
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -56,14 +56,13 @@ protected:
|
|||||||
int m_crashed;
|
int m_crashed;
|
||||||
sgVec3 m_surface_avoidance_vector ;
|
sgVec3 m_surface_avoidance_vector ;
|
||||||
int m_first_time ;
|
int m_first_time ;
|
||||||
|
#ifndef BULLET
|
||||||
float collectIsectData ( sgVec3 start, sgVec3 end ) ;
|
float collectIsectData ( sgVec3 start, sgVec3 end ) ;
|
||||||
|
#endif
|
||||||
sgCoord* m_history_velocity;
|
sgCoord* m_history_velocity;
|
||||||
sgCoord* m_history_position;
|
sgCoord* m_history_position;
|
||||||
#ifdef BULLET
|
|
||||||
btRigidBody* m_body;
|
btRigidBody* m_body;
|
||||||
btDefaultMotionState* m_motion_state;
|
btDefaultMotionState* m_motion_state;
|
||||||
#endif
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -94,8 +93,9 @@ public:
|
|||||||
// there is a 'reset' material under the moveable --> karts need to be
|
// there is a 'reset' material under the moveable --> karts need to be
|
||||||
// rescued, missiles should explode.
|
// rescued, missiles should explode.
|
||||||
virtual void OutsideTrack (int isReset) {}
|
virtual void OutsideTrack (int isReset) {}
|
||||||
|
#ifndef BULLET
|
||||||
float getIsectData (sgVec3 start, sgVec3 end );
|
float getIsectData (sgVec3 start, sgVec3 end );
|
||||||
|
#endif
|
||||||
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; }
|
||||||
|
146
src/physics.cpp
146
src/physics.cpp
@ -18,8 +18,6 @@
|
|||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
|
||||||
#ifdef BULLET
|
|
||||||
|
|
||||||
#include "bullet/Demos/OpenGL/GL_ShapeDrawer.h"
|
#include "bullet/Demos/OpenGL/GL_ShapeDrawer.h"
|
||||||
|
|
||||||
#include "physics.hpp"
|
#include "physics.hpp"
|
||||||
@ -34,10 +32,22 @@
|
|||||||
|
|
||||||
/** Initialise physics. */
|
/** Initialise physics. */
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Handling of triangle specific friction and special attributes (e.g. reset,
|
||||||
|
// zipper).
|
||||||
|
extern ContactAddedCallback gContactAddedCallback;
|
||||||
|
bool HandleTerrainFriction(btManifoldPoint& cp,
|
||||||
|
const btCollisionObject* colObj0,int partId0,int index0,
|
||||||
|
const btCollisionObject* colObj1,int partId1,int index1);
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
float const Physics::NOHIT=-99999.9f;
|
float const Physics::NOHIT=-99999.9f;
|
||||||
|
|
||||||
Physics::Physics(float gravity) : btSequentialImpulseConstraintSolver()
|
Physics::Physics(float gravity) : btSequentialImpulseConstraintSolver()
|
||||||
{
|
{
|
||||||
|
// Set the contact handler for friction computation (and reset triggering)
|
||||||
|
gContactAddedCallback = HandleTerrainFriction;
|
||||||
|
|
||||||
m_collision_conf = new btDefaultCollisionConfiguration();
|
m_collision_conf = new btDefaultCollisionConfiguration();
|
||||||
m_dispatcher = new btCollisionDispatcher(m_collision_conf);
|
m_dispatcher = new btCollisionDispatcher(m_collision_conf);
|
||||||
|
|
||||||
@ -68,90 +78,6 @@ Physics::~Physics()
|
|||||||
|
|
||||||
} // ~Physics
|
} // ~Physics
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
//* Convert the ssg track tree into its physics equivalents.
|
|
||||||
void Physics::setTrack(ssgEntity* track)
|
|
||||||
{
|
|
||||||
if(!track) return;
|
|
||||||
sgMat4 mat;
|
|
||||||
sgMakeIdentMat4(mat);
|
|
||||||
btTriangleMesh *track_mesh = new btTriangleMesh();
|
|
||||||
|
|
||||||
// Collect all triangles in the track_mesh
|
|
||||||
convertTrack(track, 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);
|
|
||||||
btRigidBody *body=new btRigidBody(0.0f, myMotionState, mesh_shape);
|
|
||||||
// FIXME: can the mesh_shape and or track_mesh be deleted now?
|
|
||||||
m_dynamics_world->addRigidBody(body);
|
|
||||||
body->setUserPointer(0);
|
|
||||||
} // setTrack
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
//* Convert the ssg track tree into its physics equivalents.
|
|
||||||
void Physics::convertTrack(ssgEntity *track, sgMat4 m, btTriangleMesh* track_mesh)
|
|
||||||
{
|
|
||||||
if(!track) return;
|
|
||||||
MovingPhysics *mp = dynamic_cast<MovingPhysics*>(track);
|
|
||||||
if(mp)
|
|
||||||
{
|
|
||||||
// If the track contains obect of type MovingPhysics,
|
|
||||||
// these objects will be real rigid body and are already
|
|
||||||
// part of the world. So these objects must not be converted
|
|
||||||
// to triangle meshes.
|
|
||||||
}
|
|
||||||
else if(track->isAKindOf(ssgTypeLeaf()))
|
|
||||||
{
|
|
||||||
ssgLeaf *leaf = (ssgLeaf*)(track);
|
|
||||||
Material *mat = material_manager->getMaterial(leaf);
|
|
||||||
// Don't convert triangles with material that is ignored (e.g. fuzzy_sand)
|
|
||||||
if(!mat || mat->isIgnore()) return;
|
|
||||||
|
|
||||||
for(int i=0; i<leaf->getNumTriangles(); i++)
|
|
||||||
{
|
|
||||||
short v1,v2,v3;
|
|
||||||
sgVec3 vv1, vv2, vv3;
|
|
||||||
|
|
||||||
leaf->getTriangle(i, &v1, &v2, &v3);
|
|
||||||
sgXformPnt3 ( vv1, leaf->getVertex(v1), m );
|
|
||||||
sgXformPnt3 ( vv2, leaf->getVertex(v2), m );
|
|
||||||
sgXformPnt3 ( vv3, leaf->getVertex(v3), m );
|
|
||||||
btVector3 vb1(vv1[0],vv1[1],vv1[2]);
|
|
||||||
btVector3 vb2(vv2[0],vv2[1],vv2[2]);
|
|
||||||
btVector3 vb3(vv3[0],vv3[1],vv3[2]);
|
|
||||||
track_mesh->addTriangle(vb1, vb2, vb3);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // if(track isAKindOf leaf)
|
|
||||||
else if(track->isAKindOf(ssgTypeTransform()))
|
|
||||||
{
|
|
||||||
ssgBaseTransform *t = (ssgBaseTransform*)(track);
|
|
||||||
sgMat4 tmpT, tmpM;
|
|
||||||
t->getTransform(tmpT);
|
|
||||||
sgCopyMat4(tmpM, m);
|
|
||||||
sgPreMultMat4(tmpM,tmpT);
|
|
||||||
for(ssgEntity *e = t->getKid(0); e!=NULL; e=t->getNextKid())
|
|
||||||
{
|
|
||||||
convertTrack(e, tmpM, track_mesh);
|
|
||||||
} // for i
|
|
||||||
}
|
|
||||||
else if (track->isAKindOf(ssgTypeBranch()))
|
|
||||||
{
|
|
||||||
ssgBranch *b =(ssgBranch*)track;
|
|
||||||
for(ssgEntity* e=b->getKid(0); e!=NULL; e=b->getNextKid()) {
|
|
||||||
convertTrack(e, m, track_mesh);
|
|
||||||
} // for i<getNumKids
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
assert(!"Unkown ssg type in convertTrack");
|
|
||||||
}
|
|
||||||
} // convertTrack
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
//* Adds a kart to the physics engine
|
//* Adds a kart to the physics engine
|
||||||
void Physics::addKart(const Kart *kart, btRaycastVehicle *vehicle)
|
void Physics::addKart(const Kart *kart, btRaycastVehicle *vehicle)
|
||||||
@ -357,15 +283,26 @@ float Physics::getHAT(btVector3 pos)
|
|||||||
{
|
{
|
||||||
btVector3 to_pos(pos);
|
btVector3 to_pos(pos);
|
||||||
to_pos.setZ(-100000.f);
|
to_pos.setZ(-100000.f);
|
||||||
btCollisionWorld::ClosestRayResultCallback
|
btCollisionWorld::ClosestRayResultCallback rayCallback(pos, to_pos);
|
||||||
rayCallback(pos, to_pos);
|
|
||||||
|
|
||||||
m_dynamics_world->rayTest(pos, to_pos, rayCallback);
|
m_dynamics_world->rayTest(pos, to_pos, rayCallback);
|
||||||
if(!rayCallback.HasHit()) return NOHIT;
|
if(!rayCallback.HasHit()) return NOHIT;
|
||||||
|
|
||||||
return pos.getZ()-rayCallback.m_hitPointWorld.getZ();
|
return pos.getZ()-rayCallback.m_hitPointWorld.getZ();
|
||||||
} // getHAT
|
} // getHAT
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
float Physics::getHOT(btVector3 pos)
|
||||||
|
{
|
||||||
|
btVector3 to_pos(pos);
|
||||||
|
to_pos.setZ(-100000.f);
|
||||||
|
|
||||||
|
btCollisionWorld::ClosestRayResultCallback rayCallback(pos, to_pos);
|
||||||
|
|
||||||
|
m_dynamics_world->rayTest(pos, to_pos, rayCallback);
|
||||||
|
if(!rayCallback.HasHit()) return NOHIT;
|
||||||
|
|
||||||
|
return rayCallback.m_hitPointWorld.getZ();
|
||||||
|
} // getHOT
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
bool Physics::getTerrainNormal(btVector3 pos, btVector3* normal)
|
bool Physics::getTerrainNormal(btVector3 pos, btVector3* normal)
|
||||||
{
|
{
|
||||||
btVector3 to_pos(pos);
|
btVector3 to_pos(pos);
|
||||||
@ -380,6 +317,36 @@ bool Physics::getTerrainNormal(btVector3 pos, btVector3* normal)
|
|||||||
return true;
|
return true;
|
||||||
} // getTerrainNormal
|
} // getTerrainNormal
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
bool HandleTerrainFriction(btManifoldPoint& cp,
|
||||||
|
const btCollisionObject* colObj0,int partId0,int index0,
|
||||||
|
const btCollisionObject* colObj1,int partId1,int index1)
|
||||||
|
{
|
||||||
|
const btCollisionObject* obj0 = static_cast<const btCollisionObject*>(colObj0);
|
||||||
|
const btCollisionObject* obj1 = static_cast<const btCollisionObject*>(colObj1);
|
||||||
|
Moveable *mov0 = static_cast<Moveable*>(obj0->getUserPointer());
|
||||||
|
Moveable *mov1 = static_cast<Moveable*>(obj1->getUserPointer());
|
||||||
|
// make sure that indeed one of the two objects is the track, i.e. has no user pointer
|
||||||
|
assert(mov0==0 || mov1==0);
|
||||||
|
Moveable *other;
|
||||||
|
other = (mov0==0) ? mov1 : mov0; // get the non-track object.
|
||||||
|
|
||||||
|
// This can happen when moving_physics objects exist
|
||||||
|
if(!other) return false;
|
||||||
|
|
||||||
|
int indx = (mov0==0) ? index0 : index1; // get the track index
|
||||||
|
// Don't do anything if a projectile (or any other non-kart object) hit sthe track
|
||||||
|
if(other->getMoveableType()!=Moveable::MOV_KART) return false;
|
||||||
|
|
||||||
|
const Material *mat= Track::getMaterial(indx);
|
||||||
|
if(mat->isReset())
|
||||||
|
{
|
||||||
|
((Kart*)other)->forceRescue();
|
||||||
|
}
|
||||||
|
cp.m_combinedFriction = mat->getFriction();
|
||||||
|
return true;
|
||||||
|
} // CustomTriangleHandler
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
//*
|
//*
|
||||||
void Physics::draw()
|
void Physics::draw()
|
||||||
@ -415,6 +382,5 @@ void Physics::debugDraw(float m[16], btCollisionShape *s, const btVector3 color)
|
|||||||
} // debugDraw
|
} // debugDraw
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
#endif
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
||||||
|
@ -85,7 +85,6 @@ private:
|
|||||||
void KartKartCollision(Kart *ka, Kart *kb);
|
void KartKartCollision(Kart *ka, Kart *kb);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void convertTrack (ssgEntity *track, sgMat4 m, btTriangleMesh* track_mesh);
|
|
||||||
Physics (float gravity);
|
Physics (float gravity);
|
||||||
~Physics ();
|
~Physics ();
|
||||||
void addKart (const Kart *k, btRaycastVehicle *v);
|
void addKart (const Kart *k, btRaycastVehicle *v);
|
||||||
@ -94,12 +93,12 @@ public:
|
|||||||
void removeBody (btRigidBody* b) {m_dynamics_world->removeRigidBody(b);}
|
void removeBody (btRigidBody* b) {m_dynamics_world->removeRigidBody(b);}
|
||||||
void update (float dt);
|
void update (float dt);
|
||||||
void draw ();
|
void draw ();
|
||||||
void setTrack (ssgEntity *track);
|
|
||||||
btDynamicsWorld*
|
btDynamicsWorld*
|
||||||
getPhysicsWorld () const {return m_dynamics_world;}
|
getPhysicsWorld () const {return m_dynamics_world;}
|
||||||
void debugDraw (float m[16], btCollisionShape *s, const btVector3 color);
|
void debugDraw (float m[16], btCollisionShape *s, const btVector3 color);
|
||||||
static const float NOHIT;
|
static const float NOHIT;
|
||||||
float getHAT (btVector3 pos);
|
float getHAT (btVector3 pos);
|
||||||
|
float getHOT (btVector3 pos);
|
||||||
bool getTerrainNormal(btVector3 pos, btVector3* normal);
|
bool getTerrainNormal(btVector3 pos, btVector3* normal);
|
||||||
virtual btScalar solveGroup(btCollisionObject** bodies, int numBodies,
|
virtual btScalar solveGroup(btCollisionObject** bodies, int numBodies,
|
||||||
btPersistentManifold** manifold,int numManifolds,
|
btPersistentManifold** manifold,int numManifolds,
|
||||||
|
@ -56,22 +56,22 @@ void PlayerKart::action(KartAction action, int value)
|
|||||||
case KA_BRAKE:
|
case KA_BRAKE:
|
||||||
if (value)
|
if (value)
|
||||||
m_accel_val = 0;
|
m_accel_val = 0;
|
||||||
m_controls.brake = value;
|
m_controls.brake = (value!=0); // This syntax avoid visual c++ warning (when brake=value)
|
||||||
break;
|
break;
|
||||||
case KA_WHEELIE:
|
case KA_WHEELIE:
|
||||||
m_controls.wheelie = value;
|
m_controls.wheelie = (value!=0);
|
||||||
break;
|
break;
|
||||||
case KA_RESCUE:
|
case KA_RESCUE:
|
||||||
m_controls.rescue = value;
|
m_controls.rescue = (value!=0);
|
||||||
break;
|
break;
|
||||||
case KA_FIRE:
|
case KA_FIRE:
|
||||||
m_controls.fire = value;
|
m_controls.fire = (value!=0);
|
||||||
break;
|
break;
|
||||||
case KA_LOOK_BACK:
|
case KA_LOOK_BACK:
|
||||||
m_camera->setReverseHeading(value);
|
m_camera->setReverseHeading(value!=0);
|
||||||
break;
|
break;
|
||||||
case KA_JUMP:
|
case KA_JUMP:
|
||||||
m_controls.jump = value;
|
m_controls.jump = (value!=0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
342
src/track.cpp
342
src/track.cpp
@ -29,10 +29,21 @@
|
|||||||
#include "stk_config.hpp"
|
#include "stk_config.hpp"
|
||||||
#include "translation.hpp"
|
#include "translation.hpp"
|
||||||
#include "scene.hpp"
|
#include "scene.hpp"
|
||||||
|
#include "moving_physics.hpp"
|
||||||
|
#include "world.hpp"
|
||||||
|
#include "material_manager.hpp"
|
||||||
|
#include "isect.hpp"
|
||||||
|
#include "ssg_help.hpp"
|
||||||
|
#include "user_config.hpp"
|
||||||
|
#include "herring.hpp"
|
||||||
|
#include "herring_manager.hpp"
|
||||||
|
|
||||||
#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;
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
Track::Track( std::string filename_, float w, float h, bool stretch )
|
Track::Track( std::string filename_, float w, float h, bool stretch )
|
||||||
{
|
{
|
||||||
m_filename = filename_;
|
m_filename = filename_;
|
||||||
@ -53,6 +64,15 @@ Track::Track( std::string filename_, float w, float h, bool stretch )
|
|||||||
Track::~Track()
|
Track::~Track()
|
||||||
{
|
{
|
||||||
} // ~Track
|
} // ~Track
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Removes the physical body from the world.
|
||||||
|
* Called at the end of a race.
|
||||||
|
*/
|
||||||
|
void Track::cleanup()
|
||||||
|
{
|
||||||
|
world->getPhysics()->removeBody(m_body);
|
||||||
|
delete m_body;
|
||||||
|
} // ~Track
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/** Finds on which side of the line segment a given point is.
|
/** Finds on which side of the line segment a given point is.
|
||||||
@ -122,27 +142,27 @@ void Track::findRoadSector( const sgVec3 XYZ, int *sector )const
|
|||||||
that forms each track segment.
|
that forms each track segment.
|
||||||
*/
|
*/
|
||||||
std::vector <SegmentTriangle> possible_segment_tris;
|
std::vector <SegmentTriangle> possible_segment_tris;
|
||||||
const unsigned int DRIVELINE_SIZE = m_left_driveline.size();
|
const unsigned int DRIVELINE_SIZE = (unsigned int)m_left_driveline.size();
|
||||||
int triangle;
|
int triangle;
|
||||||
int next;
|
int next;
|
||||||
|
|
||||||
for( size_t i = 0; i < DRIVELINE_SIZE ; ++i )
|
for( size_t i = 0; i < DRIVELINE_SIZE ; ++i )
|
||||||
{
|
{
|
||||||
next = i + 1 < DRIVELINE_SIZE ? i + 1 : 0;
|
next = (unsigned int)i + 1 < DRIVELINE_SIZE ? (int)i + 1 : 0;
|
||||||
triangle = pointInQuad( m_left_driveline[i], m_right_driveline[i],
|
triangle = pointInQuad( m_left_driveline[i], m_right_driveline[i],
|
||||||
m_right_driveline[next], m_left_driveline[next],
|
m_right_driveline[next], m_left_driveline[next],
|
||||||
XYZ );
|
XYZ );
|
||||||
|
|
||||||
if (triangle != QUAD_TRI_NONE && ((XYZ[2]-m_left_driveline[i][2]) < 1.0f))
|
if (triangle != QUAD_TRI_NONE && ((XYZ[2]-m_left_driveline[i][2]) < 1.0f))
|
||||||
{
|
{
|
||||||
possible_segment_tris.push_back(SegmentTriangle(i, triangle));
|
possible_segment_tris.push_back(SegmentTriangle((int)i, triangle));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Since xyz can be on more than one 2D track segment, we have to
|
/* Since xyz can be on more than one 2D track segment, we have to
|
||||||
find on top of which one of the possible track segments it is.
|
find on top of which one of the possible track segments it is.
|
||||||
*/
|
*/
|
||||||
const int POS_SEG_SIZE = possible_segment_tris.size();
|
const int POS_SEG_SIZE = (int)possible_segment_tris.size();
|
||||||
if( POS_SEG_SIZE == 0 )
|
if( POS_SEG_SIZE == 0 )
|
||||||
{
|
{
|
||||||
//xyz is not on the road
|
//xyz is not on the road
|
||||||
@ -164,7 +184,7 @@ void Track::findRoadSector( const sgVec3 XYZ, int *sector )const
|
|||||||
for( int i = 0; i < POS_SEG_SIZE; ++i )
|
for( int i = 0; i < POS_SEG_SIZE; ++i )
|
||||||
{
|
{
|
||||||
segment = possible_segment_tris[i].segment;
|
segment = possible_segment_tris[i].segment;
|
||||||
next = segment + 1 < DRIVELINE_SIZE ? segment + 1 : 0;
|
next = segment + 1 < DRIVELINE_SIZE ? (int)segment + 1 : 0;
|
||||||
|
|
||||||
if( possible_segment_tris[i].triangle == QUAD_TRI_FIRST )
|
if( possible_segment_tris[i].triangle == QUAD_TRI_FIRST )
|
||||||
{
|
{
|
||||||
@ -242,7 +262,7 @@ int Track::findOutOfRoadSector
|
|||||||
int sector = UNKNOWN_SECTOR;
|
int sector = UNKNOWN_SECTOR;
|
||||||
float dist;
|
float dist;
|
||||||
float nearest_dist = 99999;
|
float nearest_dist = 99999;
|
||||||
const unsigned int DRIVELINE_SIZE = m_left_driveline.size();
|
const unsigned int DRIVELINE_SIZE = (unsigned int)m_left_driveline.size();
|
||||||
|
|
||||||
int begin_sector = 0;
|
int begin_sector = 0;
|
||||||
int end_sector = DRIVELINE_SIZE - 1;
|
int end_sector = DRIVELINE_SIZE - 1;
|
||||||
@ -324,7 +344,7 @@ int Track::spatialToTrack
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsigned int DRIVELINE_SIZE = m_driveline.size();
|
const unsigned int DRIVELINE_SIZE = (unsigned int)m_driveline.size();
|
||||||
const size_t PREV = SECTOR == 0 ? DRIVELINE_SIZE - 1 : SECTOR - 1;
|
const size_t PREV = SECTOR == 0 ? DRIVELINE_SIZE - 1 : SECTOR - 1;
|
||||||
const size_t NEXT = (size_t)SECTOR+1 >= DRIVELINE_SIZE ? 0 : SECTOR + 1;
|
const size_t NEXT = (size_t)SECTOR+1 >= DRIVELINE_SIZE ? 0 : SECTOR + 1;
|
||||||
|
|
||||||
@ -361,7 +381,7 @@ int Track::spatialToTrack
|
|||||||
/ (m_distance_from_start[p2]-m_distance_from_start[p1]);
|
/ (m_distance_from_start[p2]-m_distance_from_start[p1]);
|
||||||
dst[2] = m_path_width[p1]*(1-fraction)+fraction*m_path_width[p2];
|
dst[2] = m_path_width[p1]*(1-fraction)+fraction*m_path_width[p2];
|
||||||
|
|
||||||
return p1;
|
return (int)p1;
|
||||||
} // spatialToTrack
|
} // spatialToTrack
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -370,11 +390,6 @@ void Track::trackToSpatial ( sgVec3 xyz, const int SECTOR ) const
|
|||||||
sgCopyVec3 ( xyz, m_driveline [ SECTOR ] ) ;
|
sgCopyVec3 ( xyz, m_driveline [ SECTOR ] ) ;
|
||||||
} // trackToSpatial
|
} // trackToSpatial
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void Track::createHash(ssgEntity* track_branch, unsigned int n) {
|
|
||||||
m_static_ssg = new StaticSSG(track_branch, n);
|
|
||||||
} // createHash
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/** Returns the start coordinates for a kart on a given position pos
|
/** Returns the start coordinates for a kart on a given position pos
|
||||||
(with 0<=pos).
|
(with 0<=pos).
|
||||||
@ -385,7 +400,7 @@ void Track::getStartCoords(unsigned int pos, sgCoord* coords) const {
|
|||||||
// This kart would not get any lap counting done in the first
|
// This kart would not get any lap counting done in the first
|
||||||
// lap! Therefor -1.5 is subtracted from the y position - which
|
// lap! Therefor -1.5 is subtracted from the y position - which
|
||||||
// is a somewhat arbitrary value.
|
// is a somewhat arbitrary value.
|
||||||
coords->xyz[0] = pos<m_start_x.size() ? m_start_x[pos] : ((pos%2==0)?1.5:-1.5f);
|
coords->xyz[0] = pos<m_start_x.size() ? m_start_x[pos] : ((pos%2==0)?1.5f:-1.5f);
|
||||||
coords->xyz[1] = pos<m_start_y.size() ? m_start_y[pos] : -1.5f*pos-1.5f;
|
coords->xyz[1] = pos<m_start_y.size() ? m_start_y[pos] : -1.5f*pos-1.5f;
|
||||||
// height must be larger than the actual hight for which hot is computed.
|
// height must be larger than the actual hight for which hot is computed.
|
||||||
coords->xyz[2] = pos<m_start_z.size() ? m_start_z[pos] : 1.0f;
|
coords->xyz[2] = pos<m_start_z.size() ? m_start_z[pos] : 1.0f;
|
||||||
@ -394,10 +409,8 @@ void Track::getStartCoords(unsigned int pos, sgCoord* coords) const {
|
|||||||
coords->hpr[1] = 0.0f;
|
coords->hpr[1] = 0.0f;
|
||||||
coords->hpr[2] = 0.0f;
|
coords->hpr[2] = 0.0f;
|
||||||
|
|
||||||
ssgLeaf *leaf;
|
btVector3 tmp_pos(coords->xyz[0],coords->xyz[1],coords->xyz[2]);
|
||||||
sgVec4* normal;
|
coords->xyz[2] = world->getPhysics()->getHOT(tmp_pos);
|
||||||
const float hot = m_static_ssg->hot(coords->xyz, coords->xyz, &leaf, &normal);
|
|
||||||
coords->xyz[2] = hot;
|
|
||||||
|
|
||||||
} // getStartCoords
|
} // getStartCoords
|
||||||
|
|
||||||
@ -413,8 +426,8 @@ bool Track::isShortcut(const int OLDSEC, const int NEWSEC) const
|
|||||||
unsigned int distance_sectors = abs(OLDSEC-NEWSEC);
|
unsigned int distance_sectors = abs(OLDSEC-NEWSEC);
|
||||||
// Handle 'wrap around': if the distance is more than half the
|
// Handle 'wrap around': if the distance is more than half the
|
||||||
// number of driveline poins, assume it's a 'wrap around'
|
// number of driveline poins, assume it's a 'wrap around'
|
||||||
if(2*distance_sectors > m_driveline.size())
|
if(2*distance_sectors > (unsigned int)m_driveline.size())
|
||||||
distance_sectors = m_driveline.size() - distance_sectors;
|
distance_sectors = (unsigned int)m_driveline.size() - distance_sectors;
|
||||||
return (distance_sectors>stk_config->m_shortcut_segments);
|
return (distance_sectors>stk_config->m_shortcut_segments);
|
||||||
} // isShortcut
|
} // isShortcut
|
||||||
|
|
||||||
@ -507,7 +520,7 @@ void Track::drawScaled2D(float x, float y, float w, float h) const
|
|||||||
sy = sx;
|
sy = sx;
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsigned int DRIVELINE_SIZE = m_driveline.size();
|
const unsigned int DRIVELINE_SIZE = (unsigned int)m_driveline.size();
|
||||||
|
|
||||||
glPushAttrib ( GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_LINE_BIT );
|
glPushAttrib ( GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_LINE_BIT );
|
||||||
|
|
||||||
@ -621,7 +634,7 @@ void Track::drawScaled2D(float x, float y, float w, float h) const
|
|||||||
void Track::draw2Dview (float x_offset, float y_offset) const
|
void Track::draw2Dview (float x_offset, float y_offset) const
|
||||||
{
|
{
|
||||||
|
|
||||||
const unsigned int DRIVELINE_SIZE = m_driveline.size();
|
const unsigned int DRIVELINE_SIZE = (unsigned int)m_driveline.size();
|
||||||
|
|
||||||
glPushAttrib ( GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_LINE_BIT );
|
glPushAttrib ( GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_LINE_BIT );
|
||||||
|
|
||||||
@ -757,12 +770,12 @@ void Track::loadTrack(std::string filename_)
|
|||||||
m_fog_end = 1000.0f;
|
m_fog_end = 1000.0f;
|
||||||
m_gravity = 9.80665f;
|
m_gravity = 9.80665f;
|
||||||
|
|
||||||
sgSetVec3 ( m_sun_position, 0.4f, 0.4f, 0.4f );
|
sgSetVec3 ( m_sun_position, 0.4f, 0.4f, 0.4f );
|
||||||
sgSetVec4 ( m_sky_color , 0.3f, 0.7f, 0.9f, 1.0f );
|
sgSetVec4 ( m_sky_color, 0.3f, 0.7f, 0.9f, 1.0f );
|
||||||
sgSetVec4 ( m_fog_color , 0.3f, 0.7f, 0.9f, 1.0f );
|
sgSetVec4 ( m_fog_color, 0.3f, 0.7f, 0.9f, 1.0f );
|
||||||
sgSetVec4 ( m_ambient_col , 0.5f, 0.5f, 0.5f, 1.0f );
|
sgSetVec4 ( m_ambient_col, 0.5f, 0.5f, 0.5f, 1.0f );
|
||||||
sgSetVec4 ( m_specular_col, 1.0f, 1.0f, 1.0f, 1.0f );
|
sgSetVec4 ( m_specular_col, 1.0f, 1.0f, 1.0f, 1.0f );
|
||||||
sgSetVec4 ( m_diffuse_col , 1.0f, 1.0f, 1.0f, 1.0f );
|
sgSetVec4 ( m_diffuse_col, 1.0f, 1.0f, 1.0f, 1.0f );
|
||||||
|
|
||||||
lisp::Parser parser;
|
lisp::Parser parser;
|
||||||
const lisp::Lisp* const ROOT = parser.parse(loader->getPath(m_filename));
|
const lisp::Lisp* const ROOT = parser.parse(loader->getPath(m_filename));
|
||||||
@ -815,7 +828,7 @@ Track::loadDriveline()
|
|||||||
{
|
{
|
||||||
readDrivelineFromFile(m_left_driveline, ".drvl");
|
readDrivelineFromFile(m_left_driveline, ".drvl");
|
||||||
|
|
||||||
const unsigned int DRIVELINE_SIZE = m_left_driveline.size();
|
const unsigned int DRIVELINE_SIZE = (unsigned int)m_left_driveline.size();
|
||||||
m_right_driveline.reserve(DRIVELINE_SIZE);
|
m_right_driveline.reserve(DRIVELINE_SIZE);
|
||||||
readDrivelineFromFile(m_right_driveline, ".drvr");
|
readDrivelineFromFile(m_right_driveline, ".drvr");
|
||||||
|
|
||||||
@ -970,5 +983,276 @@ Track::readDrivelineFromFile(std::vector<sgVec3Wrapper>& line, const std::string
|
|||||||
}
|
}
|
||||||
|
|
||||||
fclose ( fd ) ;
|
fclose ( fd ) ;
|
||||||
}
|
} // readDrivelineFromFile
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
//* Convert the ssg track tree into its physics equivalents.
|
||||||
|
void Track::createPhysicsModel()
|
||||||
|
{
|
||||||
|
if(!m_model) return;
|
||||||
|
sgMat4 mat;
|
||||||
|
sgMakeIdentMat4(mat);
|
||||||
|
btTriangleMesh *track_mesh = new btTriangleMesh();
|
||||||
|
m_triangleIndex2Material.clear();
|
||||||
|
// Collect all triangles in the track_mesh
|
||||||
|
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
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
//* Convert the ssg track tree into its physics equivalents.
|
||||||
|
void Track::convertTrackToBullet(ssgEntity *track, sgMat4 m, btTriangleMesh* track_mesh)
|
||||||
|
{
|
||||||
|
if(!track) return;
|
||||||
|
MovingPhysics *mp = dynamic_cast<MovingPhysics*>(track);
|
||||||
|
if(mp)
|
||||||
|
{
|
||||||
|
// If the track contains obect of type MovingPhysics,
|
||||||
|
// these objects will be real rigid body and are already
|
||||||
|
// part of the world. So these objects must not be converted
|
||||||
|
// to triangle meshes.
|
||||||
|
}
|
||||||
|
else if(track->isAKindOf(ssgTypeLeaf()))
|
||||||
|
{
|
||||||
|
ssgLeaf *leaf = (ssgLeaf*)(track);
|
||||||
|
Material *mat = material_manager->getMaterial(leaf);
|
||||||
|
// Don't convert triangles with material that is ignored (e.g. fuzzy_sand)
|
||||||
|
if(!mat || mat->isIgnore()) return;
|
||||||
|
|
||||||
|
for(int i=0; i<leaf->getNumTriangles(); i++)
|
||||||
|
{
|
||||||
|
short v1,v2,v3;
|
||||||
|
sgVec3 vv1, vv2, vv3;
|
||||||
|
|
||||||
|
leaf->getTriangle(i, &v1, &v2, &v3);
|
||||||
|
sgXformPnt3 ( vv1, leaf->getVertex(v1), m );
|
||||||
|
sgXformPnt3 ( vv2, leaf->getVertex(v2), m );
|
||||||
|
sgXformPnt3 ( vv3, leaf->getVertex(v3), m );
|
||||||
|
btVector3 vb1(vv1[0],vv1[1],vv1[2]);
|
||||||
|
btVector3 vb2(vv2[0],vv2[1],vv2[2]);
|
||||||
|
btVector3 vb3(vv3[0],vv3[1],vv3[2]);
|
||||||
|
track_mesh->addTriangle(vb1, vb2, vb3);
|
||||||
|
m_triangleIndex2Material.push_back(mat);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // if(track isAKindOf leaf)
|
||||||
|
else if(track->isAKindOf(ssgTypeTransform()))
|
||||||
|
{
|
||||||
|
ssgBaseTransform *t = (ssgBaseTransform*)(track);
|
||||||
|
sgMat4 tmpT, tmpM;
|
||||||
|
t->getTransform(tmpT);
|
||||||
|
sgCopyMat4(tmpM, m);
|
||||||
|
sgPreMultMat4(tmpM,tmpT);
|
||||||
|
for(ssgEntity *e = t->getKid(0); e!=NULL; e=t->getNextKid())
|
||||||
|
{
|
||||||
|
convertTrackToBullet(e, tmpM, track_mesh);
|
||||||
|
} // for i
|
||||||
|
}
|
||||||
|
else if (track->isAKindOf(ssgTypeBranch()))
|
||||||
|
{
|
||||||
|
ssgBranch *b =(ssgBranch*)track;
|
||||||
|
for(ssgEntity* e=b->getKid(0); e!=NULL; e=b->getNextKid()) {
|
||||||
|
convertTrackToBullet(e, m, track_mesh);
|
||||||
|
} // for i<getNumKids
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(!"Unkown ssg type in convertTrackToBullet");
|
||||||
|
}
|
||||||
|
} // convertTrackToBullet
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void Track::loadTrackModel()
|
||||||
|
{
|
||||||
|
std::string path = "data/";
|
||||||
|
path += getIdent();
|
||||||
|
path += ".loc";
|
||||||
|
path = loader->getPath(path.c_str());
|
||||||
|
|
||||||
|
FILE *fd = fopen (path.c_str(), "r" );
|
||||||
|
if ( fd == NULL )
|
||||||
|
{
|
||||||
|
char msg[MAX_ERROR_MESSAGE_LENGTH];
|
||||||
|
snprintf(msg, sizeof(msg),"Can't open track location file '%s'.\n",
|
||||||
|
path.c_str());
|
||||||
|
throw std::runtime_error(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start building the scene graph
|
||||||
|
m_model = new ssgBranch ;
|
||||||
|
scene->add(m_model);
|
||||||
|
|
||||||
|
char s [ 1024 ] ;
|
||||||
|
|
||||||
|
while ( fgets ( s, 1023, fd ) != NULL )
|
||||||
|
{
|
||||||
|
if ( *s == '#' || *s < ' ' )
|
||||||
|
continue ;
|
||||||
|
|
||||||
|
int need_hat = false ;
|
||||||
|
int fit_skin = false ;
|
||||||
|
char fname [ 1024 ] ;
|
||||||
|
sgCoord loc ;
|
||||||
|
sgZeroVec3 ( loc.xyz ) ;
|
||||||
|
sgZeroVec3 ( loc.hpr ) ;
|
||||||
|
|
||||||
|
char htype = '\0' ;
|
||||||
|
|
||||||
|
if ( sscanf ( s, "%cHERRING,%f,%f,%f", &htype,
|
||||||
|
&(loc.xyz[0]), &(loc.xyz[1]), &(loc.xyz[2]) ) == 4 )
|
||||||
|
{
|
||||||
|
herring_command(&loc.xyz, htype, false) ;
|
||||||
|
}
|
||||||
|
else if ( sscanf ( s, "%cHERRING,%f,%f", &htype,
|
||||||
|
&(loc.xyz[0]), &(loc.xyz[1]) ) == 3 )
|
||||||
|
{
|
||||||
|
herring_command (&loc.xyz, htype, true) ;
|
||||||
|
}
|
||||||
|
else if ( s[0] == '\"' )
|
||||||
|
{
|
||||||
|
if ( sscanf ( s, "\"%[^\"]\",%f,%f,%f,%f,%f,%f",
|
||||||
|
fname, &(loc.xyz[0]), &(loc.xyz[1]), &(loc.xyz[2]),
|
||||||
|
&(loc.hpr[0]), &(loc.hpr[1]), &(loc.hpr[2]) ) == 7 )
|
||||||
|
{
|
||||||
|
/* All 6 DOF specified */
|
||||||
|
need_hat = false;
|
||||||
|
}
|
||||||
|
else if ( sscanf ( s, "\"%[^\"]\",%f,%f,{},%f,%f,%f",
|
||||||
|
fname, &(loc.xyz[0]), &(loc.xyz[1]),
|
||||||
|
&(loc.hpr[0]), &(loc.hpr[1]), &(loc.hpr[2])) == 6 )
|
||||||
|
{
|
||||||
|
/* All 6 DOF specified - but need height */
|
||||||
|
need_hat = true ;
|
||||||
|
}
|
||||||
|
else if ( sscanf ( s, "\"%[^\"]\",%f,%f,%f,%f",
|
||||||
|
fname, &(loc.xyz[0]), &(loc.xyz[1]), &(loc.xyz[2]),
|
||||||
|
&(loc.hpr[0]) ) == 5 )
|
||||||
|
{
|
||||||
|
/* No Roll/Pitch specified - assumed zero */
|
||||||
|
need_hat = false ;
|
||||||
|
}
|
||||||
|
else if ( sscanf ( s, "\"%[^\"]\",%f,%f,{},%f,{},{}",
|
||||||
|
fname, &(loc.xyz[0]), &(loc.xyz[1]),
|
||||||
|
&(loc.hpr[0]) ) == 3 )
|
||||||
|
{
|
||||||
|
/* All 6 DOF specified - but need height, roll, pitch */
|
||||||
|
need_hat = true ;
|
||||||
|
fit_skin = true ;
|
||||||
|
}
|
||||||
|
else if ( sscanf ( s, "\"%[^\"]\",%f,%f,{},%f",
|
||||||
|
fname, &(loc.xyz[0]), &(loc.xyz[1]),
|
||||||
|
&(loc.hpr[0]) ) == 4 )
|
||||||
|
{
|
||||||
|
/* No Roll/Pitch specified - but need height */
|
||||||
|
need_hat = true ;
|
||||||
|
}
|
||||||
|
else if ( sscanf ( s, "\"%[^\"]\",%f,%f,%f",
|
||||||
|
fname, &(loc.xyz[0]), &(loc.xyz[1]),
|
||||||
|
&(loc.xyz[2]) ) == 4 )
|
||||||
|
{
|
||||||
|
/* No Heading/Roll/Pitch specified - but need height */
|
||||||
|
need_hat = false ;
|
||||||
|
}
|
||||||
|
else if ( sscanf ( s, "\"%[^\"]\",%f,%f,{}",
|
||||||
|
fname, &(loc.xyz[0]), &(loc.xyz[1]) ) == 3 )
|
||||||
|
{
|
||||||
|
/* No Roll/Pitch specified - but need height */
|
||||||
|
need_hat = true ;
|
||||||
|
}
|
||||||
|
else if ( sscanf ( s, "\"%[^\"]\",%f,%f",
|
||||||
|
fname, &(loc.xyz[0]), &(loc.xyz[1]) ) == 3 )
|
||||||
|
{
|
||||||
|
/* No Z/Heading/Roll/Pitch specified */
|
||||||
|
need_hat = false ;
|
||||||
|
}
|
||||||
|
else if ( sscanf ( s, "\"%[^\"]\"", fname ) == 1 )
|
||||||
|
{
|
||||||
|
/* Nothing specified */
|
||||||
|
need_hat = false ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fclose(fd);
|
||||||
|
char msg[MAX_ERROR_MESSAGE_LENGTH];
|
||||||
|
snprintf(msg, sizeof(msg), "Syntax error in '%s': %s",
|
||||||
|
path.c_str(), s);
|
||||||
|
throw std::runtime_error(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( need_hat )
|
||||||
|
{
|
||||||
|
sgVec3 nrm ;
|
||||||
|
|
||||||
|
loc.xyz[2] = 1000.0f ;
|
||||||
|
loc.xyz[2] = getHeightAndNormal ( m_model, loc.xyz, nrm ) ;
|
||||||
|
|
||||||
|
if ( fit_skin )
|
||||||
|
{
|
||||||
|
float sy = sin ( -loc.hpr [ 0 ] * SG_DEGREES_TO_RADIANS ) ;
|
||||||
|
float cy = cos ( -loc.hpr [ 0 ] * SG_DEGREES_TO_RADIANS ) ;
|
||||||
|
|
||||||
|
loc.hpr[2] = SG_RADIANS_TO_DEGREES * atan2 ( nrm[0] * cy -
|
||||||
|
nrm[1] * sy, nrm[2] ) ;
|
||||||
|
loc.hpr[1] = -SG_RADIANS_TO_DEGREES * atan2 ( nrm[1] * cy +
|
||||||
|
nrm[0] * sy, nrm[2] ) ;
|
||||||
|
}
|
||||||
|
} // if need_hat
|
||||||
|
|
||||||
|
ssgEntity *obj = loader->load(fname, CB_TRACK);
|
||||||
|
createDisplayLists(obj);
|
||||||
|
ssgRangeSelector *lod = new ssgRangeSelector ;
|
||||||
|
ssgTransform *trans = new ssgTransform ( & loc ) ;
|
||||||
|
|
||||||
|
float r [ 2 ] = { -10.0f, 2000.0f } ;
|
||||||
|
|
||||||
|
lod -> addKid(obj );
|
||||||
|
trans -> addKid(lod );
|
||||||
|
m_model-> addKid(trans );
|
||||||
|
lod -> setRanges(r, 2);
|
||||||
|
if(user_config->m_track_debug)
|
||||||
|
addDebugToScene(user_config->m_track_debug);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// fclose(fd);
|
||||||
|
// char msg[MAX_ERROR_MESSAGE_LENGTH];
|
||||||
|
// snprintf(msg, sizeof(msg), "Syntax error in '%s': %s",
|
||||||
|
fprintf(stderr, "Warning: Syntax error in '%s': %s",
|
||||||
|
path.c_str(), s);
|
||||||
|
// throw std::runtime_error(msg);
|
||||||
|
}
|
||||||
|
} // while fgets
|
||||||
|
|
||||||
|
fclose ( fd ) ;
|
||||||
|
|
||||||
|
createPhysicsModel();
|
||||||
|
} // loadTrack
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void Track::herring_command (sgVec3 *xyz, char htype, int bNeedHeight )
|
||||||
|
{
|
||||||
|
|
||||||
|
// if only 2d coordinates are given, let the herring fall from very heigh
|
||||||
|
if(bNeedHeight) (*xyz)[2] = 1000000.0f;
|
||||||
|
|
||||||
|
// Even if 3d data are given, make sure that the herring is on the ground
|
||||||
|
(*xyz)[2] = getHeight ( m_model, *xyz ) + 0.06f;
|
||||||
|
herringType type=HE_GREEN;
|
||||||
|
if ( htype=='Y' || htype=='y' ) { type = HE_GOLD ;}
|
||||||
|
if ( htype=='G' || htype=='g' ) { type = HE_GREEN ;}
|
||||||
|
if ( htype=='R' || htype=='r' ) { type = HE_RED ;}
|
||||||
|
if ( htype=='S' || htype=='s' ) { type = HE_SILVER ;}
|
||||||
|
herring_manager->newHerring(type, xyz);
|
||||||
|
} // herring_command
|
||||||
|
@ -33,21 +33,24 @@
|
|||||||
#include <plib/ssg.h>
|
#include <plib/ssg.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "static_ssg.hpp"
|
#include "btBulletDynamicsCommon.h"
|
||||||
|
#include "material.hpp"
|
||||||
|
|
||||||
class Track
|
class Track
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
float m_gravity;
|
float m_gravity;
|
||||||
std::string m_ident;
|
std::string m_ident;
|
||||||
std::string m_screenshot;
|
std::string m_screenshot;
|
||||||
std::string m_top_view;
|
std::string m_top_view;
|
||||||
std::vector<std::string> m_music_filenames;
|
std::vector<std::string> m_music_filenames;
|
||||||
std::vector<float> m_start_x, m_start_y, m_start_z, m_start_heading;
|
std::vector<float> m_start_x, m_start_y, m_start_z, m_start_heading;
|
||||||
std::string m_herring_style;
|
std::string m_herring_style;
|
||||||
std::string m_description;
|
std::string m_description;
|
||||||
std::string m_filename;
|
std::string m_filename;
|
||||||
StaticSSG* m_static_ssg;
|
ssgBranch* m_model;
|
||||||
|
btRigidBody* m_body;
|
||||||
|
static std::vector<const Material*> m_triangleIndex2Material;
|
||||||
|
|
||||||
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 };
|
||||||
@ -136,7 +139,7 @@ public:
|
|||||||
Track (std::string filename,float w=100,
|
Track (std::string filename,float w=100,
|
||||||
float h=100, bool stretch=1);
|
float h=100, bool stretch=1);
|
||||||
~Track ();
|
~Track ();
|
||||||
|
void cleanup ();
|
||||||
void addDebugToScene (int type ) const;
|
void addDebugToScene (int type ) const;
|
||||||
void draw2Dview (float x_offset,
|
void draw2Dview (float x_offset,
|
||||||
float y_offset ) const;
|
float y_offset ) const;
|
||||||
@ -152,36 +155,34 @@ public:
|
|||||||
const sgVec2 POS,
|
const sgVec2 POS,
|
||||||
const int SECTOR ) const;
|
const int SECTOR ) const;
|
||||||
void trackToSpatial (sgVec3 xyz, const int SECTOR) const;
|
void trackToSpatial (sgVec3 xyz, const int SECTOR) const;
|
||||||
|
ssgBranch* getModel () const {return m_model;}
|
||||||
|
void loadTrackModel ();
|
||||||
bool isShortcut (const int OLDSEC, const int NEWSEC) const;
|
bool isShortcut (const int OLDSEC, const int NEWSEC) const;
|
||||||
float getGravity () const {return m_gravity; }
|
float getGravity () const {return m_gravity; }
|
||||||
float getTrackLength () const {return m_total_distance;}
|
float getTrackLength () const {return m_total_distance; }
|
||||||
const char* getIdent () const {return m_ident.c_str(); }
|
const char* getIdent () const {return m_ident.c_str(); }
|
||||||
const char* getName () const {return m_name.c_str(); }
|
const char* getName () const {return m_name.c_str(); }
|
||||||
const std::string& getMusic () const;
|
const std::string& getMusic () const;
|
||||||
const std::string& getFilename () const {return m_filename; }
|
const std::string& getFilename () const {return m_filename; }
|
||||||
const sgVec3& getSunPos () const {return m_sun_position; }
|
const sgVec3& getSunPos () const {return m_sun_position; }
|
||||||
const sgVec4& getAmbientCol () const {return m_ambient_col; }
|
const sgVec4& getAmbientCol () const {return m_ambient_col; }
|
||||||
const sgVec4& getDiffuseCol () const {return m_diffuse_col; }
|
const sgVec4& getDiffuseCol () const {return m_diffuse_col; }
|
||||||
const sgVec4& getSpecularCol () const {return m_specular_col; }
|
const sgVec4& getSpecularCol () const {return m_specular_col; }
|
||||||
const bool& useFog () const {return m_use_fog; }
|
const bool& useFog () const {return m_use_fog; }
|
||||||
const sgVec4& getFogColor () const {return m_fog_color; }
|
const sgVec4& getFogColor () const {return m_fog_color; }
|
||||||
const float& getFogDensity () const {return m_fog_density; }
|
const float& getFogDensity () const {return m_fog_density; }
|
||||||
const float& getFogStart () const {return m_fog_start; }
|
const float& getFogStart () const {return m_fog_start; }
|
||||||
const float& getFogEnd () const {return m_fog_end; }
|
const float& getFogEnd () const {return m_fog_end; }
|
||||||
const sgVec4& getSkyColor () const {return m_sky_color; }
|
const sgVec4& getSkyColor () const {return m_sky_color; }
|
||||||
const std::string& getDescription () const {return m_description; }
|
const std::string& getDescription () const {return m_description; }
|
||||||
const std::string& getTopviewFile () const {return m_top_view; }
|
const std::string& getTopviewFile () const {return m_top_view; }
|
||||||
const std::string& getScreenshotFile() const {return m_screenshot; }
|
const std::string& getScreenshotFile() const {return m_screenshot; }
|
||||||
const std::vector<sgVec3Wrapper>& getDriveline () const {return m_driveline;}
|
const std::vector<sgVec3Wrapper>& getDriveline () const {return m_driveline;}
|
||||||
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 createHash (ssgEntity* track_branch, unsigned int n);
|
|
||||||
void getStartCoords (unsigned int pos, sgCoord* coords) const;
|
void getStartCoords (unsigned int pos, sgCoord* coords) const;
|
||||||
int Collision(sgSphere* s, AllHits *a) const
|
static const Material* getMaterial (unsigned int n) {return m_triangleIndex2Material[n];}
|
||||||
{return m_static_ssg->collision(s,a); }
|
void createPhysicsModel ();
|
||||||
float GetHOT(sgVec3 start, sgVec3 end,
|
|
||||||
ssgLeaf** l, sgVec4** nrm) const
|
|
||||||
{return m_static_ssg->hot(start, end, l, nrm);}
|
|
||||||
void glVtx (sgVec2 v, float x_offset, float y_offset) const
|
void glVtx (sgVec2 v, float x_offset, float y_offset) const
|
||||||
{
|
{
|
||||||
glVertex2f(
|
glVertex2f(
|
||||||
@ -191,9 +192,12 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void loadTrack (std::string filename);
|
void loadTrack (std::string filename);
|
||||||
|
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,
|
||||||
|
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;
|
||||||
|
235
src/world.cpp
235
src/world.cpp
@ -37,7 +37,6 @@
|
|||||||
#include "loader.hpp"
|
#include "loader.hpp"
|
||||||
#include "player_kart.hpp"
|
#include "player_kart.hpp"
|
||||||
#include "auto_kart.hpp"
|
#include "auto_kart.hpp"
|
||||||
#include "isect.hpp"
|
|
||||||
#include "track.hpp"
|
#include "track.hpp"
|
||||||
#include "kart_properties_manager.hpp"
|
#include "kart_properties_manager.hpp"
|
||||||
#include "track_manager.hpp"
|
#include "track_manager.hpp"
|
||||||
@ -47,7 +46,6 @@
|
|||||||
#include "history.hpp"
|
#include "history.hpp"
|
||||||
#include "constants.hpp"
|
#include "constants.hpp"
|
||||||
#include "sound_manager.hpp"
|
#include "sound_manager.hpp"
|
||||||
#include "ssg_help.hpp"
|
|
||||||
#include "translation.hpp"
|
#include "translation.hpp"
|
||||||
#include "highscore_manager.hpp"
|
#include "highscore_manager.hpp"
|
||||||
#include "scene.hpp"
|
#include "scene.hpp"
|
||||||
@ -93,10 +91,6 @@ World::World(const RaceSetup& raceSetup_) : m_race_setup(raceSetup_)
|
|||||||
throw std::runtime_error(msg);
|
throw std::runtime_error(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start building the scene graph
|
|
||||||
m_track_branch = new ssgBranch ;
|
|
||||||
scene->add ( m_track_branch ) ;
|
|
||||||
|
|
||||||
// Create the physics
|
// Create the physics
|
||||||
m_physics = new Physics(getGravity());
|
m_physics = new Physics(getGravity());
|
||||||
|
|
||||||
@ -104,9 +98,7 @@ World::World(const RaceSetup& raceSetup_) : m_race_setup(raceSetup_)
|
|||||||
|
|
||||||
// Load the track models - this must be done before the karts so that the
|
// Load the track models - this must be done before the karts so that the
|
||||||
// karts can be positioned properly on (and not in) the tracks.
|
// karts can be positioned properly on (and not in) the tracks.
|
||||||
loadTrack ( ) ;
|
loadTrack() ;
|
||||||
|
|
||||||
m_track->createHash(m_track_branch, 1000);
|
|
||||||
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
int playerIndex = 0;
|
int playerIndex = 0;
|
||||||
@ -164,7 +156,7 @@ World::World(const RaceSetup& raceSetup_) : m_race_setup(raceSetup_)
|
|||||||
? Highscores::HST_TIMETRIAL_OVERALL_TIME
|
? Highscores::HST_TIMETRIAL_OVERALL_TIME
|
||||||
: Highscores::HST_RACE_OVERALL_TIME;
|
: Highscores::HST_RACE_OVERALL_TIME;
|
||||||
|
|
||||||
m_highscores = highscore_manager->getHighscores(hst, m_kart.size(),
|
m_highscores = highscore_manager->getHighscores(hst, (int)m_kart.size(),
|
||||||
m_race_setup.m_difficulty,
|
m_race_setup.m_difficulty,
|
||||||
m_track->getName(),
|
m_track->getName(),
|
||||||
m_race_setup.m_num_laps);
|
m_race_setup.m_num_laps);
|
||||||
@ -205,7 +197,7 @@ World::~World()
|
|||||||
#ifdef HAVE_GHOST_REPLAY
|
#ifdef HAVE_GHOST_REPLAY
|
||||||
saveReplayHumanReadable( "test" );
|
saveReplayHumanReadable( "test" );
|
||||||
#endif
|
#endif
|
||||||
|
m_track->cleanup();
|
||||||
// Clear all callbacks
|
// Clear all callbacks
|
||||||
callback_manager->clear(CB_TRACK);
|
callback_manager->clear(CB_TRACK);
|
||||||
|
|
||||||
@ -275,16 +267,16 @@ void World::draw()
|
|||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void World::update(float delta)
|
void World::update(float dt)
|
||||||
{
|
{
|
||||||
if(user_config->m_replay_history) delta=history->GetNextDelta();
|
if(user_config->m_replay_history) dt=history->GetNextDelta();
|
||||||
|
|
||||||
checkRaceStatus();
|
checkRaceStatus();
|
||||||
// this line was before checkRaceStatus. but m_clock is set to 0.0 in
|
// this line was before checkRaceStatus. but m_clock is set to 0.0 in
|
||||||
// checkRaceStatus on start, so m_clock would not be synchron and the
|
// checkRaceStatus on start, so m_clock would not be synchron and the
|
||||||
// first delta would not be added .. that would cause a gap in
|
// first delta would not be added .. that would cause a gap in
|
||||||
// replay-recording
|
// replay-recording
|
||||||
m_clock += delta;
|
m_clock += dt;
|
||||||
|
|
||||||
// Count the number of collision in the next 'FRAMES_FOR_TRAFFIC_JAM' frames.
|
// Count the number of collision in the next 'FRAMES_FOR_TRAFFIC_JAM' frames.
|
||||||
// If a kart has more than one hit, play 'traffic jam' noise.
|
// If a kart has more than one hit, play 'traffic jam' noise.
|
||||||
@ -311,8 +303,8 @@ void World::update(float delta)
|
|||||||
|
|
||||||
// Don't record the time for the last kart, since it didn't finish
|
// Don't record the time for the last kart, since it didn't finish
|
||||||
// the race - unless it's timetrial (then there is only one kart)
|
// the race - unless it's timetrial (then there is only one kart)
|
||||||
unsigned int karts_to_enter = (m_race_setup.m_mode==RaceSetup::RM_TIME_TRIAL)
|
unsigned int karts_to_enter = (m_race_setup.m_mode==RaceSetup::RM_TIME_TRIAL)
|
||||||
? m_kart.size() : m_kart.size()-1;
|
? (unsigned int)m_kart.size() : (unsigned int)m_kart.size()-1;
|
||||||
for(unsigned int pos=0; pos<karts_to_enter; pos++)
|
for(unsigned int pos=0; pos<karts_to_enter; pos++)
|
||||||
{
|
{
|
||||||
// Only record times for player karts
|
// Only record times for player karts
|
||||||
@ -323,7 +315,7 @@ void World::update(float delta)
|
|||||||
Highscores::HighscoreType hst = (m_race_setup.m_mode==RaceSetup::RM_TIME_TRIAL)
|
Highscores::HighscoreType hst = (m_race_setup.m_mode==RaceSetup::RM_TIME_TRIAL)
|
||||||
? Highscores::HST_TIMETRIAL_OVERALL_TIME
|
? Highscores::HST_TIMETRIAL_OVERALL_TIME
|
||||||
: Highscores::HST_RACE_OVERALL_TIME;
|
: Highscores::HST_RACE_OVERALL_TIME;
|
||||||
if(m_highscores->addData(hst, m_kart.size(),
|
if(m_highscores->addData(hst, (int)m_kart.size(),
|
||||||
m_race_setup.m_difficulty,
|
m_race_setup.m_difficulty,
|
||||||
m_track->getName(),
|
m_track->getName(),
|
||||||
k->getName(),
|
k->getName(),
|
||||||
@ -338,35 +330,15 @@ void World::update(float delta)
|
|||||||
pause();
|
pause();
|
||||||
menu_manager->pushMenu(MENUID_RACERESULT);
|
menu_manager->pushMenu(MENUID_RACERESULT);
|
||||||
}
|
}
|
||||||
|
if(!user_config->m_replay_history) history->StoreDelta(dt);
|
||||||
float inc = 0.05f;
|
m_physics->update(dt);
|
||||||
float dt = delta;
|
for ( Karts::size_type i = 0 ; i < m_kart.size(); ++i)
|
||||||
while (dt>0.0)
|
|
||||||
{
|
{
|
||||||
if(dt>=inc)
|
m_kart[i]->update(dt) ;
|
||||||
{
|
}
|
||||||
dt-=inc;
|
|
||||||
if(user_config->m_replay_history) delta=history->GetNextDelta();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
inc=dt;
|
|
||||||
dt=0.0;
|
|
||||||
}
|
|
||||||
// The same delta is stored over and over again! This helps to use
|
|
||||||
// the same index in History:allDeltas, and the history* arrays here,
|
|
||||||
// and makes writing easier, since we had to write delta the first
|
|
||||||
// time, and then inc from then on.
|
|
||||||
if(!user_config->m_replay_history) history->StoreDelta(delta);
|
|
||||||
m_physics->update(inc);
|
|
||||||
for ( Karts::size_type i = 0 ; i < m_kart.size(); ++i)
|
|
||||||
{
|
|
||||||
m_kart[i]->update(inc) ;
|
|
||||||
}
|
|
||||||
} // while dt>0
|
|
||||||
|
|
||||||
projectile_manager->update(delta);
|
projectile_manager->update(dt);
|
||||||
herring_manager->update(delta);
|
herring_manager->update(dt);
|
||||||
|
|
||||||
for ( Karts::size_type i = 0 ; i < m_kart.size(); ++i)
|
for ( Karts::size_type i = 0 ; i < m_kart.size(); ++i)
|
||||||
{
|
{
|
||||||
@ -375,7 +347,7 @@ void World::update(float delta)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Routine stuff we do even when paused */
|
/* Routine stuff we do even when paused */
|
||||||
callback_manager->update(delta);
|
callback_manager->update(dt);
|
||||||
|
|
||||||
// Check for traffic jam. The sound is played even if it's
|
// Check for traffic jam. The sound is played even if it's
|
||||||
// not a player kart - a traffic jam happens rarely anyway.
|
// not a player kart - a traffic jam happens rarely anyway.
|
||||||
@ -621,23 +593,6 @@ void World::updateRacePosition ( int k )
|
|||||||
m_kart [ k ] -> setPosition ( p ) ;
|
m_kart [ k ] -> setPosition ( p ) ;
|
||||||
} // updateRacePosition
|
} // updateRacePosition
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void World::herring_command (sgVec3 *xyz, char htype, int bNeedHeight )
|
|
||||||
{
|
|
||||||
|
|
||||||
// if only 2d coordinates are given, let the herring fall from very heigh
|
|
||||||
if(bNeedHeight) (*xyz)[2] = 1000000.0f;
|
|
||||||
|
|
||||||
// Even if 3d data are given, make sure that the herring is on the ground
|
|
||||||
(*xyz)[2] = getHeight ( m_track_branch, *xyz ) + 0.06f;
|
|
||||||
herringType type=HE_GREEN;
|
|
||||||
if ( htype=='Y' || htype=='y' ) { type = HE_GOLD ;}
|
|
||||||
if ( htype=='G' || htype=='g' ) { type = HE_GREEN ;}
|
|
||||||
if ( htype=='R' || htype=='r' ) { type = HE_RED ;}
|
|
||||||
if ( htype=='S' || htype=='s' ) { type = HE_SILVER ;}
|
|
||||||
herring_manager->newHerring(type, xyz);
|
|
||||||
} // herring_command
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void World::loadTrack()
|
void World::loadTrack()
|
||||||
@ -680,161 +635,7 @@ void World::loadTrack()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *fd = fopen (path.c_str(), "r" );
|
m_track->loadTrackModel();
|
||||||
if ( fd == NULL )
|
|
||||||
{
|
|
||||||
char msg[MAX_ERROR_MESSAGE_LENGTH];
|
|
||||||
snprintf(msg, sizeof(msg),"Can't open track location file '%s'.\n",
|
|
||||||
path.c_str());
|
|
||||||
throw std::runtime_error(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
char s [ 1024 ] ;
|
|
||||||
|
|
||||||
while ( fgets ( s, 1023, fd ) != NULL )
|
|
||||||
{
|
|
||||||
if ( *s == '#' || *s < ' ' )
|
|
||||||
continue ;
|
|
||||||
|
|
||||||
int need_hat = false ;
|
|
||||||
int fit_skin = false ;
|
|
||||||
char fname [ 1024 ] ;
|
|
||||||
sgCoord loc ;
|
|
||||||
sgZeroVec3 ( loc.xyz ) ;
|
|
||||||
sgZeroVec3 ( loc.hpr ) ;
|
|
||||||
|
|
||||||
char htype = '\0' ;
|
|
||||||
|
|
||||||
if ( sscanf ( s, "%cHERRING,%f,%f,%f", &htype,
|
|
||||||
&(loc.xyz[0]), &(loc.xyz[1]), &(loc.xyz[2]) ) == 4 )
|
|
||||||
{
|
|
||||||
herring_command(&loc.xyz, htype, false) ;
|
|
||||||
}
|
|
||||||
else if ( sscanf ( s, "%cHERRING,%f,%f", &htype,
|
|
||||||
&(loc.xyz[0]), &(loc.xyz[1]) ) == 3 )
|
|
||||||
{
|
|
||||||
herring_command (&loc.xyz, htype, true) ;
|
|
||||||
}
|
|
||||||
else if ( s[0] == '\"' )
|
|
||||||
{
|
|
||||||
if ( sscanf ( s, "\"%[^\"]\",%f,%f,%f,%f,%f,%f",
|
|
||||||
fname, &(loc.xyz[0]), &(loc.xyz[1]), &(loc.xyz[2]),
|
|
||||||
&(loc.hpr[0]), &(loc.hpr[1]), &(loc.hpr[2]) ) == 7 )
|
|
||||||
{
|
|
||||||
/* All 6 DOF specified */
|
|
||||||
need_hat = false;
|
|
||||||
}
|
|
||||||
else if ( sscanf ( s, "\"%[^\"]\",%f,%f,{},%f,%f,%f",
|
|
||||||
fname, &(loc.xyz[0]), &(loc.xyz[1]),
|
|
||||||
&(loc.hpr[0]), &(loc.hpr[1]), &(loc.hpr[2])) == 6 )
|
|
||||||
{
|
|
||||||
/* All 6 DOF specified - but need height */
|
|
||||||
need_hat = true ;
|
|
||||||
}
|
|
||||||
else if ( sscanf ( s, "\"%[^\"]\",%f,%f,%f,%f",
|
|
||||||
fname, &(loc.xyz[0]), &(loc.xyz[1]), &(loc.xyz[2]),
|
|
||||||
&(loc.hpr[0]) ) == 5 )
|
|
||||||
{
|
|
||||||
/* No Roll/Pitch specified - assumed zero */
|
|
||||||
need_hat = false ;
|
|
||||||
}
|
|
||||||
else if ( sscanf ( s, "\"%[^\"]\",%f,%f,{},%f,{},{}",
|
|
||||||
fname, &(loc.xyz[0]), &(loc.xyz[1]),
|
|
||||||
&(loc.hpr[0]) ) == 3 )
|
|
||||||
{
|
|
||||||
/* All 6 DOF specified - but need height, roll, pitch */
|
|
||||||
need_hat = true ;
|
|
||||||
fit_skin = true ;
|
|
||||||
}
|
|
||||||
else if ( sscanf ( s, "\"%[^\"]\",%f,%f,{},%f",
|
|
||||||
fname, &(loc.xyz[0]), &(loc.xyz[1]),
|
|
||||||
&(loc.hpr[0]) ) == 4 )
|
|
||||||
{
|
|
||||||
/* No Roll/Pitch specified - but need height */
|
|
||||||
need_hat = true ;
|
|
||||||
}
|
|
||||||
else if ( sscanf ( s, "\"%[^\"]\",%f,%f,%f",
|
|
||||||
fname, &(loc.xyz[0]), &(loc.xyz[1]),
|
|
||||||
&(loc.xyz[2]) ) == 4 )
|
|
||||||
{
|
|
||||||
/* No Heading/Roll/Pitch specified - but need height */
|
|
||||||
need_hat = false ;
|
|
||||||
}
|
|
||||||
else if ( sscanf ( s, "\"%[^\"]\",%f,%f,{}",
|
|
||||||
fname, &(loc.xyz[0]), &(loc.xyz[1]) ) == 3 )
|
|
||||||
{
|
|
||||||
/* No Roll/Pitch specified - but need height */
|
|
||||||
need_hat = true ;
|
|
||||||
}
|
|
||||||
else if ( sscanf ( s, "\"%[^\"]\",%f,%f",
|
|
||||||
fname, &(loc.xyz[0]), &(loc.xyz[1]) ) == 3 )
|
|
||||||
{
|
|
||||||
/* No Z/Heading/Roll/Pitch specified */
|
|
||||||
need_hat = false ;
|
|
||||||
}
|
|
||||||
else if ( sscanf ( s, "\"%[^\"]\"", fname ) == 1 )
|
|
||||||
{
|
|
||||||
/* Nothing specified */
|
|
||||||
need_hat = false ;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fclose(fd);
|
|
||||||
char msg[MAX_ERROR_MESSAGE_LENGTH];
|
|
||||||
snprintf(msg, sizeof(msg), "Syntax error in '%s': %s",
|
|
||||||
path.c_str(), s);
|
|
||||||
throw std::runtime_error(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( need_hat )
|
|
||||||
{
|
|
||||||
sgVec3 nrm ;
|
|
||||||
|
|
||||||
loc.xyz[2] = 1000.0f ;
|
|
||||||
loc.xyz[2] = getHeightAndNormal ( m_track_branch, loc.xyz, nrm ) ;
|
|
||||||
|
|
||||||
if ( fit_skin )
|
|
||||||
{
|
|
||||||
float sy = sin ( -loc.hpr [ 0 ] * SG_DEGREES_TO_RADIANS ) ;
|
|
||||||
float cy = cos ( -loc.hpr [ 0 ] * SG_DEGREES_TO_RADIANS ) ;
|
|
||||||
|
|
||||||
loc.hpr[2] = SG_RADIANS_TO_DEGREES * atan2 ( nrm[0] * cy -
|
|
||||||
nrm[1] * sy, nrm[2] ) ;
|
|
||||||
loc.hpr[1] = -SG_RADIANS_TO_DEGREES * atan2 ( nrm[1] * cy +
|
|
||||||
nrm[0] * sy, nrm[2] ) ;
|
|
||||||
}
|
|
||||||
} // if need_hat
|
|
||||||
|
|
||||||
ssgEntity *obj = loader->load(fname, CB_TRACK);
|
|
||||||
createDisplayLists(obj);
|
|
||||||
ssgRangeSelector *lod = new ssgRangeSelector ;
|
|
||||||
ssgTransform *trans = new ssgTransform ( & loc ) ;
|
|
||||||
|
|
||||||
float r [ 2 ] = { -10.0f, 2000.0f } ;
|
|
||||||
|
|
||||||
lod -> addKid ( obj ) ;
|
|
||||||
trans -> addKid ( lod ) ;
|
|
||||||
m_track_branch -> addKid ( trans ) ;
|
|
||||||
lod -> setRanges ( r, 2 ) ;
|
|
||||||
if(user_config->m_track_debug)
|
|
||||||
m_track->addDebugToScene(user_config->m_track_debug);
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// fclose(fd);
|
|
||||||
// char msg[MAX_ERROR_MESSAGE_LENGTH];
|
|
||||||
// snprintf(msg, sizeof(msg), "Syntax error in '%s': %s",
|
|
||||||
fprintf(stderr, "Warning: Syntax error in '%s': %s",
|
|
||||||
path.c_str(), s);
|
|
||||||
// throw std::runtime_error(msg);
|
|
||||||
}
|
|
||||||
} // while fgets
|
|
||||||
|
|
||||||
fclose ( fd ) ;
|
|
||||||
#ifdef BULLET
|
|
||||||
m_physics->setTrack(m_track_branch);
|
|
||||||
#endif
|
|
||||||
} // loadTrack
|
} // loadTrack
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -68,15 +68,13 @@ public:
|
|||||||
/** debug text that will be overlaid to the screen */
|
/** debug text that will be overlaid to the screen */
|
||||||
std::string m_debug_text[10];
|
std::string m_debug_text[10];
|
||||||
|
|
||||||
/** Reference to the track inside the scene */
|
|
||||||
ssgBranch *m_track_branch ;
|
|
||||||
|
|
||||||
|
|
||||||
World(const RaceSetup& raceSetup);
|
World(const RaceSetup& raceSetup);
|
||||||
virtual ~World();
|
virtual ~World();
|
||||||
|
#ifndef BULLET
|
||||||
float GetHOT(sgVec3 start, sgVec3 end, ssgLeaf** leaf, sgVec4** nrm)
|
float GetHOT(sgVec3 start, sgVec3 end, ssgLeaf** leaf, sgVec4** nrm)
|
||||||
{return m_track->GetHOT(start, end, leaf, nrm);}
|
{return m_track->GetHOT(start, end, leaf, nrm);}
|
||||||
int Collision(sgSphere* s, AllHits *a) const {return m_track->Collision(s,a); }
|
int Collision(sgSphere* s, AllHits *a) const {return m_track->Collision(s,a); }
|
||||||
|
#endif
|
||||||
void draw();
|
void draw();
|
||||||
void update(float delta);
|
void update(float delta);
|
||||||
void restartRace();
|
void restartRace();
|
||||||
@ -124,7 +122,6 @@ private:
|
|||||||
|
|
||||||
void updateRacePosition( int k );
|
void updateRacePosition( int k );
|
||||||
void loadTrack();
|
void loadTrack();
|
||||||
void herring_command(sgVec3* loc, char htype, int bNeedHeight);
|
|
||||||
void checkRaceStatus();
|
void checkRaceStatus();
|
||||||
void resetAllKarts();
|
void resetAllKarts();
|
||||||
Kart* loadRobot(const KartProperties *kart_properties, int position,
|
Kart* loadRobot(const KartProperties *kart_properties, int position,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user