Merge remote-tracking branch 'origin/master' into Flakebi-fixes

This commit is contained in:
hiker 2015-07-20 09:10:05 +10:00
commit cd8fd7fb16
38 changed files with 616 additions and 384 deletions

View File

@ -154,15 +154,6 @@
otherwise obstricts too much of the view. --> otherwise obstricts too much of the view. -->
<camera distance="1.0" forward-up-angle="15" <camera distance="1.0" forward-up-angle="15"
backward-up-angle="5"/> backward-up-angle="5"/>
<!-- Options to affect the graphical chassis:
y-offset: Additional offset to move graphical chassis with regards
to the physics, used to reduce frequencey of graphical
chassis in terrain.
prevent-chassis-in-terrain: a hard flag to prevent nearly all instances
of chassis in terrain. Can (atm) cause some stuttering. -->
<graphics y-offset="0.0"
prevent-chassis-in-terrain="true"
/>
<!-- Jump animation related values: <!-- Jump animation related values:
animation-time: only if the estimated time for a jump is larger animation-time: only if the estimated time for a jump is larger
@ -386,20 +377,20 @@
<!-- Suspension related values. stiffness: kart's suspension stiffness. <!-- Suspension related values. stiffness: kart's suspension stiffness.
rest: Length of suspension when at rest. rest: Length of suspension when at rest.
travel-cm: maximum movement of suspension - in cm!! travel: maximum movement of suspension!!
exp-string-response: dampen the suspension spring reaction exp-string-response: dampen the suspension spring reaction
exponentially. exponentially.
max-force: Maximum suspension force --> max-force: Maximum suspension force -->
<suspension stiffness="140" rest="0.3" travel-cm="29" <suspension stiffness="140" rest="0.3" travel="0.29"
exp-spring-response="false" max-force="12000"/> exp-spring-response="false" max-force="12000"/>
<!-- Wheel related parameters: damping-relaxation/compression: for <!-- Wheel related parameters: damping-relaxation/compression: for
bullet, damping parameters. Radius and width of wheel. bullet, damping parameters.
front-right, front-left, rear-right and rear-left give the front-right, front-left, rear-right and rear-left give the
position of the physics raycast wheels relative to the center of position of the physics raycast wheels relative to the center of
gravity. Default is to use the corners of the chassis to attach gravity. Default is to use the corners of the chassis to attach
the wheels to. --> the wheels to. -->
<wheels damping-relaxation="35" damping-compression="5" radius="0.25"> <wheels damping-relaxation="35" damping-compression="5">
<front-right position="0.38 0 0.6" /> <front-right position="0.38 0 0.6" />
<front-left position="-0.38 0 0.6" /> <front-left position="-0.38 0 0.6" />
<rear-right position="0.38 0 -0.6" /> <rear-right position="0.38 0 -0.6" />

View File

@ -77,7 +77,7 @@ btWheelInfo& btRaycastVehicle::addWheel( const btVector3& connectionPointCS, con
ci.m_wheelsDampingRelaxation = tuning.m_suspensionDamping; ci.m_wheelsDampingRelaxation = tuning.m_suspensionDamping;
ci.m_frictionSlip = tuning.m_frictionSlip; ci.m_frictionSlip = tuning.m_frictionSlip;
ci.m_bIsFrontWheel = isFrontWheel; ci.m_bIsFrontWheel = isFrontWheel;
ci.m_maxSuspensionTravelCm = tuning.m_maxSuspensionTravelCm; ci.m_maxSuspensionTravel = tuning.m_maxSuspensionTravel;
ci.m_maxSuspensionForce = tuning.m_maxSuspensionForce; ci.m_maxSuspensionForce = tuning.m_maxSuspensionForce;
m_wheelInfo.push_back( btWheelInfo(ci)); m_wheelInfo.push_back( btWheelInfo(ci));
@ -118,7 +118,7 @@ void btRaycastVehicle::updateWheelTransform( int wheelIndex , bool interpolatedT
btQuaternion steeringOrn(up,steering);//wheel.m_steering); btQuaternion steeringOrn(up,steering);//wheel.m_steering);
btMatrix3x3 steeringMat(steeringOrn); btMatrix3x3 steeringMat(steeringOrn);
btQuaternion rotatingOrn(right,-wheel.m_rotation); btQuaternion rotatingOrn(right,0);
btMatrix3x3 rotatingMat(rotatingOrn); btMatrix3x3 rotatingMat(rotatingOrn);
btMatrix3x3 basis2( btMatrix3x3 basis2(
@ -203,8 +203,8 @@ btScalar btRaycastVehicle::rayCast(btWheelInfo& wheel)
wheel.m_raycastInfo.m_suspensionLength = hitDistance - wheel.m_wheelsRadius; wheel.m_raycastInfo.m_suspensionLength = hitDistance - wheel.m_wheelsRadius;
//clamp on max suspension travel //clamp on max suspension travel
btScalar minSuspensionLength = wheel.getSuspensionRestLength() - wheel.m_maxSuspensionTravelCm*btScalar(0.01); btScalar minSuspensionLength = wheel.getSuspensionRestLength() - wheel.m_maxSuspensionTravel;
btScalar maxSuspensionLength = wheel.getSuspensionRestLength()+ wheel.m_maxSuspensionTravelCm*btScalar(0.01); btScalar maxSuspensionLength = wheel.getSuspensionRestLength()+ wheel.m_maxSuspensionTravel;
if (wheel.m_raycastInfo.m_suspensionLength < minSuspensionLength) if (wheel.m_raycastInfo.m_suspensionLength < minSuspensionLength)
{ {
wheel.m_raycastInfo.m_suspensionLength = minSuspensionLength; wheel.m_raycastInfo.m_suspensionLength = minSuspensionLength;
@ -345,17 +345,7 @@ void btRaycastVehicle::updateVehicle( btScalar step )
fwd -= wheel.m_raycastInfo.m_contactNormalWS * proj; fwd -= wheel.m_raycastInfo.m_contactNormalWS * proj;
btScalar proj2 = fwd.dot(vel); btScalar proj2 = fwd.dot(vel);
wheel.m_deltaRotation = (proj2 * step) / (wheel.m_wheelsRadius);
wheel.m_rotation += wheel.m_deltaRotation;
} else
{
wheel.m_rotation += wheel.m_deltaRotation;
} }
wheel.m_deltaRotation *= btScalar(0.99);//damping of rotation when not in contact
} }

View File

@ -43,7 +43,7 @@ public:
:m_suspensionStiffness(btScalar(5.88)), :m_suspensionStiffness(btScalar(5.88)),
m_suspensionCompression(btScalar(0.83)), m_suspensionCompression(btScalar(0.83)),
m_suspensionDamping(btScalar(0.88)), m_suspensionDamping(btScalar(0.88)),
m_maxSuspensionTravelCm(btScalar(500.)), m_maxSuspensionTravel(btScalar(5.)),
m_frictionSlip(btScalar(10.5)), m_frictionSlip(btScalar(10.5)),
m_maxSuspensionForce(btScalar(6000.)) m_maxSuspensionForce(btScalar(6000.))
{ {
@ -51,7 +51,7 @@ public:
btScalar m_suspensionStiffness; btScalar m_suspensionStiffness;
btScalar m_suspensionCompression; btScalar m_suspensionCompression;
btScalar m_suspensionDamping; btScalar m_suspensionDamping;
btScalar m_maxSuspensionTravelCm; btScalar m_maxSuspensionTravel;
btScalar m_frictionSlip; btScalar m_frictionSlip;
btScalar m_maxSuspensionForce; btScalar m_maxSuspensionForce;

View File

@ -22,7 +22,7 @@ struct btWheelInfoConstructionInfo
btVector3 m_wheelDirectionCS; btVector3 m_wheelDirectionCS;
btVector3 m_wheelAxleCS; btVector3 m_wheelAxleCS;
btScalar m_suspensionRestLength; btScalar m_suspensionRestLength;
btScalar m_maxSuspensionTravelCm; btScalar m_maxSuspensionTravel;
btScalar m_wheelRadius; btScalar m_wheelRadius;
btScalar m_suspensionStiffness; btScalar m_suspensionStiffness;
@ -59,7 +59,7 @@ struct btWheelInfo
btVector3 m_wheelDirectionCS;//const btVector3 m_wheelDirectionCS;//const
btVector3 m_wheelAxleCS; // const or modified by steering btVector3 m_wheelAxleCS; // const or modified by steering
btScalar m_suspensionRestLength1;//const btScalar m_suspensionRestLength1;//const
btScalar m_maxSuspensionTravelCm; btScalar m_maxSuspensionTravel;
btScalar getSuspensionRestLength() const; btScalar getSuspensionRestLength() const;
btScalar m_wheelsRadius;//const btScalar m_wheelsRadius;//const
btScalar m_suspensionStiffness;//const btScalar m_suspensionStiffness;//const
@ -67,8 +67,6 @@ struct btWheelInfo
btScalar m_wheelsDampingRelaxation;//const btScalar m_wheelsDampingRelaxation;//const
btScalar m_frictionSlip; btScalar m_frictionSlip;
btScalar m_steering; btScalar m_steering;
btScalar m_rotation;
btScalar m_deltaRotation;
btScalar m_rollInfluence; btScalar m_rollInfluence;
btScalar m_maxSuspensionForce; btScalar m_maxSuspensionForce;
@ -87,7 +85,7 @@ struct btWheelInfo
{ {
m_suspensionRestLength1 = ci.m_suspensionRestLength; m_suspensionRestLength1 = ci.m_suspensionRestLength;
m_maxSuspensionTravelCm = ci.m_maxSuspensionTravelCm; m_maxSuspensionTravel = ci.m_maxSuspensionTravel;
m_wheelsRadius = ci.m_wheelRadius; m_wheelsRadius = ci.m_wheelRadius;
m_suspensionStiffness = ci.m_suspensionStiffness; m_suspensionStiffness = ci.m_suspensionStiffness;
@ -99,8 +97,6 @@ struct btWheelInfo
m_frictionSlip = ci.m_frictionSlip; m_frictionSlip = ci.m_frictionSlip;
m_steering = btScalar(0.); m_steering = btScalar(0.);
m_engineForce = btScalar(0.); m_engineForce = btScalar(0.);
m_rotation = btScalar(0.);
m_deltaRotation = btScalar(0.);
m_brake = btScalar(0.); m_brake = btScalar(0.);
m_rollInfluence = btScalar(0.1); m_rollInfluence = btScalar(0.1);
m_bIsFrontWheel = ci.m_bIsFrontWheel; m_bIsFrontWheel = ci.m_bIsFrontWheel;

View File

@ -257,7 +257,8 @@ void SFXManager::queueCommand(SFXCommand *command)
race_manager->getMinorMode() != RaceManager::MINOR_MODE_CUTSCENE) race_manager->getMinorMode() != RaceManager::MINOR_MODE_CUTSCENE)
{ {
if(command->m_command==SFX_POSITION || command->m_command==SFX_LOOP || if(command->m_command==SFX_POSITION || command->m_command==SFX_LOOP ||
command->m_command==SFX_SPEED ) command->m_command==SFX_SPEED ||
command->m_command==SFX_SPEED_POSITION )
{ {
delete command; delete command;
static int count_messages = 0; static int count_messages = 0;

View File

@ -463,7 +463,7 @@ void Camera::getCameraSettings(float *above_kart, float *cam_angle,
{ {
*above_kart = 0; *above_kart = 0;
*cam_angle = 0; *cam_angle = 0;
*distance = -m_kart->getKartModel()->getLength(); *distance = -m_kart->getKartModel()->getLength()-1.0f;
} }
else if(UserConfigParams::m_camera_debug==4) else if(UserConfigParams::m_camera_debug==4)
{ {

View File

@ -18,23 +18,28 @@
#include "graphics/shadow.hpp" #include "graphics/shadow.hpp"
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "karts/kart_properties.hpp"
#include <IMesh.h> #include <IMesh.h>
#include <IMeshSceneNode.h> #include <IMeshSceneNode.h>
#include <ISceneNode.h> #include <ISceneNode.h>
Shadow::Shadow(video::ITexture *texture, scene::ISceneNode *node, Shadow::Shadow(const KartProperties *kart_properties,
float scale = 1.0, float x_offset = 0.0, float y_offset = 0.0, scene::ISceneNode *node,
float z_offset = 0.0) float y_offset = 0.0)
{ {
m_shadow_enabled = false;
video::SMaterial m; video::SMaterial m;
m.setTexture(0, texture); m.setTexture(0, kart_properties->getShadowTexture());
m.BackfaceCulling = false; m.BackfaceCulling = false;
m.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; m.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
m.setFlag(video::EMF_ZWRITE_ENABLE , false); m.setFlag(video::EMF_ZWRITE_ENABLE , false);
m_mesh = irr_driver->createQuadMesh(&m, /*create_one_quad*/true); m_mesh = irr_driver->createQuadMesh(&m, /*create_one_quad*/true);
scene::IMeshBuffer *buffer = m_mesh->getMeshBuffer(0); scene::IMeshBuffer *buffer = m_mesh->getMeshBuffer(0);
irr::video::S3DVertex* v=(video::S3DVertex*)buffer->getVertices(); irr::video::S3DVertex* v=(video::S3DVertex*)buffer->getVertices();
float scale = kart_properties->getShadowScale();
float x_offset = kart_properties->getShadowXOffset();
float z_offset = kart_properties->getShadowXOffset();
v[0].Pos.X = -scale+x_offset; v[0].Pos.Z = scale+z_offset; v[0].Pos.Y = 0.01f-y_offset; v[0].Pos.X = -scale+x_offset; v[0].Pos.Z = scale+z_offset; v[0].Pos.Y = 0.01f-y_offset;
v[1].Pos.X = scale+x_offset; v[1].Pos.Z = scale+z_offset; v[1].Pos.Y = 0.01f-y_offset; v[1].Pos.X = scale+x_offset; v[1].Pos.Z = scale+z_offset; v[1].Pos.Y = 0.01f-y_offset;
v[2].Pos.X = scale+x_offset; v[2].Pos.Z = -scale+z_offset; v[2].Pos.Y = 0.01f-y_offset; v[2].Pos.X = scale+x_offset; v[2].Pos.Z = -scale+z_offset; v[2].Pos.Y = 0.01f-y_offset;
@ -70,18 +75,17 @@ Shadow::~Shadow()
} // ~Shadow } // ~Shadow
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** Removes the shadow, used for the simplified shadow when the kart is in /** Updates the simulated shadow. It takes the offset (distance from visual
* the air. * chassis to ground) to position the shadow quad exactly on the ground.
* It also disables the shadow if requested (e.g. if the kart is in the air).
* \param enabled If the shadow should be shown or not.
* \param offset Distance from visual chassis to ground = position of the
* shadow to make sure it is exactly on the ground.
*/ */
void Shadow::disableShadow() void Shadow::update(bool enabled, float offset)
{ {
m_node->setVisible(false); m_node->setVisible(enabled);
} core::vector3df pos = m_node->getPosition();
// ---------------------------------------------------------------------------- pos.Y = offset;
/** Enables the shadow again, after it was disabled with disableShadow(). m_node->setPosition(pos);
*/ } // update
void Shadow::enableShadow()
{
m_node->setVisible(true);
}
// ----------------------------------------------------------------------------

View File

@ -21,7 +21,7 @@
#include "utils/no_copy.hpp" #include "utils/no_copy.hpp"
#include <string> class KartProperties;
namespace irr namespace irr
{ {
@ -41,19 +41,24 @@ class Shadow : public NoCopy
private: private:
/** The scene node for the shadow. */ /** The scene node for the shadow. */
scene::ISceneNode *m_node; scene::ISceneNode *m_node;
/** The mesh of the shadow. */ /** The mesh of the shadow. */
scene::IMesh *m_mesh; scene::IMesh *m_mesh;
/** The scene node of the kart to which this shadow belongs. */ /** The scene node of the kart to which this shadow belongs. */
scene::ISceneNode *m_parent_kart_node; scene::ISceneNode *m_parent_kart_node;
/** If a kart is flying, the shadow is disabled (since it is
* stuck to the kart, i.e. the shadow would be flying, too). */
bool m_shadow_enabled;
public: public:
Shadow(video::ITexture *texture, scene::ISceneNode *node, Shadow(const KartProperties *kart_properties,
float scale, float x_offset, float y_offset,float z_offset); scene::ISceneNode *node, float y_offset);
~Shadow(); ~Shadow();
void enableShadow(); void update(bool enabled, float hot);
void disableShadow();
}; // Shadow }; // Shadow
#endif #endif
/* EOF */ /* EOF */

View File

@ -374,7 +374,7 @@ void Item::collected(const AbstractKart *kart, float t)
if (m_listener != NULL) if (m_listener != NULL)
{ {
m_listener->onTriggerItemApproached(this); m_listener->onTriggerItemApproached();
} }
if (dynamic_cast<ThreeStrikesBattle*>(World::getWorld()) != NULL) if (dynamic_cast<ThreeStrikesBattle*>(World::getWorld()) != NULL)

View File

@ -51,7 +51,7 @@ class TriggerItemListener
{ {
public: public:
virtual ~TriggerItemListener() {} virtual ~TriggerItemListener() {}
virtual void onTriggerItemApproached(Item* who) = 0; virtual void onTriggerItemApproached() = 0;
}; };
/** /**

View File

@ -115,7 +115,6 @@ Kart::Kart (const std::string& ident, unsigned int world_kart_id,
m_bubblegum_torque = 0.0f; m_bubblegum_torque = 0.0f;
m_invulnerable_time = 0.0f; m_invulnerable_time = 0.0f;
m_squash_time = 0.0f; m_squash_time = 0.0f;
m_shadow_enabled = false;
m_shadow = NULL; m_shadow = NULL;
m_wheel_box = NULL; m_wheel_box = NULL;
@ -142,8 +141,6 @@ Kart::Kart (const std::string& ident, unsigned int world_kart_id,
// Set position and heading: // Set position and heading:
m_reset_transform = init_transform; m_reset_transform = init_transform;
m_speed = 0.0f; m_speed = 0.0f;
m_wheel_rotation = 0;
m_wheel_rotation_dt = 0;
m_kart_model->setKart(this); m_kart_model->setKart(this);
@ -347,7 +344,6 @@ void Kart::reset()
m_node->setScale(core::vector3df(1.0f, 1.0f, 1.0f)); m_node->setScale(core::vector3df(1.0f, 1.0f, 1.0f));
m_collected_energy = 0; m_collected_energy = 0;
m_has_started = false; m_has_started = false;
m_wheel_rotation = 0;
m_bounce_back_time = 0.0f; m_bounce_back_time = 0.0f;
m_brake_time = 0.0f; m_brake_time = 0.0f;
m_time_last_crash = 0.0f; m_time_last_crash = 0.0f;
@ -385,22 +381,6 @@ void Kart::reset()
{ {
m_vehicle->reset(); m_vehicle->reset();
} }
// Randomize wheel rotation if needed
if (m_kart_properties->hasRandomWheels() && m_vehicle && m_kart_model)
{
scene::ISceneNode** graphic_wheels = m_kart_model->getWheelNodes();
// FIXME Hardcoded i < 4 comes from the arrays in KartModel
for (int i = 0; i < m_vehicle->getNumWheels() && i < 4; i++)
{
// Physics
btWheelInfo& wheel = m_vehicle->getWheelInfo(i);
wheel.m_rotation = btScalar(rand() % 360);
// And graphics
core::vector3df wheel_rotation(wheel.m_rotation, 0, 0);
if (graphic_wheels[i])
graphic_wheels[i]->setRotation(wheel_rotation);
} // for wheels
} // if random wheel rotation
setTrans(m_reset_transform); setTrans(m_reset_transform);
@ -618,17 +598,12 @@ void Kart::createPhysics()
// All wheel positions are relative to the center of // All wheel positions are relative to the center of
// the collision shape. // the collision shape.
wheel_pos[index].setX(x*0.5f*kart_width); wheel_pos[index].setX(x*0.5f*kart_width);
float radius = getKartProperties()->getWheelRadius();
// The y position of the wheels (i.e. the points where // The y position of the wheels (i.e. the points where
// the suspension is attached to) is just at the // the suspension is attached to) is just at the
// bottom of the kart. That is half the kart height // bottom of the kart. That is half the kart height
// down. The wheel radius is added to the suspension // down.
// length in the physics, so we move the connection wheel_pos[index].setY(- 0.5f*kart_height);
// point 'radius' up. That means that if the suspension wheel_pos[index].setZ((0.5f*kart_length-0.25f)* z);
// is fully compressed (0), the wheel will just be at
// the bottom of the kart chassis and touch the ground
wheel_pos[index].setY(- 0.5f*kart_height + radius);
wheel_pos[index].setZ((0.5f*kart_length - radius)* z);
} }
else else
@ -683,15 +658,14 @@ void Kart::createPhysics()
// Add wheels // Add wheels
// ---------- // ----------
float wheel_radius = m_kart_properties->getWheelRadius();
float suspension_rest = m_kart_properties->getSuspensionRest(); float suspension_rest = m_kart_properties->getSuspensionRest();
btVector3 wheel_direction(0.0f, -1.0f, 0.0f); btVector3 wheel_direction(0.0f, -1.0f, 0.0f);
btVector3 wheel_axle(-1.0f, 0.0f, 0.0f); btVector3 wheel_axle(-1.0f, 0.0f, 0.0f);
btKart::btVehicleTuning tuning; btKart::btVehicleTuning tuning;
tuning.m_maxSuspensionTravelCm = tuning.m_maxSuspensionTravel =
m_kart_properties->getSuspensionTravelCM(); m_kart_properties->getSuspensionTravel();
tuning.m_maxSuspensionForce = tuning.m_maxSuspensionForce =
m_kart_properties->getMaxSuspensionForce(); m_kart_properties->getMaxSuspensionForce();
@ -702,7 +676,8 @@ void Kart::createPhysics()
btWheelInfo& wheel = m_vehicle->addWheel( btWheelInfo& wheel = m_vehicle->addWheel(
wheel_pos[i]+cs, wheel_pos[i]+cs,
wheel_direction, wheel_axle, suspension_rest, wheel_direction, wheel_axle, suspension_rest,
wheel_radius, tuning, is_front_wheel); m_kart_model->getWheelGraphicsRadius(i),
tuning, is_front_wheel);
wheel.m_suspensionStiffness = m_kart_properties->getSuspensionStiffness(); wheel.m_suspensionStiffness = m_kart_properties->getSuspensionStiffness();
wheel.m_wheelsDampingRelaxation = m_kart_properties->getWheelDampingRelaxation(); wheel.m_wheelsDampingRelaxation = m_kart_properties->getWheelDampingRelaxation();
wheel.m_wheelsDampingCompression = m_kart_properties->getWheelDampingCompression(); wheel.m_wheelsDampingCompression = m_kart_properties->getWheelDampingCompression();
@ -1180,11 +1155,6 @@ void Kart::update(float dt)
m_kart_properties->getChassisAngularDamping()); m_kart_properties->getChassisAngularDamping());
} }
//m_wheel_rotation gives the rotation around the X-axis
m_wheel_rotation_dt = m_speed*dt / m_kart_properties->getWheelRadius();
m_wheel_rotation += m_wheel_rotation_dt;
m_wheel_rotation = fmodf(m_wheel_rotation, 2*M_PI);
if(m_kart_animation) if(m_kart_animation)
m_kart_animation->update(dt); m_kart_animation->update(dt);
@ -1393,21 +1363,6 @@ void Kart::update(float dt)
} }
} }
//const bool dyn_shadows = World::getWorld()->getTrack()->hasShadows() &&
// UserConfigParams::m_shadows &&
// irr_driver->isGLSL();
// Disable the fake shadow if we're flying
if(m_shadow && (!isOnGround() || emergency) && m_shadow_enabled)
{
m_shadow_enabled = false;
m_shadow->disableShadow();
}
if(m_shadow && !m_shadow_enabled && isOnGround() && !emergency)
{
m_shadow->enableShadow();
m_shadow_enabled = true;
}
} // update } // update
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -2132,11 +2087,11 @@ void Kart::updatePhysics(float dt)
// Only apply if near ground instead of purely based on speed avoiding // Only apply if near ground instead of purely based on speed avoiding
// the "parachute on top" look. // the "parachute on top" look.
const Vec3 &v = m_body->getLinearVelocity(); const Vec3 &v = m_body->getLinearVelocity();
if(/*isNearGround() &&*/ v.getY() < - m_kart_properties->getSuspensionTravelCM()*0.01f*60) if(/*isNearGround() &&*/ v.getY() < - m_kart_properties->getSuspensionTravel()*60)
{ {
Vec3 v_clamped = v; Vec3 v_clamped = v;
// clamp the speed to 99% of the maxium falling speed. // clamp the speed to 99% of the maxium falling speed.
v_clamped.setY(-m_kart_properties->getSuspensionTravelCM()*0.01f*60 * 0.99f); v_clamped.setY(-m_kart_properties->getSuspensionTravel()*60 * 0.99f);
//m_body->setLinearVelocity(v_clamped); //m_body->setLinearVelocity(v_clamped);
} }
@ -2453,12 +2408,8 @@ void Kart::loadData(RaceManager::KartType type, bool is_animated_model)
if (!CVS->supportsShadows()) if (!CVS->supportsShadows())
{ {
m_shadow = new Shadow(m_kart_properties->getShadowTexture(), m_shadow = new Shadow(m_kart_properties, m_node,
m_node, -m_kart_model->getLowestPoint());
m_kart_properties->getShadowScale(),
m_kart_properties->getShadowXOffset(),
m_kart_properties->getGraphicalYOffset(),
m_kart_properties->getShadowZOffset());
} }
World::getWorld()->kartAdded(this, m_node); World::getWorld()->kartAdded(this, m_node);
} // loadData } // loadData
@ -2492,11 +2443,12 @@ void Kart::applyEngineForce(float force)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** Computes the transform of the graphical kart chasses with regards to the /** Computes the transform of the graphical kart chasses with regards to the
* physical chassis. This function is called once the kart comes to rest * physical chassis. This function is called once the kart comes to rest
* before the race starts. Based on the current physical kart position, it * before the race starts (see World::resetAllKarts). Based on the current
* computes an (at this stage Y-only) offset by which the graphical chassis * physical kart position it computes an (at this stage Y-only) offset by
* is moved so that it appears the way it is designed in blender. This means * which the graphical chassis is moved so that it appears the way it is
* that the distance of the wheels from the chassis (i.e. suspension) appears * designed in blender. This means that the distance of the wheels from the
* as in blender when karts are in rest. * chassis (i.e. suspension) appears as in blender when karts are in rest.
* See updateGraphics for more details.
*/ */
void Kart::kartIsInRestNow() void Kart::kartIsInRestNow()
{ {
@ -2505,21 +2457,116 @@ void Kart::kartIsInRestNow()
for(int i=0; i<m_vehicle->getNumWheels(); i++) for(int i=0; i<m_vehicle->getNumWheels(); i++)
{ {
const btWheelInfo &wi = m_vehicle->getWheelInfo(i); const btWheelInfo &wi = m_vehicle->getWheelInfo(i);
f += wi.m_chassisConnectionPointCS.getY() f += wi.m_raycastInfo.m_suspensionLength;
- wi.m_raycastInfo.m_suspensionLength - wi.m_wheelsRadius;
} }
m_graphical_y_offset = f/m_vehicle->getNumWheels()
+ getKartProperties()->getGraphicalYOffset(); // The offset 'lowest point' is added to avoid that the
// visual chassis appears in the ground (it could be any
// constant, there is no real reason to use the lowest point
// but that value has worked good in the past). See documentation
// for updateGraphics() for full details.
m_graphical_y_offset = -f / m_vehicle->getNumWheels()
+ m_kart_model->getLowestPoint();
m_kart_model->setDefaultSuspension(); m_kart_model->setDefaultSuspension();
} // kartIsInRestNow } // kartIsInRestNow
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** Updates the graphics model. Mainly set the graphical position to be the /** Updates the graphics model. It is responsible for positioning the graphical
* same as the physics position, but uses offsets to position and rotation * chasses at an 'appropriate' position: typically, the physical model has
* for special gfx effects (e.g. skidding will turn the karts more). These * much longer suspension, so if the graphical chassis would be at the same
* variables are actually not used here atm, but are defined here and then * location as the physical chassis, the wheels would be too far away.
* used in Moveable. * Instead the default suspension length is saved once the kart have been
* settled at start up (see World::resetAllKarts, which just runs several
* physics-only simulation steps so that karts come to a rest). Then at
* race time, only the difference between the current suspension length and
* this default suspension length is used. The graphical kart chassis will be
* offset so that when the kart is in rest, i.e. suspension length ==
* default suspension length, the kart will look the way it was modelled in
* blender. To explain the various offsets used, here a view from the side
* focusing on the Y axis only (X/Z position of the graphical chassis is
* identical to the physical chassis):
*
* Y| | visual kart | physical kart
* | | |
* | | |
* | | |
* | | +-------------COG---------------
* | | :
* | +---------low------ :
* | O :
* +--------------------------------------------------------------------------
* X
* 'O' : visual wheel ':' : raycast from physics
* 'low' : lowest Y coordinate of COG : Center of gravity (at bottom of
* model chassis)
*
* The visual kart is stored so that if it is shown at (0,0,0) it would be
* the same as in blender. This on the other hand means, if the kart is shown
* at the position of the physical chassis (which is at COG in the picture
* above), the kart and its wheels would be floating in the air (exactly by
* as much as the suspension length), and the wheels would be exactly at the
* bottom of the physical chassis (i.e. just on the plane going through COG
* and parallel to the ground).
* If we want to align the visual chassis to be the same as the physical
* chassis, we would need to subtract 'low' from the physical position.
* If the kart is then displayed at COG.y-low, the bottom of the kart (which
* is at 'low' above ground) would be at COG.y-low + low = COG.y --> visual
* and physical chassis are identical.
*
* Unfortunately, the suspension length used in the physics is much too high,
* the karts would be way above their wheels, basically disconneccted
* (typical physical suspension length is around 0.28, while the distance
* between wheel and chassis in blender is in the order of 0.10 --> so there
* would be an additional distance of around 0.18 between wheel chassis as
* designed in blender and in stk - even more if the kart is driving downhill
* when the suspension extends further to keep contact with the ground).
* To make the visuals look closer to what they are in blender, an additional
* offset is added: before the start of a race the physics simulation is run
* to find a stable position for each kart (see World::resetAllKarts). Once
* a kart is stable, we save this suspension length in m_graphical_y_offset.
* This offset is subtracted from the COG of the kart. So if the kart is in
* rest (i.e. suspenion == default_suspension == m_graphical_y_offset),
* The kart is showen exactly at the same height above ground as it is in
* blender. If the suspension is shorter by DY (because the kart is
* accelerating, the ground goes up, ...), the visual chassis is lowered by
* DY as well.
*
* While the above algorithm indeed results in the right position of the
* visual chassis, in reality the visual chassis is too low. For example,
* nolok's chassis has its lowest point at the rear at around 0.10 above the
* ground (and the lowest point overall is 0.05, though this is at the front
* and so not easily visible), so if the suspension is compressed by more than
* that, the chassiswill appear to be in the ground. Testing on the sand track
* shows that the suspension is compressed by 0.12 (and up to 0.16 in some
* extreme points), which means that the chassis will appear to be in the
* ground quite easily. Therefore the chassis is actually moved up a bit to
* avoid this problem. Historically (due to never sorting out that formula
* properly) the chassis was moved twice as high as its lowest point, e.g.
* nolok's lowest point is at 0.05, so the whole chassis was raised by 0.05
* (this was not done by design, but because of a bug ;) ). Since this visual
* offset has worked well in the past, the visual chassis is moved by the
* same amount higher.
*
* Of course this means that the Y position of the wheels (relative to the
* visual kart chassis) needs to be adjusted: if the kart is in rest, the
* wheels are exactly on the ground. If the suspension is shorter, that wheel
* would appear to be partly in the ground, and if the suspension is longer,
* the wheel would not touch the ground.
*
* The wheels must be offset by how much the current suspension length is
* longer or shorter than the default (i.e. at rest) suspension length.
* This is done in KartModel (pos is the position of the wheel relative
* to the visual kart chassis):
* pos.Y += m_default_physics_suspension[i]
* - wi.m_raycastInfo.m_suspensionLength
* But since the chassis is raised an additional 'getLowestPoint' (see
* desctiption two paragraphs above), the wheels need to be lowered by that
* amount so that they still touch the ground (the wheel nodes are child of
* the chassis scene node, so if the chassis is raised by X, the wheels need
* to be lowered by X).
* This function also takes additional graphical effects into account, e.g.
* a (visual only) jump when skidding, and leaning of the kart.
* \param offset_xyz Offset to be added to the position. * \param offset_xyz Offset to be added to the position.
* \param rotation Additional rotation. * \param rotation Additional rotation.
*/ */
@ -2601,60 +2648,37 @@ void Kart::updateGraphics(float dt, const Vec3& offset_xyz,
} }
} }
m_kart_model->update(dt, m_wheel_rotation_dt, getSteerPercent(), m_speed);
// If the kart is leaning, part of the kart might end up 'in' the track. // If the kart is leaning, part of the kart might end up 'in' the track.
// To avoid this, raise the kart enough to offset the leaning. // To avoid this, raise the kart enough to offset the leaning.
float lean_height = tan(fabsf(m_current_lean)) * getKartWidth()*0.5f; float lean_height = tan(fabsf(m_current_lean)) * getKartWidth()*0.5f;
float heading = m_skidding->getVisualSkidRotation(); Vec3 center_shift(0, 0, 0);
float xx = fabsf(m_speed)* getKartProperties()->getDownwardImpulseFactor()*0.0006f;
Vec3 center_shift = Vec3(0, m_skidding->getGraphicalJumpOffset()
+ lean_height +m_graphical_y_offset+xx, 0);
// Try to prevent the graphical chassis to be inside of the terrain:
if(m_kart_properties->getPreventChassisInTerrain())
{
// Get the shortest suspension length (=closest point to terrain).
float min_susp_len = 99.9f;
for (int i = 0; i < getVehicle()->getNumWheels(); i++)
{
float susp_len = getVehicle()->getWheelInfo(i).m_raycastInfo
.m_suspensionLength;
if (susp_len < min_susp_len)
min_susp_len = susp_len;
} // for i<num_wheels
const btWheelInfo &w = getVehicle()->getWheelInfo(0);
// Recompute the default average suspension length, see
// kartIsInRestNow() how to get from y-offset to susp. len.
float av_sus_len = -m_graphical_y_offset
+ w.m_chassisConnectionPointCS.getY()
- w.m_wheelsRadius;
float delta = av_sus_len - min_susp_len;
// If the suspension length is so short, that it is less than the
// lowest point of the kart, it indicates that the graphical chassis
// would be inside of the track:
if (delta > m_kart_model->getLowestPoint())
{
center_shift.setY(center_shift.getY() + delta - m_kart_model->getLowestPoint());
}
// FIXME: for now, debug output in case we have to debug it
//Log::verbose("kart", "min %f y off %f overall off %f lowest %f delta %f asl %f",
// min_susp_len, m_graphical_y_offset, center_shift.getY(),
// m_kart_model->getLowestPoint(),
// delta,
// av_sus_len
// );
}
center_shift.setY(m_skidding->getGraphicalJumpOffset()
+ lean_height
+m_graphical_y_offset);
center_shift = getTrans().getBasis() * center_shift; center_shift = getTrans().getBasis() * center_shift;
float heading = m_skidding->getVisualSkidRotation();
Moveable::updateGraphics(dt, center_shift, Moveable::updateGraphics(dt, center_shift,
btQuaternion(heading, 0, m_current_lean)); btQuaternion(heading, 0, m_current_lean));
// m_speed*dt is the distance the kart has moved, which determines
// how much the wheels need to rotate.
m_kart_model->update(dt, m_speed*dt, getSteerPercent(), m_speed);
// Determine the shadow position from the terrain Y position. This
// leaves the shadow on the ground even if the kart is jumping because
// of skidding (shadows are disabled when wheel are not on the track).
if (m_shadow)
{
const bool emergency = getKartAnimation() != NULL;
m_shadow->update(isOnGround() && !emergency,
m_terrain_info->getHoT() - getXYZ().getY()
- m_skidding->getGraphicalJumpOffset()
- m_graphical_y_offset
- m_kart_model->getLowestPoint());
}
#ifdef XX #ifdef XX
// cheap wheelie effect // cheap wheelie effect
if (m_controls.m_nitro) if (m_controls.m_nitro)

View File

@ -173,10 +173,6 @@ private:
/** The shadow of a kart. */ /** The shadow of a kart. */
Shadow *m_shadow; Shadow *m_shadow;
/** If a kart is flying, the shadow is disabled (since it is
* stuck to the kart, i.e. the shadow would be flying, too). */
bool m_shadow_enabled;
ParticleEmitter *m_sky_particles_emitter; ParticleEmitter *m_sky_particles_emitter;
/** All particle effects. */ /** All particle effects. */
@ -188,12 +184,6 @@ private:
/** Handles all slipstreaming. */ /** Handles all slipstreaming. */
SlipStream *m_slipstream; SlipStream *m_slipstream;
/** Rotation compared to the start position, same for all wheels */
float m_wheel_rotation;
/** Rotation change in the last time delta, same for all wheels */
float m_wheel_rotation_dt;
/** The skidmarks object for this kart. */ /** The skidmarks object for this kart. */
SkidMarks *m_skidmarks; SkidMarks *m_skidmarks;

View File

@ -49,21 +49,28 @@ float KartModel::UNDEFINED = -99.9f;
SpeedWeightedObject::Properties::Properties() SpeedWeightedObject::Properties::Properties()
{ {
m_strength_factor = m_speed_factor = m_texture_speed.X = m_texture_speed.Y = SPEED_WEIGHTED_OBJECT_PROPERTY_UNDEFINED; m_strength_factor = SPEED_WEIGHTED_OBJECT_PROPERTY_UNDEFINED;
} m_speed_factor = SPEED_WEIGHTED_OBJECT_PROPERTY_UNDEFINED;
m_texture_speed.X = SPEED_WEIGHTED_OBJECT_PROPERTY_UNDEFINED;
m_texture_speed.Y = SPEED_WEIGHTED_OBJECT_PROPERTY_UNDEFINED;
} // SpeedWeightedObject::Properties::Properties
// ----------------------------------------------------------------------------
void SpeedWeightedObject::Properties::loadFromXMLNode(const XMLNode* xml_node) void SpeedWeightedObject::Properties::loadFromXMLNode(const XMLNode* xml_node)
{ {
xml_node->get("strength-factor", &m_strength_factor); xml_node->get("strength-factor", &m_strength_factor);
xml_node->get("speed-factor", &m_speed_factor); xml_node->get("speed-factor", &m_speed_factor);
xml_node->get("texture-speed-x", &m_texture_speed.X); xml_node->get("texture-speed-x", &m_texture_speed.X);
xml_node->get("texture-speed-y", &m_texture_speed.Y); xml_node->get("texture-speed-y", &m_texture_speed.Y);
} } // SpeedWeightedObject::Properties::loadFromXMLNode
// ----------------------------------------------------------------------------
void SpeedWeightedObject::Properties::checkAllSet() void SpeedWeightedObject::Properties::checkAllSet()
{ {
#define CHECK_NEG( a,strA) if(a<=SPEED_WEIGHTED_OBJECT_PROPERTY_UNDEFINED) { \ #define CHECK_NEG( a,strA) if(a<=SPEED_WEIGHTED_OBJECT_PROPERTY_UNDEFINED) \
Log::fatal("SpeedWeightedObject", "Missing default value for '%s'.", \ { \
Log::fatal("SpeedWeightedObject", \
"Missing default value for '%s'.", \
strA); \ strA); \
} }
CHECK_NEG(m_strength_factor, "speed-weighted strength-factor" ); CHECK_NEG(m_strength_factor, "speed-weighted strength-factor" );
@ -71,8 +78,9 @@ void SpeedWeightedObject::Properties::checkAllSet()
CHECK_NEG(m_texture_speed.X, "speed-weighted texture speed X" ); CHECK_NEG(m_texture_speed.X, "speed-weighted texture speed X" );
CHECK_NEG(m_texture_speed.Y, "speed-weighted texture speed Y" ); CHECK_NEG(m_texture_speed.Y, "speed-weighted texture speed Y" );
#undef CHECK_NEG #undef CHECK_NEG
} } // SpeedWeightedObject::Properties::checkAllSet
// ============================================================================
/** Default constructor which initialises all variables with defaults. /** Default constructor which initialises all variables with defaults.
* Note that the KartModel is copied, so make sure to update makeCopy * Note that the KartModel is copied, so make sure to update makeCopy
* if any more variables are added to this object. * if any more variables are added to this object.
@ -451,10 +459,12 @@ scene::ISceneNode* KartModel::attachModel(bool animated_models, bool always_anim
obj.m_node = NULL; obj.m_node = NULL;
if(obj.m_model) if(obj.m_model)
{ {
obj.m_node = irr_driver->addAnimatedMesh(obj.m_model, "speedweighted", node); obj.m_node = irr_driver->addAnimatedMesh(obj.m_model,
"speedweighted", node);
obj.m_node->grab(); obj.m_node->grab();
obj.m_node->setFrameLoop(m_animation_frame[AF_SPEED_WEIGHTED_START], m_animation_frame[AF_SPEED_WEIGHTED_END]); obj.m_node->setFrameLoop(m_animation_frame[AF_SPEED_WEIGHTED_START],
m_animation_frame[AF_SPEED_WEIGHTED_END]);
#ifdef DEBUG #ifdef DEBUG
std::string debug_name = obj.m_name+" (speed-weighted)"; std::string debug_name = obj.m_name+" (speed-weighted)";
@ -553,14 +563,6 @@ bool KartModel::loadModels(const KartProperties &kart_properties)
} }
} }
float y_off = kart_properties.getGraphicalYOffset();
if(y_off!=0)
{
for (unsigned int i = 0; i < 4; i++)
m_wheel_graphics_position[i].setY(
m_wheel_graphics_position[i].getY() - y_off);
}
// Load the wheel models. This can't be done early, since the default // Load the wheel models. This can't be done early, since the default
// values for the graphical position must be defined, which in turn // values for the graphical position must be defined, which in turn
// depend on the size of the model. // depend on the size of the model.
@ -644,6 +646,14 @@ void KartModel::loadWheelInfo(const XMLNode &node,
*/ */
void KartModel::reset() void KartModel::reset()
{ {
for (unsigned int i = 0; i < 4; i++)
{
if (m_wheel_node[i])
{
core::vector3df rotation(btScalar(rand() % 360), 0, 0);
m_wheel_node[i]->setRotation(rotation);
}
}
update(0.0f, 0.0f, 0.0f, 0.0f); update(0.0f, 0.0f, 0.0f, 0.0f);
// Stop any animations currently being played. // Stop any animations currently being played.
@ -766,49 +776,44 @@ void KartModel::setDefaultSuspension()
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** Rotates and turns the wheels appropriately, and adjust for suspension /** Rotates and turns the wheels appropriately, and adjust for suspension
+ updates the speed-weighted objects' animations. * updates the speed-weighted objects' animations.
*
* \param dt time since last frame * \param dt time since last frame
* \param rotation_dt How far the wheels have rotated since last time. * \param distance How far the wheels have rotated since last time.
* \param steer The actual steer settings. * \param steer The actual steer settings.
* \param suspension Suspension height for all four wheels. * \param suspension Suspension height for all four wheels.
* \param speed The speed of the kart in meters/sec, used for the * \param speed The speed of the kart in meters/sec, used for the
* speed-weighted objects' animations * speed-weighted objects' animations
*/ */
void KartModel::update(float dt, float rotation_dt, float steer, float speed) void KartModel::update(float dt, float distance, float steer, float speed)
{ {
core::vector3df wheel_steer(0, steer*30.0f, 0); core::vector3df wheel_steer(0, steer*30.0f, 0);
for(unsigned int i=0; i<4; i++) for(unsigned int i=0; i<4; i++)
{ {
if (!m_kart || !m_wheel_node[i]) continue; if (!m_kart || !m_wheel_node[i]) continue;
float rel_suspension = 0; #ifdef DEBUG
if (!dynamic_cast<GhostKart*>(m_kart)) if (UserConfigParams::m_physics_debug &&
!dynamic_cast<GhostKart*>(m_kart) )
{ {
const btWheelInfo &wi = m_kart->getVehicle()->getWheelInfo(i); const btWheelInfo &wi = m_kart->getVehicle()->getWheelInfo(i);
#ifdef DEBUG
if (UserConfigParams::m_physics_debug && m_kart)
{
// Make wheels that are not touching the ground invisible // Make wheels that are not touching the ground invisible
m_wheel_node[i]->setVisible(wi.m_raycastInfo.m_isInContact); m_wheel_node[i]->setVisible(wi.m_raycastInfo.m_isInContact);
} }
#endif #endif
rel_suspension = wi.m_raycastInfo.m_suspensionLength
- m_default_physics_suspension[i];
}
// If the suspension is too compressed
if(rel_suspension< m_min_suspension[i])
rel_suspension = m_min_suspension[i];
else if(rel_suspension > m_max_suspension[i])
rel_suspension = m_max_suspension[i];
core::vector3df pos = m_wheel_graphics_position[i].toIrrVector(); core::vector3df pos = m_wheel_graphics_position[i].toIrrVector();
pos.Y -= rel_suspension;
const btWheelInfo &wi = m_kart->getVehicle()->getWheelInfo(i);
// Check documentation of Kart::updateGraphics for the following line
pos.Y += m_default_physics_suspension[i]
- wi.m_raycastInfo.m_suspensionLength
- m_kart_lowest_point;
m_wheel_node[i]->setPosition(pos); m_wheel_node[i]->setPosition(pos);
// Now calculate the new rotation: (old + change) mod 360 // Now calculate the new rotation: (old + change) mod 360
float new_rotation = m_wheel_node[i]->getRotation().X float new_rotation = m_wheel_node[i]->getRotation().X
+ rotation_dt * RAD_TO_DEGREE; + distance / m_wheel_graphics_radius[i] * RAD_TO_DEGREE;
new_rotation = fmodf(new_rotation, 360); new_rotation = fmodf(new_rotation, 360);
core::vector3df wheel_rotation(new_rotation, 0, 0); core::vector3df wheel_rotation(new_rotation, 0, 0);
// Only apply steer to first 2 wheels. // Only apply steer to first 2 wheels.

View File

@ -232,7 +232,7 @@ public:
void loadInfo(const XMLNode &node); void loadInfo(const XMLNode &node);
bool loadModels(const KartProperties &kart_properties); bool loadModels(const KartProperties &kart_properties);
void setDefaultSuspension(); void setDefaultSuspension();
void update(float dt, float rotation_dt, float steer, void update(float dt, float distance, float steer,
float speed); float speed);
void finishedRace(); void finishedRace();
scene::ISceneNode* scene::ISceneNode*

View File

@ -70,11 +70,11 @@ KartProperties::KartProperties(const std::string &filename)
m_nitro_max_speed_increase = m_nitro_duration = m_nitro_fade_out_time = m_nitro_max_speed_increase = m_nitro_duration = m_nitro_fade_out_time =
m_suspension_stiffness = m_wheel_damping_relaxation = m_wheel_base = m_suspension_stiffness = m_wheel_damping_relaxation = m_wheel_base =
m_wheel_damping_compression = m_friction_slip = m_roll_influence = m_wheel_damping_compression = m_friction_slip = m_roll_influence =
m_wheel_radius = m_chassis_linear_damping = m_max_suspension_force = m_chassis_linear_damping = m_max_suspension_force =
m_chassis_angular_damping = m_suspension_rest = m_chassis_angular_damping = m_suspension_rest =
m_max_speed_reverse_ratio = m_rescue_vert_offset = m_max_speed_reverse_ratio = m_rescue_vert_offset =
m_collision_terrain_impulse = m_collision_impulse = m_restitution = m_collision_terrain_impulse = m_collision_impulse = m_restitution =
m_collision_impulse_time = m_suspension_travel_cm = m_collision_impulse_time = m_suspension_travel =
m_track_connection_accel = m_rubber_band_max_length = m_track_connection_accel = m_rubber_band_max_length =
m_rubber_band_force = m_rubber_band_duration = m_rubber_band_force = m_rubber_band_duration =
m_rubber_band_speed_increase = m_rubber_band_fade_out_time = m_rubber_band_speed_increase = m_rubber_band_fade_out_time =
@ -93,7 +93,6 @@ KartProperties::KartProperties(const std::string &filename)
m_bubblegum_fade_in_time = m_bubblegum_speed_fraction = m_bubblegum_fade_in_time = m_bubblegum_speed_fraction =
m_bubblegum_time = m_bubblegum_torque = m_jump_animation_time = m_bubblegum_time = m_bubblegum_torque = m_jump_animation_time =
m_smooth_flying_impulse = m_physical_wheel_position = m_smooth_flying_impulse = m_physical_wheel_position =
m_graphical_y_offset =
UNDEFINED; UNDEFINED;
m_engine_power.resize(RaceManager::DIFFICULTY_COUNT, UNDEFINED); m_engine_power.resize(RaceManager::DIFFICULTY_COUNT, UNDEFINED);
@ -105,13 +104,11 @@ KartProperties::KartProperties(const std::string &filename)
m_gravity_center_shift = Vec3(UNDEFINED); m_gravity_center_shift = Vec3(UNDEFINED);
m_bevel_factor = Vec3(UNDEFINED); m_bevel_factor = Vec3(UNDEFINED);
m_exp_spring_response = false; m_exp_spring_response = false;
m_prevent_chassis_in_terrain = false;
m_version = 0; m_version = 0;
m_color = video::SColor(255, 0, 0, 0); m_color = video::SColor(255, 0, 0, 0);
m_shape = 32; // close enough to a circle. m_shape = 32; // close enough to a circle.
m_engine_sfx_type = "engine_small"; m_engine_sfx_type = "engine_small";
m_kart_model = NULL; m_kart_model = NULL;
m_has_rand_wheels = false;
m_nitro_min_consumption = 0.53f; m_nitro_min_consumption = 0.53f;
// The default constructor for stk_config uses filename="" // The default constructor for stk_config uses filename=""
if (filename != "") if (filename != "")
@ -281,7 +278,13 @@ void KartProperties::load(const std::string &filename, const std::string &node)
{ {
m_gravity_center_shift.setX(0); m_gravity_center_shift.setX(0);
// Default: center at the very bottom of the kart. // Default: center at the very bottom of the kart.
// If the kart is 'too high', its height will be changed in
// kart.cpp, the same adjustment needs to be made here.
if (m_kart_model->getHeight() > m_kart_model->getLength()*0.6f)
m_gravity_center_shift.setY(m_kart_model->getLength()*0.6f*0.5f);
else
m_gravity_center_shift.setY(m_kart_model->getHeight()*0.5f); m_gravity_center_shift.setY(m_kart_model->getHeight()*0.5f);
m_gravity_center_shift.setZ(0); m_gravity_center_shift.setZ(0);
} }
@ -292,7 +295,10 @@ void KartProperties::load(const std::string &filename, const std::string &node)
// moved to be on the corner of the shape. In order to retain the same // moved to be on the corner of the shape. In order to retain the same
// steering behaviour, the wheel base (which in turn determines the // steering behaviour, the wheel base (which in turn determines the
// turn angle at certain speeds) is shortened by 2*wheel_radius // turn angle at certain speeds) is shortened by 2*wheel_radius
m_wheel_base = fabsf(m_kart_model->getLength() - 2*m_wheel_radius); // Wheel radius was always 0.25, and is now not used anymore, but in order
// to keep existing steering behaviour, the same formula is still
// used.
m_wheel_base = fabsf(m_kart_model->getLength() - 2*0.25f);
// Now convert the turn radius into turn angle: // Now convert the turn radius into turn angle:
for(unsigned int i=0; i<m_turn_angle_at_speed.size(); i++) for(unsigned int i=0; i<m_turn_angle_at_speed.size(); i++)
@ -330,8 +336,6 @@ void KartProperties::getAllData(const XMLNode * root)
root->get("groups", &m_groups ); root->get("groups", &m_groups );
root->get("random-wheel-rot", &m_has_rand_wheels );
root->get("shadow-scale", &m_shadow_scale ); root->get("shadow-scale", &m_shadow_scale );
root->get("shadow-x-offset", &m_shadow_x_offset ); root->get("shadow-x-offset", &m_shadow_x_offset );
root->get("shadow-z-offset", &m_shadow_z_offset ); root->get("shadow-z-offset", &m_shadow_z_offset );
@ -357,7 +361,7 @@ void KartProperties::getAllData(const XMLNode * root)
{ {
suspension_node->get("stiffness", &m_suspension_stiffness); suspension_node->get("stiffness", &m_suspension_stiffness);
suspension_node->get("rest", &m_suspension_rest ); suspension_node->get("rest", &m_suspension_rest );
suspension_node->get("travel-cm", &m_suspension_travel_cm); suspension_node->get("travel", &m_suspension_travel );
suspension_node->get("exp-spring-response", &m_exp_spring_response ); suspension_node->get("exp-spring-response", &m_exp_spring_response );
suspension_node->get("max-force", &m_max_suspension_force); suspension_node->get("max-force", &m_max_suspension_force);
} }
@ -366,7 +370,6 @@ void KartProperties::getAllData(const XMLNode * root)
{ {
wheels_node->get("damping-relaxation", &m_wheel_damping_relaxation ); wheels_node->get("damping-relaxation", &m_wheel_damping_relaxation );
wheels_node->get("damping-compression", &m_wheel_damping_compression); wheels_node->get("damping-compression", &m_wheel_damping_compression);
wheels_node->get("radius", &m_wheel_radius );
} }
if(const XMLNode *speed_weighted_objects_node = root->getNode("speed-weighted-objects")) if(const XMLNode *speed_weighted_objects_node = root->getNode("speed-weighted-objects"))
@ -627,13 +630,6 @@ void KartProperties::getAllData(const XMLNode * root)
startup_node->get("boost", &m_startup_boost); startup_node->get("boost", &m_startup_boost);
} }
if(const XMLNode *graphics_node = root->getNode("graphics"))
{
graphics_node->get("y-offset", &m_graphical_y_offset);
graphics_node->get("prevent-chassis-in-terrain",
&m_prevent_chassis_in_terrain);
}
if(m_kart_model) if(m_kart_model)
m_kart_model->loadInfo(*root); m_kart_model->loadInfo(*root);
} // getAllData } // getAllData
@ -681,7 +677,6 @@ void KartProperties::checkAllSet(const std::string &filename)
CHECK_NEG(m_time_reset_steer, "turn time-reset-steer" ); CHECK_NEG(m_time_reset_steer, "turn time-reset-steer" );
CHECK_NEG(m_wheel_damping_relaxation, "wheels damping-relaxation" ); CHECK_NEG(m_wheel_damping_relaxation, "wheels damping-relaxation" );
CHECK_NEG(m_wheel_damping_compression, "wheels damping-compression" ); CHECK_NEG(m_wheel_damping_compression, "wheels damping-compression" );
CHECK_NEG(m_wheel_radius, "wheels radius" );
CHECK_NEG(m_friction_slip, "friction slip" ); CHECK_NEG(m_friction_slip, "friction slip" );
CHECK_NEG(m_roll_influence, "stability roll-influence" ); CHECK_NEG(m_roll_influence, "stability roll-influence" );
CHECK_NEG(m_chassis_linear_damping, "stability chassis-linear-damping" ); CHECK_NEG(m_chassis_linear_damping, "stability chassis-linear-damping" );
@ -694,7 +689,7 @@ void KartProperties::checkAllSet(const std::string &filename)
CHECK_NEG(m_brake_time_increase, "engine brake-time-increase" ); CHECK_NEG(m_brake_time_increase, "engine brake-time-increase" );
CHECK_NEG(m_suspension_stiffness, "suspension stiffness" ); CHECK_NEG(m_suspension_stiffness, "suspension stiffness" );
CHECK_NEG(m_suspension_rest, "suspension rest" ); CHECK_NEG(m_suspension_rest, "suspension rest" );
CHECK_NEG(m_suspension_travel_cm, "suspension travel-cm" ); CHECK_NEG(m_suspension_travel, "suspension travel" );
CHECK_NEG(m_max_suspension_force, "suspension max-force" ); CHECK_NEG(m_max_suspension_force, "suspension max-force" );
CHECK_NEG(m_collision_impulse, "collision impulse" ); CHECK_NEG(m_collision_impulse, "collision impulse" );
CHECK_NEG(m_collision_impulse_time, "collision impulse-time" ); CHECK_NEG(m_collision_impulse_time, "collision impulse-time" );
@ -754,7 +749,7 @@ void KartProperties::checkAllSet(const std::string &filename)
CHECK_NEG(m_explosion_invulnerability_time, CHECK_NEG(m_explosion_invulnerability_time,
"explosion invulnerability-time"); "explosion invulnerability-time");
CHECK_NEG(m_explosion_radius, "explosion radius" ); CHECK_NEG(m_explosion_radius, "explosion radius" );
CHECK_NEG(m_graphical_y_offset, "graphics y-offset" );
for(unsigned int i=RaceManager::DIFFICULTY_FIRST; for(unsigned int i=RaceManager::DIFFICULTY_FIRST;
i<=RaceManager::DIFFICULTY_LAST; i++) i<=RaceManager::DIFFICULTY_LAST; i++)
{ {

View File

@ -208,11 +208,6 @@ private:
* chassis. Useful for karts that don't have enough space for suspension * chassis. Useful for karts that don't have enough space for suspension
* compression. */ * compression. */
float m_graphical_y_offset; float m_graphical_y_offset;
/** A hard flag that moves the graphical chassis higher if it's insde
* the track. Might cause stuttering. */
bool m_prevent_chassis_in_terrain;
/** If the kart is supposed to have random wheel rotation at start. */
bool m_has_rand_wheels;
/** Max. length of plunger rubber band. */ /** Max. length of plunger rubber band. */
float m_rubber_band_max_length; float m_rubber_band_max_length;
/** Force of an attached rubber band. */ /** Force of an attached rubber band. */
@ -288,7 +283,6 @@ private:
float m_max_suspension_force; float m_max_suspension_force;
float m_friction_slip; float m_friction_slip;
float m_roll_influence; float m_roll_influence;
float m_wheel_radius;
/** Parameters for the speed-weighted objects */ /** Parameters for the speed-weighted objects */
SpeedWeightedObject::Properties m_speed_weighted_object_properties; SpeedWeightedObject::Properties m_speed_weighted_object_properties;
@ -324,7 +318,7 @@ private:
bool m_exp_spring_response; bool m_exp_spring_response;
float m_suspension_rest; float m_suspension_rest;
float m_suspension_travel_cm; float m_suspension_travel;
public: public:
/** STK can add an impulse to push karts away from the track in case /** STK can add an impulse to push karts away from the track in case
@ -571,22 +565,6 @@ public:
/** Returns roll influence. */ /** Returns roll influence. */
float getRollInfluence () const {return m_roll_influence; } float getRollInfluence () const {return m_roll_influence; }
// ------------------------------------------------------------------------
/** Returns wheel radius. */
float getWheelRadius () const {return m_wheel_radius; }
// ------------------------------------------------------------------------
/** Return the additional Y offset added to the y position of the graphical
* chassis. Useful for karts that don't have enough space for suspension
* compression. */
float getGraphicalYOffset() const {return m_graphical_y_offset; }
// ------------------------------------------------------------------------
/** A hard flag that moves the graphical chassis higher if it's insde
* the track. Might cause stuttering. */
bool getPreventChassisInTerrain() const
{
return m_prevent_chassis_in_terrain;
} // getPreventChassisInTerrain
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns parameters for the speed-weighted objects */ /** Returns parameters for the speed-weighted objects */
const SpeedWeightedObject::Properties& getSpeedWeightedObjectProperties() const const SpeedWeightedObject::Properties& getSpeedWeightedObjectProperties() const
@ -685,7 +663,7 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the amount the suspension can extend. */ /** Returns the amount the suspension can extend. */
float getSuspensionTravelCM () const {return m_suspension_travel_cm; } float getSuspensionTravel () const {return m_suspension_travel; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns if the spring should be exponentially dampened. */ /** Returns if the spring should be exponentially dampened. */
@ -926,9 +904,6 @@ public:
* animation. */ * animation. */
float getJumpAnimationTime() const { return m_jump_animation_time; } float getJumpAnimationTime() const { return m_jump_animation_time; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns true if wheels should have random rotation at start. */
bool hasRandomWheels() const { return m_has_rand_wheels; }
// ------------------------------------------------------------------------
/** Returns minimum time during which nitro is consumed when pressing nitro /** Returns minimum time during which nitro is consumed when pressing nitro
* key, to prevent using nitro in very short bursts * key, to prevent using nitro in very short bursts
*/ */

71
src/karts/patch Normal file
View File

@ -0,0 +1,71 @@
diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp
index de14bbe..47bbee9 100644
--- a/src/karts/kart.cpp
+++ b/src/karts/kart.cpp
@@ -2476,11 +2476,12 @@ void Kart::kartIsInRestNow()
for(int i=0; i<m_vehicle->getNumWheels(); i++)
{
const btWheelInfo &wi = m_vehicle->getWheelInfo(i);
- f += wi.m_chassisConnectionPointCS.getY()
- - wi.m_raycastInfo.m_suspensionLength - wi.m_wheelsRadius;
+ f += wi.m_raycastInfo.m_suspensionLength;
}
+ m_terrain_info->update(getTrans());
m_graphical_y_offset = f/m_vehicle->getNumWheels()
+ getKartProperties()->getGraphicalYOffset();
+ m_graphical_y_offset = m_kart_model->getLowestPoint() - (getXYZ().getY() - m_terrain_info->getHoT());
m_kart_model->setDefaultSuspension();
} // kartIsInRestNow
@@ -2595,11 +2596,6 @@ void Kart::updateGraphics(float dt, const Vec3& offset_xyz,
} // for i<num_wheels
const btWheelInfo &w = getVehicle()->getWheelInfo(0);
- // Determine the shadow position from the terrain Y position. This
- // leaves the shadow on the ground even if the kart is jumping because
- // of skidding (shadows are disabled when wheel are not on the track).
- m_shadow->update(m_terrain_info->getHoT() - getXYZ().getY()
- -m_skidding->getGraphicalJumpOffset());
// Recompute the default average suspension length, see
// kartIsInRestNow() how to get from y-offset to susp. len.
float av_sus_len = -m_graphical_y_offset
@@ -2628,6 +2624,9 @@ void Kart::updateGraphics(float dt, const Vec3& offset_xyz,
+ lean_height
- m_kart_model->getLowestPoint());
+ center_shift.setY(m_skidding->getGraphicalJumpOffset()
+ + lean_height
+ +m_graphical_y_offset);
center_shift = getTrans().getBasis() * center_shift;
Moveable::updateGraphics(dt, center_shift,
@@ -2637,6 +2636,14 @@ void Kart::updateGraphics(float dt, const Vec3& offset_xyz,
// how much the wheels need to rotate.
m_kart_model->update(dt, m_speed*dt, getSteerPercent(), m_speed);
+ // Determine the shadow position from the terrain Y position. This
+ // leaves the shadow on the ground even if the kart is jumping because
+ // of skidding (shadows are disabled when wheel are not on the track).
+ m_shadow->update( m_terrain_info->getHoT() - getXYZ().getY()
+ - m_skidding->getGraphicalJumpOffset()
+ - m_graphical_y_offset
+ - m_kart_model->getLowestPoint());
+
#ifdef XX
// cheap wheelie effect
if (m_controls.m_nitro)
diff --git a/src/karts/kart_model.cpp b/src/karts/kart_model.cpp
index 65879d3..36b03b7 100644
--- a/src/karts/kart_model.cpp
+++ b/src/karts/kart_model.cpp
@@ -813,7 +813,9 @@ void KartModel::update(float dt, float distance, float steer, float speed)
core::vector3df pos = m_wheel_graphics_position[i].toIrrVector();
const btWheelInfo &wi = m_kart->getVehicle()->getWheelInfo(i);
- pos.Y = -wi.m_raycastInfo.m_suspensionLength + m_wheel_graphics_radius[i] + getLowestPoint();
+ pos.Y += m_default_physics_suspension[i]
+ - wi.m_raycastInfo.m_suspensionLength
+ - getLowestPoint();
m_wheel_node[i]->setPosition(pos);
// Now calculate the new rotation: (old + change) mod 360

View File

@ -173,7 +173,13 @@ public:
{ {
return m_kart_info[kart_index].m_track_sector; return m_kart_info[kart_index].m_track_sector;
} // getTrackSector } // getTrackSector
// ------------------------------------------------------------------------
void setLastTriggeredCheckline(unsigned int kart_index, int index)
{
if (m_kart_info.size() == 0)
return;
m_kart_info[kart_index].m_track_sector.setLastTriggeredCheckline(index);
}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns how far the kart has driven so far (i.e. /** Returns how far the kart has driven so far (i.e.
* number-of-laps-finished times track-length plus distance-on-track. * number-of-laps-finished times track-length plus distance-on-track.

View File

@ -128,6 +128,7 @@ void OverWorld::update(float dt)
m_karts[n]->setEnergy(100.0f); m_karts[n]->setEnergy(100.0f);
} }
/*
TrackObjectManager* tom = getTrack()->getTrackObjectManager(); TrackObjectManager* tom = getTrack()->getTrackObjectManager();
PtrVector<TrackObject>& objects = tom->getObjects(); PtrVector<TrackObject>& objects = tom->getObjects();
for(unsigned int i=0; i<objects.size(); i++) for(unsigned int i=0; i<objects.size(); i++)
@ -145,6 +146,7 @@ void OverWorld::update(float dt)
obj->reset(); obj->reset();
} }
} }
*/
if (m_return_to_garage) if (m_return_to_garage)
{ {

View File

@ -83,7 +83,7 @@ btWheelInfo& btKart::addWheel(const btVector3& connectionPointCS,
ci.m_wheelsDampingCompression = tuning.m_suspensionCompression; ci.m_wheelsDampingCompression = tuning.m_suspensionCompression;
ci.m_wheelsDampingRelaxation = tuning.m_suspensionDamping; ci.m_wheelsDampingRelaxation = tuning.m_suspensionDamping;
ci.m_frictionSlip = tuning.m_frictionSlip; ci.m_frictionSlip = tuning.m_frictionSlip;
ci.m_maxSuspensionTravelCm = tuning.m_maxSuspensionTravelCm; ci.m_maxSuspensionTravel = tuning.m_maxSuspensionTravel;
ci.m_maxSuspensionForce = tuning.m_maxSuspensionForce; ci.m_maxSuspensionForce = tuning.m_maxSuspensionForce;
m_wheelInfo.push_back( btWheelInfo(ci)); m_wheelInfo.push_back( btWheelInfo(ci));
@ -112,7 +112,6 @@ void btKart::reset()
{ {
btWheelInfo &wheel = m_wheelInfo[i]; btWheelInfo &wheel = m_wheelInfo[i];
wheel.m_raycastInfo.m_suspensionLength = 0; wheel.m_raycastInfo.m_suspensionLength = 0;
wheel.m_rotation = 0;
updateWheelTransform(i, true); updateWheelTransform(i, true);
} }
m_visual_wheels_touch_ground = false; m_visual_wheels_touch_ground = false;
@ -159,16 +158,13 @@ void btKart::updateWheelTransform(int wheelIndex, bool interpolatedTransform)
btQuaternion steeringOrn(up,steering);//wheel.m_steering); btQuaternion steeringOrn(up,steering);//wheel.m_steering);
btMatrix3x3 steeringMat(steeringOrn); btMatrix3x3 steeringMat(steeringOrn);
btQuaternion rotatingOrn(right,-wheel.m_rotation);
btMatrix3x3 rotatingMat(rotatingOrn);
btMatrix3x3 basis2( btMatrix3x3 basis2(
right[0],fwd[0],up[0], right[0],fwd[0],up[0],
right[1],fwd[1],up[1], right[1],fwd[1],up[1],
right[2],fwd[2],up[2] right[2],fwd[2],up[2]
); );
wheel.m_worldTransform.setBasis(steeringMat * rotatingMat * basis2); wheel.m_worldTransform.setBasis(steeringMat * basis2);
wheel.m_worldTransform.setOrigin( wheel.m_worldTransform.setOrigin(
wheel.m_raycastInfo.m_hardPointWS wheel.m_raycastInfo.m_hardPointWS
+ wheel.m_raycastInfo.m_wheelDirectionWS + wheel.m_raycastInfo.m_wheelDirectionWS
@ -235,8 +231,8 @@ btScalar btKart::rayCast(unsigned int index)
updateWheelTransformsWS( wheel,false); updateWheelTransformsWS( wheel,false);
btScalar max_susp_len = wheel.getSuspensionRestLength()+wheel.m_wheelsRadius btScalar max_susp_len = wheel.getSuspensionRestLength()
+ wheel.m_maxSuspensionTravelCm*0.01f; + wheel.m_maxSuspensionTravel;
// Do a slightly longer raycast to see if the kart might soon hit the // Do a slightly longer raycast to see if the kart might soon hit the
// ground and some 'cushioning' is needed to avoid that the chassis // ground and some 'cushioning' is needed to avoid that the chassis
@ -266,13 +262,13 @@ btScalar btKart::rayCast(unsigned int index)
wheel.m_raycastInfo.m_triangle_index = rayResults.m_triangle_index;; wheel.m_raycastInfo.m_triangle_index = rayResults.m_triangle_index;;
wheel.m_raycastInfo.m_groundObject = &getFixedBody(); wheel.m_raycastInfo.m_groundObject = &getFixedBody();
wheel.m_raycastInfo.m_suspensionLength = depth - wheel.m_wheelsRadius; wheel.m_raycastInfo.m_suspensionLength = depth;
//clamp on max suspension travel //clamp on max suspension travel
btScalar minSuspensionLength = wheel.getSuspensionRestLength() btScalar minSuspensionLength = wheel.getSuspensionRestLength()
- wheel.m_maxSuspensionTravelCm*btScalar(0.01); - wheel.m_maxSuspensionTravel;
btScalar maxSuspensionLength = wheel.getSuspensionRestLength() btScalar maxSuspensionLength = wheel.getSuspensionRestLength()
+ wheel.m_maxSuspensionTravelCm*btScalar(0.01); + wheel.m_maxSuspensionTravel;
if (wheel.m_raycastInfo.m_suspensionLength < minSuspensionLength) if (wheel.m_raycastInfo.m_suspensionLength < minSuspensionLength)
{ {
wheel.m_raycastInfo.m_suspensionLength = minSuspensionLength; wheel.m_raycastInfo.m_suspensionLength = minSuspensionLength;
@ -524,15 +520,8 @@ void btKart::updateVehicle( btScalar step )
btScalar proj2 = fwd.dot(vel); btScalar proj2 = fwd.dot(vel);
wheel.m_deltaRotation = (proj2 * step) / (wheel.m_wheelsRadius);
wheel.m_rotation += wheel.m_deltaRotation;
} else
{
wheel.m_rotation += wheel.m_deltaRotation;
} }
//damping of rotation when not in contact
wheel.m_deltaRotation *= btScalar(0.99);
} }

View File

@ -37,7 +37,7 @@ public:
:m_suspensionStiffness(btScalar(5.88)), :m_suspensionStiffness(btScalar(5.88)),
m_suspensionCompression(btScalar(0.83)), m_suspensionCompression(btScalar(0.83)),
m_suspensionDamping(btScalar(0.88)), m_suspensionDamping(btScalar(0.88)),
m_maxSuspensionTravelCm(btScalar(500.)), m_maxSuspensionTravel(btScalar(5.)),
m_frictionSlip(btScalar(10.5)), m_frictionSlip(btScalar(10.5)),
m_maxSuspensionForce(btScalar(6000.)) m_maxSuspensionForce(btScalar(6000.))
{ {
@ -46,7 +46,7 @@ public:
btScalar m_suspensionStiffness; btScalar m_suspensionStiffness;
btScalar m_suspensionCompression; btScalar m_suspensionCompression;
btScalar m_suspensionDamping; btScalar m_suspensionDamping;
btScalar m_maxSuspensionTravelCm; btScalar m_maxSuspensionTravel;
btScalar m_frictionSlip; btScalar m_frictionSlip;
btScalar m_maxSuspensionForce; btScalar m_maxSuspensionForce;

View File

@ -172,7 +172,7 @@ void Physics::update(float dt)
Scripting::ScriptEngine* script_engine = World::getWorld()->getScriptEngine(); Scripting::ScriptEngine* script_engine = World::getWorld()->getScriptEngine();
int kartid1 = p->getUserPointer(0)->getPointerKart()->getWorldKartId(); int kartid1 = p->getUserPointer(0)->getPointerKart()->getWorldKartId();
int kartid2 = p->getUserPointer(1)->getPointerKart()->getWorldKartId(); int kartid2 = p->getUserPointer(1)->getPointerKart()->getWorldKartId();
script_engine->runFunction("void onKartKartCollision(int, int)", script_engine->runFunction(false, "void onKartKartCollision(int, int)",
[=](asIScriptContext* ctx) { [=](asIScriptContext* ctx) {
ctx->SetArgDWord(0, kartid1); ctx->SetArgDWord(0, kartid1);
ctx->SetArgDWord(1, kartid2); ctx->SetArgDWord(1, kartid2);
@ -201,7 +201,7 @@ void Physics::update(float dt)
if (scripting_function.size() > 0) if (scripting_function.size() > 0)
{ {
script_engine->runFunction("void " + scripting_function + "(int, const string, const string)", script_engine->runFunction(true, "void " + scripting_function + "(int, const string, const string)",
[&](asIScriptContext* ctx) { [&](asIScriptContext* ctx) {
ctx->SetArgDWord(0, kartId); ctx->SetArgDWord(0, kartId);
ctx->SetArgObject(1, lib_id_ptr); ctx->SetArgObject(1, lib_id_ptr);
@ -274,7 +274,7 @@ void Physics::update(float dt)
std::string scripting_function = obj->getOnItemCollisionFunction(); std::string scripting_function = obj->getOnItemCollisionFunction();
if (scripting_function.size() > 0) if (scripting_function.size() > 0)
{ {
script_engine->runFunction("void " + scripting_function + "(int, int, const string)", script_engine->runFunction(true, "void " + scripting_function + "(int, int, const string)",
[&](asIScriptContext* ctx) { [&](asIScriptContext* ctx) {
ctx->SetArgDWord(0, (int)flyable->getType()); ctx->SetArgDWord(0, (int)flyable->getType());
ctx->SetArgDWord(1, flyable->getOwnerId()); ctx->SetArgDWord(1, flyable->getOwnerId());

View File

@ -175,20 +175,20 @@ namespace Scripting
/** runs the specified script /** runs the specified script
* \param string scriptName = name of script to run * \param string scriptName = name of script to run
*/ */
void ScriptEngine::runFunction(std::string function_name) void ScriptEngine::runFunction(bool warn_if_not_found, std::string function_name)
{ {
std::function<void(asIScriptContext*)> callback; std::function<void(asIScriptContext*)> callback;
std::function<void(asIScriptContext*)> get_return_value; std::function<void(asIScriptContext*)> get_return_value;
runFunction(function_name, callback, get_return_value); runFunction(warn_if_not_found, function_name, callback, get_return_value);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void ScriptEngine::runFunction(std::string function_name, void ScriptEngine::runFunction(bool warn_if_not_found, std::string function_name,
std::function<void(asIScriptContext*)> callback) std::function<void(asIScriptContext*)> callback)
{ {
std::function<void(asIScriptContext*)> get_return_value; std::function<void(asIScriptContext*)> get_return_value;
runFunction(function_name, callback, get_return_value); runFunction(warn_if_not_found, function_name, callback, get_return_value);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -196,7 +196,7 @@ namespace Scripting
/** runs the specified script /** runs the specified script
* \param string scriptName = name of script to run * \param string scriptName = name of script to run
*/ */
void ScriptEngine::runFunction(std::string function_name, void ScriptEngine::runFunction(bool warn_if_not_found, std::string function_name,
std::function<void(asIScriptContext*)> callback, std::function<void(asIScriptContext*)> callback,
std::function<void(asIScriptContext*)> get_return_value) std::function<void(asIScriptContext*)> get_return_value)
{ {
@ -217,6 +217,9 @@ namespace Scripting
if (func == NULL) if (func == NULL)
{ {
if (warn_if_not_found)
Log::warn("Scripting", "Scripting function was not found : %s", function_name.c_str());
else
Log::debug("Scripting", "Scripting function was not found : %s", function_name.c_str()); Log::debug("Scripting", "Scripting function was not found : %s", function_name.c_str());
m_functions_cache[function_name] = NULL; // remember that this function is unavailable m_functions_cache[function_name] = NULL; // remember that this function is unavailable
return; return;
@ -233,6 +236,8 @@ namespace Scripting
if (func == NULL) if (func == NULL)
{ {
if (warn_if_not_found)
Log::warn("Scripting", "Scripting function was not found : %s", function_name.c_str());
return; // function unavailable return; // function unavailable
} }
@ -425,7 +430,7 @@ namespace Scripting
curr.m_time -= dt; curr.m_time -= dt;
if (curr.m_time <= 0.0) if (curr.m_time <= 0.0)
{ {
runFunction("void " + curr.m_callback_name + "()"); runFunction(true, "void " + curr.m_callback_name + "()");
m_pending_timeouts.erase(m_pending_timeouts.begin() + i); m_pending_timeouts.erase(m_pending_timeouts.begin() + i);
} }
} }

View File

@ -47,10 +47,10 @@ namespace Scripting
ScriptEngine(); ScriptEngine();
~ScriptEngine(); ~ScriptEngine();
void runFunction(std::string function_name); void runFunction(bool warn_if_not_found, std::string function_name);
void runFunction(std::string function_name, void runFunction(bool warn_if_not_found, std::string function_name,
std::function<void(asIScriptContext*)> callback); std::function<void(asIScriptContext*)> callback);
void runFunction(std::string function_name, void runFunction(bool warn_if_not_found, std::string function_name,
std::function<void(asIScriptContext*)> callback, std::function<void(asIScriptContext*)> callback,
std::function<void(asIScriptContext*)> get_return_value); std::function<void(asIScriptContext*)> get_return_value);
void evalScript(std::string script_fragment); void evalScript(std::string script_fragment);

View File

@ -101,11 +101,11 @@ namespace Scripting
return StringUtils::wide_to_utf8(out.c_str()); return StringUtils::wide_to_utf8(out.c_str());
} }
/** Runs the script specified by the given string */ /** Runs the script function specified by the given string */
void runScript(const std::string* str) void runScript(const std::string* str)
{ {
ScriptEngine* script_engine = World::getWorld()->getScriptEngine(); ScriptEngine* script_engine = World::getWorld()->getScriptEngine();
script_engine->runFunction(*str); script_engine->runFunction(true, *str);
} }
/** Generate a random integer value */ /** Generate a random integer value */

View File

@ -0,0 +1,77 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2009-2015 Joerg Henrichs
//
// 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
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "tracks/check_cylinder.hpp"
#include <string>
#include <stdio.h>
#include "io/xml_node.hpp"
#include "items/item.hpp"
#include "modes/world.hpp"
#include "race/race_manager.hpp"
CheckCylinder::CheckCylinder(const XMLNode &node, unsigned int index, TriggerItemListener* listener)
: CheckStructure(node, index)
{
m_radius2 = 1;
m_height = 0;
m_listener = listener;
node.get("height", &m_height);
node.get("radius", &m_radius2);
m_radius2 *= m_radius2;
node.get("xyz", &m_center_point);
unsigned int num_karts = race_manager->getNumberOfKarts();
m_is_inside.resize(num_karts);
m_distance2.resize(num_karts);
for (unsigned int i=0; i<num_karts; i++)
{
m_is_inside[i] = false;
}
} // CheckCylinder
// ----------------------------------------------------------------------------
/** True if going from old_pos to new_pos enters or leaves this sphere. This
* function is called from update (of the checkline structure). It also
* updates the flag about which karts are inside
* \param old_pos Position in previous frame.
* \param new_pos Position in current frame.
* \param kart_id Index of the kart, can be used to store kart specific
* additional data.
*/
bool CheckCylinder::isTriggered(const Vec3 &old_pos, const Vec3 &new_pos,
unsigned int kart_id)
{
// TODO: this is the code for a sphere, rewrite for cylinder
Vec3 old_pos_xz(old_pos.x(), 0.0f, old_pos.z());
Vec3 new_pos_xz(new_pos.x(), 0.0f, new_pos.z());
Vec3 center_xz(m_center_point.x(), 0.0f, m_center_point.z());
float old_dist2 = (old_pos_xz - center_xz).length2();
float new_dist2 = (new_pos_xz - center_xz).length2();
m_is_inside[kart_id] = new_dist2<m_radius2;
m_distance2[kart_id] = new_dist2;
// Trigger if the kart goes from outside (or border) to inside,
// or inside ro outside (or border).
bool triggered = (old_dist2>=m_radius2 && new_dist2 < m_radius2) ||
(old_dist2< m_radius2 && new_dist2 >=m_radius2);
if (triggered && m_listener != NULL)
m_listener->onTriggerItemApproached();
return triggered;
} // isTriggered

View File

@ -0,0 +1,69 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2009-2015 Joerg Henrichs
//
// 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
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_CHECK_CYLINDER_HPP
#define HEADER_CHECK_CYLINDER_HPP
#include "tracks/check_structure.hpp"
class XMLNode;
class CheckManager;
class TriggerItemListener;
/** This class implements a check sphere that is used to change the ambient
* light if a kart is inside this sphere. Besides a normal radius this
* sphere also has a 2nd 'inner' radius: player karts inside the inner
* radius will have the full new ambient light, karts outside the default
* light, and karts in between will mix the light dependent on distance.
*
* \ingroup tracks
*/
class CheckCylinder : public CheckStructure
{
private:
/** Center of the sphere. */
Vec3 m_center_point;
/** Squared radius of the cylinder. */
float m_radius2;
float m_height;
/** A flag for each kart to indicate if it's inside of the sphere. */
std::vector<bool> m_is_inside;
/** Stores the distance of each kart from the center of this sphere.
* This saves some computations. */
std::vector<float> m_distance2;
TriggerItemListener* m_listener;
public:
CheckCylinder(const XMLNode &node, unsigned int index,
TriggerItemListener* listener);
virtual ~CheckCylinder() {};
virtual bool isTriggered(const Vec3 &old_pos, const Vec3 &new_pos,
unsigned int kart_id);
// ------------------------------------------------------------------------
/** Returns if kart indx is currently inside of the sphere. */
bool isInside(int index) const { return m_is_inside[index]; }
// -------------------------------------------------------------------------
/** Returns the squared distance of kart index from the enter of
* this sphere. */
float getDistance2ForKart(int index) const { return m_distance2[index];}
// -------------------------------------------------------------------------
/** Returns the square of the radius of this sphere. */
float getRadius2() const { return m_radius2; }
}; // CheckCylinder
#endif

View File

@ -55,27 +55,42 @@ void CheckLap::reset(const Track &track)
* is called from update (of the checkline structure). * is called from update (of the checkline structure).
* \param old_pos Position in previous frame. * \param old_pos Position in previous frame.
* \param new_pos Position in current frame. * \param new_pos Position in current frame.
* \param indx Index of the kart, can be used to store kart specific * \param kart_index Index of the kart, can be used to store kart specific
* additional data. * additional data.
*/ */
bool CheckLap::isTriggered(const Vec3 &old_pos, const Vec3 &new_pos, bool CheckLap::isTriggered(const Vec3 &old_pos, const Vec3 &new_pos,
unsigned int indx) unsigned int kart_index)
{ {
float track_length = World::getWorld()->getTrack()->getTrackLength(); World* w = World::getWorld();
LinearWorld *lin_world = dynamic_cast<LinearWorld*>(World::getWorld()); LinearWorld* lin_world = dynamic_cast<LinearWorld*>(w);
if (lin_world != NULL)
{
lin_world->getTrackSector(kart_index).setLastTriggeredCheckline(m_index);
}
float track_length = w->getTrack()->getTrackLength();
// Can happen if a non-lap based race mode is used with a scene file that // Can happen if a non-lap based race mode is used with a scene file that
// has check defined. // has check defined.
if(!lin_world) if(!lin_world)
return false; return false;
float current_distance = lin_world->getDistanceDownTrackForKart(indx); float current_distance = lin_world->getDistanceDownTrackForKart(kart_index);
bool result =(m_previous_distance[indx]>0.95f*track_length && bool result = (m_previous_distance[kart_index]>0.95f*track_length &&
current_distance<7.0f); current_distance<7.0f);
if (UserConfigParams::m_check_debug && result) if (UserConfigParams::m_check_debug && result)
{
Log::info("CheckLap", "Kart %s crossed start line from %f to %f.", Log::info("CheckLap", "Kart %s crossed start line from %f to %f.",
World::getWorld()->getKart(indx)->getIdent().c_str(), World::getWorld()->getKart(kart_index)->getIdent().c_str(),
m_previous_distance[indx], current_distance); m_previous_distance[kart_index], current_distance);
}
m_previous_distance[indx] = current_distance; m_previous_distance[kart_index] = current_distance;
if (result)
{
LinearWorld* lw = dynamic_cast<LinearWorld*>(w);
if (lw != NULL)
lw->setLastTriggeredCheckline(kart_index, m_index);
}
return result; return result;
} // isTriggered } // isTriggered

View File

@ -22,6 +22,7 @@
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "io/xml_node.hpp" #include "io/xml_node.hpp"
#include "karts/abstract_kart.hpp" #include "karts/abstract_kart.hpp"
#include "modes/linear_world.hpp"
#include "modes/world.hpp" #include "modes/world.hpp"
#include "race/race_manager.hpp" #include "race/race_manager.hpp"
@ -151,14 +152,15 @@ void CheckLine::changeDebugColor(bool is_active)
* additional data. * additional data.
*/ */
bool CheckLine::isTriggered(const Vec3 &old_pos, const Vec3 &new_pos, bool CheckLine::isTriggered(const Vec3 &old_pos, const Vec3 &new_pos,
unsigned int indx) unsigned int kart_index)
{ {
World* w = World::getWorld();
core::vector2df p=new_pos.toIrrVector2d(); core::vector2df p=new_pos.toIrrVector2d();
bool sign = m_line.getPointOrientation(p)>=0; bool sign = m_line.getPointOrientation(p)>=0;
bool result; bool result;
// If the sign has changed, i.e. the infinite line was crossed somewhere, // If the sign has changed, i.e. the infinite line was crossed somewhere,
// check if the finite line was actually crossed: // check if the finite line was actually crossed:
if(sign!=m_previous_sign[indx] && if (sign != m_previous_sign[kart_index] &&
m_line.intersectWith(core::line2df(old_pos.toIrrVector2d(), m_line.intersectWith(core::line2df(old_pos.toIrrVector2d(),
new_pos.toIrrVector2d()), new_pos.toIrrVector2d()),
m_cross_point) ) m_cross_point) )
@ -175,17 +177,24 @@ bool CheckLine::isTriggered(const Vec3 &old_pos, const Vec3 &new_pos,
if(World::getWorld()->getNumKarts()>0) if(World::getWorld()->getNumKarts()>0)
Log::info("CheckLine", "Kart %s crosses line, but wrong height " Log::info("CheckLine", "Kart %s crosses line, but wrong height "
"(%f vs %f).", "(%f vs %f).",
World::getWorld()->getKart(indx)->getIdent().c_str(), World::getWorld()->getKart(kart_index)->getIdent().c_str(),
new_pos.getY(), m_min_height); new_pos.getY(), m_min_height);
else else
Log::info("CheckLine", "Kart %d crosses line, but wrong height " Log::info("CheckLine", "Kart %d crosses line, but wrong height "
"(%f vs %f).", "(%f vs %f).",
indx, new_pos.getY(), m_min_height); kart_index, new_pos.getY(), m_min_height);
} }
} }
else else
result = false; result = false;
m_previous_sign[indx] = sign; m_previous_sign[kart_index] = sign;
if (result)
{
LinearWorld* lw = dynamic_cast<LinearWorld*>(w);
if (lw != NULL)
lw->setLastTriggeredCheckline(kart_index, m_index);
}
return result; return result;
} // isTriggered } // isTriggered

View File

@ -59,8 +59,7 @@ void CheckManager::load(const XMLNode &node)
} }
else if(type=="check-sphere") else if(type=="check-sphere")
{ {
AmbientLightSphere *cs = new AmbientLightSphere(*check_node, CheckSphere *cs = new CheckSphere(*check_node, i);
i);
m_all_checks.push_back(cs); m_all_checks.push_back(cs);
} // checksphere } // checksphere
else else

View File

@ -44,6 +44,7 @@ private:
CheckManager() {m_all_checks.clear();}; CheckManager() {m_all_checks.clear();};
~CheckManager(); ~CheckManager();
public: public:
void add(CheckStructure* strct) { m_all_checks.push_back(strct); }
void load(const XMLNode &node); void load(const XMLNode &node);
void update(float dt); void update(float dt);
void reset(const Track &track); void reset(const Track &track);

View File

@ -198,13 +198,6 @@ void CheckStructure::changeStatus(const std::vector<int> &indices,
*/ */
void CheckStructure::trigger(unsigned int kart_index) void CheckStructure::trigger(unsigned int kart_index)
{ {
World* w = World::getWorld();
LinearWorld* lw = dynamic_cast<LinearWorld*>(w);
if (lw != NULL)
{
lw->getTrackSector(kart_index).setLastTriggeredCheckline(m_index);
}
switch(m_check_type) switch(m_check_type)
{ {
case CT_NEW_LAP : case CT_NEW_LAP :

View File

@ -1200,7 +1200,7 @@ bool Track::loadMainTrack(const XMLNode &root)
unsigned char result = -1; unsigned char result = -1;
Scripting::ScriptEngine* script_engine = World::getWorld()->getScriptEngine(); Scripting::ScriptEngine* script_engine = World::getWorld()->getScriptEngine();
std::function<void(asIScriptContext*)> null_callback; std::function<void(asIScriptContext*)> null_callback;
script_engine->runFunction("bool " + condition + "()", null_callback, script_engine->runFunction(true, "bool " + condition + "()", null_callback,
[&](asIScriptContext* ctx) { result = ctx->GetReturnByte(); }); [&](asIScriptContext* ctx) { result = ctx->GetReturnByte(); });
if (result == 0) if (result == 0)
continue; continue;
@ -1217,7 +1217,7 @@ bool Track::loadMainTrack(const XMLNode &root)
unsigned char result = -1; unsigned char result = -1;
Scripting::ScriptEngine* script_engine = World::getWorld()->getScriptEngine(); Scripting::ScriptEngine* script_engine = World::getWorld()->getScriptEngine();
std::function<void(asIScriptContext*)> null_callback; std::function<void(asIScriptContext*)> null_callback;
script_engine->runFunction("bool " + neg_condition + "()", null_callback, script_engine->runFunction(true, "bool " + neg_condition + "()", null_callback,
[&](asIScriptContext* ctx) { result = ctx->GetReturnByte(); }); [&](asIScriptContext* ctx) { result = ctx->GetReturnByte(); });
if (result != 0) if (result != 0)
continue; continue;
@ -1488,7 +1488,7 @@ void Track::update(float dt)
if (!m_startup_run) // first time running update = good point to run startup script if (!m_startup_run) // first time running update = good point to run startup script
{ {
Scripting::ScriptEngine* script_engine = World::getWorld()->getScriptEngine(); Scripting::ScriptEngine* script_engine = World::getWorld()->getScriptEngine();
script_engine->runFunction("void onStart()"); script_engine->runFunction(false, "void onStart()");
m_startup_run = true; m_startup_run = true;
} }
m_track_object_manager->update(dt); m_track_object_manager->update(dt);
@ -2444,8 +2444,7 @@ bool Track::findGround(AbstractKart *kart)
// length of the suspension with the weight of the kart resting on // length of the suspension with the weight of the kart resting on
// it). On the other hand this initial bouncing looks nice imho // it). On the other hand this initial bouncing looks nice imho
// - so I'll leave it in for now. // - so I'll leave it in for now.
float offset = kart->getKartProperties()->getSuspensionRest() + float offset = kart->getKartProperties()->getSuspensionRest();
kart->getKartProperties()->getWheelRadius();
t.setOrigin(hit_point+Vec3(0, offset, 0) ); t.setOrigin(hit_point+Vec3(0, offset, 0) );
kart->getBody()->setCenterOfMassTransform(t); kart->getBody()->setCenterOfMassTransform(t);
kart->setTrans(t); kart->setTrans(t);

View File

@ -71,9 +71,7 @@ TrackObject::TrackObject(const core::vector3df& xyz, const core::vector3df& hpr,
m_presentation = presentation; m_presentation = presentation;
m_is_driveable = false; m_is_driveable = false;
m_soccer_ball = false; m_soccer_ball = false;
m_garage = false;
m_initially_visible = false; m_initially_visible = false;
m_distance = 0;
m_type = ""; m_type = "";
if (m_interaction != "ghost" && m_interaction != "none" && if (m_interaction != "ghost" && m_interaction != "none" &&
@ -127,9 +125,6 @@ void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent,
m_soccer_ball = false; m_soccer_ball = false;
xml_node.get("soccer_ball", &m_soccer_ball); xml_node.get("soccer_ball", &m_soccer_ball);
m_garage = false;
m_distance = 0;
std::string type; std::string type;
xml_node.get("type", &type ); xml_node.get("type", &type );
@ -147,7 +142,7 @@ void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent,
unsigned char result = -1; unsigned char result = -1;
Scripting::ScriptEngine* script_engine = World::getWorld()->getScriptEngine(); Scripting::ScriptEngine* script_engine = World::getWorld()->getScriptEngine();
std::function<void(asIScriptContext*)> null_callback; std::function<void(asIScriptContext*)> null_callback;
script_engine->runFunction("bool " + condition + "()", null_callback, script_engine->runFunction(true, "bool " + condition + "()", null_callback,
[&](asIScriptContext* ctx) { result = ctx->GetReturnByte(); }); [&](asIScriptContext* ctx) { result = ctx->GetReturnByte(); });
if (result == 0) if (result == 0)
@ -179,16 +174,9 @@ void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent,
} }
else if (type == "action-trigger") else if (type == "action-trigger")
{ {
std::string m_action; std::string action;
xml_node.get("action", &m_action); xml_node.get("action", &action);
xml_node.get("distance", &m_distance); m_name = action; //adds action as name so that it can be found by using getName()
m_name = m_action;
//adds action as name so that it can be found by using getName()
if (m_action == "garage")
{
m_garage = true;
}
m_presentation = new TrackObjectPresentationActionTrigger(xml_node); m_presentation = new TrackObjectPresentationActionTrigger(xml_node);
} }
else if (type == "billboard") else if (type == "billboard")

View File

@ -80,13 +80,9 @@ protected:
bool m_soccer_ball; bool m_soccer_ball;
bool m_garage;
/** True if a kart can drive on this object. This will */ /** True if a kart can drive on this object. This will */
bool m_is_driveable; bool m_is_driveable;
float m_distance;
PhysicalObject* m_physical_object; PhysicalObject* m_physical_object;
ThreeDAnimation* m_animator; ThreeDAnimation* m_animator;
@ -161,10 +157,6 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
bool isSoccerBall() const { return m_soccer_ball; } bool isSoccerBall() const { return m_soccer_ball; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
bool isGarage() const { return m_garage; }
// ------------------------------------------------------------------------
float getDistance() const { return m_distance; }
// ------------------------------------------------------------------------
const PhysicalObject* getPhysicalObject() const { return m_physical_object; } const PhysicalObject* getPhysicalObject() const { return m_physical_object; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
PhysicalObject* getPhysicalObject() { return m_physical_object; } PhysicalObject* getPhysicalObject() { return m_physical_object; }

View File

@ -40,6 +40,9 @@
#include "modes/world.hpp" #include "modes/world.hpp"
#include "scriptengine/script_engine.hpp" #include "scriptengine/script_engine.hpp"
#include "states_screens/dialogs/tutorial_message_dialog.hpp" #include "states_screens/dialogs/tutorial_message_dialog.hpp"
#include "tracks/check_cylinder.hpp"
#include "tracks/check_manager.hpp"
#include "tracks/check_sphere.hpp"
#include "tracks/model_definition_loader.hpp" #include "tracks/model_definition_loader.hpp"
#include "tracks/track.hpp" #include "tracks/track.hpp"
#include "tracks/track_manager.hpp" #include "tracks/track_manager.hpp"
@ -649,7 +652,7 @@ void TrackObjectPresentationSound::update(float dt)
} // update } // update
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void TrackObjectPresentationSound::onTriggerItemApproached(Item* who) void TrackObjectPresentationSound::onTriggerItemApproached()
{ {
if (m_sound != NULL && m_sound->getStatus() != SFXBase::SFX_PLAYING) if (m_sound != NULL && m_sound->getStatus() != SFXBase::SFX_PLAYING)
{ {
@ -935,12 +938,40 @@ TrackObjectPresentationActionTrigger::TrackObjectPresentationActionTrigger(
xml_node.get("distance", &trigger_distance); xml_node.get("distance", &trigger_distance);
xml_node.get("action", &m_action ); xml_node.get("action", &m_action );
std::string trigger_type;
xml_node.get("trigger-type", &trigger_type);
if (trigger_type == "point")
{
m_type = TRIGGER_TYPE_POINT;
}
else if (trigger_type == "cylinder")
{
m_type = TRIGGER_TYPE_CYLINDER;
}
else
{
assert(false);
}
m_action_active = true; m_action_active = true;
if (m_action.size() == 0) if (m_action.size() == 0)
Log::warn("TrackObject", "Action-trigger has no action defined."); Log::warn("TrackObject", "Action-trigger has no action defined.");
if (m_type == TRIGGER_TYPE_POINT)
{
// TODO: rewrite as a sphere check structure?
ItemManager::get()->newItem(m_init_xyz, trigger_distance, this); ItemManager::get()->newItem(m_init_xyz, trigger_distance, this);
// CheckManager::get()->add(new CheckSphere(xml_node, 0 /* TODO what is this? */));
}
else if (m_type == TRIGGER_TYPE_CYLINDER)
{
CheckManager::get()->add(new CheckCylinder(xml_node, 0 /* TODO what is this? */, this));
}
else
{
assert(false);
}
} // TrackObjectPresentationActionTrigger } // TrackObjectPresentationActionTrigger
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -956,11 +987,12 @@ TrackObjectPresentationActionTrigger::TrackObjectPresentationActionTrigger(
float trigger_distance = distance; float trigger_distance = distance;
m_action = script_name; m_action = script_name;
m_action_active = true; m_action_active = true;
m_type = TRIGGER_TYPE_POINT;
ItemManager::get()->newItem(m_init_xyz, trigger_distance, this); ItemManager::get()->newItem(m_init_xyz, trigger_distance, this);
} // TrackObjectPresentationActionTrigger } // TrackObjectPresentationActionTrigger
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void TrackObjectPresentationActionTrigger::onTriggerItemApproached(Item* who) void TrackObjectPresentationActionTrigger::onTriggerItemApproached()
{ {
if (!m_action_active) return; if (!m_action_active) return;
@ -971,6 +1003,6 @@ void TrackObjectPresentationActionTrigger::onTriggerItemApproached(Item* who)
Camera* camera = Camera::getActiveCamera(); Camera* camera = Camera::getActiveCamera();
if (camera != NULL && camera->getKart() != NULL) if (camera != NULL && camera->getKart() != NULL)
idKart = camera->getKart()->getWorldKartId(); idKart = camera->getKart()->getWorldKartId();
script_engine->runFunction("void " + m_action + "(int)", script_engine->runFunction(true, "void " + m_action + "(int)",
[=](asIScriptContext* ctx) { ctx->SetArgDWord(0, idKart); }); [=](asIScriptContext* ctx) { ctx->SetArgDWord(0, idKart); });
} // onTriggerItemApproached } // onTriggerItemApproached

View File

@ -270,7 +270,7 @@ public:
TrackObjectPresentationSound(const XMLNode& xml_node, TrackObjectPresentationSound(const XMLNode& xml_node,
scene::ISceneNode* parent); scene::ISceneNode* parent);
virtual ~TrackObjectPresentationSound(); virtual ~TrackObjectPresentationSound();
virtual void onTriggerItemApproached(Item* who) OVERRIDE; virtual void onTriggerItemApproached() OVERRIDE;
virtual void update(float dt) OVERRIDE; virtual void update(float dt) OVERRIDE;
virtual void move(const core::vector3df& xyz, const core::vector3df& hpr, virtual void move(const core::vector3df& xyz, const core::vector3df& hpr,
const core::vector3df& scale, bool isAbsoluteCoord) OVERRIDE; const core::vector3df& scale, bool isAbsoluteCoord) OVERRIDE;
@ -349,6 +349,13 @@ public:
}; // TrackObjectPresentationLight }; // TrackObjectPresentationLight
// ============================================================================ // ============================================================================
enum ActionTriggerType
{
TRIGGER_TYPE_POINT = 0,
TRIGGER_TYPE_CYLINDER = 1
};
/** \ingroup tracks /** \ingroup tracks
* A track object representation that consists of an action trigger * A track object representation that consists of an action trigger
*/ */
@ -361,6 +368,8 @@ private:
bool m_action_active; bool m_action_active;
ActionTriggerType m_type;
public: public:
TrackObjectPresentationActionTrigger(const XMLNode& xml_node); TrackObjectPresentationActionTrigger(const XMLNode& xml_node);
TrackObjectPresentationActionTrigger(const core::vector3df& xyz, TrackObjectPresentationActionTrigger(const core::vector3df& xyz,
@ -369,7 +378,7 @@ public:
virtual ~TrackObjectPresentationActionTrigger() {} virtual ~TrackObjectPresentationActionTrigger() {}
virtual void onTriggerItemApproached(Item* who) OVERRIDE; virtual void onTriggerItemApproached() OVERRIDE;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Reset the trigger (i.e. sets it to active again). */ /** Reset the trigger (i.e. sets it to active again). */
virtual void reset() OVERRIDE { m_action_active = true; } virtual void reset() OVERRIDE { m_action_active = true; }