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:
parent
86c02f2a73
commit
c32741b11a
@ -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 ¢er_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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user