Each kart instance has now its own copy of kart_model instead of a shared
version of it. This avoids animation issues (in some circumstances e.g. a win/lose animation could be shown for a kart still driving), and an assert crash (bug 3058787) is also avoided. Note that the animation issues are usually not easy to see since the random AI kart selection makes usually sure that the player kart is not used more than once, so this issue can only be seen in AI karts. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@5935 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
@@ -72,6 +72,14 @@ Kart::Kart (const std::string& ident, int position,
|
||||
{
|
||||
m_kart_properties = kart_properties_manager->getKart(ident);
|
||||
assert(m_kart_properties != NULL);
|
||||
// We have to take a copy of the kart model, since otherwise
|
||||
// the animations will be mixed up (i.e. different instances of
|
||||
// the same model will set different animation frames).
|
||||
// Technically the mesh in m_kart_model needs to be grab'ed and
|
||||
// released when the kart is deleted, but since the original
|
||||
// kart_model is stored in the kart_properties all the time,
|
||||
// there is no risk of a mesh being deleted to early.
|
||||
m_kart_model = *(m_kart_properties->getKartModel());
|
||||
m_initial_position = position;
|
||||
m_race_position = position;
|
||||
m_collected_energy = 0;
|
||||
@@ -183,10 +191,9 @@ void Kart::createPhysics()
|
||||
{
|
||||
// First: Create the chassis of the kart
|
||||
// -------------------------------------
|
||||
const KartModel *km = m_kart_properties->getKartModel();
|
||||
float kart_width = km->getWidth();
|
||||
float kart_length = km->getLength();
|
||||
float kart_height = km->getHeight();
|
||||
float kart_width = getKartWidth();
|
||||
float kart_length = getKartLength();
|
||||
float kart_height = getKartHeight();
|
||||
|
||||
btBoxShape *shape = new btBoxShape(btVector3(0.5f*kart_width,
|
||||
0.5f*kart_height,
|
||||
@@ -241,7 +248,7 @@ void Kart::createPhysics()
|
||||
{
|
||||
bool is_front_wheel = i<2;
|
||||
btWheelInfo& wheel = m_vehicle->addWheel(
|
||||
m_kart_properties->getKartModel()->getWheelPhysicsPosition(i),
|
||||
m_kart_model.getWheelPhysicsPosition(i),
|
||||
wheel_direction, wheel_axle, suspension_rest,
|
||||
wheel_radius, *m_tuning, is_front_wheel);
|
||||
wheel.m_suspensionStiffness = m_kart_properties->getSuspensionStiffness();
|
||||
@@ -367,7 +374,7 @@ void Kart::reset()
|
||||
}
|
||||
|
||||
// Stop any animations currently being played.
|
||||
m_kart_properties->getKartModel()->setAnimation(KartModel::AF_DEFAULT);
|
||||
m_kart_model.setAnimation(KartModel::AF_DEFAULT);
|
||||
// If the controller was replaced (e.g. replaced by end controller),
|
||||
// restore the original controller.
|
||||
if(m_saved_controller)
|
||||
@@ -375,7 +382,7 @@ void Kart::reset()
|
||||
m_controller = m_saved_controller;
|
||||
m_saved_controller = NULL;
|
||||
}
|
||||
m_kart_properties->getKartModel()->setAnimation(KartModel::AF_DEFAULT);
|
||||
m_kart_model.setAnimation(KartModel::AF_DEFAULT);
|
||||
m_view_blocked_by_plunger = 0.0;
|
||||
m_attachment->clear();
|
||||
m_powerup.reset();
|
||||
@@ -466,9 +473,9 @@ void Kart::finishedRace(float time)
|
||||
setController(new EndController(this, m_controller->getPlayer()));
|
||||
if(m_race_position<=0.5f*race_manager->getNumberOfKarts() ||
|
||||
m_race_position==1)
|
||||
m_kart_properties->getKartModel()->setAnimation(KartModel::AF_WIN_START);
|
||||
m_kart_model.setAnimation(KartModel::AF_WIN_START);
|
||||
else
|
||||
m_kart_properties->getKartModel()->setAnimation(KartModel::AF_LOSE_START);
|
||||
m_kart_model.setAnimation(KartModel::AF_LOSE_START);
|
||||
|
||||
// Not all karts have a camera
|
||||
if (m_camera) m_camera->setMode(Camera::CM_FINAL);
|
||||
@@ -485,9 +492,9 @@ void Kart::finishedRace(float time)
|
||||
// start end animation
|
||||
setController(new EndController(this, m_controller->getPlayer()));
|
||||
if(m_race_position<=2)
|
||||
m_kart_properties->getKartModel()->setAnimation(KartModel::AF_WIN_START);
|
||||
m_kart_model.setAnimation(KartModel::AF_WIN_START);
|
||||
else if(m_race_position>=0.7f*race_manager->getNumberOfKarts())
|
||||
m_kart_properties->getKartModel()->setAnimation(KartModel::AF_LOSE_START);
|
||||
m_kart_model.setAnimation(KartModel::AF_LOSE_START);
|
||||
|
||||
// Not all karts have a camera
|
||||
if (m_camera) m_camera->setMode(Camera::CM_REVERSE);
|
||||
@@ -1327,7 +1334,7 @@ void Kart::updatePhysics(float dt)
|
||||
*/
|
||||
void Kart::loadData()
|
||||
{
|
||||
m_kart_properties->getKartModel()->attachModel(&m_node);
|
||||
m_kart_model.attachModel(&m_node);
|
||||
// Attachment must be created after attachModel, since only then the
|
||||
// scene node will exist (to which the attachment is added). But the
|
||||
// attachment is needed in createPhysics (which gets the mass, which
|
||||
@@ -1403,7 +1410,6 @@ void Kart::updateGraphics(const Vec3& offset_xyz,
|
||||
const btQuaternion& rotation)
|
||||
{
|
||||
float wheel_up_axis[4];
|
||||
KartModel *kart_model = m_kart_properties->getKartModel();
|
||||
for(unsigned int i=0; i<4; i++)
|
||||
{
|
||||
// Set the suspension length
|
||||
@@ -1417,15 +1423,15 @@ void Kart::updateGraphics(const Vec3& offset_xyz,
|
||||
// auto_skid = m_controls.m_steer*30.0f*((auto_skid_visual - m_skidding) / 0.8f); // divisor comes from max_skid - AUTO_SKID_VISUAL
|
||||
// else
|
||||
auto_skid = m_controls.m_steer*30.0f;
|
||||
kart_model->update(m_wheel_rotation, auto_skid,
|
||||
getSteerPercent(), wheel_up_axis);
|
||||
m_kart_model.update(m_wheel_rotation, auto_skid,
|
||||
getSteerPercent(), wheel_up_axis);
|
||||
|
||||
Vec3 center_shift = getGravityCenterShift();
|
||||
float y = m_vehicle->getWheelInfo(0).m_chassisConnectionPointCS.getY()
|
||||
- m_default_suspension_length[0]
|
||||
- m_vehicle->getWheelInfo(0).m_wheelsRadius
|
||||
- (kart_model->getWheelGraphicsRadius(0)
|
||||
-kart_model->getWheelGraphicsPosition(0).getY() );
|
||||
- (m_kart_model.getWheelGraphicsRadius(0)
|
||||
-m_kart_model.getWheelGraphicsPosition(0).getY() );
|
||||
center_shift.setY(y);
|
||||
|
||||
if(m_smoke_system)
|
||||
|
||||
@@ -29,11 +29,13 @@
|
||||
#include "items/powerup.hpp"
|
||||
#include "karts/emergency_animation.hpp"
|
||||
#include "karts/moveable.hpp"
|
||||
#include "karts/kart_model.hpp"
|
||||
#include "karts/kart_properties.hpp"
|
||||
#include "karts/controller/controller.hpp"
|
||||
#include "karts/controller/kart_control.hpp"
|
||||
#include "karts/kart_model.hpp"
|
||||
#include "tracks/terrain_info.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
|
||||
class btKart;
|
||||
class btUprightConstraint;
|
||||
@@ -58,7 +60,8 @@ class WaterSplash;
|
||||
* and TerrainInfo, which manages the terrain the kart is on.
|
||||
* \ingroup karts
|
||||
*/
|
||||
class Kart : public TerrainInfo, public Moveable, public EmergencyAnimation
|
||||
class Kart : public TerrainInfo, public Moveable, public EmergencyAnimation,
|
||||
public NoCopy
|
||||
{
|
||||
private:
|
||||
/** Reset position. */
|
||||
@@ -201,7 +204,10 @@ private:
|
||||
|
||||
protected:
|
||||
const KartProperties *m_kart_properties;
|
||||
|
||||
/** This stores a copy of the kart model. It has to be a copy
|
||||
* since otherwise incosistencies can happen if the same kart
|
||||
* is used more than once. */
|
||||
KartModel m_kart_model;
|
||||
|
||||
public:
|
||||
Kart(const std::string& ident, int position,
|
||||
@@ -334,14 +340,12 @@ public:
|
||||
float getMaxSpeedOnTerrain() const {return m_max_speed-
|
||||
m_max_speed_reduction; }
|
||||
/** Returns the length of the kart. */
|
||||
float getKartLength () const
|
||||
{return m_kart_properties->getKartModel()->getLength(); }
|
||||
float getKartLength () const {return m_kart_model.getLength(); }
|
||||
/** Returns the height of the kart. */
|
||||
float getKartHeight () const
|
||||
{return m_kart_properties->getKartModel()->getHeight(); }
|
||||
float getKartHeight () const {return m_kart_model.getHeight(); }
|
||||
/** Returns the width of the kart. */
|
||||
float getKartWidth () const
|
||||
{return m_kart_properties->getKartModel()->getWidth(); }
|
||||
float getKartWidth () const {return m_kart_model.getWidth(); }
|
||||
/** Returns the bullet vehicle which represents this kart. */
|
||||
btKart *getVehicle () const {return m_vehicle; }
|
||||
btUprightConstraint *getUprightConstraint() const {return m_uprightConstraint;}
|
||||
void createPhysics ();
|
||||
|
||||
@@ -28,8 +28,18 @@
|
||||
|
||||
float KartModel::UNDEFINED = -99.9f;
|
||||
|
||||
/** The constructor reads the model file name and wheel specification from the
|
||||
* kart config file.
|
||||
/** Default constructor which initialises all variables with defaults.
|
||||
* Note that the KartModel is copied, so make sure that all variables
|
||||
* are safe to be copied, or write a custom copy function.
|
||||
* ATM there are two pointers:
|
||||
* - to the scene node (which is otherwise handled by kart and set
|
||||
* later anyway)
|
||||
* - to the mesh. Sharing mesh is supported in irrlicht, so that's
|
||||
* no problem.
|
||||
* Technically the scene node and mesh should be grab'ed on copy,
|
||||
* and dropped when the copy is deleted. But since the master copy
|
||||
* in the kart_properties_manager is always kept, there is no risk of
|
||||
* a mesh being deleted to early.
|
||||
*/
|
||||
KartModel::KartModel()
|
||||
{
|
||||
@@ -94,6 +104,12 @@ void KartModel::loadInfo(const XMLNode &node)
|
||||
*/
|
||||
KartModel::~KartModel()
|
||||
{
|
||||
for(unsigned int i=0; i<4; i++)
|
||||
{
|
||||
m_wheel_node[i]->remove();
|
||||
//m_wheel_node[i]->drop();
|
||||
}
|
||||
|
||||
} // ~KartModel
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -125,13 +141,13 @@ void KartModel::attachModel(scene::ISceneNode **node)
|
||||
|
||||
for(unsigned int i=0; i<4; i++)
|
||||
{
|
||||
m_wheel_node[i] = irr_driver->addMesh(m_wheel_model[i]);
|
||||
m_wheel_node[i]->setPosition(m_wheel_graphics_position[i].toIrrVector());
|
||||
m_wheel_node[i] = irr_driver->addMesh(m_wheel_model[i],
|
||||
*node);
|
||||
#ifdef DEBUG
|
||||
std::string debug_name = m_wheel_filename[i]+" (wheel)";
|
||||
m_wheel_node[i]->setName(debug_name.c_str());
|
||||
#endif
|
||||
(*node)->addChild(m_wheel_node[i]);
|
||||
m_wheel_node[i]->setPosition(m_wheel_graphics_position[i].toIrrVector());
|
||||
}
|
||||
} // attachModel
|
||||
|
||||
|
||||
@@ -213,8 +213,6 @@ void KartProperties::getAllData(const XMLNode * root)
|
||||
|
||||
root->get("groups", &m_groups );
|
||||
|
||||
//m_kart_model.loadInfo(lisp);
|
||||
|
||||
if(const XMLNode *dimensions_node = root->getNode("center"))
|
||||
dimensions_node->get("gravity-shift", &m_gravity_center_shift);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user