Selfie camera and updated camera menus

This commit is contained in:
luiscuenca 2019-09-17 17:15:16 -07:00
parent 481917ae8a
commit 1054e8fcde
No known key found for this signature in database
GPG key ID: 2387ECD129A6961D
8 changed files with 158 additions and 51 deletions

View file

@ -3,8 +3,8 @@
"channels": [ "channels": [
{ "from": "Keyboard.A", "when": ["Keyboard.RightMouseButton", "!Keyboard.Control"], "to": "Actions.LATERAL_LEFT" }, { "from": "Keyboard.A", "when": ["Keyboard.RightMouseButton", "!Keyboard.Control"], "to": "Actions.LATERAL_LEFT" },
{ "from": "Keyboard.D", "when": ["Keyboard.RightMouseButton", "!Keyboard.Control"], "to": "Actions.LATERAL_RIGHT" }, { "from": "Keyboard.D", "when": ["Keyboard.RightMouseButton", "!Keyboard.Control"], "to": "Actions.LATERAL_RIGHT" },
{ "from": "Keyboard.E", "when": "!Keyboard.Control", "to": "Actions.LATERAL_RIGHT" }, { "from": "Keyboard.E", "when": ["!Application.CameraLookAt", "!Keyboard.Control"], "to": "Actions.LATERAL_RIGHT" },
{ "from": "Keyboard.Q", "when": "!Keyboard.Control", "to": "Actions.LATERAL_LEFT" }, { "from": "Keyboard.Q", "when": ["!Application.CameraLookAt", "!Keyboard.Control"], "to": "Actions.LATERAL_LEFT" },
{ "from": "Keyboard.T", "when": "!Keyboard.Control", "to": "Actions.TogglePushToTalk" }, { "from": "Keyboard.T", "when": "!Keyboard.Control", "to": "Actions.TogglePushToTalk" },
{ "comment" : "Mouse turn need to be small continuous increments", { "comment" : "Mouse turn need to be small continuous increments",
@ -39,7 +39,6 @@
] ]
}, },
{ "from": { "makeAxis" : [ { "from": { "makeAxis" : [
["Keyboard.Left" ], ["Keyboard.Left" ],
["Keyboard.Right"] ["Keyboard.Right"]
@ -95,6 +94,15 @@
"to": "Actions.Yaw" "to": "Actions.Yaw"
}, },
{ "from": { "makeAxis" : [
["Keyboard.Left"],
["Keyboard.Right"]
]
},
"when": ["Application.CameraSelfie", "!Keyboard.Shift"],
"to": "Actions.Yaw"
},
{ "from": { "makeAxis" : [ { "from": { "makeAxis" : [
["Keyboard.A"], ["Keyboard.A"],
["Keyboard.D"] ["Keyboard.D"]
@ -113,12 +121,21 @@
"to": "Actions.Yaw" "to": "Actions.Yaw"
}, },
{ "from": { "makeAxis" : [
["Keyboard.Q"],
["Keyboard.E"]
]
},
"when": ["Application.CameraLookAt", "!Keyboard.Control"],
"to": "Actions.Yaw"
},
{ "from": { "makeAxis" : [ { "from": { "makeAxis" : [
["Keyboard.A"], ["Keyboard.A"],
["Keyboard.D"] ["Keyboard.D"]
] ]
}, },
"when": ["Application.CameraLookAt", "!Keyboard.Control"], "when": ["Application.CameraSelfie", "!Keyboard.Control"],
"to": "Actions.Yaw" "to": "Actions.Yaw"
}, },
@ -149,6 +166,15 @@
"to": "Actions.Yaw" "to": "Actions.Yaw"
}, },
{ "from": { "makeAxis" : [
["Keyboard.TouchpadLeft"],
["Keyboard.TouchpadRight"]
]
},
"when": "Application.CameraSelfie",
"to": "Actions.Yaw"
},
{ "from": { "makeAxis" : ["Keyboard.MouseMoveLeft", "Keyboard.MouseMoveRight"] }, { "from": { "makeAxis" : ["Keyboard.MouseMoveLeft", "Keyboard.MouseMoveRight"] },
"when": "Keyboard.RightMouseButton", "when": "Keyboard.RightMouseButton",
"to": "Actions.DeltaYaw", "to": "Actions.DeltaYaw",
@ -159,7 +185,16 @@
}, },
{ "from": { "makeAxis" : ["Keyboard.MouseMoveUp", "Keyboard.MouseMoveDown"] }, { "from": { "makeAxis" : ["Keyboard.MouseMoveUp", "Keyboard.MouseMoveDown"] },
"when": "Keyboard.RightMouseButton", "when": ["!Application.CameraSelfie", "Keyboard.RightMouseButton"],
"to": "Actions.DeltaPitch",
"filters":
[
{ "type": "scale", "scale": 0.6 }
]
},
{ "from": { "makeAxis" : ["Keyboard.MouseMoveDown", "Keyboard.MouseMoveUp"] },
"when": ["Application.CameraSelfie", "Keyboard.RightMouseButton"],
"to": "Actions.DeltaPitch", "to": "Actions.DeltaPitch",
"filters": "filters":
[ [
@ -169,6 +204,8 @@
{ "from": "Keyboard.W", "when": "!Keyboard.Control", "to": "Actions.LONGITUDINAL_FORWARD" }, { "from": "Keyboard.W", "when": "!Keyboard.Control", "to": "Actions.LONGITUDINAL_FORWARD" },
{ "from": "Keyboard.S", "when": "!Keyboard.Control", "to": "Actions.LONGITUDINAL_BACKWARD" }, { "from": "Keyboard.S", "when": "!Keyboard.Control", "to": "Actions.LONGITUDINAL_BACKWARD" },
{ "from": "Keyboard.A", "when": "Application.CameraLookAt", "to": "Actions.LATERAL_LEFT" },
{ "from": "Keyboard.D", "when": "Application.CameraLookAt", "to": "Actions.LATERAL_RIGHT" },
{ "from": "Keyboard.Shift", "when": ["!Keyboard.Left", "!Keyboard.Right"], "to": "Actions.SPRINT" }, { "from": "Keyboard.Shift", "when": ["!Keyboard.Left", "!Keyboard.Right"], "to": "Actions.SPRINT" },
{ "from": "Keyboard.C", "when": "!Keyboard.Control", "to": "Actions.VERTICAL_DOWN" }, { "from": "Keyboard.C", "when": "!Keyboard.Control", "to": "Actions.VERTICAL_DOWN" },
{ "from": "Keyboard.Left", "when": "Keyboard.Shift", "to": "Actions.LATERAL_LEFT" }, { "from": "Keyboard.Left", "when": "Keyboard.Shift", "to": "Actions.LATERAL_LEFT" },
@ -176,9 +213,11 @@
{ "from": "Keyboard.Up", "when": "Application.CameraFirstPerson", "to": "Actions.LONGITUDINAL_FORWARD" }, { "from": "Keyboard.Up", "when": "Application.CameraFirstPerson", "to": "Actions.LONGITUDINAL_FORWARD" },
{ "from": "Keyboard.Up", "when": "Application.CameraThirdPerson", "to": "Actions.LONGITUDINAL_FORWARD" }, { "from": "Keyboard.Up", "when": "Application.CameraThirdPerson", "to": "Actions.LONGITUDINAL_FORWARD" },
{ "from": "Keyboard.Up", "when": "Application.CameraLookAt", "to": "Actions.LONGITUDINAL_FORWARD" }, { "from": "Keyboard.Up", "when": "Application.CameraLookAt", "to": "Actions.LONGITUDINAL_FORWARD" },
{ "from": "Keyboard.Up", "when": "Application.CameraSelfie", "to": "Actions.LONGITUDINAL_FORWARD" },
{ "from": "Keyboard.Down", "when": "Application.CameraFirstPerson", "to": "Actions.LONGITUDINAL_BACKWARD" }, { "from": "Keyboard.Down", "when": "Application.CameraFirstPerson", "to": "Actions.LONGITUDINAL_BACKWARD" },
{ "from": "Keyboard.Down", "when": "Application.CameraThirdPerson", "to": "Actions.LONGITUDINAL_BACKWARD" }, { "from": "Keyboard.Down", "when": "Application.CameraThirdPerson", "to": "Actions.LONGITUDINAL_BACKWARD" },
{ "from": "Keyboard.Down", "when": "Application.CameraLookAt", "to": "Actions.LONGITUDINAL_BACKWARD" }, { "from": "Keyboard.Down", "when": "Application.CameraLookAt", "to": "Actions.LONGITUDINAL_BACKWARD" },
{ "from": "Keyboard.Down", "when": "Application.CameraSelfie", "to": "Actions.LONGITUDINAL_BACKWARD" },
{ "from": "Keyboard.PgDown", "to": "Actions.VERTICAL_DOWN" }, { "from": "Keyboard.PgDown", "to": "Actions.VERTICAL_DOWN" },
{ "from": "Keyboard.PgUp", "to": "Actions.VERTICAL_UP" }, { "from": "Keyboard.PgUp", "to": "Actions.VERTICAL_UP" },

View file

@ -710,6 +710,7 @@ static const QString STATE_CAMERA_THIRD_PERSON = "CameraThirdPerson";
static const QString STATE_CAMERA_ENTITY = "CameraEntity"; static const QString STATE_CAMERA_ENTITY = "CameraEntity";
static const QString STATE_CAMERA_INDEPENDENT = "CameraIndependent"; static const QString STATE_CAMERA_INDEPENDENT = "CameraIndependent";
static const QString STATE_CAMERA_LOOK_AT = "CameraLookAt"; static const QString STATE_CAMERA_LOOK_AT = "CameraLookAt";
static const QString STATE_CAMERA_SELFIE = "CameraSelfie";
static const QString STATE_SNAP_TURN = "SnapTurn"; static const QString STATE_SNAP_TURN = "SnapTurn";
static const QString STATE_ADVANCED_MOVEMENT_CONTROLS = "AdvancedMovement"; static const QString STATE_ADVANCED_MOVEMENT_CONTROLS = "AdvancedMovement";
static const QString STATE_GROUNDED = "Grounded"; static const QString STATE_GROUNDED = "Grounded";
@ -926,7 +927,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) {
DependencyManager::set<AudioInjectorManager>(); DependencyManager::set<AudioInjectorManager>();
DependencyManager::set<MessagesClient>(); DependencyManager::set<MessagesClient>();
controller::StateController::setStateVariables({ { STATE_IN_HMD, STATE_CAMERA_FULL_SCREEN_MIRROR, controller::StateController::setStateVariables({ { STATE_IN_HMD, STATE_CAMERA_FULL_SCREEN_MIRROR,
STATE_CAMERA_FIRST_PERSON, STATE_CAMERA_THIRD_PERSON, STATE_CAMERA_ENTITY, STATE_CAMERA_INDEPENDENT, STATE_CAMERA_LOOK_AT, STATE_CAMERA_FIRST_PERSON, STATE_CAMERA_THIRD_PERSON, STATE_CAMERA_ENTITY, STATE_CAMERA_INDEPENDENT, STATE_CAMERA_LOOK_AT, STATE_CAMERA_SELFIE,
STATE_SNAP_TURN, STATE_ADVANCED_MOVEMENT_CONTROLS, STATE_GROUNDED, STATE_NAV_FOCUSED, STATE_SNAP_TURN, STATE_ADVANCED_MOVEMENT_CONTROLS, STATE_GROUNDED, STATE_NAV_FOCUSED,
STATE_PLATFORM_WINDOWS, STATE_PLATFORM_MAC, STATE_PLATFORM_ANDROID, STATE_LEFT_HAND_DOMINANT, STATE_RIGHT_HAND_DOMINANT, STATE_STRAFE_ENABLED } }); STATE_PLATFORM_WINDOWS, STATE_PLATFORM_MAC, STATE_PLATFORM_ANDROID, STATE_LEFT_HAND_DOMINANT, STATE_RIGHT_HAND_DOMINANT, STATE_STRAFE_ENABLED } });
DependencyManager::set<UserInputMapper>(); DependencyManager::set<UserInputMapper>();
@ -1876,6 +1877,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
_applicationStateDevice->setInputVariant(STATE_CAMERA_LOOK_AT, []() -> float { _applicationStateDevice->setInputVariant(STATE_CAMERA_LOOK_AT, []() -> float {
return qApp->getCamera().getMode() == CAMERA_MODE_LOOK_AT ? 1 : 0; return qApp->getCamera().getMode() == CAMERA_MODE_LOOK_AT ? 1 : 0;
}); });
_applicationStateDevice->setInputVariant(STATE_CAMERA_SELFIE, []() -> float {
return qApp->getCamera().getMode() == CAMERA_MODE_SELFIE ? 1 : 0;
});
_applicationStateDevice->setInputVariant(STATE_CAMERA_ENTITY, []() -> float { _applicationStateDevice->setInputVariant(STATE_CAMERA_ENTITY, []() -> float {
return qApp->getCamera().getMode() == CAMERA_MODE_ENTITY ? 1 : 0; return qApp->getCamera().getMode() == CAMERA_MODE_ENTITY ? 1 : 0;
}); });
@ -3611,7 +3615,9 @@ void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) {
_myCamera.setPosition(myAvatar->getDefaultEyePosition()); _myCamera.setPosition(myAvatar->getDefaultEyePosition());
_myCamera.setOrientation(myAvatar->getMyHead()->getHeadOrientation()); _myCamera.setOrientation(myAvatar->getMyHead()->getHeadOrientation());
} }
} else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON || _myCamera.getMode() == CAMERA_MODE_LOOK_AT) { } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON ||
_myCamera.getMode() == CAMERA_MODE_LOOK_AT ||
_myCamera.getMode() == CAMERA_MODE_SELFIE) {
if (isHMDMode()) { if (isHMDMode()) {
if (!_thirdPersonHMDCameraBoomValid) { if (!_thirdPersonHMDCameraBoomValid) {
@ -3640,8 +3646,12 @@ void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) {
+ myAvatar->getWorldOrientation() * boomOffset); + myAvatar->getWorldOrientation() * boomOffset);
} }
} else { } else {
glm::quat lookAtOffset = myAvatar->getLookAtOffset();
if (_myCamera.getMode() == CAMERA_MODE_SELFIE) {
lookAtOffset = lookAtOffset * glm::angleAxis(PI, myAvatar->getWorldOrientation() * Vectors::UP);
}
_myCamera.setPosition(myAvatar->getDefaultEyePosition() _myCamera.setPosition(myAvatar->getDefaultEyePosition()
+ myAvatar->getLookAtOffset() * boomOffset); + lookAtOffset * boomOffset);
_myCamera.lookAt(myAvatar->getDefaultEyePosition()); _myCamera.lookAt(myAvatar->getDefaultEyePosition());
} }
} }
@ -3683,8 +3693,7 @@ void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) {
glm::vec3(0.0f, 0.0f, -1.0f) * myAvatar->getBoomLength() * _scaleMirror); glm::vec3(0.0f, 0.0f, -1.0f) * myAvatar->getBoomLength() * _scaleMirror);
} }
renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE;
} } else if (_myCamera.getMode() == CAMERA_MODE_ENTITY) {
else if (_myCamera.getMode() == CAMERA_MODE_ENTITY) {
_thirdPersonHMDCameraBoomValid= false; _thirdPersonHMDCameraBoomValid= false;
EntityItemPointer cameraEntity = _myCamera.getCameraEntityPointer(); EntityItemPointer cameraEntity = _myCamera.getCameraEntityPointer();
if (cameraEntity != nullptr) { if (cameraEntity != nullptr) {
@ -4401,15 +4410,19 @@ void Application::keyPressEvent(QKeyEvent* event) {
} }
case Qt::Key_2: { case Qt::Key_2: {
Menu* menu = Menu::getInstance(); Menu* menu = Menu::getInstance();
menu->triggerOption(MenuOption::FullscreenMirror); menu->triggerOption(MenuOption::SelfieScreen);
break; break;
} }
case Qt::Key_3: { case Qt::Key_3: {
Menu* menu = Menu::getInstance(); Menu* menu = Menu::getInstance();
menu->triggerOption(MenuOption::ThirdPerson); menu->triggerOption(MenuOption::LookAtScreen);
break;
}
case Qt::Key_4: {
Menu* menu = Menu::getInstance();
menu->triggerOption(MenuOption::FullscreenMirror);
break; break;
} }
case Qt::Key_4:
case Qt::Key_5: case Qt::Key_5:
case Qt::Key_6: case Qt::Key_6:
case Qt::Key_7: case Qt::Key_7:
@ -5968,11 +5981,16 @@ void Application::cycleCamera() {
} else if (menu->isOptionChecked(MenuOption::FirstPerson)) { } else if (menu->isOptionChecked(MenuOption::FirstPerson)) {
menu->setIsOptionChecked(MenuOption::FirstPerson, false); menu->setIsOptionChecked(MenuOption::FirstPerson, false);
menu->setIsOptionChecked(MenuOption::ThirdPerson, true); menu->setIsOptionChecked(MenuOption::LookAtScreen, true);
} else if (menu->isOptionChecked(MenuOption::ThirdPerson)) { } else if (menu->isOptionChecked(MenuOption::LookAtScreen)) {
menu->setIsOptionChecked(MenuOption::ThirdPerson, false); menu->setIsOptionChecked(MenuOption::LookAtScreen, false);
menu->setIsOptionChecked(MenuOption::SelfieScreen, true);
} else if (menu->isOptionChecked(MenuOption::SelfieScreen)) {
menu->setIsOptionChecked(MenuOption::SelfieScreen, false);
menu->setIsOptionChecked(MenuOption::FullscreenMirror, true); menu->setIsOptionChecked(MenuOption::FullscreenMirror, true);
} }
@ -5985,7 +6003,10 @@ void Application::cameraModeChanged() {
Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, true); Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, true);
break; break;
case CAMERA_MODE_LOOK_AT: case CAMERA_MODE_LOOK_AT:
Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, true); Menu::getInstance()->setIsOptionChecked(MenuOption::LookAtScreen, true);
break;
case CAMERA_MODE_SELFIE:
Menu::getInstance()->setIsOptionChecked(MenuOption::SelfieScreen, true);
break; break;
case CAMERA_MODE_MIRROR: case CAMERA_MODE_MIRROR:
Menu::getInstance()->setIsOptionChecked(MenuOption::FullscreenMirror, true); Menu::getInstance()->setIsOptionChecked(MenuOption::FullscreenMirror, true);
@ -6027,13 +6048,20 @@ void Application::cameraMenuChanged() {
_myCamera.setMode(CAMERA_MODE_FIRST_PERSON); _myCamera.setMode(CAMERA_MODE_FIRST_PERSON);
getMyAvatar()->setBoomLength(MyAvatar::ZOOM_MIN); getMyAvatar()->setBoomLength(MyAvatar::ZOOM_MIN);
} }
} else if (menu->isOptionChecked(MenuOption::ThirdPerson)) { } else if (menu->isOptionChecked(MenuOption::LookAtScreen)) {
if (_myCamera.getMode() != CAMERA_MODE_LOOK_AT) { if (_myCamera.getMode() != CAMERA_MODE_LOOK_AT) {
_myCamera.setMode(CAMERA_MODE_LOOK_AT); _myCamera.setMode(CAMERA_MODE_LOOK_AT);
if (getMyAvatar()->getBoomLength() == MyAvatar::ZOOM_MIN) { if (getMyAvatar()->getBoomLength() == MyAvatar::ZOOM_MIN) {
getMyAvatar()->setBoomLength(MyAvatar::ZOOM_DEFAULT); getMyAvatar()->setBoomLength(MyAvatar::ZOOM_DEFAULT);
} }
} }
} else if (menu->isOptionChecked(MenuOption::SelfieScreen)) {
if (_myCamera.getMode() != CAMERA_MODE_SELFIE) {
_myCamera.setMode(CAMERA_MODE_SELFIE);
if (getMyAvatar()->getBoomLength() == MyAvatar::ZOOM_MIN) {
getMyAvatar()->setBoomLength(MyAvatar::ZOOM_DEFAULT);
}
}
} }
} }
@ -9117,9 +9145,11 @@ void Application::setDisplayPlugin(DisplayPluginPointer newDisplayPlugin) {
cameraMenuChanged(); cameraMenuChanged();
} }
// Remove the mirror camera option from menu if in HMD mode // Remove the mirror and selfie camera options from menu if in HMD mode
auto mirrorAction = menu->getActionForOption(MenuOption::FullscreenMirror); auto mirrorAction = menu->getActionForOption(MenuOption::FullscreenMirror);
mirrorAction->setVisible(!isHmd); mirrorAction->setVisible(!isHmd);
auto selfieAction = menu->getActionForOption(MenuOption::SelfieScreen);
selfieAction->setVisible(!isHmd);
} }
Q_ASSERT_X(_displayPlugin, "Application::updateDisplayMode", "could not find an activated display plugin"); Q_ASSERT_X(_displayPlugin, "Application::updateDisplayMode", "could not find an activated display plugin");

View file

@ -177,12 +177,19 @@ Menu::Menu() {
firstPersonAction->setProperty(EXCLUSION_GROUP_KEY, QVariant::fromValue(cameraModeGroup)); firstPersonAction->setProperty(EXCLUSION_GROUP_KEY, QVariant::fromValue(cameraModeGroup));
// View > Third Person // View > Look At
auto thirdPersonAction = cameraModeGroup->addAction(addCheckableActionToQMenuAndActionHash( auto lookAtAction = cameraModeGroup->addAction(addCheckableActionToQMenuAndActionHash(
viewMenu, MenuOption::ThirdPerson, 0, viewMenu, MenuOption::LookAtScreen, 0,
false, qApp, SLOT(cameraMenuChanged()))); false, qApp, SLOT(cameraMenuChanged())));
thirdPersonAction->setProperty(EXCLUSION_GROUP_KEY, QVariant::fromValue(cameraModeGroup)); lookAtAction->setProperty(EXCLUSION_GROUP_KEY, QVariant::fromValue(cameraModeGroup));
// View > Selfie
auto selfieAction = cameraModeGroup->addAction(addCheckableActionToQMenuAndActionHash(
viewMenu, MenuOption::SelfieScreen, 0,
false, qApp, SLOT(cameraMenuChanged())));
selfieAction->setProperty(EXCLUSION_GROUP_KEY, QVariant::fromValue(cameraModeGroup));
// View > Mirror // View > Mirror
auto viewMirrorAction = cameraModeGroup->addAction(addCheckableActionToQMenuAndActionHash( auto viewMirrorAction = cameraModeGroup->addAction(addCheckableActionToQMenuAndActionHash(

View file

@ -129,6 +129,7 @@ namespace MenuOption {
const QString Login = "Login/Sign Up"; const QString Login = "Login/Sign Up";
const QString Log = "Log"; const QString Log = "Log";
const QString LogExtraTimings = "Log Extra Timing Details"; const QString LogExtraTimings = "Log Extra Timing Details";
const QString LookAtScreen = "Look At";
const QString LowVelocityFilter = "Low Velocity Filter"; const QString LowVelocityFilter = "Low Velocity Filter";
const QString MeshVisible = "Draw Mesh"; const QString MeshVisible = "Draw Mesh";
const QString MuteEnvironment = "Mute Environment"; const QString MuteEnvironment = "Mute Environment";
@ -181,6 +182,7 @@ namespace MenuOption {
const QString RunTimingTests = "Run Timing Tests"; const QString RunTimingTests = "Run Timing Tests";
const QString ScriptedMotorControl = "Enable Scripted Motor Control"; const QString ScriptedMotorControl = "Enable Scripted Motor Control";
const QString ShowTrackedObjects = "Show Tracked Objects"; const QString ShowTrackedObjects = "Show Tracked Objects";
const QString SelfieScreen = "Selfie";
const QString SendWrongDSConnectVersion = "Send wrong DS connect version"; const QString SendWrongDSConnectVersion = "Send wrong DS connect version";
const QString SendWrongProtocolVersion = "Send wrong protocol version"; const QString SendWrongProtocolVersion = "Send wrong protocol version";
const QString SetHomeLocation = "Set Home Location"; const QString SetHomeLocation = "Set Home Location";

View file

@ -455,7 +455,7 @@ QByteArray MyAvatar::toByteArrayStateful(AvatarDataDetail dataDetail, bool dropF
_globalBoundingBoxDimensions.y = _characterController.getCapsuleHalfHeight(); _globalBoundingBoxDimensions.y = _characterController.getCapsuleHalfHeight();
_globalBoundingBoxDimensions.z = _characterController.getCapsuleRadius(); _globalBoundingBoxDimensions.z = _characterController.getCapsuleRadius();
_globalBoundingBoxOffset = _characterController.getCapsuleLocalOffset(); _globalBoundingBoxOffset = _characterController.getCapsuleLocalOffset();
if (mode == CAMERA_MODE_THIRD_PERSON || mode == CAMERA_MODE_INDEPENDENT || mode == CAMERA_MODE_LOOK_AT) { if (mode == CAMERA_MODE_THIRD_PERSON || mode == CAMERA_MODE_INDEPENDENT || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE) {
// fake the avatar position that is sent up to the AvatarMixer // fake the avatar position that is sent up to the AvatarMixer
glm::vec3 oldPosition = getWorldPosition(); glm::vec3 oldPosition = getWorldPosition();
setWorldPosition(getSkeletonPosition()); setWorldPosition(getSkeletonPosition());
@ -940,7 +940,7 @@ void MyAvatar::simulate(float deltaTime, bool inView) {
head->setPosition(headPosition); head->setPosition(headPosition);
head->setScale(getModelScale()); head->setScale(getModelScale());
head->simulate(deltaTime); head->simulate(deltaTime);
if (_scriptControlsHeadLookAt || qApp->getCamera().getMode() == CAMERA_MODE_LOOK_AT) { if (_scriptControlsHeadLookAt || qApp->getCamera().getMode() == CAMERA_MODE_LOOK_AT || qApp->getCamera().getMode() == CAMERA_MODE_SELFIE) {
updateHeadLookAt(deltaTime); updateHeadLookAt(deltaTime);
} else if (_headLookAtActive){ } else if (_headLookAtActive){
resetHeadLookAt(); resetHeadLookAt();
@ -2566,7 +2566,7 @@ void MyAvatar::useFullAvatarURL(const QUrl& fullAvatarURL, const QString& modelN
glm::vec3 MyAvatar::getSkeletonPosition() const { glm::vec3 MyAvatar::getSkeletonPosition() const {
CameraMode mode = qApp->getCamera().getMode(); CameraMode mode = qApp->getCamera().getMode();
if (mode == CAMERA_MODE_THIRD_PERSON || mode == CAMERA_MODE_INDEPENDENT || mode == CAMERA_MODE_LOOK_AT) { if (mode == CAMERA_MODE_THIRD_PERSON || mode == CAMERA_MODE_INDEPENDENT || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE) {
// The avatar is rotated PI about the yAxis, so we have to correct for it // The avatar is rotated PI about the yAxis, so we have to correct for it
// to get the skeleton offset contribution in the world-frame. // to get the skeleton offset contribution in the world-frame.
const glm::quat FLIP = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f)); const glm::quat FLIP = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f));
@ -3333,13 +3333,15 @@ void MyAvatar::setRotationThreshold(float angleRadians) {
void MyAvatar::updateOrientation(float deltaTime) { void MyAvatar::updateOrientation(float deltaTime) {
// Smoothly rotate body with arrow keys // Smoothly rotate body with arrow keys
float targetSpeed = getDriveKey(YAW) * _yawSpeed; float targetSpeed = getDriveKey(YAW) * _yawSpeed;
bool faceForward = false; bool computeCameraLookAt = (qApp->getCamera().getMode() == CAMERA_MODE_LOOK_AT ||
const float FPS = 60.0f; qApp->getCamera().getMode() == CAMERA_MODE_SELFIE) && isReadyForPhysics();
if (qApp->getCamera().getMode() == CAMERA_MODE_LOOK_AT) { if (computeCameraLookAt) {
float TIMESCALE_SPEED_CORRECTOR = deltaTime != 0.0f ? 1.0f / (FPS * deltaTime) : 1.0f; // Rotate directly proportional to delta yaw and delta pitch from right-click mouse movement.
targetSpeed = (getDriveKey(YAW) + getDriveKey(STEP_YAW) + getDriveKey(DELTA_YAW)) * _yawSpeed * TIMESCALE_SPEED_CORRECTOR; float speedFromDeltaYaw = deltaTime > FLT_EPSILON ? getDriveKey(DELTA_YAW) / deltaTime : 0.0f;
faceForward = getDriveKey(TRANSLATE_Z) != 0.0f || getDriveKey(TRANSLATE_X) != 0.0f; speedFromDeltaYaw *= _yawSpeed / YAW_SPEED_DEFAULT;
targetSpeed += speedFromDeltaYaw;
} }
if (targetSpeed != 0.0f) { if (targetSpeed != 0.0f) {
const float ROTATION_RAMP_TIMESCALE = 0.5f; const float ROTATION_RAMP_TIMESCALE = 0.5f;
float blend = deltaTime / ROTATION_RAMP_TIMESCALE; float blend = deltaTime / ROTATION_RAMP_TIMESCALE;
@ -3362,13 +3364,9 @@ void MyAvatar::updateOrientation(float deltaTime) {
} }
} }
float totalBodyYaw = _bodyYawDelta * deltaTime; float totalBodyYaw = _bodyYawDelta * deltaTime;
// Rotate directly proportional to delta yaw and delta pitch from right-click mouse movement.
bool computeCameraLookAt = qApp->getCamera().getMode() == CAMERA_MODE_LOOK_AT && isReadyForPhysics();
if (!computeCameraLookAt) { if (!computeCameraLookAt) {
totalBodyYaw += getDriveKey(DELTA_YAW) * _yawSpeed / YAW_SPEED_DEFAULT; totalBodyYaw += getDriveKey(DELTA_YAW) * _yawSpeed / YAW_SPEED_DEFAULT;
} }
// Comfort Mode: If you press any of the left/right rotation drive keys or input, you'll // Comfort Mode: If you press any of the left/right rotation drive keys or input, you'll
// get an instantaneous 15 degree turn. If you keep holding the key down you'll get another // get an instantaneous 15 degree turn. If you keep holding the key down you'll get another
// snap turn every half second. // snap turn every half second.
@ -3377,7 +3375,6 @@ void MyAvatar::updateOrientation(float deltaTime) {
totalBodyYaw += getDriveKey(STEP_YAW); totalBodyYaw += getDriveKey(STEP_YAW);
snapTurn = true; snapTurn = true;
} }
// Use head/HMD roll to turn while flying, but not when standing still. // Use head/HMD roll to turn while flying, but not when standing still.
if (qApp->isHMDMode() && getCharacterController()->getState() == CharacterController::State::Hover && _hmdRollControlEnabled && hasDriveInput()) { if (qApp->isHMDMode() && getCharacterController()->getState() == CharacterController::State::Hover && _hmdRollControlEnabled && hasDriveInput()) {
@ -3413,6 +3410,10 @@ void MyAvatar::updateOrientation(float deltaTime) {
// update body orientation by movement inputs // update body orientation by movement inputs
glm::quat initialOrientation = getOrientationOutbound(); glm::quat initialOrientation = getOrientationOutbound();
glm::vec3 eyesPosition = getDefaultEyePosition(); glm::vec3 eyesPosition = getDefaultEyePosition();
const float FPS = 60.0f;
float timeScale = deltaTime * FPS;
bool faceForward = false;
if (!computeCameraLookAt) { if (!computeCameraLookAt) {
setWorldOrientation(getWorldOrientation() * glm::quat(glm::radians(glm::vec3(0.0f, totalBodyYaw, 0.0f)))); setWorldOrientation(getWorldOrientation() * glm::quat(glm::radians(glm::vec3(0.0f, totalBodyYaw, 0.0f))));
_lookAtCameraTarget = eyesPosition + getWorldOrientation() * Vectors::FRONT; _lookAtCameraTarget = eyesPosition + getWorldOrientation() * Vectors::FRONT;
@ -3423,8 +3424,9 @@ void MyAvatar::updateOrientation(float deltaTime) {
if (totalBodyYaw != 0.0f) { if (totalBodyYaw != 0.0f) {
_lookAtOffsetYaw = _lookAtOffsetYaw * glm::quat(glm::radians(glm::vec3(0.0f, totalBodyYaw, 0.0f))); _lookAtOffsetYaw = _lookAtOffsetYaw * glm::quat(glm::radians(glm::vec3(0.0f, totalBodyYaw, 0.0f)));
} }
float deltalPitchSign = 1.0f;// qApp->getCamera().getMode() == CAMERA_MODE_SELFIE ? -1.0f : 1.0f;
float pitchIncrement = getDriveKey(PITCH) * _pitchSpeed * deltaTime float pitchIncrement = getDriveKey(PITCH) * _pitchSpeed * deltaTime
+ getDriveKey(DELTA_PITCH) * _pitchSpeed / PITCH_SPEED_DEFAULT; + deltalPitchSign * getDriveKey(DELTA_PITCH) * _pitchSpeed / PITCH_SPEED_DEFAULT;
if (pitchIncrement != 0.0f) { if (pitchIncrement != 0.0f) {
glm::quat _previousLookAtOffsetPitch = _lookAtOffsetPitch; glm::quat _previousLookAtOffsetPitch = _lookAtOffsetPitch;
_lookAtOffsetPitch = _lookAtOffsetPitch * glm::quat(glm::radians(glm::vec3(pitchIncrement, 0.0f, 0.0f))); _lookAtOffsetPitch = _lookAtOffsetPitch * glm::quat(glm::radians(glm::vec3(pitchIncrement, 0.0f, 0.0f)));
@ -3435,15 +3437,21 @@ void MyAvatar::updateOrientation(float deltaTime) {
_lookAtOffsetPitch = _previousLookAtOffsetPitch; _lookAtOffsetPitch = _previousLookAtOffsetPitch;
} }
} }
bool isMovingFwdBwd = getDriveKey(TRANSLATE_Z) != 0.0f;
bool isMovingSideways = getDriveKey(TRANSLATE_X) != 0.0f;
faceForward = computeCameraLookAt && (isMovingFwdBwd || isMovingSideways);
// Blend the avatar orientation with the camera look at if moving forward. // Blend the avatar orientation with the camera look at if moving forward.
if (faceForward || _shouldTurnToFaceCamera != 0) { if (faceForward || _shouldTurnToFaceCamera) {
const float FACE_FORWARD_BLEND = 0.25f; const float REORIENT_FORWARD_BLEND = 0.25f;
const float FACE_TURN_BLEND = 0.03f; const float REORIENT_TURN_BLEND = 0.03f;
const float DIAGONAL_TURN_BLEND = 0.02f; const float DIAGONAL_TURN_BLEND = 0.02f;
float blend = _shouldTurnToFaceCamera ? FACE_TURN_BLEND : FACE_FORWARD_BLEND; float blend = (_shouldTurnToFaceCamera ? REORIENT_TURN_BLEND : REORIENT_FORWARD_BLEND) * timeScale;
if (blend > 1.0f) {
blend = 1.0f;
}
glm::quat faceRotation = _lookAtOffsetYaw; glm::quat faceRotation = _lookAtOffsetYaw;
if (getDriveKey(TRANSLATE_Z) != 0.0f && getDriveKey(TRANSLATE_X) != 0.0f) { if (isMovingFwdBwd && isMovingSideways) {
// Reorient avatar to face camera diagonal
blend = DIAGONAL_TURN_BLEND; blend = DIAGONAL_TURN_BLEND;
if (getDriveKey(TRANSLATE_X) > 0.0f) { if (getDriveKey(TRANSLATE_X) > 0.0f) {
faceRotation = _lookAtOffsetYaw * glm::angleAxis(-0.25f * PI, Vectors::UP); faceRotation = _lookAtOffsetYaw * glm::angleAxis(-0.25f * PI, Vectors::UP);
@ -3451,7 +3459,7 @@ void MyAvatar::updateOrientation(float deltaTime) {
faceRotation = _lookAtOffsetYaw * glm::angleAxis(0.25f * PI, Vectors::UP); faceRotation = _lookAtOffsetYaw * glm::angleAxis(0.25f * PI, Vectors::UP);
} }
} }
setWorldOrientation(glm::slerp(getWorldOrientation(), faceRotation, blend * deltaTime * FPS)); setWorldOrientation(glm::slerp(getWorldOrientation(), faceRotation, blend));
} }
} }
@ -3527,11 +3535,14 @@ void MyAvatar::updateOrientation(float deltaTime) {
const float TARGET_DISTANCE_FROM_EYES = 20.0f; const float TARGET_DISTANCE_FROM_EYES = 20.0f;
glm::vec3 targetPoint = eyesPosition + TARGET_DISTANCE_FROM_EYES * glm::normalize(cameraVector); glm::vec3 targetPoint = eyesPosition + TARGET_DISTANCE_FROM_EYES * glm::normalize(cameraVector);
// const float LOOKAT_MIX_ALPHA = 0.05f; // const float LOOKAT_MIX_ALPHA = 0.25f;
if (getDriveKey(TRANSLATE_Y) == 0.0f) { if (getDriveKey(TRANSLATE_Y) == 0.0f) {
// Approximate the head's look at vector to the camera look at vector with some delay. // Approximate the head's look at vector to the camera look at vector with some delay.
float mixAlpha = (frontBackDot > 0.0f ? _backLookAtSpeed : _frontLookAtSpeed) * deltaTime * FPS; float mixAlpha = (frontBackDot > 0.0f ? _backLookAtSpeed : _frontLookAtSpeed) * timeScale;
if (mixAlpha > 1.0f) {
mixAlpha = 1.0f;
}
_lookAtCameraTarget = glm::mix(_lookAtCameraTarget, targetPoint, mixAlpha); _lookAtCameraTarget = glm::mix(_lookAtCameraTarget, targetPoint, mixAlpha);
} else { } else {
_lookAtCameraTarget = targetPoint; _lookAtCameraTarget = targetPoint;
@ -6459,6 +6470,7 @@ void MyAvatar::updateHeadLookAt(float deltaTime) {
glm::vec3 lookAtTarget = _scriptControlsHeadLookAt ? _lookAtScriptTarget : _lookAtCameraTarget; glm::vec3 lookAtTarget = _scriptControlsHeadLookAt ? _lookAtScriptTarget : _lookAtCameraTarget;
glm::vec3 avatarXVector = glm::normalize(getWorldOrientation() * Vectors::UNIT_X); glm::vec3 avatarXVector = glm::normalize(getWorldOrientation() * Vectors::UNIT_X);
glm::vec3 avatarYVector = glm::normalize(getWorldOrientation() * Vectors::UNIT_Y); glm::vec3 avatarYVector = glm::normalize(getWorldOrientation() * Vectors::UNIT_Y);
glm::vec3 avatarZVector = glm::normalize(getWorldOrientation() * Vectors::UNIT_Z);
glm::vec3 headToTargetVector = lookAtTarget - getDefaultEyePosition(); glm::vec3 headToTargetVector = lookAtTarget - getDefaultEyePosition();
if (glm::length(headToTargetVector) > EPSILON) { if (glm::length(headToTargetVector) > EPSILON) {
headToTargetVector = glm::normalize(headToTargetVector); headToTargetVector = glm::normalize(headToTargetVector);
@ -6469,6 +6481,11 @@ void MyAvatar::updateHeadLookAt(float deltaTime) {
float xDot = glm::dot(avatarXVector, headToTargetVector); float xDot = glm::dot(avatarXVector, headToTargetVector);
float yDot = glm::dot(avatarYVector, headToTargetVector); float yDot = glm::dot(avatarYVector, headToTargetVector);
float zDot = glm::dot(avatarZVector, headToTargetVector);
// Force the head to look at one of the sides when the look at point is behind the avatar
if (zDot > 0.0f && xDot != 0.0f) {
//xDot /= fabsf(xDot);
}
// Make sure dot products are in range to avoid acosf returning NaN // Make sure dot products are in range to avoid acosf returning NaN
xDot = glm::min(glm::max(xDot, -1.0f), 1.0f); xDot = glm::min(glm::max(xDot, -1.0f), 1.0f);
@ -6496,9 +6513,9 @@ void MyAvatar::updateHeadLookAt(float deltaTime) {
} }
} }
void MyAvatar::headLookAt(const glm::vec3& lookAtTarget) { void MyAvatar::setHeadLookAt(const glm::vec3& lookAtTarget) {
if (QThread::currentThread() != thread()) { if (QThread::currentThread() != thread()) {
BLOCKING_INVOKE_METHOD(this, "headLookAt", BLOCKING_INVOKE_METHOD(this, "setHeadLookAt",
Q_ARG(const glm::vec3&, lookAtTarget)); Q_ARG(const glm::vec3&, lookAtTarget));
return; return;
} }

View file

@ -1749,10 +1749,17 @@ public:
/**jsdoc /**jsdoc
* Turn the avatar's head until it faces the target point within the 90/-90 degrees range. * Turn the avatar's head until it faces the target point within the 90/-90 degrees range.
* @function MyAvatar.headLookAt * @function MyAvatar.setHeadLookAt
* @param {Vec3} lookAtTarget - The target 3D point. * @param {Vec3} lookAtTarget - The target 3D point.
*/ */
Q_INVOKABLE void headLookAt(const glm::vec3& lookAtTarget); Q_INVOKABLE void setHeadLookAt(const glm::vec3& lookAtTarget);
/**jsdoc
* Returns the current head look at target point in world coordenates.
* @function MyAvatar.getHeadLookAt
* @returns {Vec3} Default position between your avatar's eyes in world coordinates.
*/
Q_INVOKABLE glm::vec3 getHeadLookAt() { return _lookAtCameraTarget; }
glm::quat getLookAtOffset() { return _lookAtOffsetYaw * _lookAtOffsetPitch; } glm::quat getLookAtOffset() { return _lookAtOffsetYaw * _lookAtOffsetPitch; }

View file

@ -69,6 +69,8 @@ CameraMode stringToMode(const QString& mode) {
return CAMERA_MODE_ENTITY; return CAMERA_MODE_ENTITY;
} else if (mode == "look at") { } else if (mode == "look at") {
return CAMERA_MODE_LOOK_AT; return CAMERA_MODE_LOOK_AT;
} else if (mode == "selfie") {
return CAMERA_MODE_SELFIE;
} }
return CAMERA_MODE_NULL; return CAMERA_MODE_NULL;
} }
@ -86,6 +88,8 @@ QString modeToString(CameraMode mode) {
return "entity"; return "entity";
} else if (mode == CAMERA_MODE_LOOK_AT) { } else if (mode == CAMERA_MODE_LOOK_AT) {
return "look at"; return "look at";
} else if (mode == CAMERA_MODE_SELFIE) {
return "selfie";
} }
return "unknown"; return "unknown";
} }

View file

@ -24,6 +24,7 @@ enum CameraMode
CAMERA_MODE_INDEPENDENT, CAMERA_MODE_INDEPENDENT,
CAMERA_MODE_ENTITY, CAMERA_MODE_ENTITY,
CAMERA_MODE_LOOK_AT, CAMERA_MODE_LOOK_AT,
CAMERA_MODE_SELFIE,
NUM_CAMERA_MODES NUM_CAMERA_MODES
}; };