1) Made 'reverse' camera a normal camera mode (instead of an additional

feature)
2) Cleaned up camera handling.
3) Some work on replacing sg* with bt* data structures.


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@1814 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk
2008-05-05 06:58:42 +00:00
parent 1e40021b91
commit 5385c3f9b2
8 changed files with 126 additions and 169 deletions

View File

@@ -27,94 +27,83 @@
#include "user_config.hpp"
#include "constants.hpp"
void Camera::setScreenPosition ( int numPlayers, int pos )
Camera::Camera(int camera_index, const Kart* kart)
{
assert(pos >= 0 && pos <= 3);
m_mode = CM_NORMAL;
m_context = new ssgContext ;
m_distance = kart->getKartProperties()->getCameraDistance();
m_kart = kart;
if (numPlayers == 1)
btVector3 start_pos = m_kart->getPos();
sgSetVec3(m_current_pos.xyz, start_pos.getX(), start_pos.getY(), start_pos.getZ());
sgSetVec3(m_current_pos.hpr, 0, 0, 0);
// FIXME: clipping should be configurable for slower machines
const Track* track = world->getTrack();
if (track->useFog())
m_context -> setNearFar ( 0.05f, track->getFogEnd() ) ;
else
m_context -> setNearFar ( 0.05f, 1000.0f ) ;
setScreenPosition(camera_index);
} // Camera
// ----------------------------------------------------------------------------
void Camera::setScreenPosition(int camera_index)
{
const int num_players = race_manager->getNumPlayers();
assert(camera_index >= 0 && camera_index <= 3);
if (num_players == 1)
{
m_context -> setFOV ( 75.0f, 0.0f ) ;
m_x = 0.0f; m_y = 0.0f; m_w = 1.0f; m_h = 1.0f ;
}
else if (numPlayers == 2)
else if (num_players == 2)
{
m_context -> setFOV ( 85.0f, 85.0f*3.0f/8.0f ) ;
switch ( pos )
switch ( camera_index )
{
case 0 : m_x = 0.0f; m_y = 0.5f; m_w = 1.0f; m_h = 0.5f;
break;
case 1 : m_x = 0.0f; m_y = 0.0f; m_w = 1.0f; m_h = 0.5f;
break;
case 0 : m_x = 0.0f; m_y = 0.5f; m_w = 1.0f; m_h = 0.5f; break;
case 1 : m_x = 0.0f; m_y = 0.0f; m_w = 1.0f; m_h = 0.5f; break;
}
}
else if (numPlayers == 3)
else if (num_players == 3)
{
m_context -> setFOV ( 50.0f, 0.0f );
switch ( pos )
switch ( camera_index )
{
case 0 : m_x = 0.0f; m_y = 0.5f; m_w = 0.5f; m_h = 0.5f;
break;
case 1 : m_x = 0.5f; m_y = 0.5f; m_w = 0.5f; m_h = 0.5f;
break;
case 0 : m_x = 0.0f; m_y = 0.5f; m_w = 0.5f; m_h = 0.5f; break;
case 1 : m_x = 0.5f; m_y = 0.5f; m_w = 0.5f; m_h = 0.5f; break;
case 2 : m_x = 0.0f; m_y = 0.0f; m_w = 1.0f; m_h = 0.5f;
m_context -> setFOV ( 85.0f, 85.0f*3.0f/8.0f ) ;
break;
m_context -> setFOV ( 85.0f, 85.0f*3.0f/8.0f ); break;
}
}
else if (numPlayers == 4)
else if (num_players == 4)
{
m_context -> setFOV ( 50.0f, 0.0f );
switch ( pos )
switch ( camera_index )
{
case 0 : m_x = 0.0f; m_y = 0.5f; m_w = 0.5f; m_h = 0.5f;
break;
case 1 : m_x = 0.5f; m_y = 0.5f; m_w = 0.5f; m_h = 0.5f;
break;
case 2 : m_x = 0.0f; m_y = 0.0f; m_w = 0.5f; m_h = 0.5f;
break;
case 3 : m_x = 0.5f; m_y = 0.0f; m_w = 0.5f; m_h = 0.5f;
break;
case 0 : m_x = 0.0f; m_y = 0.5f; m_w = 0.5f; m_h = 0.5f; break;
case 1 : m_x = 0.5f; m_y = 0.5f; m_w = 0.5f; m_h = 0.5f; break;
case 2 : m_x = 0.0f; m_y = 0.0f; m_w = 0.5f; m_h = 0.5f; break;
case 3 : m_x = 0.5f; m_y = 0.0f; m_w = 0.5f; m_h = 0.5f; break;
}
}
m_last_pitch = 0.0f;
} // setScreenPosition
//-----------------------------------------------------------------------------
Camera::Camera(int numPlayers, int which)
: m_reverse(false)
{
m_mode = CM_NORMAL;
m_context = new ssgContext ;
m_which_kart = which;
if(m_which_kart >= int(race_manager->getNumKarts()) || m_which_kart < 0 )
m_which_kart =0;
// FIXME: clipping should be configurable for slower machines
const Track* track = world->getTrack();
if (track->useFog())
m_context -> setNearFar ( 0.05f, track->getFogEnd() ) ;
else
m_context -> setNearFar ( 0.05f, 1000.0f ) ;
setScreenPosition ( numPlayers, m_which_kart ) ;
m_last_steer_offset = 0;
} // Camera
//-----------------------------------------------------------------------------
void Camera::setMode(Mode mode)
{
m_mode = mode;
m_last_pitch = 0.0f;
if(m_mode==CM_LEADER_MODE)
setReverseHeading(true);
if(m_mode==CM_CLOSEUP)
m_distance = 2.5f;
else
m_distance = m_kart->getKartProperties()->getCameraDistance();
} // setMode
//-----------------------------------------------------------------------------
void Camera::setReverseHeading(bool b)
{
m_reverse = b;
} // setReverseHeading
//-----------------------------------------------------------------------------
/** Reset is called when a new race starts. Make sure that the camera
is aligned neutral, and not like in the previous race
@@ -129,24 +118,20 @@ void Camera::update (float dt)
{
sgCoord kartcoord;
const Kart *kart;
// Update the camera
// First define the position of the kart
if(m_mode==CM_LEADER_MODE)
{
kart=world->getKart(0);
sgCopyCoord(&kartcoord, kart->getCoord());
// This gives a camera slightly above the kart, facing downwards
// But this works only when the karts are within a certain distance
// otherwise only the track is seen :(
// kartcoord.xyz[2]+=3.0f; // raise camera
// kartcoord.hpr[1]+=17; // face downwards
}
else
{
kart=world->getPlayerKart(m_which_kart);
kart = m_kart;
sgCopyCoord(&kartcoord, kart->getCoord());
// Use the terrain pitch to avoid the camera following a wheelie the kart is doing
kartcoord.hpr[1]=RAD_TO_DEGREE( kart->getTerrainPitch(DEGREE_TO_RAD(kartcoord.hpr[0])) );
kartcoord.hpr[1]=RAD_TO_DEGREE(m_kart->getTerrainPitch(DEGREE_TO_RAD(kartcoord.hpr[0])) );
kartcoord.hpr[2] = 0;
// Only adjust the pitch if it's not the first frame (which is indicated by having
// dt=0). Otherwise the camera will change pitch during ready-set-go.
@@ -165,60 +150,30 @@ void Camera::update (float dt)
} // dt>0.0
m_last_pitch = kartcoord.hpr[1];
} // m_mode!=CM_LEADER_MODE
if(m_mode==CM_SIMPLE_REPLAY) kartcoord.hpr[0] = 0;
if (m_mode == CM_SIMPLE_REPLAY)
kartcoord.hpr[0] = 0;
// Uncomment this for a simple MarioKart-like replay-camera
// kartcoord.hpr[0] = 0;
// Set the camera position relative to the kart
// --------------------------------------------
sgMat4 cam_pos;
// 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;
sgMakeTransMat4(cam_pos, 0.f, -m_distance, reverse ? 0.75f : 1.5f);
// Set the camera rotation
// -----------------------
sgMat4 cam_rot;
sgMakeRotMat4(cam_rot, reverse ? 180.0f : 0.0f,
m_mode==CM_CLOSEUP ? -15.0f : -5.0f,
0);
// Matrix that transforms stuff to kart-space
sgMat4 tokart;
sgMakeCoordMat4 (tokart, &kartcoord);
// Relative position from the middle of the kart
sgMat4 relative;
sgMat4 cam_pos;
if (m_mode == CM_CLOSEUP)
sgMakeTransMat4(cam_pos, 0.f, -2.5f, 1.5f);
else
sgMakeTransMat4(cam_pos, 0.f,
-kart->getKartProperties()->getCameraDistance(), 1.5f);
if (m_reverse)
{
// If player is looking back all other camera options are ignored.
sgMat4 cam_lb;
sgMakeTransMat4(cam_pos, 0.f, -2.5f, 0.75f);
// Applies 'look back' rotation.
sgMakeRotMat4(cam_lb, 180, 0, 0);
sgMultMat4(relative, cam_pos, cam_lb);
}
else if (m_mode == CM_NO_FAKE_DRIFT)
{
const float STEER_OFFSET = kart->getSteerAngle()*-10.0f;
sgMat4 cam_rot;
sgMat4 tmp;
sgMakeRotMat4(cam_rot, 0, -5, 0);
sgMultMat4(tmp, cam_pos, cam_rot);
sgMakeRotMat4(cam_rot, STEER_OFFSET, 0, 0);
sgMultMat4(relative, cam_rot, tmp);
}
else
{
sgMat4 cam_rot;
if (m_mode == CM_CLOSEUP)
sgMakeRotMat4(cam_rot, 0, -15, 0);
else
sgMakeRotMat4(cam_rot, 0, -5, 0);
sgMultMat4(relative, cam_pos, cam_rot);
}
sgMultMat4(relative, cam_pos, cam_rot);
sgMat4 result;
sgMultMat4(result, tokart, relative);

View File

@@ -22,46 +22,40 @@
#ifndef HEADER_CAMERA_H
#define HEADER_CAMERA_H
#include "LinearMath/btVector3.h"
class ssgContext;
class Kart;
class Camera
{
public:
enum Mode {
CM_NORMAL,
CM_CLOSEUP,
CM_NORMAL, // Normal camera mode
CM_CLOSEUP, // Normal camera, closer to kart
CM_DRIFTING, // FIXME: drifting behind when accelerating = not yet implemented
CM_LEADER_MODE, // for deleted player karts in follow the leader
//FIXME: NO_FAKE_DRIFT is broken
CM_NO_FAKE_DRIFT,
CM_REVERSE, // Camera is pointing backwards
CM_SIMPLE_REPLAY
};
protected:
ssgContext *m_context ;
sgCoord m_current_pos;
int m_which_kart;
Mode m_mode;
float m_last_steer_offset;
float m_x, m_y, m_w, m_h;
const Kart *m_kart; // the kart the camera is attached to
Mode m_mode; // CM_ value, see above
float m_x, m_y, m_w, m_h; // window to us
float m_current_speed; // current speed of camera
float m_last_pitch;
float m_last_pitch; // for tiling the camera when going downhill
float m_distance; // distance between camera and kart
bool m_reverse;
public:
Camera ( int numPlayers, int id ) ;
/** Set the camera to the given mode */
void setMode(Mode mode_);
void setReverseHeading(bool);
void setScreenPosition ( int numPlayers, int pos ) ;
void reset();
void update (float dt) ;
void apply () ;
int getKartId() const { return m_which_kart; }
Camera (int camera_index, const Kart* kart);
void setMode (Mode mode_); /** Set the camera to the given mode */
void setScreenPosition(int pos);
void reset ();
void update (float dt);
void apply ();
} ;
#endif

View File

@@ -28,8 +28,39 @@
#include "gui/menu_manager.hpp"
#include "gui/race_gui.hpp"
#include "translation.hpp"
#include "scene.hpp"
#include "camera.hpp"
PlayerKart::PlayerKart(const std::string& kart_name, int position, Player *player,
sgCoord init_pos, int player_index) :
Kart(kart_name, position, init_pos)
{
m_player = player;
m_penalty_time = 0.0f;
m_camera = scene->createCamera(player_index, this);
m_camera->setMode(Camera::CM_NORMAL);
reset();
} // PlayerKart
//-----------------------------------------------------------------------------
void PlayerKart::reset()
{
m_steer_val_l = 0;
m_steer_val_r = 0;
m_steer_val = 0;
m_accel_val = 0;
m_controls.accel = 0.0;
m_controls.brake =false;
m_controls.fire = false;
m_controls.wheelie = false;
m_controls.jump = false;
m_penalty_time = 0;
m_time_last_crash_sound = -10.0f;
m_camera->setMode(Camera::CM_NORMAL); // can be changed if camera was eliminated
Kart::reset();
} // reset
// ----------------------------------------------------------------------------
void PlayerKart::action(KartAction action, int value)
{
switch (action)
@@ -68,7 +99,7 @@ void PlayerKart::action(KartAction action, int value)
m_controls.fire = (value!=0);
break;
case KA_LOOK_BACK:
m_camera->setReverseHeading(value!=0);
m_camera->setMode(value!=0 ? Camera::CM_REVERSE : Camera::CM_NORMAL);
break;
case KA_JUMP:
m_controls.jump = (value!=0);
@@ -205,25 +236,6 @@ void PlayerKart::collectedHerring(Herring* herring)
sound_manager->playSfx ( ( herring->getType()==HE_GREEN ) ? SOUND_UGH:SOUND_GRAB);
} // collectedHerring
//-----------------------------------------------------------------------------
void PlayerKart::reset()
{
m_steer_val_l = 0;
m_steer_val_r = 0;
m_steer_val = 0;
m_accel_val = 0;
m_controls.accel = 0.0;
m_controls.brake =false;
m_controls.fire = false;
m_controls.wheelie = false;
m_controls.jump = false;
m_penalty_time = 0;
m_time_last_crash_sound = -10.0f;
m_camera->setMode(Camera::CM_NORMAL); // can be changed if camera was eliminated
m_camera->setReverseHeading(false);
Kart::reset();
} // reset
//-----------------------------------------------------------------------------
/** This function is called by world to add any messages to the race gui. This
* can't be done (in some cases) in the update() function, since update can be

View File

@@ -44,9 +44,7 @@ private:
public:
PlayerKart(const std::string& kart_name,
int position, Player *_player,
sgCoord init_pos, Camera *cam) :
Kart(kart_name, position, init_pos), m_player(_player),
m_penalty_time(0.0), m_camera(cam) {reset(); }
sgCoord init_pos, int player_index);
int earlyStartPenalty () {return m_penalty_time>0; }
Player* getPlayer () {return m_player; }

View File

@@ -62,10 +62,9 @@ void Scene::clear ()
//-----------------------------------------------------------------------------
Camera *
Scene::createCamera(int numPlayers, int playerId)
Camera *Scene::createCamera(int playerId, const Kart* kart)
{
Camera *cam = new Camera(numPlayers, playerId);
Camera *cam = new Camera(playerId, kart);
m_cameras.push_back(cam);

View File

@@ -21,7 +21,7 @@
//FIXME: make the camera a pointer to vector so it can be forward declared.
#include <vector>
//#include <plib/ssg.h>
#include "LinearMath/btVector3.h"
class ssgRoot;
class ssgEntity;
@@ -44,8 +44,7 @@ public:
void remove(ssgEntity *kid);
void draw(float dt);
Camera *createCamera(int numPlayers, int playerId);
Camera *createCamera(int playerId, const Kart* kart);
};
extern Scene *scene;

View File

@@ -284,7 +284,8 @@ void SoundManager::switchToFastMusic()
}
else
{
m_mode = SOUND_FASTER;
// FIXME: for now this music is too annoying,
// m_mode = SOUND_FASTER;
}
} // switchToFastMusic
//-----------------------------------------------------------------------------

View File

@@ -109,18 +109,17 @@ World::World()
// karts can be seen.
if(i==race_manager->getNumKarts()-1)
{
scene->createCamera(race_manager->getNumPlayers(), playerIndex);
btVector3 startpos(init_pos.xyz[0], init_pos.xyz[1], init_pos.xyz[2]);
scene->createCamera(playerIndex, newkart);
}
}
else
{
if (race_manager->isPlayer(i))
{
Camera *cam = scene->createCamera(race_manager->getNumPlayers(), playerIndex);
// the given position belongs to a player
newkart = new PlayerKart(kart_name, position,
&(user_config->m_player[playerIndex]),
init_pos, cam);
init_pos, playerIndex);
m_player_karts.push_back((PlayerKart*)newkart);
playerIndex++;
}