created transitions between camera modes

This commit is contained in:
Jeffrey Ventrella 2013-05-13 16:53:45 -07:00
parent 6c3de00bcd
commit 54010d36c4
3 changed files with 83 additions and 56 deletions

View file

@ -12,6 +12,8 @@
#include "Camera.h" #include "Camera.h"
const float MODE_SHIFT_RATE = 5.0f;
Camera::Camera() { Camera::Camera() {
_needsToInitialize = true; _needsToInitialize = true;
@ -22,12 +24,10 @@ Camera::Camera() {
_fieldOfView = 60.0; // default _fieldOfView = 60.0; // default
_nearClip = 0.08; // default _nearClip = 0.08; // default
_farClip = 50.0 * TREE_SCALE; // default _farClip = 50.0 * TREE_SCALE; // default
_modeShift = 0.0;
_yaw = 0.0; _yaw = 0.0;
_pitch = 0.0; _pitch = 0.0;
_roll = 0.0; _roll = 0.0;
_upShift = 0.0; _upShift = 0.0;
_rightShift = 0.0;
_distance = 0.0; _distance = 0.0;
_idealYaw = 0.0; _idealYaw = 0.0;
_idealPitch = 0.0; _idealPitch = 0.0;
@ -36,28 +36,27 @@ Camera::Camera() {
_position = glm::vec3(0.0, 0.0, 0.0); _position = glm::vec3(0.0, 0.0, 0.0);
_idealPosition = glm::vec3(0.0, 0.0, 0.0); _idealPosition = glm::vec3(0.0, 0.0, 0.0);
_orientation.setToIdentity(); _orientation.setToIdentity();
for (int m = 0; m < NUM_CAMERA_MODES; m ++) {
_attributes[m].upShift = 0.0f;
_attributes[m].distance = 0.0f;
_attributes[m].tightness = 0.0f;
}
} }
void Camera::update(float deltaTime) { void Camera::update(float deltaTime) {
if (_mode == CAMERA_MODE_NULL) { if (_mode != CAMERA_MODE_NULL) {
_modeShift = 0.0; // use iterative forces to push the camera towards the target position and angle
} else {
// use iterative forces to push the camera towards the desired position and angle
updateFollowMode(deltaTime); updateFollowMode(deltaTime);
}
if (_modeShift < 1.0f) {
_modeShift += MODE_SHIFT_RATE * deltaTime;
if (_modeShift > 1.0f) {
_modeShift = 1.0f;
}
}
}
// do this AFTER making any changes to yaw pitch and roll.... // do this AFTER making any changes to yaw pitch and roll....
generateOrientation(); generateOrientation();
} }
// generate the ortho-normals for the orientation based on the three Euler angles // generate the ortho-normals for the orientation based on the three Euler angles
void Camera::generateOrientation() { void Camera::generateOrientation() {
_orientation.setToIdentity(); _orientation.setToIdentity();
@ -74,7 +73,7 @@ void Camera::updateFollowMode(float deltaTime) {
if (t > 1.0) { if (t > 1.0) {
t = 1.0; t = 1.0;
} }
// update Euler angles (before position!) // update Euler angles (before position!)
if (_needsToInitialize || OculusManager::isConnected()) { if (_needsToInitialize || OculusManager::isConnected()) {
_yaw = _idealYaw; _yaw = _idealYaw;
@ -104,15 +103,27 @@ void Camera::updateFollowMode(float deltaTime) {
_position = _idealPosition; _position = _idealPosition;
_needsToInitialize = false; _needsToInitialize = false;
} else { } else {
// pull position towards ideal position // force position towards ideal position
_position += (_idealPosition - _position) * t; _position += (_idealPosition - _position) * t;
} }
//transition to the attributes of the current mode
_upShift += (_attributes[_mode].upShift - _upShift ) * deltaTime * MODE_SHIFT_RATE;
_distance += (_attributes[_mode].distance - _distance ) * deltaTime * MODE_SHIFT_RATE;
_tightness += (_attributes[_mode].tightness - _tightness) * deltaTime * MODE_SHIFT_RATE;
} }
void Camera::setMode(CameraMode m, CameraFollowingAttributes a) {
_attributes[m].upShift = a.upShift;
_attributes[m].distance = a.distance;
_attributes[m].tightness = a.tightness;
setMode(m);
}
void Camera::setMode(CameraMode m) { void Camera::setMode(CameraMode m) {
_mode = m; _mode = m;
_modeShift = 0.0f;
_needsToInitialize = true; _needsToInitialize = true;
} }

View file

@ -20,13 +20,18 @@ enum CameraMode
NUM_CAMERA_MODES NUM_CAMERA_MODES
}; };
const float MODE_SHIFT_RATE = 2.0f;
class Camera class Camera
{ {
public: public:
Camera(); Camera();
struct CameraFollowingAttributes
{
float upShift;
float distance;
float tightness;
};
void initialize(); // instantly put the camera at the ideal position and rotation. void initialize(); // instantly put the camera at the ideal position and rotation.
void update( float deltaTime ); void update( float deltaTime );
@ -35,7 +40,6 @@ public:
void setPitch ( float p ) { _pitch = p; } void setPitch ( float p ) { _pitch = p; }
void setRoll ( float r ) { _roll = r; } void setRoll ( float r ) { _roll = r; }
void setUpShift ( float u ) { _upShift = u; } void setUpShift ( float u ) { _upShift = u; }
void setRightShift ( float r ) { _rightShift = r; }
void setDistance ( float d ) { _distance = d; } void setDistance ( float d ) { _distance = d; }
void setTargetPosition( glm::vec3 t ) { _targetPosition = t; } void setTargetPosition( glm::vec3 t ) { _targetPosition = t; }
void setTargetYaw ( float y ) { _idealYaw = y; } void setTargetYaw ( float y ) { _idealYaw = y; }
@ -43,8 +47,8 @@ public:
void setTightness ( float t ) { _tightness = t; } void setTightness ( float t ) { _tightness = t; }
void setTargetRotation( float yaw, float pitch, float roll ); void setTargetRotation( float yaw, float pitch, float roll );
void setMode ( CameraMode m ); void setMode ( CameraMode m );
void setMode ( CameraMode m, CameraFollowingAttributes attributes );
void setFieldOfView ( float f ); void setFieldOfView ( float f );
void setAspectRatio ( float a ); void setAspectRatio ( float a );
void setNearClip ( float n ); void setNearClip ( float n );
@ -56,7 +60,6 @@ public:
glm::vec3 getPosition () { return _position; } glm::vec3 getPosition () { return _position; }
Orientation getOrientation() { return _orientation; } Orientation getOrientation() { return _orientation; }
CameraMode getMode () { return _mode; } CameraMode getMode () { return _mode; }
float getModeShift () { return _modeShift; }
float getFieldOfView() { return _fieldOfView; } float getFieldOfView() { return _fieldOfView; }
float getAspectRatio() { return _aspectRatio; } float getAspectRatio() { return _aspectRatio; }
float getNearClip () { return _nearClip; } float getNearClip () { return _nearClip; }
@ -68,7 +71,6 @@ private:
bool _needsToInitialize; bool _needsToInitialize;
CameraMode _mode; CameraMode _mode;
float _modeShift; // 0.0 to 1.0
bool _frustumNeedsReshape; bool _frustumNeedsReshape;
glm::vec3 _position; glm::vec3 _position;
glm::vec3 _idealPosition; glm::vec3 _idealPosition;
@ -81,13 +83,14 @@ private:
float _pitch; float _pitch;
float _roll; float _roll;
float _upShift; float _upShift;
float _rightShift;
float _idealYaw; float _idealYaw;
float _idealPitch; float _idealPitch;
float _idealRoll; float _idealRoll;
float _distance; float _distance;
float _tightness; float _tightness;
Orientation _orientation; Orientation _orientation;
CameraFollowingAttributes _attributes[NUM_CAMERA_MODES];
void generateOrientation(); void generateOrientation();
void updateFollowMode( float deltaTime ); void updateFollowMode( float deltaTime );

View file

@ -114,9 +114,6 @@ float MOUSE_VIEW_SHIFT_PITCH_MARGIN = (float)(::screenHeight * 0.2f);
float MOUSE_VIEW_SHIFT_YAW_LIMIT = 45.0; float MOUSE_VIEW_SHIFT_YAW_LIMIT = 45.0;
float MOUSE_VIEW_SHIFT_PITCH_LIMIT = 30.0; float MOUSE_VIEW_SHIFT_PITCH_LIMIT = 30.0;
//CameraMode defaultCameraMode = CAMERA_MODE_FIRST_PERSON;
CameraMode defaultCameraMode = CAMERA_MODE_THIRD_PERSON;
bool wantColorRandomizer = true; // for addSphere and load file bool wantColorRandomizer = true; // for addSphere and load file
Oscilloscope audioScope(256,200,true); Oscilloscope audioScope(256,200,true);
@ -335,7 +332,12 @@ void init(void) {
} }
myAvatar.setPosition(start_location); myAvatar.setPosition(start_location);
myCamera.setMode(defaultCameraMode); Camera::CameraFollowingAttributes a;
a.upShift = -0.2f;
a.distance = 1.5f;
a.tightness = 8.0f;
myCamera.setMode(CAMERA_MODE_THIRD_PERSON, a);
myAvatar.setDisplayingHead(true);
OculusManager::connect(); OculusManager::connect();
@ -1044,37 +1046,28 @@ void display(void)
glLoadIdentity(); glLoadIdentity();
// camera settings // camera settings
if (myCamera.getMode() == CAMERA_MODE_MIRROR) { if (OculusManager::isConnected()) {
myAvatar.setDisplayingHead(true); myAvatar.setDisplayingHead(false);
myCamera.setUpShift (0.0);
myCamera.setDistance (0.2);
myCamera.setTightness (100.0f);
myCamera.setTargetPosition(myAvatar.getHeadPosition());
myCamera.setTargetRotation(myAvatar.getBodyYaw() - 180.0f, 0.0f, 0.0f);
} else if (myCamera.getMode() == CAMERA_MODE_FIRST_PERSON || OculusManager::isConnected()) {
myAvatar.setDisplayingHead(false);
myCamera.setUpShift (0.0f); myCamera.setUpShift (0.0f);
myCamera.setDistance (0.0f); myCamera.setDistance (0.0f);
myCamera.setTightness (100.0f); myCamera.setTightness (100.0f);
myCamera.setTargetPosition(myAvatar.getHeadPosition()); myCamera.setTargetPosition(myAvatar.getHeadPosition());
myCamera.setTargetRotation(myAvatar.getBodyYaw() + myAvatar.getHeadYaw(), -myAvatar.getHeadPitch(), myAvatar.getHeadRoll());
} else if (myCamera.getMode() == CAMERA_MODE_MIRROR) {
myCamera.setTargetPosition(myAvatar.getSpringyHeadPosition());
myCamera.setTargetRotation(myAvatar.getBodyYaw() - 180.0f, 0.0f, 0.0f);
if (OculusManager::isConnected()) { } else {
myCamera.setTargetRotation(myAvatar.getBodyYaw() + myAvatar.getHeadYaw(), if (myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) {
-myAvatar.getHeadPitch(), myCamera.setTargetPosition(myAvatar.getSpringyHeadPosition());
myAvatar.getHeadRoll()); myCamera.setTargetRotation(myAvatar.getAbsoluteHeadYaw()- mouseViewShiftYaw, myAvatar.getRenderPitch() + mouseViewShiftPitch, 0.0f);
} else { } else if (myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
myCamera.setTargetRotation(myAvatar.getAbsoluteHeadYaw()- mouseViewShiftYaw, myAvatar.getRenderPitch() + mouseViewShiftPitch, 0.0f); myCamera.setTargetPosition(myAvatar.getHeadPosition());
myCamera.setTargetRotation(myAvatar.getBodyYaw() - mouseViewShiftYaw, mouseViewShiftPitch, 0.0f);
} }
} else if (myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
myAvatar.setDisplayingHead(true);
myCamera.setUpShift (-0.2f);
myCamera.setDistance (1.5f);
myCamera.setTightness (8.0f);
myCamera.setTargetPosition(myAvatar.getHeadPosition());
myCamera.setTargetRotation(myAvatar.getBodyYaw() - mouseViewShiftYaw, mouseViewShiftPitch, 0.0f);
} }
// important... // important...
myCamera.update( 1.f/FPS ); myCamera.update( 1.f/FPS );
@ -1245,9 +1238,19 @@ int setRenderFirstPerson(int state) {
bool value = setValue(state, &::renderFirstPersonOn); bool value = setValue(state, &::renderFirstPersonOn);
if (state == MENU_ROW_PICKED) { if (state == MENU_ROW_PICKED) {
if (::renderFirstPersonOn) { if (::renderFirstPersonOn) {
myCamera.setMode(CAMERA_MODE_FIRST_PERSON); Camera::CameraFollowingAttributes a;
a.upShift = 0.0f;
a.distance = 0.0f;
a.tightness = 100.0f;
myCamera.setMode(CAMERA_MODE_FIRST_PERSON, a);
myAvatar.setDisplayingHead(false);
} else { } else {
myCamera.setMode(CAMERA_MODE_THIRD_PERSON); Camera::CameraFollowingAttributes a;
a.upShift = -0.2f;
a.distance = 1.5f;
a.tightness = 8.0f;
myCamera.setMode(CAMERA_MODE_THIRD_PERSON, a);
myAvatar.setDisplayingHead(true);
} }
} }
return value; return value;
@ -1681,9 +1684,19 @@ void key(unsigned char k, int x, int y) {
audio.setMixerLoopbackFlag(::lookingInMirror); audio.setMixerLoopbackFlag(::lookingInMirror);
if (::lookingInMirror) { if (::lookingInMirror) {
myCamera.setMode(CAMERA_MODE_MIRROR); Camera::CameraFollowingAttributes a;
a.upShift = 0.0f;
a.distance = 0.2f;
a.tightness = 100.0f;
myCamera.setMode(CAMERA_MODE_MIRROR, a);
myAvatar.setDisplayingHead(true);
} else { } else {
myCamera.setMode(defaultCameraMode); Camera::CameraFollowingAttributes a;
a.upShift = -0.2f;
a.distance = 1.5f;
a.tightness = 8.0f;
myCamera.setMode(CAMERA_MODE_THIRD_PERSON, a);
myAvatar.setDisplayingHead(true);
} }
#endif #endif
} }