attempt at making suspension look better - made the view quadratic instead of linear (shows small moves more, big ones less), reduced amplitude to look less weird. (sorry hiker, my implementation may need to be reviewed :) The effect varies much from kart to kart, for instance on karts like hexley the effect is much more visible

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@2799 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
auria 2008-12-27 01:01:28 +00:00
parent 86c02f2a73
commit c32741b11a

View File

@ -32,18 +32,18 @@ float KartModel::UNDEFINED = -99.9f;
*/
KartModel::KartModel()
{
for(unsigned int i=0; i<4; i++)
{
m_wheel_graphics_position[i] = Vec3(UNDEFINED);
m_wheel_physics_position[i] = Vec3(UNDEFINED);
m_wheel_graphics_radius[i] = 0.0f; // for kart without separate wheels
m_wheel_model[i] = NULL;
m_min_suspension[i] = -99.9f;
m_max_suspension[i] = 99.9f;
}
m_wheel_filename[0] = "wheel-front-right.ac";
m_wheel_filename[1] = "wheel-front-left.ac";
m_wheel_filename[2] = "wheel-rear-right.ac";
for(unsigned int i=0; i<4; i++)
{
m_wheel_graphics_position[i] = Vec3(UNDEFINED);
m_wheel_physics_position[i] = Vec3(UNDEFINED);
m_wheel_graphics_radius[i] = 0.0f; // for kart without separate wheels
m_wheel_model[i] = NULL;
m_min_suspension[i] = -99.9f;
m_max_suspension[i] = 99.9f;
}
m_wheel_filename[0] = "wheel-front-right.ac";
m_wheel_filename[1] = "wheel-front-left.ac";
m_wheel_filename[2] = "wheel-rear-right.ac";
m_wheel_filename[3] = "wheel-rear-left.ac";
m_root = NULL;
@ -56,11 +56,11 @@ KartModel::KartModel()
*/
void KartModel::loadInfo(const lisp::Lisp* lisp)
{
lisp->get("model-file", m_model_filename);
loadWheelInfo(lisp, "wheel-front-right", 0);
loadWheelInfo(lisp, "wheel-front-left", 1);
loadWheelInfo(lisp, "wheel-rear-right", 2);
loadWheelInfo(lisp, "wheel-rear-left", 3);
lisp->get("model-file", m_model_filename);
loadWheelInfo(lisp, "wheel-front-right", 0);
loadWheelInfo(lisp, "wheel-front-left", 1);
loadWheelInfo(lisp, "wheel-rear-right", 2);
loadWheelInfo(lisp, "wheel-rear-left", 3);
} // init
// ----------------------------------------------------------------------------
/** Destructor.
@ -70,7 +70,7 @@ KartModel::~KartModel()
// This automatically frees the wheels and the kart model.
// m_root can be zero in case of STKConfig, which has a kart_properties
// attribute (for the default values) as well.
if(m_root) m_root->removeAllKids();
if(m_root) m_root->removeAllKids();
ssgDeRefDelete(m_root);
} // ~KartModel
@ -79,31 +79,31 @@ KartModel::~KartModel()
*/
void KartModel::loadModels()
{
ssgEntity *obj = loader->load(m_model_filename, CB_KART);
if(!obj)
{
fprintf(stderr, "Can't find kart model '%s'.\n",m_model_filename.c_str());
return;
}
m_root = new ssgTransform();
m_root->ref();
m_root->addKid(obj);
ssgStripify(obj);
Vec3 min, max;
SSGHelp::MinMax(obj, &min, &max);
m_z_offset = min.getZ();
m_kart_width = max.getX()-min.getX();
m_kart_length = max.getY()-min.getY();
m_kart_height = max.getZ()-min.getZ();
sgVec3 move_kart_to_0_z;
sgSetVec3(move_kart_to_0_z, 0, 0, m_z_offset);
m_root->setTransform(move_kart_to_0_z);
// Now set default some default parameters (if not defined) that
// depend on the size of the kart model (wheel position, center
// of gravity shift)
for(unsigned int i=0; i<4; i++)
{
ssgEntity *obj = loader->load(m_model_filename, CB_KART);
if(!obj)
{
fprintf(stderr, "Can't find kart model '%s'.\n",m_model_filename.c_str());
return;
}
m_root = new ssgTransform();
m_root->ref();
m_root->addKid(obj);
ssgStripify(obj);
Vec3 min, max;
SSGHelp::MinMax(obj, &min, &max);
m_z_offset = min.getZ();
m_kart_width = max.getX()-min.getX();
m_kart_length = max.getY()-min.getY();
m_kart_height = max.getZ()-min.getZ();
sgVec3 move_kart_to_0_z;
sgSetVec3(move_kart_to_0_z, 0, 0, m_z_offset);
m_root->setTransform(move_kart_to_0_z);
// Now set default some default parameters (if not defined) that
// depend on the size of the kart model (wheel position, center
// of gravity shift)
for(unsigned int i=0; i<4; i++)
{
if(m_wheel_graphics_position[i].getX()==UNDEFINED)
{
m_wheel_graphics_position[i].setX( ( i==1||i==3)
@ -111,72 +111,72 @@ void KartModel::loadModels()
: 0.5f*m_kart_width );
m_wheel_graphics_position[i].setY( (i<2) ? 0.5f*m_kart_length
: -0.5f*m_kart_length);
m_wheel_graphics_position[i].setZ(0);
}
}
// Load the wheel models. This can't be done early, since the default
// values for the graphical position must be defined, which in turn
// depend on the size of the model.
for(unsigned int i=0; i<4; i++)
{
m_wheel_model[i] = loader->load(m_wheel_filename[i], CB_KART);
m_wheel_graphics_position[i].setZ(0);
}
}
// Load the wheel models. This can't be done early, since the default
// values for the graphical position must be defined, which in turn
// depend on the size of the model.
for(unsigned int i=0; i<4; i++)
{
m_wheel_model[i] = loader->load(m_wheel_filename[i], CB_KART);
m_wheel_transform[i]= new ssgTransform();
#ifdef DEBUG
m_wheel_transform[i]->setName("wheeltransform");
#endif
if(m_wheel_model[i])
{
if(m_wheel_model[i])
{
m_wheel_transform[i]->addKid(m_wheel_model[i]);
m_root->addKid(m_wheel_transform[i]);
Vec3 min_wheel, max_wheel;
SSGHelp::MinMax(m_wheel_model[i], &min_wheel, &max_wheel);
m_wheel_graphics_radius[i] = (max_wheel.getZ()-min_wheel.getZ())*0.5f;
Vec3 min_wheel, max_wheel;
SSGHelp::MinMax(m_wheel_model[i], &min_wheel, &max_wheel);
m_wheel_graphics_radius[i] = (max_wheel.getZ()-min_wheel.getZ())*0.5f;
sgMat4 wheel_loc;
sgVec3 hpr;
sgZeroVec3(hpr);
sgMakeCoordMat4(wheel_loc, m_wheel_graphics_position[i].toFloat(),
hpr);
m_wheel_transform[i]->setTransform(wheel_loc);
} // if m_wheel_model[i]
} // for i<4
if(!m_wheel_model[0])
{
m_z_offset = m_kart_height*0.5f;
}
sgMakeCoordMat4(wheel_loc, m_wheel_graphics_position[i].toFloat(),
hpr);
m_wheel_transform[i]->setTransform(wheel_loc);
} // if m_wheel_model[i]
} // for i<4
if(!m_wheel_model[0])
{
m_z_offset = m_kart_height*0.5f;
}
} // load
// ----------------------------------------------------------------------------
/** Loads a single wheel node. Currently this is the name of the wheel model
* and the position of the wheel relative to the kart.
* \param wheel_name Name of the wheel, e.g. wheel-rear-left.
* \param index Index of this wheel in the global m_wheel* fields.
*/
void KartModel::loadWheelInfo(const lisp::Lisp* const lisp,
const std::string &wheel_name, int index)
{
const lisp::Lisp* const wheel = lisp->getLisp(wheel_name);
if(!wheel)
{
// Only print the warning if a model filename is given. Otherwise the
// stk_config file is read (which has no model information).
if(m_model_filename!="")
{
fprintf(stderr, "Missing wheel information '%s' for model '%s'.\n",
wheel_name.c_str(), m_model_filename.c_str());
fprintf(stderr, "This can be ignored, but the wheels will not rotate.\n");
}
return;
}
wheel->get("model", m_wheel_filename[index] );
wheel->get("position", m_wheel_graphics_position[index]);
wheel->get("physics-position", m_wheel_physics_position[index] );
wheel->get("min-suspension", m_min_suspension[index] );
wheel->get("max-suspension", m_max_suspension[index] );
} // loadWheelInfo
// ----------------------------------------------------------------------------
/** Loads a single wheel node. Currently this is the name of the wheel model
* and the position of the wheel relative to the kart.
* \param wheel_name Name of the wheel, e.g. wheel-rear-left.
* \param index Index of this wheel in the global m_wheel* fields.
*/
void KartModel::loadWheelInfo(const lisp::Lisp* const lisp,
const std::string &wheel_name, int index)
{
const lisp::Lisp* const wheel = lisp->getLisp(wheel_name);
if(!wheel)
{
// Only print the warning if a model filename is given. Otherwise the
// stk_config file is read (which has no model information).
if(m_model_filename!="")
{
fprintf(stderr, "Missing wheel information '%s' for model '%s'.\n",
wheel_name.c_str(), m_model_filename.c_str());
fprintf(stderr, "This can be ignored, but the wheels will not rotate.\n");
}
return;
}
wheel->get("model", m_wheel_filename[index] );
wheel->get("position", m_wheel_graphics_position[index]);
wheel->get("physics-position", m_wheel_physics_position[index] );
wheel->get("min-suspension", m_min_suspension[index] );
wheel->get("max-suspension", m_max_suspension[index] );
} // loadWheelInfo
// ----------------------------------------------------------------------------
/** Sets the default position for the physical wheels if they are not defined
* in the data file. The default position is to have the wheels at the corner
@ -189,23 +189,23 @@ void KartModel::loadWheelInfo(const lisp::Lisp* const lisp,
void KartModel::setDefaultPhysicsPosition(const Vec3 &center_shift,
float wheel_radius)
{
for(unsigned int i=0; i<4; i++)
{
if(m_wheel_physics_position[i].getX()==UNDEFINED)
{
for(unsigned int i=0; i<4; i++)
{
if(m_wheel_physics_position[i].getX()==UNDEFINED)
{
m_wheel_physics_position[i].setX( ( i==1||i==3)
? -0.5f*m_kart_width
: 0.5f*m_kart_width
+center_shift.getX( ));
: 0.5f*m_kart_width
+center_shift.getX( ));
m_wheel_physics_position[i].setY( (0.5f*m_kart_length-wheel_radius)
* ( (i<2) ? 1 : -1)
+center_shift.getY());
// Set the connection point so that a maximum compressed wheel
// (susp. length=0) will still poke a little bit out under the
// kart
m_wheel_physics_position[i].setZ(wheel_radius-0.05f);
} // if physics position is not defined
}
* ( (i<2) ? 1 : -1)
+center_shift.getY());
// Set the connection point so that a maximum compressed wheel
// (susp. length=0) will still poke a little bit out under the
// kart
m_wheel_physics_position[i].setZ(wheel_radius-0.05f);
} // if physics position is not defined
}
} // setDefaultPhysicsPosition
@ -227,9 +227,17 @@ void KartModel::adjustWheels(float rotation, float steer,
// the graphical wheel models don't look too wrong.
for(unsigned int i=0; i<4; i++)
{
clamped_suspension[i] = std::min(std::max(suspension[i],
m_min_suspension[i] = -1.3; // FIXME - why are these still not inited at this point?
m_max_suspension[i] = 1.3;
const float suspension_length = (m_max_suspension[i]-m_min_suspension[i])/2;
clamped_suspension[i] = std::min(std::max(suspension[i]/2.5f, // somewhat arbitrary constant to reduce visible wheel movement
m_min_suspension[i]),
m_max_suspension[i]);
m_max_suspension[i]);
float ratio = clamped_suspension[i] / suspension_length;
const int sign = ratio < 0 ? -1 : 1;
ratio = sign * fabsf(ratio*(2-ratio)); // expanded form of 1 - (1 - x)^2, i.e. making suspension display quadratic and not linear
clamped_suspension[i] = ratio*suspension_length;
} // for i<4
sgMakeRotMat4( wheel_rot, 0, RAD_TO_DEGREE(-rotation), 0);