item intersection uses y_offset, hat initialised properly and some redundant code removed.
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/irrlicht@3850 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
1033bfdf59
commit
c27a807e64
@ -48,7 +48,7 @@ Cake::Cake (Kart *kart) : Flyable(kart, POWERUP_CAKE)
|
||||
// give a speed proportional to kart speed
|
||||
m_speed = kart->getSpeed() * m_speed / 23.0f;
|
||||
if (kart->getSpeed() < 0)
|
||||
m_speed /= 3.5f; //when going backwards, decrease speed of cake by less
|
||||
m_speed /= 3.6f; //when going backwards, decrease speed of cake by less
|
||||
|
||||
m_speed += 16.0f;
|
||||
|
||||
@ -80,14 +80,10 @@ Cake::Cake (Kart *kart) : Flyable(kart, POWERUP_CAKE)
|
||||
|
||||
float fire_angle = 0.0f;
|
||||
float time_estimated = 0.0f;
|
||||
getLinearKartItemIntersection (kart->getTrans().getOrigin(), closest_kart,
|
||||
m_speed, m_gravity,
|
||||
&fire_angle, &up_velocity, &time_estimated);
|
||||
|
||||
btMatrix3x3 thisKartDirMatrix = kart->getKartHeading().getBasis();
|
||||
btVector3 thisKartDirVector(thisKartDirMatrix[0][1],
|
||||
thisKartDirMatrix[1][1],
|
||||
thisKartDirMatrix[2][1]);
|
||||
getLinearKartItemIntersection (kart->getTrans().getOrigin(), closest_kart,
|
||||
m_speed, m_gravity, y_offset,
|
||||
&fire_angle, &up_velocity, &time_estimated);
|
||||
|
||||
// apply transformation to the bullet object (without pitch)
|
||||
btMatrix3x3 m;
|
||||
@ -108,6 +104,9 @@ Cake::Cake (Kart *kart) : Flyable(kart, POWERUP_CAKE)
|
||||
new btCylinderShape(0.5f*m_extend), -m_gravity,
|
||||
true /* rotation */, false /* backwards */, &trans);
|
||||
|
||||
//do not adjust height according to terrain
|
||||
setAdjustZVelocity(false);
|
||||
|
||||
m_body->setActivationState(DISABLE_DEACTIVATION);
|
||||
|
||||
m_body->applyTorque( btVector3(5,-3,7) );
|
||||
@ -133,43 +132,31 @@ void Cake::init(const lisp::Lisp* lisp, scene::IMesh *cake_model)
|
||||
// -----------------------------------------------------------------------------
|
||||
void Cake::update(float dt)
|
||||
{
|
||||
//The following commented out code adds a lock on to the cake. It is kept
|
||||
//because it shows how to lock on to a moving target precisely with the
|
||||
//intersection algorithm and may be one day useful for something else.
|
||||
|
||||
/*
|
||||
if(m_target != NULL)
|
||||
{
|
||||
/*
|
||||
// correct direction to go towards aimed kart
|
||||
btTransform my_trans = getTrans();
|
||||
btTransform target = m_target->getTrans();
|
||||
|
||||
float fire_angle = 0.0f;
|
||||
float time_estimated = 0.0f;
|
||||
float up_velocity = 0.0f;
|
||||
getLinearKartItemIntersection (my_trans.getOrigin(), m_target,
|
||||
m_speed, m_gravity,
|
||||
|
||||
btVector3 origin = my_trans.getOrigin() - m_target->getNormal() * 0.5 * m_target->getKartHeight();
|
||||
|
||||
getLinearKartItemIntersection (origin, m_target,
|
||||
m_speed, m_gravity, 0,
|
||||
&fire_angle, &up_velocity, &time_estimated);
|
||||
|
||||
m_body->setLinearVelocity( btVector3(-m_speed * sinf (fire_angle),
|
||||
m_speed * cosf (fire_angle),
|
||||
up_velocity) );
|
||||
*/
|
||||
|
||||
/*
|
||||
// pull towards aimed kart
|
||||
btVector3 pullForce = target.getOrigin() - my_trans.getOrigin();
|
||||
pullForce.setZ(0);
|
||||
pullForce.normalize();
|
||||
pullForce *= 10;
|
||||
m_body->applyCentralImpulse( pullForce );
|
||||
*/
|
||||
/*
|
||||
// if over aimed kart, pull down
|
||||
if(fabsf(my_trans.getOrigin().getX() - target.getOrigin().getX()) < 5.0 &&
|
||||
fabsf(my_trans.getOrigin().getY() - target.getOrigin().getY()) < 5.0)
|
||||
{
|
||||
m_body->applyCentralForce( btVector3(0, 0, -20.0f) );
|
||||
}
|
||||
*/
|
||||
}
|
||||
*/
|
||||
|
||||
Flyable::update(dt);
|
||||
} // update
|
||||
|
@ -64,7 +64,7 @@ Flyable::Flyable(Kart *kart, PowerupType type, float mass) : Moveable()
|
||||
m_time_since_thrown = 0;
|
||||
m_owner_has_temporary_immunity = true;
|
||||
m_max_lifespan = -1;
|
||||
|
||||
|
||||
// Add the graphical model
|
||||
setNode(irr_driver->addMesh(m_st_model[type]));
|
||||
} // Flyable
|
||||
@ -72,7 +72,7 @@ Flyable::Flyable(Kart *kart, PowerupType type, float mass) : Moveable()
|
||||
// ----------------------------------------------------------------------------
|
||||
void Flyable::createPhysics(float y_offset, const btVector3 &velocity,
|
||||
btCollisionShape *shape, const float gravity,
|
||||
const bool rotates, const bool turn_around,
|
||||
const bool rotates, const bool turn_around,
|
||||
const btTransform* customDirection)
|
||||
{
|
||||
// Get Kart heading direction
|
||||
@ -83,7 +83,7 @@ void Flyable::createPhysics(float y_offset, const btVector3 &velocity,
|
||||
offset_transform.setIdentity();
|
||||
btVector3 offset=btVector3(0,y_offset,m_average_height);
|
||||
offset_transform.setOrigin(offset);
|
||||
|
||||
|
||||
// turn around
|
||||
if(turn_around)
|
||||
{
|
||||
@ -93,7 +93,7 @@ void Flyable::createPhysics(float y_offset, const btVector3 &velocity,
|
||||
turn_around_trans.setRotation(btQuaternion(btVector3(0, 0, 1), M_PI));
|
||||
trans *= turn_around_trans;
|
||||
}
|
||||
|
||||
|
||||
trans *= offset_transform;
|
||||
|
||||
m_shape = shape;
|
||||
@ -115,7 +115,7 @@ void Flyable::createPhysics(float y_offset, const btVector3 &velocity,
|
||||
|
||||
} // createPhysics
|
||||
// -----------------------------------------------------------------------------
|
||||
void Flyable::init(const lisp::Lisp* lisp, scene::IMesh *model,
|
||||
void Flyable::init(const lisp::Lisp* lisp, scene::IMesh *model,
|
||||
PowerupType type)
|
||||
{
|
||||
m_st_speed[type] = 25.0f;
|
||||
@ -146,37 +146,37 @@ void Flyable::getClosestKart(const Kart **minKart, float *minDistSquared,
|
||||
btVector3 *minDelta, const Kart* inFrontOf, const bool backwards) const
|
||||
{
|
||||
btTransform tProjectile = (inFrontOf != NULL ? inFrontOf->getTrans() : getTrans());
|
||||
|
||||
|
||||
*minDistSquared = -1.0f;
|
||||
*minKart = NULL;
|
||||
|
||||
|
||||
for(unsigned int i=0 ; i<race_manager->getNumKarts(); i++ )
|
||||
{
|
||||
Kart *kart = RaceManager::getKart(i);
|
||||
if(kart->isEliminated() || kart == m_owner || kart->isRescue() ) continue;
|
||||
btTransform t=kart->getTrans();
|
||||
|
||||
|
||||
btVector3 delta = t.getOrigin()-tProjectile.getOrigin();
|
||||
float distance2 = delta.length2();
|
||||
|
||||
|
||||
if(inFrontOf != NULL)
|
||||
{
|
||||
// Ignore karts behind the current one
|
||||
btVector3 to_target = kart->getXYZ() - inFrontOf->getXYZ();
|
||||
const float distance = to_target.length();
|
||||
if(distance > 50) continue; // kart too far, don't aim at it
|
||||
|
||||
|
||||
btTransform trans = inFrontOf->getTrans();
|
||||
// get heading=trans.getBasis*(0,1,0) ... so save the multiplication:
|
||||
btVector3 direction(trans.getBasis()[0][1],
|
||||
trans.getBasis()[1][1],
|
||||
trans.getBasis()[2][1]);
|
||||
|
||||
|
||||
const float angle = to_target.angle( backwards ? -direction : direction );
|
||||
|
||||
|
||||
if(fabsf(angle) > 1) continue;
|
||||
}
|
||||
|
||||
|
||||
if(distance2 < *minDistSquared || *minDistSquared < 0 /* not yet set */)
|
||||
{
|
||||
*minDistSquared = distance2;
|
||||
@ -184,54 +184,57 @@ void Flyable::getClosestKart(const Kart **minKart, float *minDistSquared,
|
||||
*minDelta = delta;
|
||||
}
|
||||
} // for i<getNumKarts
|
||||
|
||||
|
||||
} // getClosestKart
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void Flyable::getLinearKartItemIntersection (const btVector3 origin, const Kart *target_kart,
|
||||
float item_XY_speed, float gravity,
|
||||
float item_XY_speed, float gravity, float y_offset,
|
||||
float *fire_angle, float *up_velocity, float *time_estimated)
|
||||
{
|
||||
btVector3 targetKartLoc = target_kart->getTrans().getOrigin();
|
||||
|
||||
float dx = targetKartLoc.getX() - origin.getX();
|
||||
float dy = targetKartLoc.getY() - origin.getY();
|
||||
float dz = targetKartLoc.getZ() - origin.getZ();
|
||||
btVector3 relative_target_kart_loc = target_kart->getTrans().getOrigin() - origin;
|
||||
|
||||
btTransform trans = target_kart->getTrans();
|
||||
Vec3 target_direction(trans.getBasis()[0][1],
|
||||
trans.getBasis()[1][1],
|
||||
trans.getBasis()[2][1]);
|
||||
btVector3 target_direction(trans.getBasis()[0][1],
|
||||
trans.getBasis()[1][1],
|
||||
trans.getBasis()[2][1]);
|
||||
|
||||
float dx = relative_target_kart_loc.getX();
|
||||
float dy = relative_target_kart_loc.getY();
|
||||
float dz = relative_target_kart_loc.getZ();
|
||||
|
||||
float gx = target_direction.getX();
|
||||
float gy = target_direction.getY();
|
||||
float gz = target_direction.getZ();
|
||||
|
||||
float target_kart_speed = target_direction.length_2d() * target_kart->getSpeed(); //Projected onto X-Y plane
|
||||
|
||||
float target_kart_speed = hypotf(gx, gy) * target_kart->getSpeed(); //Projected onto X-Y plane
|
||||
|
||||
float target_kart_heading = atan2f(-gx, gy); //anti-clockwise
|
||||
|
||||
target_kart_heading += M_PI;
|
||||
|
||||
float dist = (target_kart_speed / item_XY_speed) * (dx * cosf(target_kart_heading) + dy * sinf(target_kart_heading));
|
||||
float dist = -(target_kart_speed / item_XY_speed) * (dx * cosf(target_kart_heading) + dy * sinf(target_kart_heading));
|
||||
|
||||
float fire_th = (dx*dist - dy * sqrtf(dx*dx + dy*dy - dist*dist)) / (dx*dx + dy*dy);
|
||||
fire_th = (((dist - dx*fire_th) / dy < 0) ? -acosf(fire_th): acosf(fire_th));
|
||||
|
||||
float time = 0.0f;
|
||||
float a = item_XY_speed * sinf (fire_th) - target_kart_speed * sinf (target_kart_heading);
|
||||
float b = item_XY_speed * cosf (fire_th) - target_kart_speed * cosf (target_kart_heading);
|
||||
float a = item_XY_speed * sinf (fire_th) + target_kart_speed * sinf (target_kart_heading);
|
||||
float b = item_XY_speed * cosf (fire_th) + target_kart_speed * cosf (target_kart_heading);
|
||||
|
||||
if (fabsf(a) > fabsf(b))
|
||||
time = fabsf (dx / a);
|
||||
else if (b != 0.0f)
|
||||
time = fabsf(dy / b);
|
||||
|
||||
fire_th += M_PI;
|
||||
if (fire_th > M_PI)
|
||||
fire_th -= M_PI;
|
||||
else
|
||||
fire_th += M_PI;
|
||||
|
||||
//createPhysics offset
|
||||
time -= y_offset / hypotf(a, b);
|
||||
|
||||
*fire_angle = fire_th;
|
||||
*up_velocity = (0.5f * time * gravity) + (dz / time) + (gz * target_kart->getSpeed());
|
||||
*up_velocity = (0.5 * time * gravity) + (dz / time) + (gz * target_kart->getSpeed());
|
||||
*time_estimated = time;
|
||||
}
|
||||
|
||||
@ -240,9 +243,9 @@ void Flyable::update(float dt)
|
||||
{
|
||||
m_time_since_thrown += dt;
|
||||
if(m_max_lifespan > -1 && m_time_since_thrown > m_max_lifespan) hit(NULL);
|
||||
|
||||
|
||||
if(m_exploded) return;
|
||||
|
||||
|
||||
Vec3 pos=getBody()->getWorldTransform().getOrigin();
|
||||
TerrainInfo::update(pos);
|
||||
|
||||
@ -280,7 +283,7 @@ void Flyable::update(float dt)
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
/** Updates the position of a projectile based on information received frmo the
|
||||
* server.
|
||||
* server.
|
||||
*/
|
||||
void Flyable::updateFromServer(const FlyableInfo &f, float dt)
|
||||
{
|
||||
@ -299,8 +302,8 @@ void Flyable::updateFromServer(const FlyableInfo &f, float dt)
|
||||
*/
|
||||
bool Flyable::isOwnerImmunity(const Kart* kart_hit) const
|
||||
{
|
||||
return m_owner_has_temporary_immunity &&
|
||||
kart_hit == m_owner &&
|
||||
return m_owner_has_temporary_immunity &&
|
||||
kart_hit == m_owner &&
|
||||
m_time_since_thrown < 2.0f;
|
||||
} // isOwnerImmunity
|
||||
|
||||
@ -309,7 +312,7 @@ void Flyable::hit(Kart *kart_hit, PhysicalObject* object)
|
||||
{
|
||||
// the owner of this flyable should not be hit by his own flyable
|
||||
if(m_exploded || isOwnerImmunity(kart_hit)) return;
|
||||
|
||||
|
||||
m_has_hit_something=true;
|
||||
// Notify the projectile manager that this rocket has hit something.
|
||||
// The manager will create the appropriate explosion object.
|
||||
@ -324,10 +327,10 @@ void Flyable::hit(Kart *kart_hit, PhysicalObject* object)
|
||||
for ( unsigned int i = 0 ; i < race_manager->getNumKarts() ; i++ )
|
||||
{
|
||||
Kart *kart = RaceManager::getKart(i);
|
||||
// Handle the actual explosion. The kart that fired a flyable will
|
||||
// Handle the actual explosion. The kart that fired a flyable will
|
||||
// only be affected if it's a direct hit. This allows karts to use
|
||||
// rockets on short distance.
|
||||
if(m_owner!=kart || m_owner==kart_hit)
|
||||
if(m_owner!=kart || m_owner==kart_hit)
|
||||
{
|
||||
// Set a flag it if was a direct hit.
|
||||
kart->handleExplosion(getXYZ(), kart==kart_hit);
|
||||
|
@ -42,13 +42,13 @@ private:
|
||||
bool m_has_hit_something;
|
||||
/** This flag is used to avoid that a rocket explodes mode than once.
|
||||
* It can happen that more than one collision between a rocket and
|
||||
* a track or kart is reported by the physics. */
|
||||
* a track or kart is reported by the physics. */
|
||||
bool m_exploded;
|
||||
/** If this flag is set, the Z velocity of the kart will not be
|
||||
* adjusted in case that the objects is too high or too low above the
|
||||
* adjusted in case that the objects is too high or too low above the
|
||||
* terrain. Otherwise gravity will not work correctly on this object. */
|
||||
bool m_adjust_z_velocity;
|
||||
|
||||
|
||||
protected:
|
||||
Kart* m_owner; // the kart which released this flyable
|
||||
btCollisionShape *m_shape;
|
||||
@ -59,7 +59,7 @@ protected:
|
||||
float m_speed;
|
||||
float m_mass;
|
||||
btVector3 m_extend;
|
||||
// The flyable class stores the values for each flyable type, e.g.
|
||||
// The flyable class stores the values for each flyable type, e.g.
|
||||
// speed, min_height, max_height. These variables must be static,
|
||||
// so we need arrays of these variables to have different values
|
||||
// for bowling balls, missiles, ...
|
||||
@ -67,27 +67,27 @@ protected:
|
||||
static scene::IMesh *m_st_model[POWERUP_MAX]; // 3d model
|
||||
static float m_st_min_height[POWERUP_MAX]; // min height above track
|
||||
static float m_st_max_height[POWERUP_MAX]; // max height above track
|
||||
static float m_st_force_updown[POWERUP_MAX]; // force pushing up/down
|
||||
static float m_st_force_updown[POWERUP_MAX]; // force pushing up/down
|
||||
static btVector3 m_st_extend[POWERUP_MAX]; // size of the model
|
||||
|
||||
/** time since thrown. used so a kart can't hit himself when trying something,
|
||||
and also to put some time limit to some collectibles */
|
||||
float m_time_since_thrown;
|
||||
|
||||
|
||||
/** set to something > -1 if this flyable should auto-destrcut after a while */
|
||||
float m_max_lifespan;
|
||||
|
||||
|
||||
/** if set to true, the kart that throwns this flyable can't collide with it
|
||||
for a short time */
|
||||
bool m_owner_has_temporary_immunity;
|
||||
|
||||
|
||||
/** Returns information on what is the closest kart and at what
|
||||
distance it is. All 3 parameters first are of type 'out'.
|
||||
'inFrontOf' can be set if you wish to know the closest
|
||||
kart in front of some karts (will ignore those behind).
|
||||
Useful e.g. for throwing projectiles in front only.
|
||||
*/
|
||||
void getClosestKart(const Kart **minKart, float *minDistSquared,
|
||||
void getClosestKart(const Kart **minKart, float *minDistSquared,
|
||||
btVector3 *minDelta, const Kart* inFrontOf=NULL,
|
||||
const bool backwards=false) const;
|
||||
|
||||
@ -96,25 +96,25 @@ protected:
|
||||
XY-plane.
|
||||
*/
|
||||
void getLinearKartItemIntersection(const btVector3 origin, const Kart *target_kart,
|
||||
float item_XY_velocity, float gravity,
|
||||
float item_XY_velocity, float gravity, float y_offset,
|
||||
float *fire_angle, float *up_velocity, float *time);
|
||||
|
||||
|
||||
/** init bullet for moving objects like projectiles */
|
||||
void createPhysics(float y_offset,
|
||||
void createPhysics(float y_offset,
|
||||
const btVector3 &velocity,
|
||||
btCollisionShape *shape, const float gravity=0.0f,
|
||||
const bool rotates=false, const bool turn_around=false,
|
||||
const bool rotates=false, const bool turn_around=false,
|
||||
const btTransform* customDirection=NULL);
|
||||
public:
|
||||
|
||||
Flyable (Kart* kart, PowerupType type, float mass=1.0f);
|
||||
virtual ~Flyable ();
|
||||
/** Enables/disables adjusting ov velocity depending on height above
|
||||
/** Enables/disables adjusting ov velocity depending on height above
|
||||
* terrain. Missiles can 'follow the terrain' with this adjustment,
|
||||
* but gravity will basically be disabled. */
|
||||
void setAdjustZVelocity(bool f) { m_adjust_z_velocity = f; }
|
||||
static void init (const lisp::Lisp* lisp, scene::IMesh *model,
|
||||
static void init (const lisp::Lisp* lisp, scene::IMesh *model,
|
||||
PowerupType type);
|
||||
virtual void update (float);
|
||||
void updateFromServer(const FlyableInfo &f, float dt);
|
||||
@ -122,13 +122,13 @@ public:
|
||||
virtual void hitTrack () {};
|
||||
virtual void hit (Kart* kart, PhysicalObject* obj=NULL);
|
||||
bool hasHit () { return m_has_hit_something; }
|
||||
/** Indicates that something was hit and that this object must
|
||||
/** Indicates that something was hit and that this object must
|
||||
* be removed. */
|
||||
void setHasHit () { m_has_hit_something = true; }
|
||||
void reset () { Moveable::reset(); }
|
||||
bool isOwnerImmunity(const Kart *kart_hit) const;
|
||||
virtual int getExplosionSound() const { return SFXManager::SOUND_EXPLOSION; }
|
||||
/** Indicates if an explosion needs to be added if this flyable
|
||||
/** Indicates if an explosion needs to be added if this flyable
|
||||
* is removed. */
|
||||
virtual bool needsExplosion() const {return true;}
|
||||
}; // Flyable
|
||||
|
@ -65,7 +65,7 @@ Plunger::Plunger(Kart *kart) : Flyable(kart, POWERUP_PLUNGER)
|
||||
float fire_angle = 0.0f;
|
||||
float time_estimated = 0.0f;
|
||||
getLinearKartItemIntersection (kart->getTrans().getOrigin(), closest_kart,
|
||||
plunger_speed, gravity,
|
||||
plunger_speed, gravity, y_offset,
|
||||
&fire_angle, &up_velocity, &time_estimated);
|
||||
|
||||
// apply transformation to the bullet object (without pitch)
|
||||
@ -86,6 +86,9 @@ Plunger::Plunger(Kart *kart) : Flyable(kart, POWERUP_PLUNGER)
|
||||
new btCylinderShape(0.5f*m_extend), gravity, false /* rotates */, m_reverse_mode, &trans );
|
||||
}
|
||||
|
||||
//adjust height according to terrain
|
||||
setAdjustZVelocity(true);
|
||||
|
||||
// pulling back makes no sense in battle mode, since this mode is not a race.
|
||||
// so in battle mode, always hide view
|
||||
if( m_reverse_mode || race_manager->isBattleMode(race_manager->getMinorMode()) )
|
||||
@ -129,23 +132,8 @@ void Plunger::update(float dt)
|
||||
// Else: update the flyable and rubber band
|
||||
Flyable::update(dt);
|
||||
if(m_rubber_band != NULL) m_rubber_band->update(dt);
|
||||
|
||||
|
||||
if(getHoT()==Track::NOHIT) return;
|
||||
float hat = getTrans().getOrigin().getZ()-getHoT();
|
||||
|
||||
// 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.
|
||||
|
||||
float delta = m_average_height - std::max(std::min(hat, m_max_height), m_min_height);
|
||||
Vec3 v = getVelocity();
|
||||
float heading = atan2f(-v.getX(), v.getY());
|
||||
float pitch = getTerrainPitch (heading);
|
||||
float vel_z = m_force_updown*(delta);
|
||||
if (hat < m_max_height) // take into account pitch of surface
|
||||
vel_z += v.length_2d()*tanf(pitch);
|
||||
v.setZ(vel_z);
|
||||
setVelocity(v);
|
||||
} // update
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -188,7 +176,7 @@ void Plunger::hit(Kart *kart, PhysicalObject *obj)
|
||||
getNode()->setPosition(hell.toIrrVector());
|
||||
}
|
||||
RaceManager::getWorld()->getPhysics()->removeBody(getBody());
|
||||
|
||||
|
||||
if(kart)
|
||||
{
|
||||
m_rubber_band->hit(kart);
|
||||
@ -208,7 +196,7 @@ void Plunger::hit(Kart *kart, PhysicalObject *obj)
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
/** Called when the plunger hits the track. In this case, notify the rubber
|
||||
* band, and remove the plunger (but keep it alive).
|
||||
* band, and remove the plunger (but keep it alive).
|
||||
*/
|
||||
void Plunger::hitTrack()
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user