Fixes for camera mode transitions, seeing inside head.

This commit is contained in:
Andrzej Kapolka 2014-02-24 11:33:52 -08:00
parent 3d1c4251e3
commit d80b52dc9f
11 changed files with 44 additions and 41 deletions

View file

@ -1983,6 +1983,9 @@ void Application::updateMouseRay() {
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
PerformanceWarning warn(showWarnings, "Application::updateMouseRay()"); PerformanceWarning warn(showWarnings, "Application::updateMouseRay()");
// make sure the frustum is up-to-date
loadViewFrustum(_myCamera, _viewFrustum);
// if the mouse pointer isn't visible, act like it's at the center of the screen // if the mouse pointer isn't visible, act like it's at the center of the screen
float x = 0.5f, y = 0.5f; float x = 0.5f, y = 0.5f;
if (!_mouseHidden) { if (!_mouseHidden) {
@ -2030,11 +2033,12 @@ void Application::updateVisage() {
_visage.update(); _visage.update();
} }
void Application::updateMyAvatarLookAtPosition(glm::vec3& lookAtSpot) { void Application::updateMyAvatarLookAtPosition() {
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
PerformanceWarning warn(showWarnings, "Application::updateMyAvatarLookAtPosition()"); PerformanceWarning warn(showWarnings, "Application::updateMyAvatarLookAtPosition()");
glm::vec3 lookAtSpot;
if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
lookAtSpot = _myCamera.getPosition(); lookAtSpot = _myCamera.getPosition();
@ -2223,21 +2227,22 @@ void Application::updateMetavoxels(float deltaTime) {
} }
} }
void Application::cameraMenuChanged() { void Application::updateCameraMode() {
float modeShiftPeriod = (_myCamera.getMode() == CAMERA_MODE_MIRROR) ? 0.0f : 1.0f;
if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) { if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) {
if (_myCamera.getMode() != CAMERA_MODE_MIRROR) { if (_myCamera.getMode() != CAMERA_MODE_MIRROR) {
_myCamera.setMode(CAMERA_MODE_MIRROR); _myCamera.setMode(CAMERA_MODE_MIRROR);
_myCamera.setModeShiftPeriod(0.00f); _myCamera.setModeShiftPeriod(0.0f);
} }
} else if (Menu::getInstance()->isOptionChecked(MenuOption::FirstPerson)) { } else if (Menu::getInstance()->isOptionChecked(MenuOption::FirstPerson)) {
if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON) { if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON) {
_myCamera.setMode(CAMERA_MODE_FIRST_PERSON); _myCamera.setMode(CAMERA_MODE_FIRST_PERSON);
_myCamera.setModeShiftPeriod(1.0f); _myCamera.setModeShiftPeriod(modeShiftPeriod);
} }
} else { } else {
if (_myCamera.getMode() != CAMERA_MODE_THIRD_PERSON) { if (_myCamera.getMode() != CAMERA_MODE_THIRD_PERSON) {
_myCamera.setMode(CAMERA_MODE_THIRD_PERSON); _myCamera.setMode(CAMERA_MODE_THIRD_PERSON);
_myCamera.setModeShiftPeriod(1.0f); _myCamera.setModeShiftPeriod(modeShiftPeriod);
} }
} }
} }
@ -2312,16 +2317,16 @@ void Application::update(float deltaTime) {
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
PerformanceWarning warn(showWarnings, "Application::update()"); PerformanceWarning warn(showWarnings, "Application::update()");
// lots of things depend on the camera mode, so get that first
updateCameraMode();
// check what's under the mouse and update the mouse voxel // check what's under the mouse and update the mouse voxel
updateMouseRay(); updateMouseRay();
// Set where I am looking based on my mouse ray (so that other people can see)
glm::vec3 lookAtSpot;
updateFaceshift(); updateFaceshift();
updateVisage(); updateVisage();
_myAvatar->updateLookAtTargetAvatar(lookAtSpot); _myAvatar->updateLookAtTargetAvatar();
updateMyAvatarLookAtPosition(lookAtSpot); updateMyAvatarLookAtPosition();
// Find the voxel we are hovering over, and respond if clicked // Find the voxel we are hovering over, and respond if clicked
float distance; float distance;
@ -2898,8 +2903,8 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
} }
} }
bool renderMyHead = (whichCamera.getInterpolatedMode() != CAMERA_MODE_FIRST_PERSON); bool forceRenderMyHead = (whichCamera.getInterpolatedMode() == CAMERA_MODE_MIRROR);
_avatarManager.renderAvatars(renderMyHead, selfAvatarOnly); _avatarManager.renderAvatars(forceRenderMyHead, selfAvatarOnly);
if (!selfAvatarOnly) { if (!selfAvatarOnly) {
// Render the world box // Render the world box

View file

@ -269,7 +269,6 @@ private slots:
void setFullscreen(bool fullscreen); void setFullscreen(bool fullscreen);
void setEnable3DTVMode(bool enable3DTVMode); void setEnable3DTVMode(bool enable3DTVMode);
void cameraMenuChanged();
void renderThrustAtVoxel(const glm::vec3& thrust); void renderThrustAtVoxel(const glm::vec3& thrust);
@ -307,7 +306,7 @@ private:
void updateMouseRay(); void updateMouseRay();
void updateFaceshift(); void updateFaceshift();
void updateVisage(); void updateVisage();
void updateMyAvatarLookAtPosition(glm::vec3& lookAtSpot); void updateMyAvatarLookAtPosition();
void updateHoverVoxels(float deltaTime, float& distance, BoxFace& face); void updateHoverVoxels(float deltaTime, float& distance, BoxFace& face);
void updateMouseVoxels(float deltaTime, float& distance, BoxFace& face); void updateMouseVoxels(float deltaTime, float& distance, BoxFace& face);
void updateHandAndTouch(float deltaTime); void updateHandAndTouch(float deltaTime);
@ -316,6 +315,7 @@ private:
void updateSerialDevices(float deltaTime); void updateSerialDevices(float deltaTime);
void updateThreads(float deltaTime); void updateThreads(float deltaTime);
void updateMetavoxels(float deltaTime); void updateMetavoxels(float deltaTime);
void updateCameraMode();
void updateCamera(float deltaTime); void updateCamera(float deltaTime);
void updateDialogs(float deltaTime); void updateDialogs(float deltaTime);
void updateAudio(float deltaTime); void updateAudio(float deltaTime);

View file

@ -123,6 +123,11 @@ void Camera::setModeShiftPeriod (float period) {
const float MIN_PERIOD = 0.001f; const float MIN_PERIOD = 0.001f;
const float MAX_PERIOD = 3.0f; const float MAX_PERIOD = 3.0f;
_modeShiftPeriod = glm::clamp(period, MIN_PERIOD, MAX_PERIOD); _modeShiftPeriod = glm::clamp(period, MIN_PERIOD, MAX_PERIOD);
// if a zero period was requested, we clearly want to snap immediately to the target
if (period == 0.0f) {
update(MIN_PERIOD);
}
} }
void Camera::setMode(CameraMode m) { void Camera::setMode(CameraMode m) {

View file

@ -55,6 +55,7 @@ public:
const glm::vec3& getPosition() const { return _position; } const glm::vec3& getPosition() const { return _position; }
const glm::quat& getRotation() const { return _rotation; } const glm::quat& getRotation() const { return _rotation; }
CameraMode getMode() const { return _mode; } CameraMode getMode() const { return _mode; }
float getModeShiftPeriod() const { return _modeShiftPeriod; }
const glm::vec3& getTargetPosition() const { return _targetPosition; } const glm::vec3& getTargetPosition() const { return _targetPosition; }
const glm::quat& getTargetRotation() const { return _targetRotation; } const glm::quat& getTargetRotation() const { return _targetRotation; }
float getFieldOfView() const { return _fieldOfView; } float getFieldOfView() const { return _fieldOfView; }

View file

@ -232,11 +232,9 @@ Menu::Menu() :
false, false,
appInstance, appInstance,
SLOT(setFullscreen(bool))); SLOT(setFullscreen(bool)));
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FirstPerson, Qt::Key_P, true, addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FirstPerson, Qt::Key_P, true);
appInstance,SLOT(cameraMenuChanged()));
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Mirror, Qt::SHIFT | Qt::Key_H, true); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Mirror, Qt::SHIFT | Qt::Key_H, true);
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FullscreenMirror, Qt::Key_H, false, addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FullscreenMirror, Qt::Key_H, false);
appInstance, SLOT(cameraMenuChanged()));
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Enable3DTVMode, 0, addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Enable3DTVMode, 0,
false, false,

View file

@ -187,7 +187,7 @@ static TextRenderer* textRenderer(TextRendererType type) {
return displayNameRenderer; return displayNameRenderer;
} }
void Avatar::render(bool forceRenderHead) { void Avatar::render() {
glm::vec3 toTarget = _position - Application::getInstance()->getAvatar()->getPosition(); glm::vec3 toTarget = _position - Application::getInstance()->getAvatar()->getPosition();
float lengthToTarget = glm::length(toTarget); float lengthToTarget = glm::length(toTarget);
@ -205,7 +205,7 @@ void Avatar::render(bool forceRenderHead) {
getHead()->getFaceModel().renderCollisionProxies(0.7f); getHead()->getFaceModel().renderCollisionProxies(0.7f);
} }
if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) { if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) {
renderBody(forceRenderHead); renderBody();
} }
// render sphere when far away // render sphere when far away
@ -286,16 +286,14 @@ glm::quat Avatar::computeRotationFromBodyToWorldUp(float proportion) const {
return glm::angleAxis(angle * proportion, axis); return glm::angleAxis(angle * proportion, axis);
} }
void Avatar::renderBody(bool forceRenderHead) { void Avatar::renderBody() {
const float BILLBOARD_DISTANCE = 40.0f; const float BILLBOARD_DISTANCE = 40.0f;
if (!_billboard.isEmpty() && getLODDistance() >= BILLBOARD_DISTANCE) { if (!_billboard.isEmpty() && getLODDistance() >= BILLBOARD_DISTANCE) {
renderBillboard(); renderBillboard();
return; return;
} }
_skeletonModel.render(1.0f); _skeletonModel.render(1.0f);
if (forceRenderHead) { getHead()->render(1.0f);
getHead()->render(1.0f);
}
getHand()->render(false); getHand()->render(false);
} }

View file

@ -74,7 +74,7 @@ public:
void init(); void init();
void simulate(float deltaTime); void simulate(float deltaTime);
void render(bool forceRenderHead); void render();
//setters //setters
void setDisplayingLookatVectors(bool displayingLookatVectors) { getHead()->setRenderLookatVectors(displayingLookatVectors); } void setDisplayingLookatVectors(bool displayingLookatVectors) { getHead()->setRenderLookatVectors(displayingLookatVectors); }
@ -176,7 +176,7 @@ private:
bool _initialized; bool _initialized;
QScopedPointer<Texture> _billboardTexture; QScopedPointer<Texture> _billboardTexture;
void renderBody(bool forceRenderHead); void renderBody();
void renderBillboard(); void renderBillboard();
void renderDisplayName(); void renderDisplayName();

View file

@ -69,7 +69,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
simulateAvatarFades(deltaTime); simulateAvatarFades(deltaTime);
} }
void AvatarManager::renderAvatars(bool forceRenderHead, bool selfAvatarOnly) { void AvatarManager::renderAvatars(bool forceRenderMyHead, bool selfAvatarOnly) {
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
"Application::renderAvatars()"); "Application::renderAvatars()");
bool renderLookAtVectors = Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors); bool renderLookAtVectors = Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors);
@ -83,16 +83,16 @@ void AvatarManager::renderAvatars(bool forceRenderHead, bool selfAvatarOnly) {
avatar->init(); avatar->init();
} }
if (avatar == static_cast<Avatar*>(_myAvatar.data())) { if (avatar == static_cast<Avatar*>(_myAvatar.data())) {
avatar->render(forceRenderHead); _myAvatar->render(forceRenderMyHead);
} else { } else {
avatar->render(true); avatar->render();
} }
avatar->setDisplayingLookatVectors(renderLookAtVectors); avatar->setDisplayingLookatVectors(renderLookAtVectors);
} }
renderAvatarFades(); renderAvatarFades();
} else { } else {
// just render myAvatar // just render myAvatar
_myAvatar->render(forceRenderHead); _myAvatar->render(forceRenderMyHead);
_myAvatar->setDisplayingLookatVectors(renderLookAtVectors); _myAvatar->setDisplayingLookatVectors(renderLookAtVectors);
} }
} }
@ -121,7 +121,7 @@ void AvatarManager::renderAvatarFades() {
foreach(const AvatarSharedPointer& fadingAvatar, _avatarFades) { foreach(const AvatarSharedPointer& fadingAvatar, _avatarFades) {
Avatar* avatar = static_cast<Avatar*>(fadingAvatar.data()); Avatar* avatar = static_cast<Avatar*>(fadingAvatar.data());
avatar->render(false); avatar->render();
} }
} }

View file

@ -30,7 +30,7 @@ public:
MyAvatar* getMyAvatar() { return _myAvatar.data(); } MyAvatar* getMyAvatar() { return _myAvatar.data(); }
void updateOtherAvatars(float deltaTime); void updateOtherAvatars(float deltaTime);
void renderAvatars(bool forceRenderHead, bool selfAvatarOnly = false); void renderAvatars(bool forceRenderMyHead, bool selfAvatarOnly = false);
void clearOtherAvatars(); void clearOtherAvatars();

View file

@ -669,7 +669,7 @@ void MyAvatar::orbit(const glm::vec3& position, int deltaX, int deltaY) {
setPosition(position + rotation * (getPosition() - position)); setPosition(position + rotation * (getPosition() - position));
} }
void MyAvatar::updateLookAtTargetAvatar(glm::vec3 &eyePosition) { void MyAvatar::updateLookAtTargetAvatar() {
Application* applicationInstance = Application::getInstance(); Application* applicationInstance = Application::getInstance();
if (!applicationInstance->isMousePressed()) { if (!applicationInstance->isMousePressed()) {
@ -683,14 +683,9 @@ void MyAvatar::updateLookAtTargetAvatar(glm::vec3 &eyePosition) {
} }
float distance; float distance;
if (avatar->findRayIntersection(mouseOrigin, mouseDirection, distance)) { if (avatar->findRayIntersection(mouseOrigin, mouseDirection, distance)) {
// rescale to compensate for head embiggening
eyePosition = (avatar->getHead()->calculateAverageEyePosition() - avatar->getHead()->getScalePivot()) *
(avatar->getScale() / avatar->getHead()->getScale()) + avatar->getHead()->getScalePivot();
_lookAtTargetAvatar = avatarPointer; _lookAtTargetAvatar = avatarPointer;
return; return;
} else {
} }
} }
_lookAtTargetAvatar.clear(); _lookAtTargetAvatar.clear();
} }
@ -724,9 +719,10 @@ void MyAvatar::renderBody(bool forceRenderHead) {
_skeletonModel.render(1.0f); _skeletonModel.render(1.0f);
// Render head so long as the camera isn't inside it // Render head so long as the camera isn't inside it
const float RENDER_HEAD_CUTOFF_DISTANCE = 0.10f; const float RENDER_HEAD_CUTOFF_DISTANCE = 0.40f;
Camera* myCamera = Application::getInstance()->getCamera(); Camera* myCamera = Application::getInstance()->getCamera();
if (forceRenderHead || (glm::length(myCamera->getPosition() - getHead()->calculateAverageEyePosition()) > RENDER_HEAD_CUTOFF_DISTANCE)) { if (forceRenderHead || (glm::length(myCamera->getPosition() - getHead()->calculateAverageEyePosition()) >
RENDER_HEAD_CUTOFF_DISTANCE * _scale)) {
getHead()->render(1.0f); getHead()->render(1.0f);
} }
getHand()->render(true); getHand()->render(true);

View file

@ -81,7 +81,7 @@ public:
void orbit(const glm::vec3& position, int deltaX, int deltaY); void orbit(const glm::vec3& position, int deltaX, int deltaY);
AvatarData* getLookAtTargetAvatar() const { return _lookAtTargetAvatar.data(); } AvatarData* getLookAtTargetAvatar() const { return _lookAtTargetAvatar.data(); }
void updateLookAtTargetAvatar(glm::vec3& eyePosition); void updateLookAtTargetAvatar();
void clearLookAtTargetAvatar(); void clearLookAtTargetAvatar();
virtual void setFaceModelURL(const QUrl& faceModelURL); virtual void setFaceModelURL(const QUrl& faceModelURL);