1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-11-22 10:22:52 +01:00

Add multiple camera angles

This commit is contained in:
Daniel Evans 2015-05-08 23:53:56 +01:00
parent 013940c38a
commit ab00f33504
2 changed files with 55 additions and 10 deletions

View File

@ -18,7 +18,8 @@
#define AUTOLOOK_TIME 2.f
IngameState::IngameState(RWGame* game, bool newgame, bool test)
: State(game), started(false), newgame(newgame), test(test), autolookTimer(0.f)
: State(game), started(false), newgame(newgame), test(test),
autolookTimer(0.f), camMode(IngameState::CAMERA_NORMAL)
{
}
@ -115,6 +116,24 @@ void IngameState::tick(float dt)
}
float viewDistance = 4.f;
switch( camMode )
{
case IngameState::CAMERA_CLOSE:
viewDistance = 2.f;
break;
case IngameState::CAMERA_NORMAL:
viewDistance = 4.0f;
break;
case IngameState::CAMERA_FAR:
viewDistance = 6.f;
break;
case IngameState::CAMERA_TOPDOWN:
viewDistance = 15.f;
break;
default:
viewDistance = 4.f;
}
auto target = getWorld()->findObject(getWorld()->state->cameraTarget);
if( target == nullptr )
@ -123,23 +142,30 @@ void IngameState::tick(float dt)
}
glm::vec3 targetPosition = target->getPosition();
glm::vec3 lookTargetPosition = targetPosition;
targetPosition += glm::vec3(0.f, 0.f, 1.f);
lookTargetPosition += glm::vec3(0.f, 0.f, 0.5f);
btCollisionObject* physTarget = player->getCharacter()->physObject;
auto vehicle = ( target->type() == GameObject::Character ) ? static_cast<CharacterObject*>(target)->getCurrentVehicle() : nullptr;
if( vehicle ) {
auto model = vehicle->model;
float maxDist = 0.f;
for(auto& g : model->resource->geometries) {
viewDistance = std::max(
(glm::length(g->geometryBounds.center) + g->geometryBounds.radius) * 4.0f,
viewDistance);
float partSize = glm::length(g->geometryBounds.center) + g->geometryBounds.radius;
maxDist = std::max(partSize, maxDist);
}
viewDistance = viewDistance + maxDist;
targetPosition = vehicle->getPosition();
targetPosition.z += (vehicle->info->handling.dimensions.z / 2.f) * 2.0f;
lookTargetPosition = targetPosition;
lookTargetPosition.z += (vehicle->info->handling.dimensions.z);
targetPosition.z += (vehicle->info->handling.dimensions.z * 2.f);
physTarget = vehicle->physBody;
}
// Non-topdown camera can orbit
if( camMode != IngameState::CAMERA_TOPDOWN )
{
// Rotate the cameraPosition vector around targetPosition by the mouse movement
auto camtotarget = targetPosition - cameraPosition;
@ -149,6 +175,10 @@ void IngameState::tick(float dt)
glm::quat rho( epsilon * glm::vec3(0.f, mouseMove.y, 0.f) );
cameraPosition = targetPosition - (theta * (rho * camtotarget));
}
else
{
cameraPosition = targetPosition + glm::vec3(0.f, 0.f, viewDistance);
}
glm::quat angle;
@ -157,20 +187,21 @@ void IngameState::tick(float dt)
float correction = glm::length(camtotarget) - viewDistance;
if( correction < 0.f )
{
float innerDist = viewDistance * 0.25f;
float innerDist = viewDistance * 0.1f;
correction = glm::min(0.f, correction + innerDist);
}
cameraPosition += dir * 10.f * correction * dt;
auto lookdir = glm::normalize(lookTargetPosition - cameraPosition);
// Calculate the yaw to look at the target.
float angleYaw = glm::atan(dir.y, dir.x);
float angleYaw = glm::atan(lookdir.y, lookdir.x);
angle = glm::quat( glm::vec3(0.f, 0.f, angleYaw) );
// Update player with camera yaw
player->updateMovementDirection(angle * _movement, _movement);
float len2d = glm::length(glm::vec2(dir));
float anglePitch = glm::atan(dir.z, len2d);
float len2d = glm::length(glm::vec2(lookdir));
float anglePitch = glm::atan(lookdir.z, len2d);
angle *= glm::quat( glm::vec3(0.f, -anglePitch, 0.f) );
// Use rays to ensure target is visible from cameraPosition
@ -247,6 +278,9 @@ void IngameState::handleEvent(const sf::Event &event)
case sf::Keyboard::LShift:
player->setRunning(true);
break;
case sf::Keyboard::C:
camMode = CameraMode((camMode+(CameraMode)1)%CAMERA_MAX);
break;
case sf::Keyboard::F:
if( player && player->isInputEnabled() ) {
if( player->getCharacter()->getCurrentVehicle()) {

View File

@ -7,6 +7,16 @@ class PlayerController;
class IngameState : public State
{
enum CameraMode
{
CAMERA_CLOSE = 0,
CAMERA_NORMAL = 1,
CAMERA_FAR = 2,
CAMERA_TOPDOWN = 3,
/** Used for counting - not a valid camera mode */
CAMERA_MAX
};
bool started;
bool test;
bool newgame;
@ -14,8 +24,9 @@ class IngameState : public State
/** Player input */
glm::vec3 _movement;
glm::vec3 cameraPosition;
/** Timer to reset _lookAngles to forward in vehicles */
/** Timer to hold user camera position */
float autolookTimer;
CameraMode camMode;
public:
IngameState(RWGame* game, bool newgame = true, bool test = false);