Add possibility to attach the fps camera to the kart

This commit is contained in:
Flakebi
2015-03-08 17:15:50 +01:00
parent b21f6f4782
commit 5b8834b48f
4 changed files with 109 additions and 22 deletions

View File

@@ -50,6 +50,7 @@ Camera* Camera::s_active_camera = NULL;
Camera::Camera(int camera_index, AbstractKart* kart) : m_kart(NULL)
{
m_smooth = false;
m_attached = false;
m_mode = CM_NORMAL;
m_index = camera_index;
m_original_kart = kart;
@@ -91,6 +92,11 @@ Camera::Camera(int camera_index, AbstractKart* kart) : m_kart(NULL)
m_target_direction = core::vector3df(0, 0, 1);
m_target_up_vector = core::vector3df(0, 1, 0);
m_direction_velocity = core::vector3df(0, 0, 0);
m_local_position = core::vector3df(0, 0, 0);
m_local_direction = core::vector3df(0, 0, 1);
m_local_up = core::vector3df(0, 1, 0);
m_angular_velocity = 0;
m_target_angular_velocity = 0;
m_max_velocity = 15;
@@ -108,6 +114,42 @@ Camera::~Camera()
s_active_camera = NULL;
} // ~Camera
//-----------------------------------------------------------------------------
/** Applies mouse movement to the first person camera.
* \param x The horizontal difference of the mouse position.
* \param y The vertical difference of the mouse position.
*/
void Camera::applyMouseMovement (float x, float y)
{
core::vector3df direction(m_target_direction);
core::vector3df up(m_camera->getUpVector());
// Set local values if the camera is attached to the kart
if (m_attached)
up = m_local_up;
core::vector3df side(direction.crossProduct(up));
direction.normalize();
up.normalize();
core::quaternion quat;
quat.fromAngleAxis(x, up);
core::quaternion quat_y;
quat_y.fromAngleAxis(y, side);
quat *= quat_y;
direction = quat * direction;
m_target_direction = direction;
// Don't do that because it looks ugly and is bad to handle ;)
/*side = direction.crossProduct(up);
// Compute new up vector
up = side.crossProduct(direction);
up.normalize();
cam->setUpVector(up);*/
}
//-----------------------------------------------------------------------------
/** Changes the owner of this camera to the new kart.
* \param new_kart The new kart to use this camera.
@@ -495,6 +537,15 @@ void Camera::update(float dt)
core::vector3df direction(m_camera->getTarget() - m_camera->getPosition());
core::vector3df up(m_camera->getUpVector());
core::vector3df side(direction.crossProduct(up));
core::vector3df pos = m_camera->getPosition();
// Set local values if the camera is attached to the kart
if (m_attached)
{
direction = m_local_direction;
up = m_local_up;
pos = m_local_position;
}
// Update smooth movement
if (m_smooth)
@@ -567,9 +618,33 @@ void Camera::update(float dt)
// Move camera
core::vector3df movement(direction * m_lin_velocity.Z +
up * m_lin_velocity.Y + side * m_lin_velocity.X);
core::vector3df pos = m_camera->getPosition();
pos = pos + movement * dt;
if (m_attached)
{
// Save current values
m_local_position = pos;
m_local_direction = direction;
m_local_up = up;
// Move the camera with the kart
btTransform t = m_kart->getTrans();
if (stk_config->m_camera_follow_skid &&
m_kart->getSkidding()->getVisualSkidRotation() != 0)
{
// If the camera should follow the graphical skid, add the
// visual rotation to the relative vector:
btQuaternion q(m_kart->getSkidding()->getVisualSkidRotation(), 0, 0);
t.setBasis(t.getBasis() * btMatrix3x3(q));
}
pos = Vec3(t(Vec3(pos))).toIrrVector();
btQuaternion q = t.getRotation();
btMatrix3x3 mat(q);
direction = Vec3(mat * Vec3(direction)).toIrrVector();
up = Vec3(mat * Vec3(up)).toIrrVector();
}
// Set camera attributes
m_camera->setPosition(pos);
m_camera->setTarget(pos + direction);

View File

@@ -113,6 +113,10 @@ private:
/** Smooth acceleration with the first person camera. */
bool m_smooth;
/** Attache the first person camera to a kart.
That means moving the kart also moves the camera. */
bool m_attached;
/** The speed at which the up-vector rotates, only used for the first person camera. */
float m_angular_velocity;
@@ -138,6 +142,15 @@ private:
/** The up vector the camera should have, only used for the first person camera. */
core::vector3df m_target_up_vector;
/** Save the local position if the first person camera is attached to the kart. */
core::vector3df m_local_position;
/** Save the local direction if the first person camera is attached to the kart. */
core::vector3df m_local_direction;
/** Save the local up vector if the first person camera is attached to the kart. */
core::vector3df m_local_up;
/** List of all cameras. */
static std::vector<Camera*> m_all_cameras;
@@ -269,6 +282,10 @@ public:
/** Returns the kart to which this camera is attached. */
AbstractKart* getKart() { return m_kart; }
// ------------------------------------------------------------------------
/** Applies mouse movement to the first person camera. */
void applyMouseMovement (float x, float y);
// ------------------------------------------------------------------------
/** Sets if the first person camera should be moved smooth. */
void setSmoothMovement (bool value) { m_smooth = value; }
@@ -277,6 +294,14 @@ public:
/** If the first person camera should be moved smooth. */
bool getSmoothMovement () { return m_smooth; }
// ------------------------------------------------------------------------
/** Sets if the first person camera should be moved with the kart. */
void setAttachedFpsCam (bool value) { m_attached = value; }
// ------------------------------------------------------------------------
/** If the first person camera should be moved with the kart. */
bool getAttachedFpsCam () { return m_attached; }
// ------------------------------------------------------------------------
/** Sets the angular velocity for this camera. */
void setMaximumVelocity (float vel) { m_max_velocity = vel; }

View File

@@ -985,27 +985,7 @@ EventPropagation InputManager::input(const SEvent& event)
(diff_x + diff_y) < 100 && (diff_x + diff_y) > -100)
{
// Rotate camera
core::vector3df up(cam->getUpVector());
core::vector3df direction(cam->getDirection());
core::vector3df side(direction.crossProduct(up));
direction.normalize();
up.normalize();
core::quaternion quat;
quat.fromAngleAxis(mouse_x, up);
core::quaternion quat_y;
quat_y.fromAngleAxis(mouse_y, side);
quat *= quat_y;
direction = quat * direction;
cam->setDirection(direction);
side = direction.crossProduct(up);
// Compute new up vector
/*up = side.crossProduct(direction);
up.normalize();
// Don't do that because it looks ugly and is bad to handle ;)
cam->setUpVector(up);*/
cam->applyMouseMovement(mouse_x, mouse_y);
// Reset mouse position to the middle of the screen when
// the mouse is far away

View File

@@ -97,6 +97,7 @@ enum DebugMenuCommand
DEBUG_GUI_CAM_WHEEL,
DEBUG_GUI_CAM_NORMAL,
DEBUG_GUI_CAM_SMOOTH,
DEBUG_GUI_CAM_ATTACH,
DEBUG_HIDE_KARTS,
DEBUG_THROTTLE_FPS,
DEBUG_VISUAL_VALUES,
@@ -260,6 +261,7 @@ bool onEvent(const SEvent &event)
sub->addItem(L"First person view", DEBUG_GUI_CAM_FREE);
sub->addItem(L"Normal view", DEBUG_GUI_CAM_NORMAL);
sub->addItem(L"Toggle smooth camera", DEBUG_GUI_CAM_SMOOTH);
sub->addItem(L"Attach fps camera to kart", DEBUG_GUI_CAM_ATTACH);
mnu->addItem(L"Adjust values", DEBUG_VISUAL_VALUES);
@@ -539,6 +541,11 @@ bool onEvent(const SEvent &event)
Camera *cam = Camera::getActiveCamera();
cam->setSmoothMovement(!cam->getSmoothMovement());
}
else if (cmdID == DEBUG_GUI_CAM_ATTACH)
{
Camera *cam = Camera::getActiveCamera();
cam->setAttachedFpsCam(!cam->getAttachedFpsCam());
}
else if (cmdID == DEBUG_PRINT_START_POS)
{
if(!world) return false;