diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index 3045e732e6..4cd66521f0 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -12,6 +12,8 @@ #include "Camera.h" +const float MODE_SHIFT_RATE = 5.0f; + Camera::Camera() { _needsToInitialize = true; @@ -22,12 +24,10 @@ Camera::Camera() { _fieldOfView = 60.0; // default _nearClip = 0.08; // default _farClip = 50.0 * TREE_SCALE; // default - _modeShift = 0.0; _yaw = 0.0; _pitch = 0.0; _roll = 0.0; _upShift = 0.0; - _rightShift = 0.0; _distance = 0.0; _idealYaw = 0.0; _idealPitch = 0.0; @@ -36,28 +36,27 @@ Camera::Camera() { _position = glm::vec3(0.0, 0.0, 0.0); _idealPosition = glm::vec3(0.0, 0.0, 0.0); _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) { - if (_mode == CAMERA_MODE_NULL) { - _modeShift = 0.0; - } else { - // use iterative forces to push the camera towards the desired position and angle + if (_mode != CAMERA_MODE_NULL) { + // use iterative forces to push the camera towards the target position and angle 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.... generateOrientation(); } + // generate the ortho-normals for the orientation based on the three Euler angles void Camera::generateOrientation() { _orientation.setToIdentity(); @@ -74,7 +73,7 @@ void Camera::updateFollowMode(float deltaTime) { if (t > 1.0) { t = 1.0; } - + // update Euler angles (before position!) if (_needsToInitialize || OculusManager::isConnected()) { _yaw = _idealYaw; @@ -104,15 +103,27 @@ void Camera::updateFollowMode(float deltaTime) { _position = _idealPosition; _needsToInitialize = false; } else { - // pull position towards ideal position + // force position towards ideal position _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) { _mode = m; - _modeShift = 0.0f; _needsToInitialize = true; } diff --git a/interface/src/Camera.h b/interface/src/Camera.h index fa087ca453..52c577e88a 100644 --- a/interface/src/Camera.h +++ b/interface/src/Camera.h @@ -20,13 +20,18 @@ enum CameraMode NUM_CAMERA_MODES }; -const float MODE_SHIFT_RATE = 2.0f; - class Camera { public: Camera(); + struct CameraFollowingAttributes + { + float upShift; + float distance; + float tightness; + }; + void initialize(); // instantly put the camera at the ideal position and rotation. void update( float deltaTime ); @@ -35,7 +40,6 @@ public: void setPitch ( float p ) { _pitch = p; } void setRoll ( float r ) { _roll = r; } void setUpShift ( float u ) { _upShift = u; } - void setRightShift ( float r ) { _rightShift = r; } void setDistance ( float d ) { _distance = d; } void setTargetPosition( glm::vec3 t ) { _targetPosition = t; } void setTargetYaw ( float y ) { _idealYaw = y; } @@ -43,8 +47,8 @@ public: void setTightness ( float t ) { _tightness = t; } void setTargetRotation( float yaw, float pitch, float roll ); - void setMode ( CameraMode m ); + void setMode ( CameraMode m, CameraFollowingAttributes attributes ); void setFieldOfView ( float f ); void setAspectRatio ( float a ); void setNearClip ( float n ); @@ -56,7 +60,6 @@ public: glm::vec3 getPosition () { return _position; } Orientation getOrientation() { return _orientation; } CameraMode getMode () { return _mode; } - float getModeShift () { return _modeShift; } float getFieldOfView() { return _fieldOfView; } float getAspectRatio() { return _aspectRatio; } float getNearClip () { return _nearClip; } @@ -68,7 +71,6 @@ private: bool _needsToInitialize; CameraMode _mode; - float _modeShift; // 0.0 to 1.0 bool _frustumNeedsReshape; glm::vec3 _position; glm::vec3 _idealPosition; @@ -81,13 +83,14 @@ private: float _pitch; float _roll; float _upShift; - float _rightShift; float _idealYaw; float _idealPitch; float _idealRoll; float _distance; float _tightness; Orientation _orientation; + + CameraFollowingAttributes _attributes[NUM_CAMERA_MODES]; void generateOrientation(); void updateFollowMode( float deltaTime ); diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 98aad1b6e1..047c2b1f23 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -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_PITCH_LIMIT = 30.0; -//CameraMode defaultCameraMode = CAMERA_MODE_FIRST_PERSON; -CameraMode defaultCameraMode = CAMERA_MODE_THIRD_PERSON; - bool wantColorRandomizer = true; // for addSphere and load file Oscilloscope audioScope(256,200,true); @@ -335,7 +332,12 @@ void init(void) { } 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(); @@ -1044,37 +1046,28 @@ void display(void) glLoadIdentity(); // camera settings - if (myCamera.getMode() == CAMERA_MODE_MIRROR) { - myAvatar.setDisplayingHead(true); - 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); + if (OculusManager::isConnected()) { + myAvatar.setDisplayingHead(false); myCamera.setUpShift (0.0f); myCamera.setDistance (0.0f); myCamera.setTightness (100.0f); 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()) { - myCamera.setTargetRotation(myAvatar.getBodyYaw() + myAvatar.getHeadYaw(), - -myAvatar.getHeadPitch(), - myAvatar.getHeadRoll()); - } else { - myCamera.setTargetRotation(myAvatar.getAbsoluteHeadYaw()- mouseViewShiftYaw, myAvatar.getRenderPitch() + mouseViewShiftPitch, 0.0f); + } else { + if (myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { + myCamera.setTargetPosition(myAvatar.getSpringyHeadPosition()); + myCamera.setTargetRotation(myAvatar.getAbsoluteHeadYaw()- mouseViewShiftYaw, myAvatar.getRenderPitch() + mouseViewShiftPitch, 0.0f); + } else if (myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { + 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... myCamera.update( 1.f/FPS ); @@ -1245,9 +1238,19 @@ int setRenderFirstPerson(int state) { bool value = setValue(state, &::renderFirstPersonOn); if (state == MENU_ROW_PICKED) { 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 { - 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; @@ -1681,9 +1684,19 @@ void key(unsigned char k, int x, int y) { audio.setMixerLoopbackFlag(::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 { - 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 }