Applied cake improvements patch by David (thanks\!)
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/irrlicht@3758 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
@@ -3,6 +3,9 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2007 Joerg Henrichs
|
||||
//
|
||||
// Physics improvements and linear intersection algorithm by
|
||||
// by David Mikos. Copyright (C) 2009.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
@@ -26,64 +29,70 @@
|
||||
|
||||
float Cake::m_st_max_distance;
|
||||
float Cake::m_st_max_distance_squared;
|
||||
float Cake::m_gravity;
|
||||
|
||||
Cake::Cake (Kart *kart) : Flyable(kart, POWERUP_CAKE)
|
||||
{
|
||||
m_target = NULL;
|
||||
|
||||
// A bit of a hack: the mass of this kinematic object is still 1.0
|
||||
// (see flyable), which enables collisions. I tried setting
|
||||
// collisionFilterGroup/mask, but still couldn't get this object to
|
||||
|
||||
// A bit of a hack: the mass of this kinematic object is still 1.0
|
||||
// (see flyable), which enables collisions. I tried setting
|
||||
// collisionFilterGroup/mask, but still couldn't get this object to
|
||||
// collide with the track. By setting the mass to 1, collisions happen.
|
||||
// (if bullet is compiled with _DEBUG, a warning will be printed the first
|
||||
// time a homing-track collision happens).
|
||||
float y_offset=kart->getKartLength()/2.0f + m_extend.getY()/2.0f;
|
||||
|
||||
|
||||
float up_velocity = m_speed/7.0f;
|
||||
|
||||
// give a speed proportinal to kart speed
|
||||
m_speed = 25.0f + kart->getSpeed()/25.0f * m_speed;
|
||||
|
||||
|
||||
// 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 += 16.0f;
|
||||
|
||||
if (m_speed < 1.0f)
|
||||
m_speed = 1.0f;
|
||||
|
||||
btTransform trans = kart->getTrans();
|
||||
|
||||
const float pitch = 0.0f; //getTerrainPitch(heading); TODO: take pitch in account
|
||||
|
||||
btMatrix3x3 thisKartDirMatrix = kart->getKartHeading().getBasis();
|
||||
btVector3 thisKartDirVector(thisKartDirMatrix[0][1],
|
||||
thisKartDirMatrix[1][1],
|
||||
thisKartDirMatrix[2][1]);
|
||||
float heading=atan2f(-thisKartDirVector.getX(), thisKartDirVector.getY());
|
||||
float pitch = kart->getTerrainPitch(heading);
|
||||
|
||||
// find closest kart in front of the current one
|
||||
const Kart *closest_kart=0; btVector3 direction; float kartDistSquared;
|
||||
getClosestKart(&closest_kart, &kartDistSquared, &direction, kart /* search in front of this kart */);
|
||||
|
||||
|
||||
// aim at this kart if 1) it's not too far, 2) if the aimed kart's speed
|
||||
// allows the projectile to catch up with it
|
||||
//
|
||||
// this code finds the correct angle and upwards velocity to hit an opponents'
|
||||
// vehicle if they were to continue travelling in the same direction and same speed
|
||||
// (barring any obstacles in the way of course)
|
||||
if(closest_kart != NULL && kartDistSquared < m_st_max_distance_squared && m_speed>closest_kart->getSpeed())
|
||||
{
|
||||
m_target = (Kart*)closest_kart;
|
||||
|
||||
// calculate appropriate initial up velocity so that the
|
||||
// projectile lands on the aimed kart (9.8 is the gravity)
|
||||
// FIXME - this approximation will be wrong if both karts' directions are not colinear
|
||||
// FIXME - this approximation will be wrong if both karts' directions are not at the same height
|
||||
const float time = sqrt(kartDistSquared) / (m_speed - closest_kart->getSpeed()/1.2f); // division is an empirical estimation
|
||||
up_velocity = time*9.8f;
|
||||
|
||||
// calculate the approximate location of the aimed kart in 'time' seconds
|
||||
btVector3 closestKartLoc = closest_kart->getTrans().getOrigin();
|
||||
closestKartLoc += time*closest_kart->getVelocity();
|
||||
|
||||
// calculate the angle at which the projectile should be thrown
|
||||
// to hit the aimed kart
|
||||
float projectileAngle=atan2(-(closestKartLoc.getX() - kart->getTrans().getOrigin().getX()),
|
||||
closestKartLoc.getY() - kart->getTrans().getOrigin().getY() );
|
||||
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]);
|
||||
|
||||
// apply transformation to the bullet object
|
||||
// apply transformation to the bullet object (without pitch)
|
||||
btMatrix3x3 m;
|
||||
m.setEulerZYX(pitch, 0.0f, projectileAngle /*+thisKartAngle*/);
|
||||
m.setEulerZYX(0.0f, 0.0f, fire_angle /*+thisKartAngle*/);
|
||||
trans.setBasis(m);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -92,18 +101,17 @@ Cake::Cake (Kart *kart) : Flyable(kart, POWERUP_CAKE)
|
||||
// straight ahead, without trying to hit anything in particular
|
||||
trans = kart->getKartHeading(pitch);
|
||||
}
|
||||
|
||||
|
||||
m_initial_velocity = btVector3(0.0f, m_speed, up_velocity);
|
||||
|
||||
createPhysics(y_offset, m_initial_velocity,
|
||||
new btCylinderShape(0.5f*m_extend), -9.8f /* gravity */,
|
||||
|
||||
createPhysics(y_offset, m_initial_velocity,
|
||||
new btCylinderShape(0.5f*m_extend), -m_gravity,
|
||||
true /* rotation */, false /* backwards */, &trans);
|
||||
|
||||
m_body->setActivationState(DISABLE_DEACTIVATION);
|
||||
|
||||
|
||||
m_body->applyTorque( btVector3(5,-3,7) );
|
||||
|
||||
|
||||
} // Cake
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -112,7 +120,12 @@ void Cake::init(const lisp::Lisp* lisp, scene::IMesh *cake_model)
|
||||
Flyable::init(lisp, cake_model, POWERUP_CAKE);
|
||||
m_st_max_distance = 80.0f;
|
||||
m_st_max_distance_squared = 80.0f * 80.0f;
|
||||
|
||||
m_gravity = 9.8f;
|
||||
|
||||
if (m_gravity < 0)
|
||||
m_gravity *= -1;
|
||||
|
||||
|
||||
lisp->get("max-distance", m_st_max_distance );
|
||||
m_st_max_distance_squared = m_st_max_distance*m_st_max_distance;
|
||||
} // init
|
||||
@@ -120,27 +133,26 @@ void Cake::init(const lisp::Lisp* lisp, scene::IMesh *cake_model)
|
||||
// -----------------------------------------------------------------------------
|
||||
void Cake::update(float dt)
|
||||
{
|
||||
|
||||
|
||||
if(m_target != NULL)
|
||||
{
|
||||
/*
|
||||
// correct direction to go towards aimed kart
|
||||
btTransform my_trans = getTrans();
|
||||
btTransform target = m_target->getTrans();
|
||||
|
||||
btVector3 ideal_direction = target.getOrigin() - my_trans.getOrigin();
|
||||
ideal_direction.normalize();
|
||||
|
||||
const btVector3& actual_direction = m_body -> getLinearVelocity();
|
||||
|
||||
ideal_direction.setInterpolate3(actual_direction.normalized(), ideal_direction, dt);
|
||||
|
||||
const float current_xy_speed = sqrt( actual_direction.getX()*actual_direction.getX() +
|
||||
actual_direction.getY()*actual_direction.getY());
|
||||
|
||||
m_body->setLinearVelocity( btVector3(ideal_direction.getX()*current_xy_speed,
|
||||
ideal_direction.getY()*current_xy_speed,
|
||||
actual_direction.getZ()) );
|
||||
|
||||
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,
|
||||
&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();
|
||||
@@ -158,6 +170,7 @@ void Cake::update(float dt)
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
Flyable::update(dt);
|
||||
} // update
|
||||
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2007 Joerg Henrichs
|
||||
//
|
||||
// Physics improvements and linear intersection algorithm by
|
||||
// by David Mikos. Copyright (C) 2009.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
@@ -30,6 +33,7 @@ class Cake : public Flyable
|
||||
private:
|
||||
static float m_st_max_distance; // maximum distance for a missile to be attracted
|
||||
static float m_st_max_distance_squared;
|
||||
static float m_gravity;
|
||||
|
||||
btVector3 m_initial_velocity;
|
||||
Kart* m_target; // which kart is targeted by this
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2007 Joerg Henrichs
|
||||
//
|
||||
// Linear item-kart intersection function written by
|
||||
// by David Mikos. Copyright (C) 2009.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
@@ -184,6 +187,54 @@ void Flyable::getClosestKart(const Kart **minKart, float *minDistSquared,
|
||||
|
||||
} // getClosestKart
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void Flyable::getLinearKartItemIntersection (const btVector3 origin, const Kart *target_kart,
|
||||
float item_XY_speed, float gravity,
|
||||
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();
|
||||
|
||||
btTransform trans = target_kart->getTrans();
|
||||
btVector3 target_direction(trans.getBasis()[0][1],
|
||||
trans.getBasis()[1][1],
|
||||
trans.getBasis()[2][1]);
|
||||
|
||||
float gx = target_direction.getX();
|
||||
float gy = target_direction.getY();
|
||||
float gz = target_direction.getZ();
|
||||
|
||||
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 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);
|
||||
|
||||
if (fabsf(a) > fabsf(b))
|
||||
time = fabsf (dx / a);
|
||||
else if (b != 0.0f)
|
||||
time = fabsf(dy / b);
|
||||
|
||||
fire_th += M_PI;
|
||||
|
||||
|
||||
*fire_angle = fire_th;
|
||||
*up_velocity = (0.5 * time * gravity) + (dz / time) + (gz * target_kart->getSpeed());
|
||||
*time_estimated = time;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void Flyable::update(float dt)
|
||||
{
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2007 Joerg Henrichs
|
||||
//
|
||||
// Linear item-kart intersection function written by
|
||||
// by David Mikos. Copyright (C) 2009.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
@@ -87,6 +90,16 @@ protected:
|
||||
void getClosestKart(const Kart **minKart, float *minDistSquared,
|
||||
btVector3 *minDelta, const Kart* inFrontOf=NULL,
|
||||
const bool backwards=false) const;
|
||||
|
||||
/** Returns information on the parameters needed to hit a target kart
|
||||
moving at constant velocity and direction for a given speed in the
|
||||
XY-plane.
|
||||
*/
|
||||
void getLinearKartItemIntersection(const btVector3 origin, const Kart *target_kart,
|
||||
float item_XY_velocity, float gravity,
|
||||
float *fire_angle, float *up_velocity, float *time);
|
||||
|
||||
|
||||
/** init bullet for moving objects like projectiles */
|
||||
void createPhysics(float y_offset,
|
||||
const btVector3 &velocity,
|
||||
|
||||
Reference in New Issue
Block a user