1) Fixed cakes.

2) Changed several animated meshes/scene nodes to use more
   general mesh/scene nodes.
3) General many more fixes for changed coordinate systems.


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/switch_coordinate_system@4926 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2010-03-04 12:35:58 +00:00
parent 7dd318d949
commit 1df83662f6
17 changed files with 205 additions and 237 deletions

View File

@ -23,7 +23,7 @@
#include "graphics/irr_driver.hpp"
Shadow::Shadow(video::ITexture *texture, scene::IAnimatedMeshSceneNode *node)
Shadow::Shadow(video::ITexture *texture, scene::ISceneNode *node)
{
video::SMaterial m;
m.setTexture(0, texture);

View File

@ -40,7 +40,7 @@ private:
scene::ISceneNode *m_parent_kart_node;
public:
Shadow(video::ITexture *texture,
scene::IAnimatedMeshSceneNode *node);
scene::ISceneNode *node);
~Shadow();
void enableShadow();
void disableShadow();

View File

@ -29,7 +29,7 @@ const int STAR_AMOUNT = 7;
const float RADIUS = 0.7f;
const float STAR_SIZE = 0.4f;
Stars::Stars(scene::IAnimatedMeshSceneNode* parentKart)
Stars::Stars(scene::ISceneNode* parentKart)
{
m_parent_kart_node = parentKart;
m_enabled = false;

View File

@ -45,7 +45,7 @@ private:
float m_remaining_time;
public:
Stars (scene::IAnimatedMeshSceneNode* parentKart);
Stars (scene::ISceneNode* parentKart);
~Stars ();
void showFor(float time);
void reset();

View File

@ -54,9 +54,9 @@ Bowling::Bowling(Kart *kart) : Flyable(kart, POWERUP_BOWLING, 50.0f /* mass */)
// Even if the ball is fired backwards, m_speed must be positive,
// otherwise the ball can start to vibrate when energy is added.
m_speed = fabsf(m_speed);
// Do not adjust the z velociy depending on height above terrain, since
// Do not adjust the up velociy depending on height above terrain, since
// this would disable gravity.
setAdjustZVelocity(false);
setAdjustUpVelocity(false);
// unset no_contact_response flags, so that the ball
// will bounce off the track
@ -92,7 +92,7 @@ void Bowling::update(float dt)
{
Flyable::update(dt);
const Kart *kart=0;
btVector3 direction;
Vec3 direction;
float minDistance;
getClosestKart(&kart, &minDistance, &direction);
if(kart && minDistance<m_st_max_distance_squared) // move bowling towards kart
@ -112,7 +112,7 @@ void Bowling::update(float dt)
// speed, which causes the speed to increase, which in turn causes
// the ball to fly higher and higher.
btTransform trans = getTrans();
float hat = trans.getOrigin().getZ();
float hat = trans.getOrigin().getY();
btVector3 v = m_body->getLinearVelocity();
float vlen = v.length2();
if (hat<= m_max_height)
@ -120,7 +120,7 @@ void Bowling::update(float dt)
if(vlen<0.8*m_speed*m_speed)
{ // bowling lost energy (less than 80%), i.e. it's too slow - speed it up:
if(vlen==0.0f) {
v = btVector3(.5f, .5f, 0.0f); // avoid 0 div.
v = btVector3(.5f, .0, 0.5f); // avoid 0 div.
}
m_body->setLinearVelocity(v*m_speed/sqrt(vlen));
} // vlen < 0.8*m_speed*m_speed

View File

@ -42,32 +42,31 @@ Cake::Cake (Kart *kart) : Flyable(kart, POWERUP_CAKE)
// 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 forward_offset=kart->getKartLength()/2.0f + m_extend.getZ()/2.0f;
float up_velocity = m_speed/7.0f;
// give a speed proportional to kart speed
m_speed = kart->getSpeed() * m_speed / 23.0f;
if (kart->getSpeed() < 0)
m_speed /= 3.6f; //when going backwards, decrease speed of cake by less
// give a speed proportional to kart speed. m_speed is defined in flyable
m_speed *= kart->getSpeed() / 23.0f;
//when going backwards, decrease speed of cake by less
if (kart->getSpeed() < 0) m_speed /= 3.6f;
m_speed += 16.0f;
if (m_speed < 1.0f)
m_speed = 1.0f;
if (m_speed < 1.0f) m_speed = 1.0f;
btTransform trans = kart->getTrans();
btMatrix3x3 thisKartDirMatrix = kart->getKartHeading().getBasis();
btVector3 thisKartDirVector(thisKartDirMatrix[0][1],
thisKartDirMatrix[1][1],
thisKartDirMatrix[2][1]);
float heading=atan2f(-thisKartDirVector.getX(), thisKartDirVector.getY());
float heading=kart->getHeading();
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 */);
// Find closest kart in front of the current one
const Kart *closest_kart=0;
Vec3 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
@ -75,21 +74,21 @@ Cake::Cake (Kart *kart) : Flyable(kart, POWERUP_CAKE)
// 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())
if(closest_kart != NULL && kartDistSquared < m_st_max_distance_squared &&
m_speed>closest_kart->getSpeed())
{
m_target = (Kart*)closest_kart;
float fire_angle = 0.0f;
float time_estimated = 0.0f;
getLinearKartItemIntersection (kart->getTrans().getOrigin(), closest_kart,
m_speed, m_gravity, y_offset,
&fire_angle, &up_velocity, &time_estimated);
getLinearKartItemIntersection (kart->getXYZ(), closest_kart,
m_speed, m_gravity, forward_offset,
&fire_angle, &up_velocity);
// apply transformation to the bullet object (without pitch)
btMatrix3x3 m;
m.setEulerZYX(0.0f, 0.0f, fire_angle /*+thisKartAngle*/);
trans.setBasis(m);
//btMatrix3x3 m;
//m.setEulerZYX(0.0f, 0.0f, fire_angle /*+thisKartAngle*/);
//trans.setBasis(m);
trans.setRotation(btQuaternion(btVector3(0,1,0), fire_angle));
}
else
{
@ -99,14 +98,14 @@ Cake::Cake (Kart *kart) : Flyable(kart, POWERUP_CAKE)
trans = kart->getKartHeading(pitch);
}
m_initial_velocity = btVector3(0.0f, m_speed, up_velocity);
m_initial_velocity = Vec3(0.0f, up_velocity, m_speed);
createPhysics(y_offset, m_initial_velocity,
createPhysics(forward_offset, m_initial_velocity,
new btCylinderShape(0.5f*m_extend), -m_gravity,
true /* rotation */, false /* backwards */, &trans);
//do not adjust height according to terrain
setAdjustZVelocity(false);
setAdjustUpVelocity(false);
m_body->setActivationState(DISABLE_DEACTIVATION);
@ -122,12 +121,11 @@ Cake::Cake (Kart *kart) : Flyable(kart, POWERUP_CAKE)
void Cake::init(const XMLNode &node, scene::IMesh *cake_model)
{
Flyable::init(node, cake_model, POWERUP_CAKE);
m_st_max_distance = 80.0f;
m_st_max_distance = 80.0f;
m_st_max_distance_squared = 80.0f * 80.0f;
m_gravity = 9.8f;
m_gravity = 9.8f;
if (m_gravity < 0)
m_gravity *= -1;
if (m_gravity < 0) m_gravity *= -1.0f;
node.get("max-distance", &m_st_max_distance );
m_st_max_distance_squared = m_st_max_distance*m_st_max_distance;
@ -150,7 +148,7 @@ void Cake::update(float dt)
float time_estimated = 0.0f;
float up_velocity = 0.0f;
btVector3 origin = my_trans.getOrigin() - m_target->getNormal() * 0.5 * m_target->getKartHeight();
Vec3 origin = my_trans.getOrigin() - m_target->getNormal() * 0.5 * m_target->getKartHeight();
getLinearKartItemIntersection (origin, m_target,
m_speed, m_gravity, 0,

View File

@ -40,27 +40,25 @@ scene::IMesh* Flyable::m_st_model[POWERUP_MAX];
float Flyable::m_st_min_height[POWERUP_MAX];
float Flyable::m_st_max_height[POWERUP_MAX];
float Flyable::m_st_force_updown[POWERUP_MAX];
btVector3 Flyable::m_st_extend[POWERUP_MAX];
Vec3 Flyable::m_st_extend[POWERUP_MAX];
// ----------------------------------------------------------------------------
Flyable::Flyable(Kart *kart, PowerupType type, float mass) : Moveable()
{
// get the appropriate data from the static fields
m_speed = m_st_speed[type];
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;
m_has_hit_something = false;
m_exploded = false;
m_shape = NULL;
m_mass = mass;
m_adjust_z_velocity = true;
m_time_since_thrown = 0;
m_speed = m_st_speed[type];
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;
m_has_hit_something = false;
m_exploded = false;
m_shape = NULL;
m_mass = mass;
m_adjust_up_velocity = true;
m_time_since_thrown = 0;
m_owner_has_temporary_immunity = true;
m_max_lifespan = -1;
@ -69,19 +67,32 @@ Flyable::Flyable(Kart *kart, PowerupType type, float mass) : Moveable()
} // Flyable
// ----------------------------------------------------------------------------
void Flyable::createPhysics(float y_offset, const btVector3 &velocity,
/** Creates a bullet physics body for the flyable item.
* \param forw_offset How far ahead of the kart the flyable should be
* positioned. Necessary to avoid exploding a rocket inside of the
* firing kart.
* \param velocity Initial velocity of the flyable.
* \param shape Collision shape of the flyable.
* \param gravity Gravity to use for this flyable.
* \param rotates True if the item should rotate, otherwise the angular factor
* is set to 0 preventing rotations from happening.
* \param turn_around True if the item is fired backwards.
* \param custom_direction If defined the initial heading for this item,
* otherwise the kart's heading will be used.
*/
void Flyable::createPhysics(float forw_offset, const Vec3 &velocity,
btCollisionShape *shape, const float gravity,
const bool rotates, const bool turn_around,
const btTransform* customDirection)
const btTransform* custom_direction)
{
// Get Kart heading direction
btTransform trans = ( customDirection == NULL ? m_owner->getKartHeading() : *customDirection );
btTransform trans = ( custom_direction == NULL ? m_owner->getKartHeading()
: *custom_direction );
// Apply offset
btTransform offset_transform;
offset_transform.setIdentity();
btVector3 offset=btVector3(0,y_offset,m_average_height);
offset_transform.setOrigin(offset);
offset_transform.setOrigin(Vec3(0,m_average_height,forw_offset));
// turn around
if(turn_around)
@ -89,7 +100,7 @@ void Flyable::createPhysics(float y_offset, const btVector3 &velocity,
btTransform turn_around_trans;
//turn_around_trans.setOrigin(trans.getOrigin());
turn_around_trans.setIdentity();
turn_around_trans.setRotation(btQuaternion(btVector3(0, 0, 1), M_PI));
turn_around_trans.setRotation(btQuaternion(btVector3(0, 1, 0), M_PI));
trans *= turn_around_trans;
}
@ -100,7 +111,7 @@ void Flyable::createPhysics(float y_offset, const btVector3 &velocity,
m_user_pointer.set(this);
World::getWorld()->getPhysics()->addBody(getBody());
m_body->setGravity(btVector3(0.0f, 0.0f, gravity));
m_body->setGravity(btVector3(0.0f, gravity, 0));
// Rotate velocity to point in the right direction
btVector3 v=trans.getBasis()*velocity;
@ -141,10 +152,18 @@ Flyable::~Flyable()
} // ~Flyable
//-----------------------------------------------------------------------------
/** 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 Flyable::getClosestKart(const Kart **minKart, float *minDistSquared,
btVector3 *minDelta, const Kart* inFrontOf, const bool backwards) const
Vec3 *minDelta, const Kart* inFrontOf,
const bool backwards) const
{
btTransform tProjectile = (inFrontOf != NULL ? inFrontOf->getTrans() : getTrans());
btTransform tProjectile = (inFrontOf != NULL ? inFrontOf->getTrans()
: getTrans());
*minDistSquared = -1.0f;
*minKart = NULL;
@ -156,24 +175,23 @@ void Flyable::getClosestKart(const Kart **minKart, float *minDistSquared,
if(kart->isEliminated() || kart == m_owner || kart->isRescue() ) continue;
btTransform t=kart->getTrans();
btVector3 delta = t.getOrigin()-tProjectile.getOrigin();
Vec3 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();
Vec3 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]);
// get heading=trans.getBasis*(0,0,1) ... so save the multiplication:
Vec3 direction(trans.getBasis().getColumn(2));
// Originally it used angle = to_target.angle( backwards ? -direction : direction );
// but since sometimes due to rounding errors we get an acos(x) with x>1, causing
// an assertion failure. So we remove the whole acos() test here:
// but sometimes due to rounding errors we get an acos(x) with x>1, causing
// an assertion failure. So we remove the whole acos() test here and copy the
// code from to_target.angle(...)
Vec3 v = backwards ? -direction : direction;
float s = sqrt(v.length2() * to_target.length2());
float c = to_target.dot(v)/s;
@ -193,42 +211,52 @@ 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 y_offset,
float *fire_angle, float *up_velocity, float *time_estimated)
/** Returns information on the parameters needed to hit a target kart moving
* at constant velocity and direction for a given speed in the XZ-plane.
* \param origin Location of the kart shooting the item.
* \param target_kart Which kart to target.
* \param item_xz_speed Speed of the item projected in XZ plane.
* \param gravity The gravity used for this item.
* \param forw_offset How far ahead of the kart the item is shot (so that
* the item does not originate inside of the shooting kart.
* \param fire_angle Returns the angle to fire the item at.
* \param up_velocity Returns the upwards velocity to use for the item.
*/
void Flyable::getLinearKartItemIntersection (const Vec3 &origin,
const Kart *target_kart,
float item_XZ_speed,
float gravity, float forw_offset,
float *fire_angle,
float *up_velocity)
{
Vec3 relative_target_kart_loc = target_kart->getTrans().getOrigin() - origin;
Vec3 relative_target_kart_loc = target_kart->getXYZ() - origin;
btTransform trans = target_kart->getTrans();
Vec3 target_direction(trans.getBasis()[0][1],
trans.getBasis()[1][1],
trans.getBasis()[2][1]);
Vec3 target_direction(trans.getBasis().getColumn(2));
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
//Projected onto X-Z plane
float target_kart_speed = target_direction.length_2d() * target_kart->getSpeed();
float target_kart_heading = atan2f(-gx, gy); //anti-clockwise
float target_kart_heading = target_kart->getHeading();
float dist = -(target_kart_speed / item_XY_speed) * (dx * cosf(target_kart_heading) + dy * sinf(target_kart_heading));
float dist = -(target_kart_speed / item_XZ_speed) * (dx * cosf(target_kart_heading) +
dz * 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 fire_th = (dx*dist - dz * sqrtf(dx*dx + dz*dz - dist*dist)) / (dx*dx + dz*dz);
fire_th = (((dist - dx*fire_th) / dz < 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_XZ_speed * sinf (fire_th) + target_kart_speed * sinf (target_kart_heading);
float b = item_XZ_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);
if (fabsf(a) > fabsf(b)) time = fabsf (dx / a);
else if (b != 0.0f) time = fabsf(dz / b);
if (fire_th > M_PI)
fire_th -= M_PI;
@ -236,12 +264,11 @@ void Flyable::getLinearKartItemIntersection (const btVector3 origin, const Kart
fire_th += M_PI;
//createPhysics offset
time -= y_offset / sqrt(a*a+b*b);
time -= forw_offset / sqrt(a*a+b*b);
*fire_angle = fire_th;
*up_velocity = (0.5f * time * gravity) + (dz / time) + (gz * target_kart->getSpeed());
*time_estimated = time;
}
*up_velocity = (0.5f * time * gravity) + (dy / time) + (gy * target_kart->getSpeed());
} // getLinearKartItemIntersection
//-----------------------------------------------------------------------------
void Flyable::update(float dt)
@ -258,15 +285,15 @@ void Flyable::update(float dt)
const Vec3 *min, *max;
World::getWorld()->getTrack()->getAABB(&min, &max);
Vec3 xyz = getXYZ();
if(xyz[0]<(*min)[0] || xyz[1]<(*min)[1] || xyz[2]<(*min)[2] ||
xyz[0]>(*max)[0] || xyz[1]>(*max)[1] )
if(xyz[0]<(*min)[0] || xyz[2]<(*min)[2] || xyz[1]<(*min)[1] ||
xyz[0]>(*max)[0] || xyz[2]>(*max)[2] )
{
hit(NULL); // flyable out of track boundary
return;
}
if(m_adjust_z_velocity)
if(m_adjust_up_velocity)
{
float hat = pos.getZ()-getHoT();
float hat = pos.getY()-getHoT();
// Use the Height Above Terrain to set the Z velocity.
// HAT is clamped by min/max height. This might be somewhat
@ -274,14 +301,14 @@ void Flyable::update(float dt)
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);
float heading = atan2f(v.getX(), v.getZ());
float pitch = getTerrainPitch(heading);
float vel_up = 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);
vel_up += v.length_2d()*tanf(pitch);
v.setY(vel_up);
setVelocity(v);
} // if m_adjust_z_velocity
} // if m_adjust_up_velocity
Moveable::update(dt);
} // update

View File

@ -45,10 +45,10 @@ private:
* It can happen that more than one collision between a rocket and
* 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
/** If this flag is set, the up velocity of the kart will not be
* 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;
bool m_adjust_up_velocity;
protected:
Kart* m_owner; // the kart which released this flyable
@ -59,7 +59,7 @@ protected:
float m_force_updown;
float m_speed;
float m_mass;
btVector3 m_extend;
Vec3 m_extend;
// 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
@ -69,7 +69,7 @@ protected:
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 btVector3 m_st_extend[POWERUP_MAX]; // size of the model
static Vec3 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 */
@ -82,28 +82,20 @@ protected:
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,
btVector3 *minDelta, const Kart* inFrontOf=NULL,
Vec3 *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 y_offset,
float *fire_angle, float *up_velocity, float *time);
void getLinearKartItemIntersection(const Vec3 &origin,
const Kart *target_kart,
float item_XY_velocity, float gravity,
float forw_offset,
float *fire_angle, float *up_velocity);
/** init bullet for moving objects like projectiles */
void createPhysics(float y_offset,
const btVector3 &velocity,
const Vec3 &velocity,
btCollisionShape *shape, const float gravity=0.0f,
const bool rotates=false, const bool turn_around=false,
const btTransform* customDirection=NULL);
@ -114,7 +106,7 @@ public:
/** 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; }
void setAdjustUpVelocity(bool f) { m_adjust_up_velocity = f; }
static void init (const XMLNode &node, scene::IMesh *model,
PowerupType type);
virtual void update (float);

View File

@ -45,15 +45,16 @@ Plunger::Plunger(Kart *kart) : Flyable(kart, POWERUP_PLUNGER)
m_reverse_mode = kart->getControls().m_look_back;
// 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 */, m_reverse_mode);
const Kart *closest_kart=0;
Vec3 direction;
float kartDistSquared;
getClosestKart(&closest_kart, &kartDistSquared, &direction,
kart /* search in front of this kart */, m_reverse_mode);
btTransform trans = kart->getTrans();
btMatrix3x3 thisKartDirMatrix = kart->getKartHeading().getBasis();
btVector3 thisKartDirVector(thisKartDirMatrix[0][1],
thisKartDirMatrix[1][1],
thisKartDirMatrix[2][1]);
btVector3 thisKartDirVector(thisKartDirMatrix.getColumn(2));
float heading=atan2f(-thisKartDirVector.getX(), thisKartDirVector.getY());
float pitch = kart->getTerrainPitch(heading);
@ -62,20 +63,20 @@ Plunger::Plunger(Kart *kart) : Flyable(kart, POWERUP_PLUNGER)
if(closest_kart != NULL && kartDistSquared < 30*30)
{
float fire_angle = 0.0f;
float time_estimated = 0.0f;
getLinearKartItemIntersection (kart->getTrans().getOrigin(), closest_kart,
getLinearKartItemIntersection (kart->getXYZ(), closest_kart,
plunger_speed, gravity, y_offset,
&fire_angle, &up_velocity, &time_estimated);
&fire_angle, &up_velocity);
// apply transformation to the bullet object (without pitch)
btMatrix3x3 m;
m.setEulerZYX(0.0f, 0.0f, fire_angle);
m.setEulerYPR(fire_angle, 0.0f, 0.0f);
trans.setBasis(m);
m_initial_velocity = btVector3(0.0f, plunger_speed, up_velocity);
m_initial_velocity = btVector3(0.0f, up_velocity, plunger_speed);
createPhysics(y_offset, m_initial_velocity,
new btCylinderShape(0.5f*m_extend), gravity, false /* rotates */, false, &trans );
new btCylinderShape(0.5f*m_extend), gravity,
/* rotates */false , /*turn around*/false, &trans );
}
else
{
@ -86,7 +87,7 @@ Plunger::Plunger(Kart *kart) : Flyable(kart, POWERUP_PLUNGER)
}
//adjust height according to terrain
setAdjustZVelocity(true);
setAdjustUpVelocity(true);
// pulling back makes no sense in battle mode, since this mode is not a race.
// so in battle mode, always hide view
@ -154,11 +155,10 @@ void Plunger::hit(Kart *kart, PhysicalObject *obj)
if(kart) kart->blockViewWithPlunger();
m_keep_alive = 0;
// Make this object invisible by placing it faaar down. Not that if this
// Make this object invisible by placing it faaar down. Note that if this
// objects is simply removed from the scene graph, it might be auto-deleted
// because the ref count reaches zero.
Vec3 hell(0, 0, -10000);
getNode()->setPosition(hell.toIrrVector());
getNode()->setVisible(false);
World::getWorld()->getPhysics()->removeBody(getBody());
}
else
@ -171,8 +171,7 @@ void Plunger::hit(Kart *kart, PhysicalObject *obj)
scene::ISceneNode *node = getNode();
if(node)
{
Vec3 hell(0, 0, -10000);
getNode()->setPosition(hell.toIrrVector());
node->setVisible(false);
}
World::getWorld()->getPhysics()->removeBody(getBody());

View File

@ -80,7 +80,6 @@ Kart::Kart (const std::string& ident, int position,
m_nitro = NULL;
m_slip_stream = NULL;
m_skidmarks = NULL;
m_animated_node = NULL;
m_camera = NULL;
m_controller = NULL;
m_saved_controller = NULL;
@ -162,19 +161,12 @@ void Kart::setController(Controller *controller)
btTransform Kart::getKartHeading(const float customPitch)
{
btTransform trans = this->getTrans();
btTransform trans = 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]);
float heading=atan2(-direction.getX(), direction.getY());
TerrainInfo::update(this->getXYZ());
float pitch = (customPitch == -1 ? getTerrainPitch(heading) : customPitch);
float pitch = (customPitch == -1 ? getTerrainPitch(getHeading()) : customPitch);
btMatrix3x3 m;
m.setEulerZYX(pitch, 0.0f, heading);
m.setEulerYPR(-getHeading(), pitch, 0.0f);
trans.setBasis(m);
return trans;
@ -1276,7 +1268,7 @@ void Kart::endRescue()
void Kart::loadData()
{
m_kart_properties->getKartModel()->attachModel(&m_animated_node);
m_kart_properties->getKartModel()->attachModel(&m_node);
createPhysics();
// Attach Particle System
@ -1289,9 +1281,9 @@ void Kart::loadData()
m_skidmarks = new SkidMarks(*this);
m_shadow = new Shadow(m_kart_properties->getShadowTexture(),
m_animated_node);
m_node);
m_stars_effect = new Stars(m_animated_node);
m_stars_effect = new Stars(m_node);
} // loadData
//-----------------------------------------------------------------------------
@ -1314,13 +1306,14 @@ void Kart::setSuspensionLength()
//-----------------------------------------------------------------------------
/** Updates the graphics model. Mainly set the graphical position to be the
* same as the physics position, but uses offsets to position and rotation
* for special gfx effects (e.g. skidding will turn the karts more). The
* for special gfx effects (e.g. skidding will turn the karts more). These
* variables are actually not used here atm, but are defined here and then
* used in Moveable.
* \param off_xyz Offset to be added to the position.
* \param off_hpr Offset to be added to rotation (euler values).
* \param offset_xyz Offset to be added to the position.
* \param rotation Additional rotation.
*/
void Kart::updateGraphics(const Vec3& off_xyz, const Vec3& off_hpr)
void Kart::updateGraphics(const Vec3& offset_xyz,
const btQuaternion& rotation)
{
float wheel_up_axis[4];
KartModel *kart_model = m_kart_properties->getKartModel();
@ -1374,7 +1367,8 @@ void Kart::updateGraphics(const Vec3& off_xyz, const Vec3& off_hpr)
* speed_ratio * m_skidding*m_skidding;
printf("heading: %f hpr %f offset %f\n",
getHeading(), getHPR().getHeading(), -offset_heading);
Moveable::updateGraphics(center_shift, Vec3(0, -offset_heading, 0));
Moveable::updateGraphics(center_shift,
btQuaternion(-offset_heading, 0, 0));
} // updateGraphics
/* EOF */

View File

@ -204,7 +204,8 @@ public:
unsigned int getWorldKartId() const { return m_world_kart_id; }
void setWorldKartId(unsigned int n) { m_world_kart_id=n; }
void loadData();
virtual void updateGraphics(const Vec3& off_xyz, const Vec3& off_hpr);
virtual void updateGraphics(const Vec3& off_xyz,
const btQuaternion& off_rotation);
const KartProperties*
getKartProperties() const { return m_kart_properties; }
// ------------------------------------------------------------------------
@ -272,7 +273,6 @@ public:
/** Returns true if this kart has finished the race. */
bool hasFinishedRace () const { return m_finished_race; }
void endRescue ();
void getClosestKart (float *cdist, int *closest);
bool hasViewBlockedByPlunger() const
{ return m_view_blocked_by_plunger > 0; }

View File

@ -84,9 +84,10 @@ KartModel::~KartModel()
/** Attach the kart model and wheels to the scene node.
* \param node Node to attach the models to.
*/
void KartModel::attachModel(scene::IAnimatedMeshSceneNode **node)
void KartModel::attachModel(scene::ISceneNode **node)
{
m_node = *node = irr_driver->addAnimatedMesh(m_mesh);
*node = irr_driver->addAnimatedMesh(m_mesh);
m_node = static_cast<scene::IAnimatedMeshSceneNode*>(*node);
m_node->setAnimationSpeed(1500);
m_node->setLoopMode(false);
for(unsigned int i=0; i<4; i++)

View File

@ -115,7 +115,7 @@ public:
~KartModel();
void loadInfo(const lisp::Lisp* lisp);
void loadModels(const KartProperties &kart_properties);
void attachModel(scene::IAnimatedMeshSceneNode **node);
void attachModel(scene::ISceneNode **node);
scene::IAnimatedMesh* getModel() const { return m_mesh; }
scene::IMesh* getWheelModel(const int wheelID) const { return m_wheel_model[wheelID]; }

View File

@ -32,9 +32,7 @@ Moveable::Moveable()
m_motion_state = 0;
m_first_time = true;
m_mesh = NULL;
m_animated_mesh = NULL;
m_node = NULL;
m_animated_node = NULL;
} // Moveable
//-----------------------------------------------------------------------------
@ -44,57 +42,38 @@ Moveable::~Moveable()
if(m_body) delete m_body;
if(m_motion_state) delete m_motion_state;
if(m_node) irr_driver->removeNode(m_node);
if(m_animated_node) irr_driver->removeNode(m_animated_node);
if(m_mesh) irr_driver->removeMesh(m_mesh);
if(m_animated_mesh) irr_driver->removeMesh(m_animated_mesh);
} // ~Moveable
//-----------------------------------------------------------------------------
/** Sets this model to be non-animated.
/** Sets the mesh for this model.
* \param n The scene node.
*/
void Moveable::setNode(scene::ISceneNode *n)
{
m_node = n;
m_animated_node = NULL;
} // setNode
//-----------------------------------------------------------------------------
/** Sets this model to be animated.
* \param n The animated scene node.
*/
void Moveable::setAnimatedNode(scene::IAnimatedMeshSceneNode *n)
{
m_node = NULL;
m_animated_node = n;
} // setAnimatedNode
//-----------------------------------------------------------------------------
/** Updates the graphics model. Mainly set the graphical position to be the
* same as the physics position, but uses offsets to position and rotation
* for special gfx effects (e.g. skidding will turn the karts more).
* \param off_xyz Offset to be added to the position.
* \param off_hpr Offset to be added to rotation (euler values).
* \param offset_xyz Offset to be added to the position.
* \param rotation Additional rotation.
*/
void Moveable::updateGraphics(const Vec3& off_xyz, const Vec3& off_hpr)
void Moveable::updateGraphics(const Vec3& offset_xyz,
const btQuaternion& rotation)
{
#ifdef DEBUG_PRINT
printf("moveable: %f %f (%f %f)\n", getXYZ().getX(), getXYZ().getZ(),
off_xyz.getX(), off_xyz.getZ());
#endif
Vec3 xyz=getXYZ()+off_xyz;
Vec3 hpr=getHPR()+off_hpr;
//sgCoord c=Coord(xyz, hpr).toSgCoord();
if(m_node)
{
m_node->setPosition(xyz.toIrrVector());
m_node->setRotation(hpr.toIrrHPR());
}
else if(m_animated_node)
{
m_animated_node->setPosition(xyz.toIrrVector());
m_animated_node->setRotation(hpr.toIrrHPR());
}
Vec3 xyz=getXYZ()+offset_xyz;
btQuaternion r_all = getRotation()*rotation;
Vec3 hpr;
hpr.setHPR(r_all);
m_node->setPosition(xyz.toIrrVector());
m_node->setRotation(hpr.toIrrHPR());
} // updateGraphics
//-----------------------------------------------------------------------------
@ -107,13 +86,10 @@ void Moveable::reset()
m_body->setAngularVelocity(btVector3(0, 0, 0));
m_body->setCenterOfMassTransform(m_transform);
}
if(m_node)
m_node->setVisible(true); // In case that the objects was eliminated
if(m_animated_node)
m_animated_node->setVisible(true);
m_node->setVisible(true); // In case that the objects was eliminated
Coord c(m_transform);
m_hpr = c.getHPR();
m_hpr.setHPR(m_transform.getRotation());
} // reset
//-----------------------------------------------------------------------------
@ -121,28 +97,11 @@ void Moveable::update(float dt)
{
m_motion_state->getWorldTransform(m_transform);
m_velocityLC = getVelocity()*m_transform.getBasis();
// The following code would synchronise bullet to irrlicht rotations, but
// heading etc. might not be 'correct', e.g. a 180 degree heading rotation
// would be reported as 180 degree roll and pitch, and 0 degree heading.
// So to get heading, pitch etc. the way needed elsewhere (camera etc),
// we would still have to rotate unit vectors and compute heading etc.
// with atan.
//btQuaternion q = m_transform.getRotation();
//core::quaternion qirr(q.getX(), q.getZ(), q.getY(), -q.getW());
//core::vector3df r;
//qirr.toEuler(r);
// Note: toIrrHPR mixes the axis back etc., so the assignments below
// mean that getIrrHPR returns exactly (r.x,r.y,r.z)*RAD_TO_DEGREE
//m_hpr.setX(-r.Y);
//m_hpr.setY(-r.X);
//m_hpr.setZ(-r.Z);
m_hpr.setHPR(m_transform.getRotation());
Vec3 forw(1, 0, 0);
Vec3 forw_vec = m_transform.getBasis().getColumn(0);
m_heading = -atan2f(forw_vec.getZ(), forw_vec.getX());
updateGraphics(Vec3(0,0,0), Vec3(0,0,0));
updateGraphics(Vec3(0,0,0), btQuaternion(0, 0, 0, 1));
m_first_time = false ;
} // update

View File

@ -49,11 +49,8 @@ private:
protected:
UserPointer m_user_pointer;
scene::IAnimatedMesh *m_animated_mesh;
scene::IMesh *m_mesh;
scene::ISceneNode *m_node;
scene::IAnimatedMeshSceneNode
*m_animated_node;
int m_first_time ;
btRigidBody *m_body;
KartMotionState *m_motion_state;
@ -61,10 +58,10 @@ protected:
public:
Moveable();
virtual ~Moveable();
/** Returns the scene node of this moveable. */
scene::ISceneNode
*getNode() const { return m_node ? m_node : m_animated_node; }
*getNode() const { return m_node; }
void setNode(scene::ISceneNode *n);
void setAnimatedNode(scene::IAnimatedMeshSceneNode *n);
virtual const btVector3
&getVelocity() const {return m_body->getLinearVelocity();}
const btVector3
@ -101,7 +98,8 @@ public:
}
// ------------------------------------------------------------------------
virtual void handleZipper () {};
virtual void updateGraphics(const Vec3& off_xyz, const Vec3& off_hpr);
virtual void updateGraphics(const Vec3& off_xyz,
const btQuaternion& off_rotation);
virtual void reset();
virtual void update(float dt) ;
btRigidBody *getBody() const {return m_body; }

View File

@ -60,13 +60,13 @@ float TerrainInfo::getTerrainPitch(float heading) const {
if(m_HoT==Track::NOHIT) return 0.0f;
const float X =-sin(heading);
const float Y = cos(heading);
const float Z = cos(heading);
// Compute the angle between the normal of the plane and the line to
// (x,y,0). (x,y,0) is normalised, so are the coordinates of the plane,
// (x,0,z). (x,0,z) is normalised, so are the coordinates of the plane,
// simplifying the computation of the scalar product.
float pitch = ( m_normal.getX()*X + m_normal.getY()*Y ); // use ( x,y,0)
float pitch = ( m_normal.getX()*X + m_normal.getZ()*Z ); // use (x, 0, z)
// The actual angle computed above is between the normal and the (x,y,0)
// The actual angle computed above is between the normal and the (x, 0, z)
// line, so to compute the actual angles 90 degrees must be subtracted.
pitch = acosf(pitch) - NINETY_DEGREE_RAD;
return pitch;

View File

@ -40,7 +40,7 @@ public:
* axis as well (so a vector3df can be stored in and restored from
* a vec3).
*/
inline Vec3(const core::vector3df &v) : btVector3(v.X, v.Y, v.Z) {}
inline Vec3(const core::vector3df &v) : btVector3(v.X, v.Y, v.Z) {}
inline Vec3(const btVector3& a) : btVector3(a) {}
inline Vec3() : btVector3() {}
inline Vec3(float x, float y, float z) : btVector3(x,y,z) {}
@ -71,10 +71,10 @@ public:
Vec3 operator-(const Vec3& v1) const {return (Vec3)(*(btVector3*)this-(btVector3)v1);}
/** Helper functions to treat this vec3 as a 2d vector. This returns the
* square of the length of the first 2 dimensions. */
float length2_2d() const {return m_x*m_x + m_y*m_y;}
float length2_2d() const {return m_x*m_x + m_z*m_z;}
/** Returns the length of this vector in the plane, i.e. the vector is
* used as a 2d vector. */
float length_2d() const {return sqrt(m_x*m_x + m_y*m_y);}
float length_2d() const {return sqrt(m_x*m_x + m_z*m_z);}
/** Sets this = max(this, a) componentwise.
* \param Vector to compare with. */
void max(const Vec3& a) {if(a.getX()>m_x) m_x=a.getX();