diff --git a/data/homingmissile.projectile b/data/homingmissile.projectile index 823fc6964..8edd69f30 100644 --- a/data/homingmissile.projectile +++ b/data/homingmissile.projectile @@ -7,9 +7,9 @@ (speed 35.0) (min-height 0.2) (max-height 1.0) + (force-updown 25.0) ;; force raising/lowering the homing missile if it's too low/high (max-distance 20.0) ;; maximum distance at which a kart is still followed (max-turn-angle 5.0) ;; maximum turn angle when following a kart - (force-updown 25.0) ;; force raising/lowering the homing missile if it's too low/high ) ;; EOF ;; diff --git a/data/missile.projectile b/data/missile.projectile index bded8a74f..0efc52126 100644 --- a/data/missile.projectile +++ b/data/missile.projectile @@ -5,9 +5,9 @@ (model "missile.ac") (icon "missile.rgb") (speed 50.0) - (min-height 0.2) + (min-height 0.3) (max-height 1.0) - (force-updown 15.0) + (force-updown 20) ) ;; EOF ;; diff --git a/data/spark.projectile b/data/spark.projectile index f118ed6e4..ccaa0d649 100644 --- a/data/spark.projectile +++ b/data/spark.projectile @@ -7,9 +7,9 @@ (speed 5.0) (min-height 0.2) ; height above terrain below which a spark is ; started to be pulled up - (max-height 3.0) ; height above terrain at which a spark is + (max-height 1.0) ; height above terrain at which a spark is ; started to be pulled back to ground - (force-updown 20.0) ; force pushing the spark down + (force-updown 2.0) ; force pushing the spark down ; when it's too high above ground (force-to-target 20) ; force with which a spark flies towards ; the nearest kart diff --git a/src/flyable.cpp b/src/flyable.cpp index 9c4a236a8..85192f953 100644 --- a/src/flyable.cpp +++ b/src/flyable.cpp @@ -43,6 +43,7 @@ Flyable::Flyable(Kart *kart, CollectableType type) : Moveable(false) m_extend = m_st_extend[type]; m_max_height = m_st_max_height[type]; m_min_height = m_st_min_height[type]; + m_average_height = (m_min_height+m_max_height)/2.0f; m_force_updown = m_st_force_updown[type]; m_owner = kart; @@ -59,7 +60,7 @@ Flyable::Flyable(Kart *kart, CollectableType type) : Moveable(false) scene->add(m); } // Flyable // ---------------------------------------------------------------------------- -void Flyable::createPhysics(const btVector3& offset, const btVector3 velocity, +void Flyable::createPhysics(float y_offset, const btVector3 velocity, btCollisionShape *shape) { // The actual transform is determined as follows: @@ -85,6 +86,7 @@ void Flyable::createPhysics(const btVector3& offset, const btVector3 velocity, // Apply rotation and offset btTransform offset_transform; offset_transform.setIdentity(); + btVector3 offset=btVector3(0,y_offset,m_average_height); offset_transform.setOrigin(offset); trans *= offset_transform; @@ -179,15 +181,18 @@ void Flyable::update (float dt) } float hat = trans.getOrigin().getZ()-getHoT(); - if(hatm_max_height) - too_high(dt); - else - right_height(dt); + + // Use the Height Above Terrain to set the Z velocity. + // HAT is clamped by min/max height. This might be somewhat + // unphysical, but feels right in the game. + hat = std::max(std::min(hat, m_max_height) , m_min_height); + float delta = m_average_height - hat; + btVector3 v=getVelocity(); + v.setZ(m_force_updown*delta); + setVelocity(v); + Moveable::update(dt); } // update - // ----------------------------------------------------------------------------- void Flyable::placeModel() { diff --git a/src/flyable.hpp b/src/flyable.hpp index c801f83e5..9fba6d8c8 100644 --- a/src/flyable.hpp +++ b/src/flyable.hpp @@ -36,6 +36,7 @@ protected: btCollisionShape *m_shape; float m_max_height; float m_min_height; + float m_average_height; // average of m_{min,ax}_height float m_force_updown; float m_speed; float m_mass; @@ -53,17 +54,7 @@ protected: void getClosestKart(const Kart **minKart, float *minDist, btVector3 *minDelta) const; - virtual void too_low (float dt) - {m_body->applyCentralForce( - btVector3(0.0f, 0.0f, m_force_updown)); } - virtual void too_high(float dt) - {m_body->applyCentralForce( - btVector3(0.0f, 0.0f, -m_force_updown)); } - virtual void right_height(float dt) - {btVector3 v=m_body->getLinearVelocity(); - v.setZ(0.0f); - m_body->setLinearVelocity(v); } - void createPhysics(const btVector3& offset, + void createPhysics(float y_offset, const btVector3 velocity, btCollisionShape *shape); public: diff --git a/src/gui/race_gui.cpp b/src/gui/race_gui.cpp index 1fefeb3c3..ffc0c7e8a 100644 --- a/src/gui/race_gui.cpp +++ b/src/gui/race_gui.cpp @@ -243,7 +243,6 @@ void RaceGUI::drawFPS () //----------------------------------------------------------------------------- void RaceGUI::drawTimer () { - return; if(world->getPhase()!=World::RACE_PHASE && world->getPhase()!=World::DELAY_FINISH_PHASE ) return; char str[256]; diff --git a/src/homing.cpp b/src/homing.cpp index 60107b6f1..92844ec80 100644 --- a/src/homing.cpp +++ b/src/homing.cpp @@ -24,16 +24,20 @@ float Homing::m_st_max_distance; float Homing::m_st_max_turn_angle; // ----------------------------------------------------------------------------- +/** A homing missile is handled as a kinematic object, since this simplifies + * computation of turning (otherwise rotational forces would have to be + * applied). As a result, the mass must be zero, and linear velocity of the + * body can not be set (asserts in bullet). So this object implements its + * own setting/getting of velocity, to be able to use flyables functions. + */ Homing::Homing (Kart *kart) : Flyable(kart, COLLECT_HOMING) { m_mass = 0.0f; // a kinematik object must have mass=0, otherwise warnings // will be printed during bullet collision handling. - btVector3 offset(0.0f, - kart->getKartLength()+2.0f*m_extend.getY(), - 0.3f ); - // The cylinder needs to be rotated by 90 degrees to face in the right direction: + float y_offset=kart->getKartLength()+2.0f*m_extend.getY(); + m_initial_velocity = btVector3(0.0f, m_speed, 0.0f); - createPhysics(offset, m_initial_velocity, new btCylinderShape(0.5f*m_extend)); + createPhysics(y_offset, m_initial_velocity, new btCylinderShape(0.5f*m_extend)); m_body->setCollisionFlags(m_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT ); m_body->setActivationState(DISABLE_DEACTIVATION); diff --git a/src/homing.hpp b/src/homing.hpp index 1f6d5580e..e21df9411 100644 --- a/src/homing.hpp +++ b/src/homing.hpp @@ -30,16 +30,15 @@ private: btVector3 m_initial_velocity; float steerTowards(btTransform& trans, btVector3& target); -protected: - virtual void too_low (float dt) {m_initial_velocity.setZ(m_force_updown*dt);} - virtual void too_high(float dt) {m_initial_velocity.setZ(-m_force_updown*dt);} - virtual void right_height(float dt) {m_initial_velocity.setZ(0.0f); } - public: Homing (Kart *kart); static void init (const lisp::Lisp* lisp, ssgEntity* homing); virtual void update (float dt); - virtual void hitTrack () { explode(NULL); } + virtual void hitTrack () { explode(NULL); } + // Kinematic objects are not allowed to have a velocity (assertion in + // bullet), so we have to do our own velocity handling here + virtual const btVector3 &getVelocity() const {return m_initial_velocity;} + virtual void setVelocity(const btVector3& v) {m_initial_velocity=v; } }; // Homing diff --git a/src/missile.cpp b/src/missile.cpp index 433618c8a..31ba34325 100644 --- a/src/missile.cpp +++ b/src/missile.cpp @@ -23,10 +23,8 @@ // ----------------------------------------------------------------------------- Missile::Missile(Kart *kart) : Flyable(kart, COLLECT_MISSILE) { - btVector3 offset(0.0f, - kart->getKartLength()+2.0f*m_extend.getY(), - 0.3f ); - createPhysics(offset, btVector3(0.0f, m_speed, 0.0f), + float y_offset=kart->getKartLength()+2.0f*m_extend.getY(); + createPhysics(y_offset, btVector3(0.0f, m_speed, 0.0f), new btCylinderShape(0.5f*m_extend)); } // Missile diff --git a/src/moveable.hpp b/src/moveable.hpp index d2b0eb555..2f919aca3 100644 --- a/src/moveable.hpp +++ b/src/moveable.hpp @@ -65,8 +65,9 @@ public: virtual ~Moveable(); ssgTransform* getModelTransform() {return m_model_transform; } - const btVector3 &getVelocity() const {return m_body->getLinearVelocity();} + virtual const btVector3 &getVelocity() const {return m_body->getLinearVelocity();} const btVector3 &getVelocityLC() const {return m_velocityLC; } + virtual void setVelocity(const btVector3& v) {m_body->setLinearVelocity(v); } sgCoord* getCoord () {return &m_curr_pos; } const sgCoord* getCoord () const {return &m_curr_pos; } const sgVec4* getNormalHOT () const {return m_normal_hot; } diff --git a/src/spark.cpp b/src/spark.cpp index 886776c9f..8e85e82b9 100644 --- a/src/spark.cpp +++ b/src/spark.cpp @@ -24,18 +24,16 @@ float Spark::m_st_force_to_target; // ----------------------------------------------------------------------------- Spark::Spark(Kart *kart) : Flyable(kart, COLLECT_SPARK) { - btVector3 offset(0.0f, - -0.5f*kart->getKartLength()-2.0f*m_extend.getY(), - 0.5f*kart->getKartHeight()); - float speed=-m_speed; + float y_offset = -0.5f*kart->getKartLength()-2.0f*m_extend.getY(); + float speed = -m_speed; // if the kart is driving backwards, release from the front if(m_owner->getSpeed()<0) { - offset.setY(0.5f*kart->getKartLength()+2.0f*m_extend.getY()); - speed = m_speed; + y_offset = -y_offset; + speed = -speed; } - createPhysics(offset, btVector3(0.0f, speed, 0.0f), + createPhysics(y_offset, btVector3(0.0f, speed, 0.0f), new btSphereShape(0.5f*m_extend.getY())); // unset no_contact_response flags, so that the spark diff --git a/src/world.cpp b/src/world.cpp index cc82aa292..29ea63c4e 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -17,13 +17,6 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -//#define DEBUG_SHOW_DRIVEPOINTS //This would place a small sphere in every point -//of the driveline, the one at the first point -//is purple, the others are yellow. -#ifdef DEBUG_SHOW_DRIVEPOINTS -#include -#endif - #include #include #include