diff --git a/src/kart.cpp b/src/kart.cpp index ff42ac1fd..592883d36 100644 --- a/src/kart.cpp +++ b/src/kart.cpp @@ -585,6 +585,16 @@ float Kart::getActualWheelForce() } // getActualWheelForce #endif +//----------------------------------------------------------------------------- +#ifdef BULLET +bool Kart::isOnGround() +{ + return m_vehicle->getWheelInfo(0).m_raycastInfo.m_isInContact && + m_vehicle->getWheelInfo(1).m_raycastInfo.m_isInContact && + m_vehicle->getWheelInfo(2).m_raycastInfo.m_isInContact && + m_vehicle->getWheelInfo(3).m_raycastInfo.m_isInContact; +} // isOnGround +#endif //----------------------------------------------------------------------------- void Kart::handleExplosion(const sgVec3& pos, bool direct_hit) { @@ -740,7 +750,7 @@ void Kart::update (float dt) updatePhysics(dt); sgCopyVec2 ( m_last_track_coords, m_curr_track_coords ); - if(m_material_hot && m_on_ground) + if(m_material_hot && isOnGround()) { float r=m_material_hot->getFriction(); if(rapplyEngineForce(-m_controls.brake*engine_power, 2); - m_vehicle->applyEngineForce(-m_controls.brake*engine_power, 3); + m_vehicle->applyEngineForce(-engine_power*m_controls.brake, 2); + m_vehicle->applyEngineForce(-engine_power*m_controls.brake, 3); } else { @@ -961,7 +971,7 @@ void Kart::updatePhysics (float dt) } } - if(m_controls.jump) + if(isOnGround() && m_controls.jump) { //Vector3 impulse(0.0f, 0.0f, 10.0f); // getVehicle()->getRigidBody()->applyCentralImpulse(impulse); @@ -1299,7 +1309,7 @@ void Kart::processSkidMarks() if(m_skid_rear || m_skid_front) { - if(m_on_ground) + if(isOnGround()) { const float LENGTH = 0.57f; if(m_skidmark_left) diff --git a/src/kart.hpp b/src/kart.hpp index f6a8c3b8e..73e493e54 100644 --- a/src/kart.hpp +++ b/src/kart.hpp @@ -242,6 +242,7 @@ public: float getSpeed () const {return m_speed; } float handleWheelie(float dt); float getActualWheelForce(); + bool isOnGround (); #endif void adjustSpeedWeight(float f); void forceRescue (); diff --git a/src/moveable.cpp b/src/moveable.cpp index ed281c72b..73aa4fde9 100644 --- a/src/moveable.cpp +++ b/src/moveable.cpp @@ -70,7 +70,9 @@ Moveable::~Moveable() //----------------------------------------------------------------------------- void Moveable::reset () { +#ifndef BULLET m_on_ground = true; +#endif m_collided = false; m_crashed = false; m_material_hot = NULL; @@ -176,16 +178,7 @@ void Moveable::update (float dt) } // if m_history_position const float HAT = m_curr_pos.xyz[2]-HOT; -#ifdef BULLET - m_on_ground = ( HAT <= 1.5 ); - // FIXME: we need a correct test here, HOT/HAT are currently not defined - // for bullet (and would require a separate raycast, which can be - // expensive. Perhaps add a function to bullet to indicate if - // all/some/?? wheels toucht the ground. - // m_on_ground is currently only used (in the bullet version) for - // the gui display anyway - -#else +#ifndef BULLET m_on_ground = ( HAT <= 0.01 ); doCollisionAnalysis(dt, HOT); #endif diff --git a/src/moveable.hpp b/src/moveable.hpp index 30d0d3924..14cf7b314 100644 --- a/src/moveable.hpp +++ b/src/moveable.hpp @@ -56,7 +56,9 @@ protected: int m_crashed; sgVec3 m_surface_avoidance_vector ; int m_first_time ; +#ifndef BULLET int m_on_ground ; +#endif float collectIsectData ( sgVec3 start, sgVec3 end ) ; sgCoord* m_history_velocity; @@ -75,7 +77,9 @@ public: virtual ~Moveable(); ssgTransform* getModel () {return m_model ; } +#ifndef BULLET int isOnGround () {return m_on_ground; } +#endif MoveableType getMoveableType() const {return m_moveable_type; } void setMoveableType(MoveableType m){m_moveable_type=m; } sgCoord* getVelocity () {return & m_velocity; } diff --git a/src/physics.cpp b/src/physics.cpp index fb2f84a1e..c72f7db17 100644 --- a/src/physics.cpp +++ b/src/physics.cpp @@ -30,6 +30,7 @@ #include "moving_physics.hpp" #include "user_config.hpp" #include "sound_manager.hpp" +#include "material_manager.hpp" /** Initialise physics. */ @@ -38,17 +39,18 @@ float Physics::NOHIT=-99999.9f; Physics::Physics(float gravity) { - btDefaultCollisionConfiguration* collisionConf - = new btDefaultCollisionConfiguration(); - m_dispatcher = new btCollisionDispatcher(collisionConf); + m_collision_conf = new btDefaultCollisionConfiguration(); + m_dispatcher = new btCollisionDispatcher(m_collision_conf); btVector3 worldMin(-1000, -1000, -1000); btVector3 worldMax( 1000, 1000, 1000); - btBroadphaseInterface *axis_sweep = new btAxisSweep3(worldMin, worldMax); + m_axis_sweep = new btAxisSweep3(worldMin, worldMax); - btConstraintSolver *constraintSolver = new btSequentialImpulseConstraintSolver(); - m_dynamics_world = new btDiscreteDynamicsWorld(m_dispatcher, axis_sweep, - constraintSolver, collisionConf); + m_constraint_solver = new btSequentialImpulseConstraintSolver(); + m_dynamics_world = new btDiscreteDynamicsWorld(m_dispatcher, + m_axis_sweep, + m_constraint_solver, + m_collision_conf); m_dynamics_world->setGravity(btVector3(0.0f, 0.0f, -gravity)); if(user_config->m_bullet_debug) { @@ -63,6 +65,11 @@ Physics::~Physics() { delete m_dispatcher; delete m_dynamics_world; + delete m_axis_sweep; + delete m_collision_conf; + delete m_constraint_solver; + if(user_config->m_bullet_debug) delete m_debug_drawer; + } // ~Physics // ----------------------------------------------------------------------------- @@ -103,7 +110,11 @@ void Physics::convertTrack(ssgEntity *track, sgMat4 m, btTriangleMesh* track_mes } else if(track->isAKindOf(ssgTypeLeaf())) { - ssgLeaf *leaf = (ssgLeaf*)(track); + 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; igetNumTriangles(); i++) { short v1,v2,v3; @@ -280,7 +291,7 @@ void Physics::handleCollisions() { } // handleCollisions // ----------------------------------------------------------------------------- -float Physics::getHOT(btVector3 pos) +float Physics::getHAT(btVector3 pos) { btVector3 to_pos(pos); to_pos.setZ(-100000.f); @@ -289,7 +300,7 @@ float Physics::getHOT(btVector3 pos) m_dynamics_world->rayTest(pos, to_pos, rayCallback); if(!rayCallback.HasHit()) return NOHIT; - return 1.0f; + return rayCallback.m_hitPointWorld.getZ() - pos.getZ(); } // getHOT // ----------------------------------------------------------------------------- bool Physics::getTerrainNormal(btVector3 pos, btVector3* normal) diff --git a/src/physics.hpp b/src/physics.hpp index 3311b8b53..c31a2fe17 100644 --- a/src/physics.hpp +++ b/src/physics.hpp @@ -29,10 +29,13 @@ class Physics { protected: - btDynamicsWorld *m_dynamics_world; - Kart *m_kart; - GLDebugDrawer *m_debug_drawer; - btCollisionDispatcher *m_dispatcher; + btDynamicsWorld *m_dynamics_world; + Kart *m_kart; + GLDebugDrawer *m_debug_drawer; + btCollisionDispatcher *m_dispatcher; + btBroadphaseInterface *m_axis_sweep; + btDefaultCollisionConfiguration *m_collision_conf; + btConstraintSolver *m_constraint_solver; void convertTrack(ssgEntity *track, sgMat4 m, btTriangleMesh* track_mesh); public: @@ -50,7 +53,7 @@ public: getPhysicsWorld () const {return m_dynamics_world;} void debugDraw (float m[16], btCollisionShape *s, const btVector3 color); static float NOHIT; - float getHOT (btVector3 pos); + float getHAT (btVector3 pos); bool getTerrainNormal(btVector3 pos, btVector3* normal); }; // For non-bullet version: empty object diff --git a/src/player_kart.cpp b/src/player_kart.cpp index 3a6dcd91f..be445cd7f 100644 --- a/src/player_kart.cpp +++ b/src/player_kart.cpp @@ -147,7 +147,7 @@ void PlayerKart::update(float dt) m_collectable.use() ; m_controls.fire = false; } - if ( m_on_ground && m_controls.rescue ) + if ( isOnGround() && m_controls.rescue ) { sound_manager -> playSfx ( SOUND_BEEP ) ; forceRescue(); diff --git a/src/projectile.cpp b/src/projectile.cpp index 9cda4be94..1193532cb 100644 --- a/src/projectile.cpp +++ b/src/projectile.cpp @@ -112,6 +112,7 @@ void Projectile::init(Kart *kart, int collectable_) // terrain is under the rocket). Once hot is done with bullet as // well, this shouldn't be necessary anymore. placeModel(); + m_current_HAT = world->getHAT(offset.getOrigin()); #else sgCoord c; @@ -146,7 +147,13 @@ void Projectile::update (float dt) { #ifdef BULLET if(m_exploded) return; - m_body->setLinearVelocity(m_initial_velocity); + m_body->setLinearVelocity(m_initial_velocity); + m_HAT_counter++; + if(m_HAT_counter==10) + { + m_current_HAT = world->getHAT(getBody()->getCenterOfMassPosition()); + m_HAT_counter = 0; + } #else // we don't even do any physics here - just set the // velocity, and ignore everything else for projectiles. diff --git a/src/projectile.hpp b/src/projectile.hpp index 80c61c9d3..a102be214 100644 --- a/src/projectile.hpp +++ b/src/projectile.hpp @@ -35,7 +35,10 @@ class Projectile : public Moveable int m_last_radar_beep; #ifdef BULLET bool m_exploded; - btVector3 m_initial_velocity; + btVector3 m_initial_velocity; + float m_current_HAT; // height above terrain + int m_HAT_counter; // compute HAT only every N timesteps + #endif public: diff --git a/src/world.hpp b/src/world.hpp index ff35d3128..1da757690 100644 --- a/src/world.hpp +++ b/src/world.hpp @@ -101,6 +101,10 @@ public: Phase getPhase() const { return m_phase; } float getGravity() const { return m_track->getGravity(); } Physics *getPhysics() const { return m_physics; } + Track *getTrack() const { return m_track; } +#ifdef BULLET + float getHAT(btVector3 pos) const { return m_physics->getHAT(pos); } +#endif Kart* getFastestKart() const { return m_fastest_kart; } float getFastestLapTime() const { return m_fastest_lap; } void setFastestLap(Kart *k, float time) {m_fastest_kart=k;m_fastest_lap=time;}