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:
hikerstk 2007-12-12 14:07:26 +00:00
parent d8dac4e85b
commit d0c1aa9e8c
11 changed files with 453 additions and 412 deletions

View File

@ -394,7 +394,6 @@ void Kart::reset()
world->m_track->spatialToTrack( m_curr_track_coords, m_curr_pos.xyz,
m_track_sector );
#ifdef BULLET
btTransform trans;
trans.setIdentity();
// Set heading:
@ -414,7 +413,6 @@ void Kart::reset()
m_vehicle->updateWheelTransform(j, true);
}
#endif
placeModel();
} // reset
@ -711,20 +709,15 @@ void Kart::update (float dt)
{
// Let the kart raise 2m in the 2 seconds of the rescue
const float rescue_time = 2.0f;
#ifdef BULLET
const float rescue_height = 2.0f;
#endif
if(m_attachment.getType() != ATTACH_TINYTUX)
{
if(isPlayerKart()) sound_manager -> playSfx ( SOUND_BZZT );
m_attachment.set( ATTACH_TINYTUX, rescue_time ) ;
#ifdef BULLET
m_rescue_pitch = m_curr_pos.hpr[1];
m_rescue_roll = m_curr_pos.hpr[2];
world->getPhysics()->removeKart(this);
#endif
}
#ifdef BULLET
m_curr_pos.xyz[2] += rescue_height*dt/rescue_time;
btTransform pos=m_body->getCenterOfMassTransform();
@ -735,13 +728,8 @@ void Kart::update (float dt)
-m_rescue_pitch*dt/rescue_time*M_PI/180.0f);
pos.setRotation(pos.getRotation()*q_roll*q_pitch);
m_body->setCenterOfMassTransform(pos);
setTrans(pos);
//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
setTrans(pos);
//printf("Set %f %f %f\n",pos.getOrigin().x(),pos.getOrigin().y(),pos.getOrigin().z());
} // if m_rescue
m_attachment.update(dt, &m_velocity);
@ -1058,7 +1046,7 @@ void Kart::endRescue()
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_rescue = false ;
#ifdef BULLET
world->getPhysics()->addKart(this, m_vehicle);
m_body->setLinearVelocity (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();
pos.setOrigin(btVector3(m_curr_pos.xyz[0],m_curr_pos.xyz[1],
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);
setTrans(pos);
#endif
} // endRescue

View File

@ -60,20 +60,20 @@ public:
int matches ( char *tx ) ;
bool isIgnore () { return m_ignore ; }
bool isZipper () { return m_zipper ; }
bool isSphereMap () { return m_sphere_map ; }
bool isCrashable () { return m_collideable ; }
bool isReset () { return m_resetter ; }
float getFriction() { return m_friction ; }
ssgSimpleState
*getState () const { return m_state ; }
bool isIgnore () const { return m_ignore; }
bool isZipper () const { return m_zipper; }
bool isSphereMap () const { return m_sphere_map; }
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 ) ;
ssgSimpleState *getState () { return m_state ; }
int getIndex () { return m_index ; }
void apply () { m_state -> apply () ; }
char *getTexFname () const { return m_texname ; }
} ;

View File

@ -240,6 +240,7 @@ void Moveable::ReadHistory(char* s, int kartNumber, int indx)
#define max(m,n) ((m)>(n) ? (m) : (n)) /* return highest number */
#ifndef BULLET
//-----------------------------------------------------------------------------
float Moveable::collectIsectData ( sgVec3 start, sgVec3 end )
{
@ -371,3 +372,4 @@ float Moveable::getIsectData ( sgVec3 start, sgVec3 end )
return HOT ;
} // getIsectData
#endif

View File

@ -56,14 +56,13 @@ protected:
int m_crashed;
sgVec3 m_surface_avoidance_vector ;
int m_first_time ;
#ifndef BULLET
float collectIsectData ( sgVec3 start, sgVec3 end ) ;
#endif
sgCoord* m_history_velocity;
sgCoord* m_history_position;
#ifdef BULLET
btRigidBody* m_body;
btDefaultMotionState* m_motion_state;
#endif
public:
@ -94,8 +93,9 @@ public:
// there is a 'reset' material under the moveable --> karts need to be
// rescued, missiles should explode.
virtual void OutsideTrack (int isReset) {}
#ifndef BULLET
float getIsectData (sgVec3 start, sgVec3 end );
#endif
void WriteHistory (char* s, int kartNumber, int indx);
void ReadHistory (char* s, int kartNumber, int indx);
btRigidBody* getBody () const {return m_body; }

View File

@ -18,8 +18,6 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifdef BULLET
#include "bullet/Demos/OpenGL/GL_ShapeDrawer.h"
#include "physics.hpp"
@ -34,10 +32,22 @@
/** 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;
Physics::Physics(float gravity) : btSequentialImpulseConstraintSolver()
{
// Set the contact handler for friction computation (and reset triggering)
gContactAddedCallback = HandleTerrainFriction;
m_collision_conf = new btDefaultCollisionConfiguration();
m_dispatcher = new btCollisionDispatcher(m_collision_conf);
@ -68,90 +78,6 @@ 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
void Physics::addKart(const Kart *kart, btRaycastVehicle *vehicle)
@ -357,15 +283,26 @@ float Physics::getHAT(btVector3 pos)
{
btVector3 to_pos(pos);
to_pos.setZ(-100000.f);
btCollisionWorld::ClosestRayResultCallback
rayCallback(pos, to_pos);
btCollisionWorld::ClosestRayResultCallback rayCallback(pos, to_pos);
m_dynamics_world->rayTest(pos, to_pos, rayCallback);
if(!rayCallback.HasHit()) return NOHIT;
return pos.getZ()-rayCallback.m_hitPointWorld.getZ();
} // 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)
{
btVector3 to_pos(pos);
@ -380,6 +317,36 @@ bool Physics::getTerrainNormal(btVector3 pos, btVector3* normal)
return true;
} // 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()
@ -415,6 +382,5 @@ void Physics::debugDraw(float m[16], btCollisionShape *s, const btVector3 color)
} // debugDraw
// -----------------------------------------------------------------------------
#endif
/* EOF */

View File

@ -85,7 +85,6 @@ private:
void KartKartCollision(Kart *ka, Kart *kb);
public:
void convertTrack (ssgEntity *track, sgMat4 m, btTriangleMesh* track_mesh);
Physics (float gravity);
~Physics ();
void addKart (const Kart *k, btRaycastVehicle *v);
@ -94,12 +93,12 @@ public:
void removeBody (btRigidBody* b) {m_dynamics_world->removeRigidBody(b);}
void update (float dt);
void draw ();
void setTrack (ssgEntity *track);
btDynamicsWorld*
getPhysicsWorld () const {return m_dynamics_world;}
void debugDraw (float m[16], btCollisionShape *s, const btVector3 color);
static const float NOHIT;
float getHAT (btVector3 pos);
float getHOT (btVector3 pos);
bool getTerrainNormal(btVector3 pos, btVector3* normal);
virtual btScalar solveGroup(btCollisionObject** bodies, int numBodies,
btPersistentManifold** manifold,int numManifolds,

View File

@ -56,22 +56,22 @@ void PlayerKart::action(KartAction action, int value)
case KA_BRAKE:
if (value)
m_accel_val = 0;
m_controls.brake = value;
m_controls.brake = (value!=0); // This syntax avoid visual c++ warning (when brake=value)
break;
case KA_WHEELIE:
m_controls.wheelie = value;
m_controls.wheelie = (value!=0);
break;
case KA_RESCUE:
m_controls.rescue = value;
m_controls.rescue = (value!=0);
break;
case KA_FIRE:
m_controls.fire = value;
m_controls.fire = (value!=0);
break;
case KA_LOOK_BACK:
m_camera->setReverseHeading(value);
m_camera->setReverseHeading(value!=0);
break;
case KA_JUMP:
m_controls.jump = value;
m_controls.jump = (value!=0);
break;
}
}

View File

@ -29,10 +29,21 @@
#include "stk_config.hpp"
#include "translation.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__)
# define snprintf _snprintf
#endif
std::vector<const Material*>Track::m_triangleIndex2Material;
// ----------------------------------------------------------------------------
Track::Track( std::string filename_, float w, float h, bool stretch )
{
m_filename = filename_;
@ -53,6 +64,15 @@ Track::Track( std::string filename_, float w, float h, bool stretch )
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.
@ -122,27 +142,27 @@ void Track::findRoadSector( const sgVec3 XYZ, int *sector )const
that forms each track segment.
*/
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 next;
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],
m_right_driveline[next], m_left_driveline[next],
XYZ );
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
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 )
{
//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 )
{
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 )
{
@ -242,7 +262,7 @@ int Track::findOutOfRoadSector
int sector = UNKNOWN_SECTOR;
float dist;
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 end_sector = DRIVELINE_SIZE - 1;
@ -324,7 +344,7 @@ int Track::spatialToTrack
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 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]);
dst[2] = m_path_width[p1]*(1-fraction)+fraction*m_path_width[p2];
return p1;
return (int)p1;
} // spatialToTrack
//-----------------------------------------------------------------------------
@ -370,11 +390,6 @@ void Track::trackToSpatial ( sgVec3 xyz, const int SECTOR ) const
sgCopyVec3 ( xyz, m_driveline [ SECTOR ] ) ;
} // 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
(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
// lap! Therefor -1.5 is subtracted from the y position - which
// 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;
// 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;
@ -394,10 +409,8 @@ void Track::getStartCoords(unsigned int pos, sgCoord* coords) const {
coords->hpr[1] = 0.0f;
coords->hpr[2] = 0.0f;
ssgLeaf *leaf;
sgVec4* normal;
const float hot = m_static_ssg->hot(coords->xyz, coords->xyz, &leaf, &normal);
coords->xyz[2] = hot;
btVector3 tmp_pos(coords->xyz[0],coords->xyz[1],coords->xyz[2]);
coords->xyz[2] = world->getPhysics()->getHOT(tmp_pos);
} // getStartCoords
@ -413,8 +426,8 @@ bool Track::isShortcut(const int OLDSEC, const int NEWSEC) const
unsigned int distance_sectors = abs(OLDSEC-NEWSEC);
// Handle 'wrap around': if the distance is more than half the
// number of driveline poins, assume it's a 'wrap around'
if(2*distance_sectors > m_driveline.size())
distance_sectors = m_driveline.size() - distance_sectors;
if(2*distance_sectors > (unsigned int)m_driveline.size())
distance_sectors = (unsigned int)m_driveline.size() - distance_sectors;
return (distance_sectors>stk_config->m_shortcut_segments);
} // isShortcut
@ -507,7 +520,7 @@ void Track::drawScaled2D(float x, float y, float w, float h) const
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 );
@ -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
{
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 );
@ -757,12 +770,12 @@ void Track::loadTrack(std::string filename_)
m_fog_end = 1000.0f;
m_gravity = 9.80665f;
sgSetVec3 ( m_sun_position, 0.4f, 0.4f, 0.4f );
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_ambient_col , 0.5f, 0.5f, 0.5f, 1.0f );
sgSetVec3 ( m_sun_position, 0.4f, 0.4f, 0.4f );
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_ambient_col, 0.5f, 0.5f, 0.5f, 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;
const lisp::Lisp* const ROOT = parser.parse(loader->getPath(m_filename));
@ -815,7 +828,7 @@ Track::loadDriveline()
{
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);
readDrivelineFromFile(m_right_driveline, ".drvr");
@ -970,5 +983,276 @@ Track::readDrivelineFromFile(std::vector<sgVec3Wrapper>& line, const std::string
}
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

View File

@ -33,21 +33,24 @@
#include <plib/ssg.h>
#include <string>
#include <vector>
#include "static_ssg.hpp"
#include "btBulletDynamicsCommon.h"
#include "material.hpp"
class Track
{
private:
float m_gravity;
std::string m_ident;
std::string m_screenshot;
std::string m_top_view;
float m_gravity;
std::string m_ident;
std::string m_screenshot;
std::string m_top_view;
std::vector<std::string> m_music_filenames;
std::vector<float> m_start_x, m_start_y, m_start_z, m_start_heading;
std::string m_herring_style;
std::string m_description;
std::string m_filename;
StaticSSG* m_static_ssg;
std::string m_herring_style;
std::string m_description;
std::string m_filename;
ssgBranch* m_model;
btRigidBody* m_body;
static std::vector<const Material*> m_triangleIndex2Material;
public:
enum RoadSide{ RS_DONT_KNOW = -1, RS_LEFT = 0, RS_RIGHT = 1 };
@ -136,7 +139,7 @@ public:
Track (std::string filename,float w=100,
float h=100, bool stretch=1);
~Track ();
void cleanup ();
void addDebugToScene (int type ) const;
void draw2Dview (float x_offset,
float y_offset ) const;
@ -152,36 +155,34 @@ public:
const sgVec2 POS,
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;
float getGravity () const {return m_gravity; }
float getTrackLength () const {return m_total_distance;}
const char* getIdent () const {return m_ident.c_str(); }
const char* getName () const {return m_name.c_str(); }
float getGravity () const {return m_gravity; }
float getTrackLength () const {return m_total_distance; }
const char* getIdent () const {return m_ident.c_str(); }
const char* getName () const {return m_name.c_str(); }
const std::string& getMusic () const;
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& getDiffuseCol () const {return m_diffuse_col; }
const sgVec4& getSpecularCol () const {return m_specular_col; }
const bool& useFog () const {return m_use_fog; }
const sgVec4& getFogColor () const {return m_fog_color; }
const float& getFogDensity () const {return m_fog_density; }
const float& getFogStart () const {return m_fog_start; }
const float& getFogEnd () const {return m_fog_end; }
const sgVec4& getSkyColor () const {return m_sky_color; }
const std::string& getDescription () const {return m_description; }
const std::string& getTopviewFile () const {return m_top_view; }
const std::string& getScreenshotFile() const {return m_screenshot; }
const bool& useFog () const {return m_use_fog; }
const sgVec4& getFogColor () const {return m_fog_color; }
const float& getFogDensity () const {return m_fog_density; }
const float& getFogStart () const {return m_fog_start; }
const float& getFogEnd () const {return m_fog_end; }
const sgVec4& getSkyColor () const {return m_sky_color; }
const std::string& getDescription () const {return m_description; }
const std::string& getTopviewFile () const {return m_top_view; }
const std::string& getScreenshotFile() const {return m_screenshot; }
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; }
void createHash (ssgEntity* track_branch, unsigned int n);
void getStartCoords (unsigned int pos, sgCoord* coords) const;
int Collision(sgSphere* s, AllHits *a) const
{return m_static_ssg->collision(s,a); }
float GetHOT(sgVec3 start, sgVec3 end,
ssgLeaf** l, sgVec4** nrm) const
{return m_static_ssg->hot(start, end, l, nrm);}
static const Material* getMaterial (unsigned int n) {return m_triangleIndex2Material[n];}
void createPhysicsModel ();
void glVtx (sgVec2 v, float x_offset, float y_offset) const
{
glVertex2f(
@ -191,9 +192,12 @@ public:
private:
void loadTrack (std::string filename);
void herring_command (sgVec3 *xyz, char htype, int bNeedHeight);
void loadDriveline ();
void readDrivelineFromFile (std::vector<sgVec3Wrapper>& line,
const std::string& file_ext );
void convertTrackToBullet (ssgEntity *track, sgMat4 m,
btTriangleMesh* track_mesh);
float pointSideToLine( const sgVec2 L1, const sgVec2 L2,
const sgVec2 P ) const;

View File

@ -37,7 +37,6 @@
#include "loader.hpp"
#include "player_kart.hpp"
#include "auto_kart.hpp"
#include "isect.hpp"
#include "track.hpp"
#include "kart_properties_manager.hpp"
#include "track_manager.hpp"
@ -47,7 +46,6 @@
#include "history.hpp"
#include "constants.hpp"
#include "sound_manager.hpp"
#include "ssg_help.hpp"
#include "translation.hpp"
#include "highscore_manager.hpp"
#include "scene.hpp"
@ -93,10 +91,6 @@ World::World(const RaceSetup& raceSetup_) : m_race_setup(raceSetup_)
throw std::runtime_error(msg);
}
// Start building the scene graph
m_track_branch = new ssgBranch ;
scene->add ( m_track_branch ) ;
// Create the physics
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
// karts can be positioned properly on (and not in) the tracks.
loadTrack ( ) ;
m_track->createHash(m_track_branch, 1000);
loadTrack() ;
int pos = 0;
int playerIndex = 0;
@ -164,7 +156,7 @@ World::World(const RaceSetup& raceSetup_) : m_race_setup(raceSetup_)
? Highscores::HST_TIMETRIAL_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_track->getName(),
m_race_setup.m_num_laps);
@ -205,7 +197,7 @@ World::~World()
#ifdef HAVE_GHOST_REPLAY
saveReplayHumanReadable( "test" );
#endif
m_track->cleanup();
// Clear all callbacks
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();
// 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
// first delta would not be added .. that would cause a gap in
// replay-recording
m_clock += delta;
m_clock += dt;
// 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.
@ -311,8 +303,8 @@ void World::update(float delta)
// 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)
unsigned int karts_to_enter = (m_race_setup.m_mode==RaceSetup::RM_TIME_TRIAL)
? m_kart.size() : m_kart.size()-1;
unsigned int karts_to_enter = (m_race_setup.m_mode==RaceSetup::RM_TIME_TRIAL)
? (unsigned int)m_kart.size() : (unsigned int)m_kart.size()-1;
for(unsigned int pos=0; pos<karts_to_enter; pos++)
{
// 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::HST_TIMETRIAL_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_track->getName(),
k->getName(),
@ -338,35 +330,15 @@ void World::update(float delta)
pause();
menu_manager->pushMenu(MENUID_RACERESULT);
}
float inc = 0.05f;
float dt = delta;
while (dt>0.0)
if(!user_config->m_replay_history) history->StoreDelta(dt);
m_physics->update(dt);
for ( Karts::size_type i = 0 ; i < m_kart.size(); ++i)
{
if(dt>=inc)
{
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
m_kart[i]->update(dt) ;
}
projectile_manager->update(delta);
herring_manager->update(delta);
projectile_manager->update(dt);
herring_manager->update(dt);
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 */
callback_manager->update(delta);
callback_manager->update(dt);
// Check for traffic jam. The sound is played even if it's
// not a player kart - a traffic jam happens rarely anyway.
@ -621,23 +593,6 @@ void World::updateRacePosition ( int k )
m_kart [ k ] -> setPosition ( p ) ;
} // 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()
@ -680,161 +635,7 @@ void World::loadTrack()
}
}
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);
}
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
m_track->loadTrackModel();
} // loadTrack
//-----------------------------------------------------------------------------

View File

@ -68,15 +68,13 @@ public:
/** debug text that will be overlaid to the screen */
std::string m_debug_text[10];
/** Reference to the track inside the scene */
ssgBranch *m_track_branch ;
World(const RaceSetup& raceSetup);
virtual ~World();
#ifndef BULLET
float GetHOT(sgVec3 start, sgVec3 end, ssgLeaf** leaf, sgVec4** nrm)
{return m_track->GetHOT(start, end, leaf, nrm);}
int Collision(sgSphere* s, AllHits *a) const {return m_track->Collision(s,a); }
#endif
void draw();
void update(float delta);
void restartRace();
@ -124,7 +122,6 @@ private:
void updateRacePosition( int k );
void loadTrack();
void herring_command(sgVec3* loc, char htype, int bNeedHeight);
void checkRaceStatus();
void resetAllKarts();
Kart* loadRobot(const KartProperties *kart_properties, int position,