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:
177
src/camera.cpp
177
src/camera.cpp
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user