1) Separated the wheel from the kart models. This is necessary

for irrlicht, simplifies the handling of the karts.
2) Current suspension is now used to display the wheels of karts.
   This currently only works for tuxkart, all other models still 
   need to be modified (and these models will not display any
   steering atm).
3) Refactored kart model handling: all plib specific kart model
   handling is now encapsulated in karts/kart_model.?pp
4) Moved some files into new subdirs.



git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@2413 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2008-11-07 01:05:52 +00:00
parent 5ef8a26157
commit c553ec77ee
23 changed files with 723 additions and 357 deletions

View File

@ -46,6 +46,7 @@
(corn-f 4 )
(corn-r 4 )
(wheelie-max-speed-ratio 0.7 ) ;; percentage of max speed for wheelies to work
(gravity-center-shift 0 0 0.3)
(wheelie-max-pitch 45.0 ) ;; maximum pitch to use when doing a wheelie
(wheelie-pitch-rate 60.0 ) ;; rate/sec with which the kart goes up
(wheelie-restore-rate 90.0 ) ;; rate/sec with which the kart does down
@ -63,7 +64,7 @@
;; allows for tighter turns at lower speeds
(min-speed-angle 0 19)
(max-speed-angle 12 6.4)
(engine-power 400 )
(engine-power 400 )
(mass 225 )
(suspension-stiffness 48.0 )
(wheel-damping-relaxation 20 )
@ -76,9 +77,6 @@
(chassis-angular-damping 0.2 )
(maximum-speed 22.22 ) ;; = 80 km/h
(max-speed-reverse-ratio 0.2 ) ;; percentage of max speed for reverse gear
(gravity-center-shift 0.0 0.0 0.3 ) ;; Shift center of gravity
(front-wheel-connection 0.38 0.6 0)
(rear-wheel-connection 0.38 -0.6 0)
(suspension-rest 0.2 )
(suspension-travel-cm 19 )
@ -93,7 +91,12 @@
;; 0.5 means: if speed <=0.5 *maxSpeed --> gear 2
;; The next vector contains the increase in max power (to simulate different
;; gears), e.g. 2.5 as first entry means: 2.5*maxPower in gear 1
;; | first | second | third |
;; | first | second | third |
(wheel-front-right (physics-position 0.38 0.6 0))
(wheel-front-left (physics-position -0.38 0.6 0))
(wheel-rear-right (physics-position 0.38 -0.6 0))
(wheel-rear-left (physics-position -0.38 -0.6 0))
(gear-switch-ratio 0.25 0.7 1.0)
(gear-power-increase 2.2 1.7 1.3)
(upright-tolerance 0.2)

View File

@ -66,6 +66,7 @@ supertuxkart_SOURCES = main.cpp \
items/missile.cpp items/missile.hpp \
items/cake.cpp items/cake.hpp \
items/bowling.cpp items/bowling.hpp \
karts/kart_model.cpp karts/kart_model.hpp \
smoke.cpp smoke.hpp \
input.hpp kart_control.hpp \
isect.cpp isect.hpp \
@ -88,7 +89,6 @@ supertuxkart_SOURCES = main.cpp \
moving_physics.hpp moving_physics.cpp \
moving_texture.hpp moving_texture.cpp \
callback_manager.cpp callback_manager.hpp \
physics.cpp physics.hpp \
skid_mark.cpp skid_mark.hpp \
shadow.cpp shadow.hpp \
particle_system.cpp particle_system.hpp \
@ -142,19 +142,21 @@ supertuxkart_SOURCES = main.cpp \
gui/grand_prix_select.cpp gui/grand_prix_select.hpp \
gui/challenges_menu.cpp gui/challenges_menu.hpp \
gui/feature_unlocked.cpp gui/feature_unlocked.hpp \
gui/font.hpp gui/font.cpp \
gui/font.hpp gui/font.cpp \
physics/physics.cpp physics/physics.hpp \
physics/kart_motion_state.hpp \
robots/default_robot.cpp robots/default_robot.hpp \
modes/follow_the_leader.cpp modes/follow_the_leader.hpp \
modes/standard_race.cpp modes/standard_race.hpp \
modes/clock.cpp modes/clock.hpp \
modes/world.cpp modes/world.hpp \
modes/linear_world.cpp modes/linear_world.hpp \
modes/standard_race.cpp modes/standard_race.hpp \
modes/clock.cpp modes/clock.hpp \
modes/world.cpp modes/world.hpp \
modes/linear_world.cpp modes/linear_world.hpp \
modes/three_strikes_battle.cpp modes/three_strikes_battle.hpp \
replay_buffer_tpl.hpp \
replay_buffers.hpp replay_buffers.cpp \
replay_base.hpp replay_base.cpp \
replay_buffers.hpp replay_buffers.cpp \
replay_base.hpp replay_base.cpp \
replay_player.hpp replay_player.cpp \
replay_recorder.hpp replay_recorder.cpp \
replay_recorder.hpp replay_recorder.cpp \
ide/vc8/supertuxkart.sln ide/vc8/supertuxkart.vcproj \
ide/vc8/bullet_lib.vcproj ide/vc8/README \
ide/vc9/supertuxkart.sln ide/vc9/supertuxkart.vcproj \

View File

@ -26,11 +26,13 @@ class btKart : public btRaycastVehicle
{
void defaultInit(const btVehicleTuning& tuning);
btScalar m_track_connect_accel;
btScalar m_skidding_factor;
public:
btKart(const btVehicleTuning& tuning,btRigidBody* chassis,
btVehicleRaycaster* raycaster, float track_connect_accel );
virtual ~btKart() ;
btScalar rayCast(btWheelInfo& wheel);
void setSkidding(btScalar sf) { m_skidding_factor = sf; }
virtual void updateVehicle(btScalar step);
void resetSuspension();
void setRaycastWheelInfo(int wheelIndex , bool isInContact,

View File

@ -188,7 +188,7 @@ void Camera::update (float dt)
// The reverse mode and the cam used in follow the leader mode (when a
// kart has been eliminated) are facing backwards:
bool reverse = m_mode==CM_REVERSE || m_mode==CM_LEADER_MODE;
Vec3 cam_rel_pos(0.f, -m_distance, reverse ? 0.75f : 1.5f) ;
Vec3 cam_rel_pos(0.f, -m_distance, reverse ? 0.75f : 1.5f);
// Set the camera rotation
// -----------------------

View File

@ -31,6 +31,7 @@
#include "material.hpp"
#include "unlock_manager.hpp"
#include "translation.hpp"
#include "karts/kart_model.hpp"
#include "network/network_manager.hpp"
#if defined(WIN32) && !defined(__CYGWIN__)
@ -242,6 +243,7 @@ void CharSel::switchGroup()
if(kart_properties_manager->kartAvailable(karts[i]))
{
m_index_avail_karts.push_back(karts[i]);
kart_properties_manager->getKartById(karts[i])->getKartModel()->resetWheels();
}
}
@ -307,9 +309,9 @@ void CharSel::switchCharacter(int n)
ssgDeRefDelete(m_kart);
m_kart = new ssgTransform;
m_kart->ref();
ssgEntity* kartentity = kp->getModel();
KartModel* kartentity = kp->getKartModel();
m_kart->addKid(kartentity);
m_kart->addKid(kartentity->getRoot());
}
} // switchCharacter

View File

@ -21,11 +21,12 @@
#include <sstream>
#include <string>
#if defined(WIN32) && !defined(__CYGWIN__)
# define snprintf _snprintf
#endif
#include <SDL/SDL.h>
#include "audio/sfx_manager.hpp"
#include "audio/sfx_base.hpp"
#include "loader.hpp"
#include "kart_properties_manager.hpp"
#include "unlock_manager.hpp"
@ -37,9 +38,9 @@
#include "translation.hpp"
#include "kart.hpp"
#include "scene.hpp"
#if defined(WIN32) && !defined(__CYGWIN__)
# define snprintf _snprintf
#endif
#include "audio/sfx_manager.hpp"
#include "audio/sfx_base.hpp"
#include "karts/kart_model.hpp"
enum WidgetTokens
{
@ -156,8 +157,8 @@ GrandPrixEnd::GrandPrixEnd()
m_kart = new ssgTransform;
m_kart->ref();
ssgEntity* kartentity = WINNING_KART->getModel();
m_kart->addKid(kartentity);
KartModel* kartentity = WINNING_KART->getKartModel();
m_kart->addKid(kartentity->getRoot());
m_winner_sound->play();

View File

@ -24,10 +24,9 @@
#include "track.hpp"
#include "menu_manager.hpp"
#include "user_config.hpp"
#include "material.hpp"
#include "material_manager.hpp"
#include "unlock_manager.hpp"
#include "translation.hpp"
#include "unlock_manager.hpp"
#if defined(WIN32) && !defined(__CYGWIN__)
# define snprintf _snprintf
#endif

View File

@ -763,10 +763,6 @@
RelativePath="../../../src\particle_system.cpp"
>
</File>
<File
RelativePath="../../../src\physics.cpp"
>
</File>
<File
RelativePath="../../../src\player_kart.cpp"
>
@ -1167,6 +1163,22 @@
>
</File>
</Filter>
<Filter
Name="physics"
>
<File
RelativePath="..\..\physics\physics.cpp"
>
</File>
</Filter>
<Filter
Name="karts"
>
<File
RelativePath="..\..\karts\kart_model.cpp"
>
</File>
</Filter>
</Filter>
<Filter
Name="Headerdateien"
@ -1301,10 +1313,6 @@
RelativePath="../../../src\particle_system.hpp"
>
</File>
<File
RelativePath="../../../src\physics.hpp"
>
</File>
<File
RelativePath="../../../src\player.hpp"
>
@ -1773,6 +1781,26 @@
>
</File>
</Filter>
<Filter
Name="physics"
>
<File
RelativePath="..\..\physics\kart_motion_state.hpp"
>
</File>
<File
RelativePath="..\..\physics\physics.hpp"
>
</File>
</Filter>
<Filter
Name="karts"
>
<File
RelativePath="..\..\karts\kart_model.hpp"
>
</File>
</Filter>
</Filter>
<Filter
Name="Ressourcendateien"

View File

@ -38,18 +38,19 @@
#include "shadow.hpp"
#include "track.hpp"
#include "kart.hpp"
#include "physics.hpp"
#include "translation.hpp"
#include "smoke.hpp"
#include "material_manager.hpp"
#include "kart_properties_manager.hpp"
#include "gui/menu_manager.hpp"
#include "gui/race_gui.hpp"
#include "audio/sound_manager.hpp"
#include "audio/sfx_manager.hpp"
#include "audio/sfx_base.hpp"
#include "gui/menu_manager.hpp"
#include "gui/race_gui.hpp"
#include "karts/kart_model.hpp"
#include "network/race_state.hpp"
#include "network/network_manager.hpp"
#include "physics/physics.hpp"
#include "utils/ssg_help.hpp"
@ -100,14 +101,9 @@ Kart::Kart (const std::string& kart_name, int position,
m_rescue = false;
m_wheel_rotation = 0;
m_wheel_front_l = NULL;
m_wheel_front_r = NULL;
m_wheel_rear_l = NULL;
m_wheel_rear_r = NULL;
m_engine_sound = sfx_manager->newSFX(SFXManager::SOUND_ENGINE);
m_beep_sound = sfx_manager->newSFX(SFXManager::SOUND_BEEP);
m_crash_sound = sfx_manager->newSFX(SFXManager::SOUND_CRASH);
m_beep_sound = sfx_manager->newSFX(SFXManager::SOUND_BEEP);
m_crash_sound = sfx_manager->newSFX(SFXManager::SOUND_CRASH);
if(!m_engine_sound)
{
@ -141,14 +137,14 @@ btTransform Kart::getKartHeading(const float customPitch)
} // getKartHeading
// ----------------------------------------------------------------------------
void Kart::createPhysics(ssgEntity *obj)
void Kart::createPhysics()
{
// First: Create the chassis of the kart
// -------------------------------------
float kart_width = m_kart_properties->getKartWidth();
float kart_length = m_kart_properties->getKartLength();
float kart_height = m_kart_properties->getKartHeight();
const KartModel *km = m_kart_properties->getKartModel();
float kart_width = km->getWidth();
float kart_length = km->getLength();
float kart_height = km->getHeight();
btBoxShape *shape = new btBoxShape(btVector3(0.5f*kart_width,
0.5f*kart_length,
@ -158,7 +154,6 @@ void Kart::createPhysics(ssgEntity *obj)
// Shift center of gravity downwards, so that the kart
// won't topple over too easy.
shiftCenterOfGravity.setOrigin(getGravityCenterShift());
m_kart_chassis.addChildShape(shiftCenterOfGravity, shape);
// Set mass and inertia
@ -196,47 +191,16 @@ void Kart::createPhysics(ssgEntity *obj)
// ----------
float wheel_radius = m_kart_properties->getWheelRadius();
float suspension_rest = m_kart_properties->getSuspensionRest();
Vec3 front_wheel = m_kart_properties->getFrontWheelConnection();
if(front_wheel.getX()==STKConfig::UNDEFINED)
front_wheel.setX(0.5f*kart_width);
if(front_wheel.getY()==STKConfig::UNDEFINED)
front_wheel.setY(0.5f*kart_length-wheel_radius);
if(front_wheel.getZ()==STKConfig::UNDEFINED)
front_wheel.setZ(0);
btVector3 wheel_direction(0.0f, 0.0f, -1.0f);
btVector3 wheel_axle(1.0f,0.0f,0.0f);
// right front wheel
m_vehicle->addWheel(front_wheel, wheel_direction, wheel_axle,
suspension_rest, wheel_radius, *m_tuning,
/* isFrontWheel: */ true);
// left front wheel: mirror X axis
front_wheel.setX(-front_wheel.getX());
m_vehicle->addWheel(front_wheel, wheel_direction, wheel_axle,
suspension_rest, wheel_radius, *m_tuning,
/* isFrontWheel: */ true);
// right rear wheel
Vec3 rear_wheel = m_kart_properties->getRearWheelConnection();
if(rear_wheel.getX()==STKConfig::UNDEFINED)
rear_wheel.setX(0.5f*kart_width);
if(rear_wheel.getY()==STKConfig::UNDEFINED)
rear_wheel.setY(-0.5f*kart_length+wheel_radius);
if(rear_wheel.getZ()==STKConfig::UNDEFINED)
rear_wheel.setZ(0);
m_vehicle->addWheel(rear_wheel, wheel_direction, wheel_axle,
suspension_rest, wheel_radius, *m_tuning,
/* isFrontWheel: */ false);
// left rear wheel: mirror X axis
rear_wheel.setX(-rear_wheel.getX());
m_vehicle->addWheel(rear_wheel, wheel_direction, wheel_axle,
suspension_rest, wheel_radius, *m_tuning,
/* isFrontWheel: */ false);
for(int i=0; i<m_vehicle->getNumWheels(); i++)
for(unsigned int i=0; i<4; i++)
{
bool is_front_wheel = i<2;
m_vehicle->addWheel(m_kart_properties->getKartModel()->getWheelPhysicsPosition(i),
wheel_direction, wheel_axle, suspension_rest,
wheel_radius, *m_tuning, is_front_wheel);
btWheelInfo& wheel = m_vehicle->getWheelInfo(i);
wheel.m_suspensionStiffness = m_kart_properties->getSuspensionStiffness();
wheel.m_wheelsDampingRelaxation = m_kart_properties->getWheelDampingRelaxation();
@ -281,17 +245,7 @@ Kart::~Kart()
if(m_smokepuff) delete m_smokepuff;
if(m_smoke_system != NULL) delete m_smoke_system;
sgMat4 wheel_steer;
sgMakeIdentMat4(wheel_steer);
if (m_wheel_front_l) m_wheel_front_l->setTransform(wheel_steer);
if (m_wheel_front_r) m_wheel_front_r->setTransform(wheel_steer);
ssgDeRefDelete(m_shadow);
ssgDeRefDelete(m_wheel_front_l);
ssgDeRefDelete(m_wheel_front_r);
ssgDeRefDelete(m_wheel_rear_l);
ssgDeRefDelete(m_wheel_rear_r);
if(m_skidmark_left ) delete m_skidmark_left ;
if(m_skidmark_right) delete m_skidmark_right;
@ -617,8 +571,8 @@ void Kart::update(float dt)
item_manager->hitItem(this);
processSkidMarks();
} // update
}
//-----------------------------------------------------------------------------
// Set zipper time, and apply one time additional speed boost
void Kart::handleZipper()
@ -645,8 +599,8 @@ void Kart::draw()
t.getOpenGLMatrix(m);
btVector3 wire_color(0.5f, 0.5f, 0.5f);
RaceManager::getWorld()->getPhysics()->debugDraw(m, m_body->getCollisionShape(),
wire_color);
//RaceManager::getWorld()->getPhysics()->debugDraw(m, m_body->getCollisionShape(),
// wire_color);
btCylinderShapeX wheelShape( btVector3(0.1f,
m_kart_properties->getWheelRadius(),
m_kart_properties->getWheelRadius()));
@ -834,7 +788,7 @@ void Kart::updatePhysics (float dt)
// when going faster, use higher pitch for engine
if(m_engine_sound && sfx_manager->sfxAllowed())
{
m_engine_sound->speed(0.6 + (float)(m_speed / max_speed)*0.7f);
m_engine_sound->speed(0.6f + (float)(m_speed / max_speed)*0.7f);
m_engine_sound->position(getXYZ());
}
@ -899,44 +853,6 @@ void Kart::processSkidMarks()
}
} // processSkidMarks
//-----------------------------------------------------------------------------
void Kart::load_wheels(ssgBranch* branch)
{
if (!branch) return;
for(ssgEntity* i = branch->getKid(0); i != NULL; i = branch->getNextKid())
{
if (i->getName())
{ // We found something that might be a wheel
if (strcmp(i->getName(), "WheelFront.L") == 0)
{
m_wheel_front_l = SSGHelp::add_transform(dynamic_cast<ssgTransform*>(i));
}
else if (strcmp(i->getName(), "WheelFront.R") == 0)
{
m_wheel_front_r = SSGHelp::add_transform(dynamic_cast<ssgTransform*>(i));
}
else if (strcmp(i->getName(), "WheelRear.L") == 0)
{
m_wheel_rear_l = SSGHelp::add_transform(dynamic_cast<ssgTransform*>(i));
}
else if (strcmp(i->getName(), "WheelRear.R") == 0)
{
m_wheel_rear_r = SSGHelp::add_transform(dynamic_cast<ssgTransform*>(i));
}
else
{
// Wasn't a wheel, continue searching
load_wheels(dynamic_cast<ssgBranch*>(i));
}
}
else
{ // Can't be a wheel,continue searching
load_wheels(dynamic_cast<ssgBranch*>(i));
}
} // for i
} // load_wheels
//-----------------------------------------------------------------------------
void Kart::loadData()
{
@ -956,15 +872,8 @@ void Kart::loadData()
m_smokepuff -> setMaterial ( GL_SPECULAR, 0, 0, 0, 1 ) ;
m_smokepuff -> setShininess ( 0 ) ;
ssgEntity *obj = m_kart_properties->getModel();
createPhysics(obj);
load_wheels(dynamic_cast<ssgBranch*>(obj));
// Optimize the model, this can't be done while loading the model
// because it seems that it removes the name of the wheels or something
// else needed to load the wheels as a separate object.
ssgFlatten(obj);
ssgEntity *obj = m_kart_properties->getKartModel()->getRoot();
createPhysics();
SSGHelp::createDisplayLists(obj); // create all display lists
ssgRangeSelector *lod = new ssgRangeSelector ;
@ -972,7 +881,7 @@ void Kart::loadData()
lod -> addKid ( obj ) ;
lod -> setRanges ( r, 2 ) ;
this-> getModelTransform() -> addKid ( lod ) ;
getModelTransform() -> addKid ( lod ) ;
// Attach Particle System
//JH sgCoord pipe_pos = {{0, 0, .3}, {0, 0, 0}} ;
@ -993,30 +902,50 @@ void Kart::loadData()
m_model_transform->addKid ( m_shadow );
} // loadData
//-----------------------------------------------------------------------------
/** Stores the current suspension length. This function is called from world
* after all karts are in resting position (see World::resetAllKarts), so
* that the default suspension rest length can be stored. This is then used
* later to move the wheels depending on actual suspension, so that when
* a kart is in rest, the wheels are at the position at which they were
* modelled.
*/
void Kart::setSuspensionLength()
{
for(unsigned int i=0; i<4; i++)
{
m_default_suspension_length[i] =
m_vehicle->getWheelInfo(i).m_raycastInfo.m_suspensionLength;
} // for i
} // setSuspensionLength
//-----------------------------------------------------------------------------
void Kart::updateGraphics(const Vec3& off_xyz, const Vec3& off_hpr)
{
sgMat4 wheel_front;
sgMat4 wheel_steer;
sgMat4 wheel_rot;
sgMakeRotMat4( wheel_rot, 0, RAD_TO_DEGREE(-m_wheel_rotation), 0);
sgMakeRotMat4( wheel_steer, m_controls.lr * 30.0f , 0, 0);
sgMultMat4(wheel_front, wheel_steer, wheel_rot);
if (m_wheel_front_l) m_wheel_front_l->setTransform(wheel_front);
if (m_wheel_front_r) m_wheel_front_r->setTransform(wheel_front);
if (m_wheel_rear_l) m_wheel_rear_l->setTransform(wheel_rot);
if (m_wheel_rear_r) m_wheel_rear_r->setTransform(wheel_rot);
float wheel_z_axis[4];
KartModel *kart_model = m_kart_properties->getKartModel();
for(unsigned int i=0; i<4; i++)
{
// The wheel z-position has to be set relative to the center of mass
// of the kart! Center of mass plus connection point is where the
// suspension is attached, subtracting from this the current extension
// of the suspension gives the location of the center of the wheel,
// which is then adjusted by the difference of physical wheel radius
// and graphical wheel radius to give the center of the graphical wheel
wheel_z_axis[i] = m_vehicle->getWheelInfo(i).m_chassisConnectionPointCS.getZ()
- (m_vehicle->getWheelInfo(i).m_raycastInfo.m_suspensionLength
- m_default_suspension_length[i])
- (m_vehicle->getWheelInfo(i).m_wheelsRadius
- kart_model->getWheelGraphicsRadius(i));
}
kart_model->adjustWheels(m_wheel_rotation, m_controls.lr*30.0f,
wheel_z_axis);
Vec3 center_shift = getGravityCenterShift();
center_shift.setZ(-center_shift.getZ()
center_shift.setZ(center_shift.getZ()-getKartHeight()*0.5f
- kart_model->getZOffset()
+ 0.3f*fabs(sin(DEGREE_TO_RAD(m_wheelie_angle))) );
const float offset_pitch = DEGREE_TO_RAD(m_wheelie_angle);
Moveable::updateGraphics(center_shift, Vec3(0, offset_pitch, 0));
Moveable::updateGraphics(center_shift, Vec3(0, offset_pitch, 0));
} // updateGraphics
/* EOF */

View File

@ -30,6 +30,7 @@
#include "kart_control.hpp"
#include "items/attachment.hpp"
#include "items/powerup.hpp"
#include "karts/kart_model.hpp"
#include "terrain_info.hpp"
class SkidMark;
@ -42,6 +43,7 @@ class Kart : public TerrainInfo, public Moveable
private:
btTransform m_reset_transform; // reset position
unsigned int m_world_kart_id; // index of kart in world
float m_skidding; /**< Accumulated skidding factor. */
protected:
Attachment m_attachment;
@ -56,7 +58,6 @@ protected:
float m_max_speed_reverse_ratio;
float m_wheelie_angle;
float m_zipper_time_left; // zipper time left
//char m_fastest_lap_message[255];
float m_bounce_back_time; // a short time after a collision acceleration
// is disabled to allow the karts to bounce back
@ -75,10 +76,11 @@ private:
ssgTransform* m_exhaust_pipe;
float m_wheel_rotation;
ssgTransform* m_wheel_front_l;
ssgTransform* m_wheel_front_r;
ssgTransform* m_wheel_rear_l;
ssgTransform* m_wheel_rear_r;
/** For each wheel it stores the suspension length after the karts are at
* the start position, i.e. the suspension will be somewhat compressed.
* The bullet suspensionRestLength is the value when the suspension is not
* at all compressed. */
float m_default_suspension_length[4];
SkidMark* m_skidmark_left;
SkidMark* m_skidmark_right;
@ -101,9 +103,6 @@ protected:
float m_rescue_pitch, m_rescue_roll;
const KartProperties *m_kart_properties;
/** Search the given branch of objects that match the wheel names
and if so assign them to wheel_* variables */
void load_wheels (ssgBranch* obj);
public:
Kart(const std::string& kart_name, int position,
@ -161,7 +160,6 @@ public:
float getMaxPower () const {return m_kart_properties->getMaxPower();}
float getTimeFullSteer () const {return m_kart_properties->getTimeFullSteer();}
float getBrakeFactor () const {return m_kart_properties->getBrakeFactor();}
float getWheelBase () const {return m_kart_properties->getWheelBase();}
float getFrictionSlip () const {return m_kart_properties->getFrictionSlip();}
float getMaxSteerAngle () const
{return m_kart_properties->getMaxSteerAngle(getSpeed());}
@ -183,12 +181,16 @@ public:
/** Sets the kart controls. Used e.g. by replaying history. */
void setControls(const KartControl &c) { m_controls = c; }
float getMaxSpeed () const {return m_max_speed; }
void createPhysics (ssgEntity *obj);
float getKartLength () const {return m_kart_properties->getKartLength();}
float getKartHeight () const {return m_kart_properties->getKartHeight();}
/** Returns the length of the kart. */
float getKartLength () const
{return m_kart_properties->getKartModel()->getLength(); }
/** Returns the height of the kart. */
float getKartHeight () const
{return m_kart_properties->getKartModel()->getHeight(); }
float getWheelieAngle () const {return m_wheelie_angle; }
btKart *getVehicle () const {return m_vehicle; }
btUprightConstraint *getUprightConstraint() const {return m_uprightConstraint;}
void createPhysics ();
void draw ();
bool isInRest () const;
//have to use this instead of moveable getVelocity to get velocity for bullet rigid body
@ -196,6 +198,7 @@ public:
/** This is used on the client side only to set the speed of the kart
* from the server information. */
void setSpeed (float s) {m_speed = s; }
void setSuspensionLength();
float handleWheelie (float dt);
float getActualWheelForce();
bool isOnGround () const;

View File

@ -29,6 +29,7 @@
#include "stk_config.hpp"
#include "translation.hpp"
#include "user_config.hpp"
#include "karts/kart_model.hpp"
#include "lisp/parser.hpp"
#include "lisp/lisp.hpp"
#include "utils/ssg_help.hpp"
@ -44,18 +45,17 @@ float KartProperties::UNDEFINED = -99.9f;
* Otherwise the defaults are taken from STKConfig (and since they are all
* defined, it is guaranteed that each kart has well defined physics values.
*/
KartProperties::KartProperties() : m_icon_material(0), m_model(0)
KartProperties::KartProperties() : m_icon_material(0)
{
m_name = "Tux";
m_ident = "tux";
m_model_file = "tuxkart.ac";
m_icon_file = "tuxicon.png";
m_shadow_file = "tuxkartshadow.png";
m_groups.clear();
// Set all other values to undefined, so that it can later be tested
// if everything is defined properly.
m_wheel_base = m_mass = m_min_speed_turn = m_angle_at_min =
m_mass = m_min_speed_turn = m_angle_at_min =
m_max_speed_turn = m_angle_at_max = m_engine_power = m_brake_factor =
m_time_full_steer = m_wheelie_max_pitch = m_wheelie_max_speed_ratio =
m_wheelie_pitch_rate = m_wheelie_restore_rate = m_wheelie_speed_boost =
@ -64,26 +64,21 @@ KartProperties::KartProperties() : m_icon_material(0), m_model(0)
m_wheel_radius = m_wheelie_power_boost = m_chassis_linear_damping =
m_chassis_angular_damping = m_maximum_speed = m_suspension_rest =
m_max_speed_reverse_ratio = m_jump_velocity = m_upright_tolerance =
m_upright_max_force = m_suspension_travel_cm = m_mass =
m_track_connection_accel = m_wheel_base = m_min_speed_turn =
m_angle_at_min = m_max_speed_turn = m_angle_at_max = m_engine_power =
m_brake_factor = m_time_full_steer = m_wheelie_max_pitch =
m_wheelie_max_speed_ratio = m_wheelie_pitch_rate = m_wheel_radius =
m_wheelie_restore_rate = m_wheelie_speed_boost = m_maximum_speed =
m_suspension_stiffness = m_wheel_damping_relaxation = m_jump_velocity =
m_wheel_damping_compression = m_friction_slip = m_roll_influence =
m_wheelie_power_boost = m_chassis_linear_damping = m_suspension_rest =
m_chassis_angular_damping = m_max_speed_reverse_ratio =
m_upright_tolerance = m_upright_max_force = m_suspension_travel_cm =
m_track_connection_accel = m_camera_max_accel = m_camera_max_brake =
m_upright_max_force = m_suspension_travel_cm =
m_track_connection_accel = m_min_speed_turn =
m_angle_at_min = m_max_speed_turn = m_angle_at_max =
m_camera_max_accel = m_camera_max_brake =
m_camera_distance = UNDEFINED;
m_gravity_center_shift = Vec3(UNDEFINED);
m_front_wheel_connection = Vec3(UNDEFINED);
m_rear_wheel_connection = Vec3(UNDEFINED);
m_gravity_center_shift = Vec3(UNDEFINED);
m_color.setValue(1.0f, 0.0f, 0.0f);
} // KartProperties
//-----------------------------------------------------------------------------
/** Destructor, dereferences the kart model. */
KartProperties::~KartProperties()
{
} // ~KartProperties
//-----------------------------------------------------------------------------
/** Loads the kart properties from a file.
* \param filename Filename to load.
@ -140,28 +135,22 @@ void KartProperties::load(const std::string &filename, const std::string &node,
m_icon_material = material_manager->getMaterial(m_icon_file);
// Load model, except when called as part of --list-karts
if(m_model_file.length()>0 && !dont_load_models)
if(!dont_load_models)
{
m_model = loader->load(m_model_file, CB_KART, false);
if(!m_model)
{
fprintf(stderr, "Can't find kart model '%s'.\n",m_model_file.c_str());
file_manager->popTextureSearchPath();
file_manager->popModelSearchPath();
return;
}
ssgStripify(m_model);
Vec3 min, max;
SSGHelp::MinMax(m_model, &min, &max);
m_kart_width = max.getX()-min.getX();
m_kart_length = max.getY()-min.getY();
m_kart_height = max.getZ()-min.getZ();
m_kart_model.loadModels();
if(m_gravity_center_shift.getX()==UNDEFINED)
m_gravity_center_shift.setX(0);
if(m_gravity_center_shift.getY()==UNDEFINED)
m_gravity_center_shift.setY(0);
// Default: center at the very bottom of the kart.
if(m_gravity_center_shift.getZ()==UNDEFINED)
m_gravity_center_shift.setZ(m_kart_model.getHeight()*0.5f);
// Useful when tweaking kart parameters
if(user_config->m_print_kart_sizes)
printf("%s:\twidth: %f\tlength: %f\theight: %f\n",getIdent().c_str(),
m_kart_width, m_kart_length, m_kart_height);
m_model->ref();
m_kart_model.getWidth(), m_kart_model.getLength(),
m_kart_model.getHeight());
} // if
file_manager->popTextureSearchPath();
@ -169,97 +158,19 @@ void KartProperties::load(const std::string &filename, const std::string &node,
} // load
//-----------------------------------------------------------------------------
/** Destructor, dereferences the kart model. */
KartProperties::~KartProperties()
{
ssgDeRefDelete(m_model);
} // ~KartProperties
//-----------------------------------------------------------------------------
/** Checks if all necessary physics values are indeed defines. This helps
* finding bugs early, e.g. missing default in stk_config.dat file.
*/
void KartProperties::checkAllSet(const std::string &filename)
{
if(m_gear_switch_ratio.size()==0)
{
fprintf(stderr,"Missing default value for 'gear-switch-ratio' in '%s'.\n",
filename.c_str());
exit(-1);
}
if(m_gear_power_increase.size()==0)
{
fprintf(stderr,"Missing default value for 'gear-power-increase' in '%s'.\n",
filename.c_str());
exit(-1);
}
if(m_gear_switch_ratio.size()!=m_gear_power_increase.size()) {
fprintf(stderr,"Number of entries for 'gear-switch-ratio' and 'gear-power-increase");
fprintf(stderr,"in '%s' must be equal.\n", filename.c_str());
exit(-1);
}
#define CHECK_NEG( a,strA) if(a<=UNDEFINED) { \
fprintf(stderr,"Missing default value for '%s' in '%s'.\n", \
strA,filename.c_str());exit(-1); \
}
CHECK_NEG(m_mass, "mass" );
CHECK_NEG(m_wheel_base, "wheel-base" );
CHECK_NEG(m_engine_power, "engine-power" );
CHECK_NEG(m_min_speed_turn, "min-speed-angle" );
CHECK_NEG(m_angle_at_min, "min-speed-angle" );
CHECK_NEG(m_max_speed_turn, "max-speed-angle" );
CHECK_NEG(m_angle_at_max, "max-speed-angle" );
CHECK_NEG(m_brake_factor, "brake-factor" );
CHECK_NEG(m_time_full_steer, "time-full-steer" );
CHECK_NEG(m_wheelie_max_speed_ratio, "wheelie-max-speed-ratio" );
CHECK_NEG(m_wheelie_max_pitch, "wheelie-max-pitch" );
CHECK_NEG(m_wheelie_pitch_rate, "wheelie-pitch-rate" );
CHECK_NEG(m_wheelie_restore_rate, "wheelie-restore-rate" );
CHECK_NEG(m_wheelie_speed_boost, "wheelie-speed-boost" );
CHECK_NEG(m_wheelie_power_boost, "wheelie-power-boost" );
//bullet physics data
CHECK_NEG(m_suspension_stiffness, "suspension-stiffness" );
CHECK_NEG(m_wheel_damping_relaxation, "wheel-damping-relaxation" );
CHECK_NEG(m_wheel_damping_compression, "wheel-damping-compression" );
CHECK_NEG(m_friction_slip, "friction-slip" );
CHECK_NEG(m_roll_influence, "roll-influence" );
CHECK_NEG(m_wheel_radius, "wheel-radius" );
CHECK_NEG(m_chassis_linear_damping, "chassis-linear-damping" );
CHECK_NEG(m_chassis_angular_damping, "chassis-angular-damping" );
CHECK_NEG(m_maximum_speed, "maximum-speed" );
CHECK_NEG(m_max_speed_reverse_ratio, "max-speed-reverse-ratio" );
CHECK_NEG(m_gravity_center_shift[0], "gravity-center-shift" );
CHECK_NEG(m_gravity_center_shift[1], "gravity-center-shift" );
CHECK_NEG(m_gravity_center_shift[2], "gravity-center-shift" );
CHECK_NEG(m_suspension_rest, "suspension-rest" );
CHECK_NEG(m_suspension_travel_cm, "suspension-travel-cm" );
CHECK_NEG(m_jump_velocity, "jump-velocity" );
CHECK_NEG(m_upright_tolerance, "upright-tolerance" );
CHECK_NEG(m_upright_max_force, "upright-max-force" );
CHECK_NEG(m_track_connection_accel, "track-connection-accel" );
CHECK_NEG(m_camera_max_accel, "camera-max-accel" );
CHECK_NEG(m_camera_max_brake, "camera-max-brake" );
CHECK_NEG(m_camera_distance, "camera-distance" );
} // checkAllSet
//-----------------------------------------------------------------------------
void KartProperties::getAllData(const lisp::Lisp* lisp)
{
lisp->get("name", m_name);
lisp->get("model-file", m_model_file);
lisp->get("icon-file", m_icon_file);
lisp->get("shadow-file", m_shadow_file);
lisp->get("rgb", m_color);
m_kart_model.loadInfo(lisp);
lisp->get("name", m_name);
lisp->get("icon-file", m_icon_file);
lisp->get("shadow-file", m_shadow_file);
lisp->get("rgb", m_color);
lisp->get("wheel-base", m_wheel_base);
lisp->get("engine-power", m_engine_power);
lisp->get("time-full-steer", m_time_full_steer);
lisp->get("brake-factor", m_brake_factor);
lisp->get("mass", m_mass);
lisp->get("engine-power", m_engine_power);
lisp->get("time-full-steer", m_time_full_steer);
lisp->get("brake-factor", m_brake_factor);
lisp->get("mass", m_mass);
std::vector<float> v;
if(lisp->getVector("max-speed-angle", v))
@ -310,8 +221,6 @@ void KartProperties::getAllData(const lisp::Lisp* lisp)
lisp->get("max-speed-reverse-ratio", m_max_speed_reverse_ratio );
lisp->get("maximum-speed", m_maximum_speed );
lisp->get("gravity-center-shift", m_gravity_center_shift );
lisp->get("front-wheel-connection", m_front_wheel_connection );
lisp->get("rear-wheel-connection", m_rear_wheel_connection );
lisp->get("suspension-rest", m_suspension_rest );
lisp->get("suspension-travel-cm", m_suspension_travel_cm );
lisp->get("jump-velocity", m_jump_velocity );
@ -335,6 +244,74 @@ void KartProperties::getAllData(const lisp::Lisp* lisp)
} // getAllData
//-----------------------------------------------------------------------------
/** Checks if all necessary physics values are indeed defines. This helps
* finding bugs early, e.g. missing default in stk_config.dat file.
* \param filename File from which the data was read (only used to print
* meaningful error messages).
*/
void KartProperties::checkAllSet(const std::string &filename)
{
if(m_gear_switch_ratio.size()==0)
{
fprintf(stderr,"Missing default value for 'gear-switch-ratio' in '%s'.\n",
filename.c_str());
exit(-1);
}
if(m_gear_power_increase.size()==0)
{
fprintf(stderr,"Missing default value for 'gear-power-increase' in '%s'.\n",
filename.c_str());
exit(-1);
}
if(m_gear_switch_ratio.size()!=m_gear_power_increase.size()) {
fprintf(stderr,"Number of entries for 'gear-switch-ratio' and 'gear-power-increase");
fprintf(stderr,"in '%s' must be equal.\n", filename.c_str());
exit(-1);
}
#define CHECK_NEG( a,strA) if(a<=UNDEFINED) { \
fprintf(stderr,"Missing default value for '%s' in '%s'.\n", \
strA,filename.c_str());exit(-1); \
}
CHECK_NEG(m_mass, "mass" );
CHECK_NEG(m_engine_power, "engine-power" );
CHECK_NEG(m_min_speed_turn, "min-speed-angle" );
CHECK_NEG(m_angle_at_min, "min-speed-angle" );
CHECK_NEG(m_max_speed_turn, "max-speed-angle" );
CHECK_NEG(m_angle_at_max, "max-speed-angle" );
CHECK_NEG(m_brake_factor, "brake-factor" );
CHECK_NEG(m_time_full_steer, "time-full-steer" );
CHECK_NEG(m_wheelie_max_speed_ratio, "wheelie-max-speed-ratio" );
CHECK_NEG(m_wheelie_max_pitch, "wheelie-max-pitch" );
CHECK_NEG(m_wheelie_pitch_rate, "wheelie-pitch-rate" );
CHECK_NEG(m_wheelie_restore_rate, "wheelie-restore-rate" );
CHECK_NEG(m_wheelie_speed_boost, "wheelie-speed-boost" );
CHECK_NEG(m_wheelie_power_boost, "wheelie-power-boost" );
//bullet physics data
CHECK_NEG(m_suspension_stiffness, "suspension-stiffness" );
CHECK_NEG(m_wheel_damping_relaxation, "wheel-damping-relaxation" );
CHECK_NEG(m_wheel_damping_compression, "wheel-damping-compression" );
CHECK_NEG(m_friction_slip, "friction-slip" );
CHECK_NEG(m_roll_influence, "roll-influence" );
CHECK_NEG(m_wheel_radius, "wheel-radius" );
CHECK_NEG(m_chassis_linear_damping, "chassis-linear-damping" );
CHECK_NEG(m_chassis_angular_damping, "chassis-angular-damping" );
CHECK_NEG(m_maximum_speed, "maximum-speed" );
CHECK_NEG(m_max_speed_reverse_ratio, "max-speed-reverse-ratio" );
CHECK_NEG(m_suspension_rest, "suspension-rest" );
CHECK_NEG(m_suspension_travel_cm, "suspension-travel-cm" );
CHECK_NEG(m_jump_velocity, "jump-velocity" );
CHECK_NEG(m_upright_tolerance, "upright-tolerance" );
CHECK_NEG(m_upright_max_force, "upright-max-force" );
CHECK_NEG(m_track_connection_accel, "track-connection-accel" );
CHECK_NEG(m_camera_max_accel, "camera-max-accel" );
CHECK_NEG(m_camera_max_brake, "camera-max-brake" );
CHECK_NEG(m_camera_distance, "camera-distance" );
} // checkAllSet
// ----------------------------------------------------------------------------
float KartProperties::getMaxSteerAngle(float speed) const
{

View File

@ -22,9 +22,10 @@
#include <string>
#include <vector>
#include "plib/ssg.h"
#include "vec3.hpp"
#include "karts/kart_model.hpp"
#include "lisp/lisp.hpp"
#include "no_copy.hpp"
class Material;
class ssgEntity;
@ -38,7 +39,10 @@ class KartProperties
private:
Material *m_icon_material; /**< The icon texture to use. */
ssgEntity *m_model; /**< The 3d model of the kart.*/
/** The kart model and wheels. It is mutable since the wheels of the
* KartModel can rotate and turn, but otherwise the kart_properties
* object is const. */
mutable KartModel m_kart_model;
std::vector<std::string> m_groups; /**< List of all groups the kart
belongs to. */
static float UNDEFINED;
@ -50,8 +54,6 @@ protected:
* driver. */
std::string m_ident; /**< The computer readable-name of the kart
* driver. */
std::string m_model_file; /**< Filename of 3d model that is used for
* kart.*/
std::string m_icon_file; /**< Filename of icon that represents the kart
* in the statusbar and the character select
* screen. */
@ -62,12 +64,7 @@ protected:
// Physic properties
// -----------------
float m_kart_width; /**< Width of kart. */
float m_kart_length; /**< Length of kart. */
float m_kart_height; /**< Height of kart. */
float m_mass; /**< Weight of kart. */
float m_wheel_base; /**< Distance between front and rear
* wheels. */
float m_engine_power; /**< Maximum force from engine. */
float m_brake_factor; /**< Braking factor * engine_power =
* braking force. */
@ -87,6 +84,14 @@ protected:
* etc. */
float m_speed_angle_increase;
ssgEntity *m_wheel_model[4]; /**< The four wheel models. */
std::string m_wheel_filename[4]; /**< Filename of the wheel models. */
/** Radius of the graphical wheels. */
float m_wheel_graphics_radius[4];
ssgTransform
*m_wheel_transform[4]; /**< The transform for the wheels, used
* to rotate the wheels and display
* the suspension in the race. */
// bullet physics data
// -------------------
float m_suspension_stiffness;
@ -100,9 +105,6 @@ protected:
float m_maximum_speed;
float m_max_speed_reverse_ratio;
Vec3 m_gravity_center_shift; /**< Shift of center of gravity. */
Vec3 m_front_wheel_connection; /**< Connection point relative to center of */
Vec3 m_rear_wheel_connection; /**< Gravity for front and rear right wheels
* (X is mirrored for left wheels). */
float m_track_connection_accel; /**< Artifical acceleration that pulls a
* kart down onto the track if one axis
* loses contact with the track. */
@ -138,7 +140,8 @@ public:
float getMaxSteerAngle (float speed) const;
Material* getIconMaterial () const {return m_icon_material; }
ssgEntity* getModel () const {return m_model; }
/** Returns a pointer to the KartModel object. */
KartModel* getKartModel () const {return &m_kart_model; }
const std::string& getName () const {return m_name; }
const std::string& getIdent () const {return m_ident; }
const std::string& getShadowFile() const {return m_shadow_file; }
@ -147,13 +150,9 @@ public:
const std::vector<std::string>&
getGroups () const {return m_groups; }
float getMass () const {return m_mass; }
float getKartLength () const {return m_kart_length; }
float getKartWidth () const {return m_kart_width; }
float getKartHeight () const {return m_kart_height; }
float getMaxPower () const {return m_engine_power; }
float getTimeFullSteer () const {return m_time_full_steer; }
float getBrakeFactor () const {return m_brake_factor; }
float getWheelBase () const {return m_wheel_base; }
float getMaxSpeedReverseRatio () const {return m_max_speed_reverse_ratio; }
float getWheelieMaxSpeedRatio () const {return m_wheelie_max_speed_ratio; }
float getWheelieMaxPitch () const {return m_wheelie_max_pitch; }
@ -173,8 +172,6 @@ public:
float getChassisAngularDamping () const {return m_chassis_angular_damping; }
float getMaximumSpeed () const {return m_maximum_speed; }
const Vec3& getGravityCenterShift() const {return m_gravity_center_shift; }
const Vec3& getFrontWheelConnection()const {return m_front_wheel_connection; }
const Vec3& getRearWheelConnection()const {return m_rear_wheel_connection; }
float getSuspensionRest () const {return m_suspension_rest; }
float getSuspensionTravelCM () const {return m_suspension_travel_cm; }
float getJumpVelocity () const {return m_jump_velocity; }

215
src/karts/kart_model.cpp Executable file
View File

@ -0,0 +1,215 @@
// $Id: kart_model.hpp 2400 2008-10-30 02:02:56Z auria $
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2008 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 "karts/kart_model.hpp"
#include "constants.hpp"
#include "loader.hpp"
#include "stk_config.hpp"
#include "user_config.hpp"
#include "utils/ssg_help.hpp"
float KartModel::UNDEFINED = -99.9f;
/** The constructor reads the model file name and wheel specification from the
* kart config file.
* \param lisp Lisp object of the kart config file.
*/
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_model[i] = NULL;
}
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;
} // KartModel
// ----------------------------------------------------------------------------
/** This function loads the information about the kart from a lisp file. It
* does not actually load the models (see load()).
* \param lisp Lisp object of configuration file.
*/
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);
} // init
// ----------------------------------------------------------------------------
/** Destructor.
*/
KartModel::~KartModel()
{
ssgDeRefDelete(m_root);
for(unsigned int i=0; i<4; i++)
if(m_wheel_model[i]) ssgDeRefDelete(m_wheel_model[i]);
} // ~KartModel
// ----------------------------------------------------------------------------
/** Loads the 3d model and all wheels.
*/
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();
// 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)
? -0.5f*m_kart_width
: 0.5f*m_kart_width );
if(m_wheel_graphics_position[i].getY()==STKConfig::UNDEFINED)
m_wheel_graphics_position[i].setY((i<2) ? 0.5f*m_kart_length
:-0.5f*m_kart_length);
if(m_wheel_graphics_position[i].getZ()==STKConfig::UNDEFINED)
m_wheel_graphics_position[i].setZ(0);
if(m_wheel_physics_position[i].getX()==UNDEFINED)
m_wheel_physics_position[i] = m_wheel_graphics_position[i];
}
// 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])
{
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();
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;
}
} // 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)
{
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] );
} // loadWheelInfo
// ----------------------------------------------------------------------------
/** Rotates and turns the wheels appropriately, and adjust for suspension.
* \param rotation How far the wheels should rotate.
* \param steer How much the front wheels are turned for steering.
* \param suspension Suspension height for all four wheels.
*/
void KartModel::adjustWheels(float rotation, float steer,
const float suspension[4])
{
sgMat4 wheel_front;
sgMat4 wheel_steer;
sgMat4 wheel_rot;
sgMakeRotMat4( wheel_rot, 0, RAD_TO_DEGREE(-rotation), 0);
sgMakeRotMat4( wheel_steer, steer , 0, 0);
sgMultMat4(wheel_front, wheel_steer, wheel_rot);
sgCopyVec3(wheel_front[3], m_wheel_graphics_position[0].toFloat());
wheel_front[3][2] += suspension[0];
m_wheel_transform[0]->setTransform(wheel_front);
sgCopyVec3(wheel_front[3], m_wheel_graphics_position[1].toFloat());
wheel_front[3][2] += suspension[1];
m_wheel_transform[1]->setTransform(wheel_front);
sgCopyVec3(wheel_rot[3], m_wheel_graphics_position[2].toFloat());
wheel_rot[3][2] += suspension[2];
m_wheel_transform[2]->setTransform(wheel_rot);
sgCopyVec3(wheel_rot[3], m_wheel_graphics_position[3].toFloat());
wheel_rot[3][2] += suspension[3];
m_wheel_transform[3]->setTransform(wheel_rot);
} // adjustWheels
// ----------------------------------------------------------------------------
/** Puts all wheels in the default position. Used when displaying the karts
* in the character selection screen.
*/
void KartModel::resetWheels()
{
for(unsigned int i=0; i<4; i++)
{
const float suspension[4]={0,0,0,0};
adjustWheels(0, 0, suspension);
}
} // reset

118
src/karts/kart_model.hpp Executable file
View File

@ -0,0 +1,118 @@
// $Id: kart_model.hpp 2400 2008-10-30 02:02:56Z auria $
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2008 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_KART_MODEL_HPP
#define HEADER_KART_MODEL_HPP
#include <string>
#define _WINSOCKAPI_
#include <plib/ssg.h>
#include "no_copy.hpp"
#include "vec3.hpp"
#include "lisp/lisp.hpp"
/** This class stores a 3D kart model. It takes especially care of attaching
* the wheels, which are loaded as separate objects. The wheels can turn
* and (for the front wheels) rotate. The implementation is dependent on the
* OpenGL library used.
*/
class KartModel
{
private:
/** The transform node/root of the kart model. */
ssgTransform *m_root;
/** Value used to indicate undefined entries. */
static float UNDEFINED;
/** Name of the 3d model file. */
std::string m_model_filename;
/** The four wheel models. */
ssgEntity *m_wheel_model[4];
/** Filename of the wheel models. */
std::string m_wheel_filename[4];
/** The position of all four wheels in the 3d model. */
Vec3 m_wheel_graphics_position[4];
/** The position of the wheels for the physics, which can be different
* from the graphical position. */
Vec3 m_wheel_physics_position[4];
/** Radius of the graphical wheels. */
float m_wheel_graphics_radius[4];
/** The transform for the wheels, used to rotate the wheels and display
* the suspension in the race. */
ssgTransform *m_wheel_transform[4];
float m_kart_width; /**< Width of kart. */
float m_kart_length; /**< Length of kart. */
float m_kart_height; /**< Height of kart. */
float m_z_offset; /**< Models are usually not at z=0 (due
* to the wheels), so this value moves
* the karts down appropriately. */
void loadWheelInfo(const lisp::Lisp* const lisp,
const std::string &wheel_name, int index);
public:
KartModel();
~KartModel();
void loadInfo(const lisp::Lisp* lisp);
void loadModels();
ssgTransform *getRoot() { return m_root; }
/** Returns the position of a wheel relative to the kart.
* \param i Index of the wheel: 0=front right, 1 = front left, 2 = rear
* right, 3 = rear left. */
const Vec3& getWheelGraphicsPosition(int i) const
{return m_wheel_graphics_position[i];}
/** Returns the position of a wheel relative to the kart for the physics.
* The physics wheels can be attached at a different place to make the
* karts more stable.
* \param i Index of the wheel: 0=front right, 1 = front left, 2 = rear
* right, 3 = rear left. */
const Vec3& getWheelPhysicsPosition(int i) const
{return m_wheel_physics_position[i];}
/** Returns the model of a wheel. */
ssgEntity *getWheelModel(int i) const {return m_wheel_model[i];}
/** Returns the radius of the graphical wheels.
* \param i Index of the wheel: 0=front right, 1 = front left, 2 = rear
* right, 3 = rear left. */
float getWheelGraphicsRadius(int i) const
{return m_wheel_graphics_radius[i]; }
float getLength () const {return m_kart_length; }
float getWidth () const {return m_kart_width; }
float getHeight () const {return m_kart_height; }
/** Returns the amount a kart has to be moved down so that the bottom of
* the kart is at z=0. */
float getZOffset () const {return m_z_offset; }
void adjustWheels(float rotation, float steer,
const float suspension[4]);
void resetWheels();
}; // KartModel
#endif

View File

@ -250,6 +250,11 @@ void World::resetAllKarts()
}
} // while
// Now store the current (i.e. in rest) suspension length for each kart,
// so that the karts can visualise the suspension.
for ( Karts::iterator i=m_kart.begin(); i!=m_kart.end(); i++)
(*i)->setSuspensionLength();
} // resetAllKarts
//-----------------------------------------------------------------------------

View File

@ -26,7 +26,7 @@
#include "track.hpp"
#include "player_kart.hpp"
#include "physics.hpp"
#include "physics/physics.hpp"
#include "kart.hpp"
#include "highscores.hpp"
#include "network/network_kart.hpp"

View File

@ -46,7 +46,7 @@ Moveable::~Moveable()
//-----------------------------------------------------------------------------
// The reset position must be set before calling reset
void Moveable::reset ()
void Moveable::reset()
{
m_material_hot = NULL;
m_normal_hot = NULL;
@ -66,7 +66,7 @@ void Moveable::createBody(float mass, btTransform& trans,
btVector3 inertia;
shape->calculateLocalInertia(mass, inertia);
m_motion_state = new btDefaultMotionState(trans);
m_motion_state = new KartMotionState(trans);
btRigidBody::btRigidBodyConstructionInfo info(mass, m_motion_state, shape, inertia);
info.m_restitution=0.5f;
@ -84,7 +84,18 @@ void Moveable::createBody(float mass, btTransform& trans,
} // createBody
//-----------------------------------------------------------------------------
void Moveable::update (float dt)
/** Places this moveable at a certain location and stores this transform in
* this Moveable, so that it can be accessed easily.
* \param t New transform for this moveable.
*/
void Moveable::setTrans(const btTransform &t)
{
m_transform=t;
m_motion_state->setWorldTransform(t);
} // setTrans
//-----------------------------------------------------------------------------
void Moveable::update(float dt)
{
m_motion_state->getWorldTransform(m_transform);
m_velocityLC = getVelocity()*getTrans().getBasis();

View File

@ -26,6 +26,7 @@
#include "vec3.hpp"
#include "btBulletDynamicsCommon.h"
#include "user_pointer.hpp"
#include "physics/kart_motion_state.hpp"
class Material;
@ -38,18 +39,18 @@ class Material;
class Moveable
{
private:
btVector3 m_velocityLC; /* velocity in kart coordinates */
btTransform m_transform;
Vec3 m_hpr;
btVector3 m_velocityLC; /* velocity in kart coordinates */
btTransform m_transform;
Vec3 m_hpr;
protected:
UserPointer m_user_pointer;
sgVec4 *m_normal_hot; /* plane on which HOT was computed */
Material *m_material_hot; /* Material at HOT */
ssgTransform *m_model_transform; // The transform where the model is under
ssgTransform *m_shadow;
int m_first_time ;
btRigidBody *m_body;
btDefaultMotionState *m_motion_state;
UserPointer m_user_pointer;
sgVec4 *m_normal_hot; /* plane on which HOT was computed */
Material *m_material_hot; /* Material at HOT */
ssgTransform *m_model_transform; // The transform where the model is under
ssgTransform *m_shadow;
int m_first_time ;
btRigidBody *m_body;
KartMotionState *m_motion_state;
public:
Moveable ();
@ -79,7 +80,7 @@ public:
void createBody(float mass, btTransform& trans,
btCollisionShape *shape);
const btTransform& getTrans() const {return m_transform;}
void setTrans (const btTransform& t){m_transform=t;m_motion_state->setWorldTransform(t);}
void setTrans (const btTransform& t);
}
; // class Moveable

View File

@ -0,0 +1,68 @@
// $Id: kart_motion_state.hpp 839 2006-10-24 00:01:56Z hiker $
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2008 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 ofati
// 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_KART_MOTION_STATE_HPP
#define HEADER_KART_MOTION_STATE_HPP
#include "LinearMath/btMotionState.h"
/** This is a very simple motion state implementation for bullet, which does
* not support any transformation from physics transform to graphics
* transform.
*/
class KartMotionState : public btMotionState
{
private:
btTransform m_center_of_mass;
public:
/** Constructor.
* \param start_trans An optional start transformation. Defaults to
* identity.
*/
KartMotionState(const btTransform& start_trans = btTransform::getIdentity())
: m_center_of_mass(start_trans)
{
} // KartMotionState
// ------------------------------------------------------------------------
/** Returns the current world transform.
* \param center_of_mass The btTransform object that stores the current
* transformation.
*/
virtual void getWorldTransform(btTransform& center_of_mass) const
{
center_of_mass = m_center_of_mass;
} // getWorldTransform
// ------------------------------------------------------------------------
/** Synchronizes world transform from physics to user.
* Bullet calls the update of worldtransform for active objects.
* \param new_trans The new transformation for the object.
*/
virtual void setWorldTransform(const btTransform &new_trans)
{
m_center_of_mass = new_trans;
} // setWorldTransform
}; // KartMotionState
#endif // HEADER_KART_MOTION_STATE

View File

@ -17,12 +17,9 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "physics.hpp"
#include "physics/physics.hpp"
#include "flyable.hpp"
#include "moving_physics.hpp"
#include "user_config.hpp"
#include "material_manager.hpp"
#include "network/race_state.hpp"
#include "utils/ssg_help.hpp"
#include "track.hpp"

View File

@ -21,15 +21,19 @@
#define HEADER_PHYSICS_H
#include <set>
#include <vector>
#define _WINSOCKAPI_
#include <plib/sg.h>
#include "kart.hpp"
#include "flyable.hpp"
#include "btBulletDynamicsCommon.h"
#include "bullet/Demos/OpenGL/GLDebugDrawer.h"
#include "bullet/Demos/OpenGL/GL_ShapeDrawer.h"
#include "user_pointer.hpp"
#include "vec3.hpp"
class Kart;
class Physics : public btSequentialImpulseConstraintSolver
{
private:
@ -54,7 +58,7 @@ private:
class CollisionPair {
public:
const UserPointer* a, *b;
const UserPointer *a, *b;
// The entries in Collision Pairs are sorted: if a projectile
// is included, it's always 'a'. If only two karts are reported

View File

@ -48,6 +48,7 @@ DefaultRobot::DefaultRobot(const std::string& kart_name,
AutoKart( kart_name, position, init_pos )
{
reset();
m_kart_length = m_kart_properties->getKartModel()->getLength();
switch( race_manager->getDifficulty())
{
@ -380,7 +381,7 @@ void DefaultRobot::handle_items( const float DELTA, const int STEPS )
if( m_time_since_last_shot > 5.0f && m_crashes.m_kart != -1 )
{
if( (getXYZ()-RaceManager::getKart(m_crashes.m_kart)->getXYZ() ).length_2d() >
m_kart_properties->getKartLength() * 2.5f )
m_kart_length * 2.5f )
{
m_controls.fire = true;
m_time_since_last_shot = 0.0f;
@ -476,11 +477,11 @@ bool DefaultRobot::do_wheelie ( const int STEPS )
is less accurate than calling findRoadSector(), but a lot faster.
*/
const int WHEELIE_STEPS = int(( getVelocityLC().getY() * CHECK_DIST )/
m_kart_properties->getKartLength() );
m_kart_length );
for( int i = WHEELIE_STEPS; i > STEPS - 1; --i )
{
step_coord = getXYZ()+vel_normal* m_kart_properties->getKartLength() * float(i);
step_coord = getXYZ()+vel_normal* m_kart_length * float(i);
RaceManager::getTrack()->spatialToTrack(step_track_coord, step_coord,
m_future_sector );
@ -622,7 +623,7 @@ void DefaultRobot::check_crashes( const int STEPS, const Vec3& pos )
for(int i = 1; STEPS > i; ++i)
{
step_coord = pos + vel_normal* m_kart_properties->getKartLength() * float(i);
step_coord = pos + vel_normal* m_kart_length * float(i);
/* Find if we crash with any kart, as long as we haven't found one
* yet
@ -636,7 +637,7 @@ void DefaultRobot::check_crashes( const int STEPS, const Vec3& pos )
kart_distance = (step_coord - RaceManager::getKart(j)->getXYZ()).length_2d();
if( kart_distance < m_kart_properties->getKartLength() + 0.125f * i )
if( kart_distance < m_kart_length + 0.125f * i )
if( getVelocityLC().getY() > RaceManager::getKart(j)->
getVelocityLC().getY() * 0.75f ) m_crashes.m_kart = j;
}
@ -734,7 +735,7 @@ void DefaultRobot::find_non_crashing_point( sgVec2 result )
direction = RaceManager::getTrack()->m_driveline[target_sector] - getXYZ();
float len=direction.length_2d();
steps = int( len / m_kart_properties->getKartLength() );
steps = int( len / m_kart_length );
if( steps < 3 ) steps = 3;
//Protection against having vel_normal with nan values
@ -746,7 +747,7 @@ void DefaultRobot::find_non_crashing_point( sgVec2 result )
//Test if we crash if we drive towards the target sector
for( int i = 2; i < steps; ++i )
{
step_coord = getXYZ()+direction*m_kart_properties->getKartLength() * float(i);
step_coord = getXYZ()+direction*m_kart_length * float(i);
RaceManager::getTrack()->spatialToTrack( step_track_coord, step_coord,
sector );
@ -755,7 +756,7 @@ void DefaultRobot::find_non_crashing_point( sgVec2 result )
: -step_track_coord[0];
//If we are outside, the previous sector is what we are looking for
if ( distance + m_kart_properties->getKartLength() * 0.5f > RaceManager::getTrack()->getWidth()[sector] )
if ( distance + m_kart_length * 0.5f > RaceManager::getTrack()->getWidth()[sector] )
{
sgCopyVec2( result, RaceManager::getTrack()->m_driveline[sector] );
@ -834,7 +835,7 @@ inline float DefaultRobot::normalize_angle( float angle )
*/
int DefaultRobot::calc_steps()
{
int steps = int( getVelocityLC().getY() / m_kart_properties->getKartLength() );
int steps = int( getVelocityLC().getY() / m_kart_length );
if( steps < m_min_steps ) steps = m_min_steps;
//Increase the steps depending on the width, if we steering hard,
@ -843,7 +844,7 @@ int DefaultRobot::calc_steps()
{
const int WIDTH_STEPS =
(int)( RaceManager::getTrack()->getWidth()[m_future_sector]
/( m_kart_properties->getKartLength() * 2.0 ) );
/( m_kart_length * 2.0 ) );
steps += WIDTH_STEPS;
}

View File

@ -98,6 +98,9 @@ private:
int m_start_kart_crash_direction; //-1 = left, 1 = right, 0 = no crash.
/** Length of the kart, storing it here saves many function calls. */
float m_kart_length;
/*Functions called directly from update(). They all represent an action
*that can be done, and end up setting their respective m_controls
*variable, except handle_race_start() that isn't associated with any