Merge pull request #3734 from birarda/lobby

bubble up a PickRay with action event, camera cleanup
This commit is contained in:
Philip Rosedale 2014-11-04 12:03:29 -08:00
commit 6b8476a87f
19 changed files with 121 additions and 139 deletions

View file

@ -23,7 +23,7 @@ var THRUST_CONTROLLER = 0;
var VIEW_CONTROLLER = 1;
function checkCamera(deltaTime) {
if (Camera.getMode() == "independent") {
if (Camera.mode == "independent") {
var THRUST_MAG_UP = 800.0;
var THRUST_MAG_DOWN = 300.0;
var THRUST_MAG_FWD = 500.0;
@ -102,19 +102,19 @@ function keyPressEvent(event) {
}
if (event.text == "1") {
Camera.setMode("first person");
Camera.mode = "first person";
}
if (event.text == "2") {
Camera.setMode("mirror");
Camera.mode = "mirror";
}
if (event.text == "3") {
Camera.setMode("third person");
Camera.mode = "third person";
}
if (event.text == "4") {
Camera.setMode("independent");
Camera.mode = "independent";
joysticksCaptured = true;
Controller.captureJoystick(THRUST_CONTROLLER);
Controller.captureJoystick(VIEW_CONTROLLER);

View file

@ -20,15 +20,15 @@ var cameraLocations = [ {x: 7971.9, y: 241.3, z: 7304.1}, {x: 7973.0, y: 241.3,
var cameraLookAts = [ {x: 7971.1, y: 241.3, z: 7304.1}, {x: 7972.1, y: 241.3, z: 7304.1}, {x: 7972.1, y: 241.3, z: 7304.1}, {x: 7972.1, y: 241.3, z: 7304.1}, {x: 7972.1, y: 241.3, z: 7304.1}, {x: 7971.3, y: 241.3, z: 7304.2} ];
function saveCameraState() {
oldMode = Camera.getMode();
oldMode = Camera.mode;
avatarPosition = MyAvatar.position;
Camera.setModeShiftPeriod(0.0);
Camera.setMode("independent");
Camera.mode = "independent";
}
function restoreCameraState() {
Camera.stopLooking();
Camera.setMode(oldMode);
Camera.mode = oldMode;
}
function update(deltaTime) {
@ -52,7 +52,7 @@ function keyPressEvent(event) {
saveCameraState();
freeCamera = true;
}
Camera.setMode("independent");
Camera.mode = "independent";
Camera.setPosition(cameraLocations[choice - 1]);
Camera.keepLookingAt(cameraLookAts[choice - 1]);
}

View file

@ -20,15 +20,15 @@ var cameraLocations = [ {x: 8027.5, y: 237.5, z: 7305.7}, {x: 8027.5, y: 237.5,
var cameraLookAts = [ {x: 8027.5, y: 237.5, z: 7304.0}, {x: 8027.5, y: 237.5, z: 7305.7}, {x: 8027.5, y: 237.5, z: 7304.0}, {x: 8027.5, y: 237.5, z: 7304.0}, {x: 8027.5, y: 237.5, z: 7304.0}, {x: 8027.5, y: 237.5, z: 7304.0} ];
function saveCameraState() {
oldMode = Camera.getMode();
oldMode = Camera.mode;
avatarPosition = MyAvatar.position;
Camera.setModeShiftPeriod(0.0);
Camera.setMode("independent");
Camera.mode = "independent";
}
function restoreCameraState() {
Camera.stopLooking();
Camera.setMode(oldMode);
Camera.mode = oldMode;
}
function update(deltaTime) {
@ -52,7 +52,7 @@ function keyPressEvent(event) {
saveCameraState();
freeCamera = true;
}
Camera.setMode("independent");
Camera.mode = "independent";
Camera.setPosition(cameraLocations[choice - 1]);
Camera.keepLookingAt(cameraLookAts[choice - 1]);
}

View file

@ -20,15 +20,15 @@ var cameraLocations = [ {x: 2921.5, y: 251.3, z: 8254.8}, {x: 2921.5, y: 251.3,
var cameraLookAts = [ {x: 2921.5, y: 251.3, z: 8255.7}, {x: 2921.5, y: 251.3, z: 8255.7}, {x: 2921.5, y: 251.3, z: 8255.7}, {x: 2921.5, y: 251.3, z: 8255.7}, {x: 2921.4 , y: 251.3, z: 8255.1} ];
function saveCameraState() {
oldMode = Camera.getMode();
oldMode = Camera.mode;
avatarPosition = MyAvatar.position;
Camera.setModeShiftPeriod(0.0);
Camera.setMode("independent");
Camera.mode = "independent";
}
function restoreCameraState() {
Camera.stopLooking();
Camera.setMode(oldMode);
Camera.mode = oldMode;
}
function update(deltaTime) {
@ -52,7 +52,7 @@ function keyPressEvent(event) {
saveCameraState();
freeCamera = true;
}
Camera.setMode("independent");
Camera.mode = "independent";
Camera.setPosition(cameraLocations[choice - 1]);
Camera.keepLookingAt(cameraLookAts[choice - 1]);
}

View file

@ -53,12 +53,12 @@ var lastYawTurned = 0.0;
var startPullbackPosition;
function saveCameraState() {
oldMode = Camera.getMode();
Camera.setMode("independent");
oldMode = Camera.mode;
Camera.mode = "independent";
}
function restoreCameraState() {
Camera.setMode(oldMode);
Camera.mode = oldMode;
}
function activateWarp() {

View file

@ -118,14 +118,14 @@ function handlePanMode(dx, dy) {
}
function saveCameraState() {
oldMode = Camera.getMode();
oldMode = Camera.mode;
var oldPosition = Camera.getPosition();
Camera.setMode("independent");
Camera.mode = "independent";
Camera.setPosition(oldPosition);
}
function restoreCameraState() {
Camera.setMode(oldMode);
Camera.mode = oldMode;
}
function handleModes() {

View file

@ -88,8 +88,8 @@ CameraManager = function() {
that.focalPoint = focalPoint;
that.setFocalPoint(focalPoint);
that.previousCameraMode = Camera.getMode();
Camera.setMode("independent");
that.previousCameraMode = Camera.mode;
Camera.mode = "independent";
that.updateCamera();
@ -102,7 +102,7 @@ CameraManager = function() {
that.mode = MODE_INACTIVE;
if (!ignoreCamera) {
Camera.setMode(that.previousCameraMode);
Camera.mode = that.previousCameraMode;
}
cameraTool.setVisible(false);
}
@ -271,7 +271,7 @@ CameraManager = function() {
}
that.updateCamera = function() {
if (!that.enabled || Camera.getMode() != "independent") return;
if (!that.enabled || Camera.mode != "independent") return;
var yRot = Quat.angleAxis(that.yaw, { x: 0, y: 1, z: 0 });
var xRot = Quat.angleAxis(that.pitch, { x: 1, y: 0, z: 0 });
@ -300,7 +300,7 @@ CameraManager = function() {
// Ease the position and orbit of the camera
that.update = function(dt) {
if (Camera.getMode() != "independent") {
if (Camera.mode != "independent") {
return;
}
@ -349,7 +349,7 @@ CameraManager = function() {
Controller.keyReleaseEvent.connect(function (event) {
if (event.text == "ESC" && that.enabled) {
Camera.setMode(lastAvatarCameraMode);
Camera.mode = lastAvatarCameraMode;
cameraManager.disable(true);
}
});

View file

@ -40,20 +40,18 @@ var ORB_SHIFT = { x: 0, y: -1.4, z: -0.8};
var HELMET_ATTACHMENT_URL = "https://hifi-public.s3.amazonaws.com/models/attachments/IronManMaskOnly.fbx"
function reticlePosition() {
var screenSize = Controller.getViewportDimensions();
var reticleRay = Camera.computePickRay(screenSize.x / 2, screenSize.y / 2);
var RETICLE_DISTANCE = 1;
return Vec3.sum(reticleRay.origin, Vec3.multiply(reticleRay.direction, RETICLE_DISTANCE));
return Vec3.sum(Camera.position, Vec3.multiply(Quat.getFront(Camera.orientation), RETICLE_DISTANCE));
}
function drawLobby() {
if (!panelWall) {
print("Adding overlays for the lobby panel wall and orb shell.");
var cameraEuler = Quat.safeEulerAngles(Camera.getOrientation());
var cameraEuler = Quat.safeEulerAngles(Camera.orientation);
var towardsMe = Quat.angleAxis(cameraEuler.y + 180, { x: 0, y: 1, z: 0});
var orbPosition = Vec3.sum(Camera.getPosition(), Vec3.multiplyQbyV(towardsMe, ORB_SHIFT));
var orbPosition = Vec3.sum(Camera.position, Vec3.multiplyQbyV(towardsMe, ORB_SHIFT));
var panelWallProps = {
url: HIFI_PUBLIC_BUCKET + "models/sets/Lobby/LobbyPrototype/Lobby5_PanelsWithFrames.fbx",
@ -76,14 +74,15 @@ function drawLobby() {
orbShell = Overlays.addOverlay("model", orbShellProps);
// for HMD wearers, create a reticle in center of screen
var RETICLE_SPHERE_SIZE = 0.025;
var CURSOR_SCALE = 0.025;
reticle = Overlays.addOverlay("sphere", {
reticle = Overlays.addOverlay("billboard", {
url: HIFI_PUBLIC_BUCKET + "images/cursor.svg",
position: reticlePosition(),
size: RETICLE_SPHERE_SIZE,
color: { red: 0, green: 255, blue: 0 },
ignoreRayIntersection: true,
isFacingAvatar: true,
alpha: 1.0,
solid: true
scale: CURSOR_SCALE
});
// add an attachment on this avatar so other people see them in the lobby
@ -130,12 +129,13 @@ function cleanupLobby() {
function actionStartEvent(event) {
if (panelWall) {
// we've got an action event and our panel wall is up
// check if we hit a panel and if we should jump there
var pickRay = Camera.computePickRay(event.x, event.y);
var result = Overlays.findRayIntersection(pickRay);
var result = Overlays.findRayIntersection(event.actionRay);
if (result.intersects && result.overlayID == panelWall) {
var panelName = result.extraInfo;
var panelStringIndex = panelName.indexOf("Panel");
if (panelStringIndex != -1) {

View file

@ -17,13 +17,13 @@
//
var lookingAtSomething = false;
var oldMode = Camera.getMode();
var oldMode = Camera.mode;
function cancelLookAt() {
if (lookingAtSomething) {
lookingAtSomething = false;
Camera.stopLooking();
Camera.setMode(oldMode);
Camera.mode = oldMode;
releaseMovementKeys();
}
}
@ -65,13 +65,13 @@ function mousePressEvent(event) {
if (intersection.intersects) {
// remember the old mode we were in
oldMode = Camera.getMode();
oldMode = Camera.mode;
print("looking at intersection point: " + intersection.intersection.x + ", "
+ intersection.intersection.y + ", " + intersection.intersection.z);
// switch to independent mode
Camera.setMode("independent");
Camera.mode = "independent";
// tell the camera to fix it's look at on the point we clicked
Camera.keepLookingAt(intersection.intersection);

View file

@ -1116,7 +1116,8 @@ void Application::keyPressEvent(QKeyEvent* event) {
case Qt::Key_Space: {
if (!event->isAutoRepeat()) {
// this starts an HFActionEvent
HFActionEvent startActionEvent(HFActionEvent::startType(), getViewportCenter());
HFActionEvent startActionEvent(HFActionEvent::startType(),
_viewFrustum.computePickRay(0.5f, 0.5f));
sendEvent(this, &startActionEvent);
}
@ -1207,7 +1208,7 @@ void Application::keyReleaseEvent(QKeyEvent* event) {
case Qt::Key_Space: {
if (!event->isAutoRepeat()) {
// this ends the HFActionEvent
HFActionEvent endActionEvent(HFActionEvent::endType(), getViewportCenter());
HFActionEvent endActionEvent(HFActionEvent::endType(), _viewFrustum.computePickRay(0.5f, 0.5f));
sendEvent(this, &endActionEvent);
}
@ -1301,7 +1302,8 @@ void Application::mousePressEvent(QMouseEvent* event, unsigned int deviceID) {
}
// nobody handled this - make it an action event on the _window object
HFActionEvent actionEvent(HFActionEvent::startType(), event->localPos());
HFActionEvent actionEvent(HFActionEvent::startType(),
_myCamera.computePickRay(event->x(), event->y()));
sendEvent(this, &actionEvent);
} else if (event->button() == Qt::RightButton) {
@ -1335,7 +1337,8 @@ void Application::mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID) {
}
// fire an action end event
HFActionEvent actionEvent(HFActionEvent::endType(), event->localPos());
HFActionEvent actionEvent(HFActionEvent::endType(),
_myCamera.computePickRay(event->x(), event->y()));
sendEvent(this, &actionEvent);
}
}
@ -3846,9 +3849,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri
scriptEngine->setAvatarData(_myAvatar, "MyAvatar"); // leave it as a MyAvatar class to expose thrust features
scriptEngine->setAvatarHashMap(&_avatarManager, "AvatarList");
CameraScriptableObject* cameraScriptable = new CameraScriptableObject(&_myCamera, &_viewFrustum);
scriptEngine->registerGlobalObject("Camera", cameraScriptable);
connect(scriptEngine, SIGNAL(finished(const QString&)), cameraScriptable, SLOT(deleteLater()));
scriptEngine->registerGlobalObject("Camera", &_myCamera);
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
scriptEngine->registerGlobalObject("SpeechRecognizer", Menu::getInstance()->getSpeechRecognizer());

View file

@ -287,8 +287,6 @@ public:
PointShader& getPointShader() { return _pointShader; }
FileLogger* getLogger() { return _logger; }
QPointF getViewportCenter() const
{ return QPointF(_glWidget->getDeviceWidth() / 2.0f, _glWidget->getDeviceHeight() / 2.0f); }
glm::vec2 getViewportDimensions() const { return glm::vec2(_glWidget->getDeviceWidth(), _glWidget->getDeviceHeight()); }
NodeToJurisdictionMap& getVoxelServerJurisdictions() { return _voxelServerJurisdictions; }
NodeToJurisdictionMap& getEntityServerJurisdictions() { return _entityServerJurisdictions; }

View file

@ -72,9 +72,9 @@ float Camera::getFarClip() const {
: std::numeric_limits<int16_t>::max() - 1;
}
void Camera::setMode(CameraMode m) {
_mode = m;
emit modeUpdated(m);
void Camera::setMode(CameraMode mode) {
_mode = mode;
emit modeUpdated(modeToString(mode));
}
@ -94,57 +94,45 @@ void Camera::setFarClip(float f) {
_farClip = f;
}
CameraScriptableObject::CameraScriptableObject(Camera* camera, ViewFrustum* viewFrustum) :
_camera(camera), _viewFrustum(viewFrustum)
{
connect(_camera, &Camera::modeUpdated, this, &CameraScriptableObject::onModeUpdated);
}
PickRay CameraScriptableObject::computePickRay(float x, float y) {
PickRay Camera::computePickRay(float x, float y) {
float screenWidth = Application::getInstance()->getGLWidget()->width();
float screenHeight = Application::getInstance()->getGLWidget()->height();
PickRay result;
if (OculusManager::isConnected()) {
result.origin = _camera->getPosition();
result.origin = getPosition();
Application::getInstance()->getApplicationOverlay().computeOculusPickRay(x / screenWidth, y / screenHeight, result.direction);
} else {
_viewFrustum->computePickRay(x / screenWidth, y / screenHeight, result.origin, result.direction);
Application::getInstance()->getViewFrustum()->computePickRay(x / screenWidth, y / screenHeight,
result.origin, result.direction);
}
return result;
}
QString CameraScriptableObject::getMode() const {
return modeToString(_camera->getMode());
}
void CameraScriptableObject::setMode(const QString& mode) {
CameraMode currentMode = _camera->getMode();
CameraMode targetMode = currentMode;
if (mode == "third person") {
targetMode = CAMERA_MODE_THIRD_PERSON;
Menu::getInstance()->setIsOptionChecked(MenuOption::FullscreenMirror, false);
Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, false);
} else if (mode == "first person") {
targetMode = CAMERA_MODE_FIRST_PERSON;
Menu::getInstance()->setIsOptionChecked(MenuOption::FullscreenMirror, false);
Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, true);
} else if (mode == "mirror") {
targetMode = CAMERA_MODE_MIRROR;
Menu::getInstance()->setIsOptionChecked(MenuOption::FullscreenMirror, true);
Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, false);
} else if (mode == "independent") {
targetMode = CAMERA_MODE_INDEPENDENT;
Menu::getInstance()->setIsOptionChecked(MenuOption::FullscreenMirror, false);
Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, false);
void Camera::setModeString(const QString& mode) {
CameraMode targetMode = stringToMode(mode);
switch (targetMode) {
case CAMERA_MODE_THIRD_PERSON:
Menu::getInstance()->setIsOptionChecked(MenuOption::FullscreenMirror, false);
Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, false);
break;
case CAMERA_MODE_MIRROR:
Menu::getInstance()->setIsOptionChecked(MenuOption::FullscreenMirror, true);
Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, false);
break;
case CAMERA_MODE_INDEPENDENT:
Menu::getInstance()->setIsOptionChecked(MenuOption::FullscreenMirror, false);
Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, false);
break;
default:
break;
}
if (currentMode != targetMode) {
_camera->setMode(targetMode);
if (_mode != targetMode) {
setMode(targetMode);
}
}
void CameraScriptableObject::onModeUpdated(CameraMode m) {
emit modeUpdated(modeToString(m));
QString Camera::getModeString() const {
return modeToString(_mode);
}

View file

@ -32,6 +32,10 @@ static int cameraModeId = qRegisterMetaType<CameraMode>();
class Camera : public QObject {
Q_OBJECT
Q_PROPERTY(glm::vec3 position READ getPosition WRITE setPosition)
Q_PROPERTY(glm::quat orientation READ getOrientation WRITE setOrientation)
Q_PROPERTY(QString mode READ getModeString WRITE setModeString)
public:
Camera();
@ -39,7 +43,6 @@ public:
void update( float deltaTime );
void setPosition(const glm::vec3& p) { _position = p; }
void setRotation(const glm::quat& rotation) { _rotation = rotation; };
void setHmdPosition(const glm::vec3& hmdPosition) { _hmdPosition = hmdPosition; }
void setHmdRotation(const glm::quat& hmdRotation) { _hmdRotation = hmdRotation; };
@ -66,12 +69,20 @@ public:
const glm::vec3& getEyeOffsetPosition() const { return _eyeOffsetPosition; }
const glm::quat& getEyeOffsetOrientation() const { return _eyeOffsetOrientation; }
float getScale() const { return _scale; }
public slots:
QString getModeString() const;
void setModeString(const QString& mode);
signals:
void modeUpdated(CameraMode newMode);
void setPosition(const glm::vec3& position) { _position = position; }
private:
void setOrientation(const glm::quat& orientation) { setRotation(orientation); }
glm::quat getOrientation() const { return getRotation(); }
PickRay computePickRay(float x, float y);
signals:
void modeUpdated(const QString& newMode);
private:
CameraMode _mode;
glm::vec3 _position;
float _fieldOfView; // degrees
@ -88,32 +99,4 @@ private:
float _scale;
};
class CameraScriptableObject : public QObject {
Q_OBJECT
public:
CameraScriptableObject(Camera* camera, ViewFrustum* viewFrustum);
public slots:
QString getMode() const;
void setMode(const QString& mode);
void setPosition(const glm::vec3& value) { _camera->setPosition(value);}
glm::vec3 getPosition() const { return _camera->getPosition(); }
void setOrientation(const glm::quat& value) { _camera->setRotation(value); }
glm::quat getOrientation() const { return _camera->getRotation(); }
PickRay computePickRay(float x, float y);
signals:
void modeUpdated(const QString& newMode);
private slots:
void onModeUpdated(CameraMode m);
private:
Camera* _camera;
ViewFrustum* _viewFrustum;
};
#endif // hifi_Camera_h

View file

@ -129,9 +129,8 @@ void JoystickScriptingInterface::update() {
: HFActionEvent::endType();
// global action events fire in the center of the screen
QPointF centerPoint = Application::getInstance()->getViewportCenter();
HFActionEvent actionEvent(actionType, centerPoint);
HFActionEvent actionEvent(actionType,
Application::getInstance()->getViewFrustum()->computePickRay(0.5f, 0.5f));
qApp->sendEvent(qApp, &actionEvent);
}

View file

@ -583,6 +583,13 @@ bool ViewFrustum::isVerySimilar(const ViewFrustum& compareTo, bool debug) const
return result;
}
PickRay ViewFrustum::computePickRay(float x, float y) {
glm::vec3 pickRayOrigin;
glm::vec3 pickRayDirection;
computePickRay(x, y, pickRayOrigin, pickRayDirection);
return PickRay(pickRayOrigin, pickRayDirection);
}
void ViewFrustum::computePickRay(float x, float y, glm::vec3& origin, glm::vec3& direction) const {
origin = _nearTopLeft + x*(_nearTopRight - _nearTopLeft) + y*(_nearBottomLeft - _nearTopLeft);
direction = glm::normalize(origin - (_position + _orientation * _eyeOffsetPosition));

View file

@ -17,6 +17,8 @@
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
#include <RegisteredMetaTypes.h>
#include "AABox.h"
#include "AACube.h"
#include "Plane.h"
@ -105,6 +107,7 @@ public:
bool isVerySimilar(const ViewFrustum& compareTo, bool debug = false) const;
bool isVerySimilar(const ViewFrustum* compareTo, bool debug = false) const { return isVerySimilar(*compareTo, debug); }
PickRay computePickRay(float x, float y);
void computePickRay(float x, float y, glm::vec3& origin, glm::vec3& direction) const;
void computeOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& nearValue, float& farValue,

View file

@ -11,9 +11,9 @@
#include "HFActionEvent.h"
HFActionEvent::HFActionEvent(QEvent::Type type, const QPointF& localPosition) :
HFActionEvent::HFActionEvent(QEvent::Type type, const PickRay& actionRay) :
HFMetaEvent(type),
localPosition(localPosition)
actionRay(actionRay)
{
}
@ -30,8 +30,7 @@ QEvent::Type HFActionEvent::endType() {
QScriptValue HFActionEvent::toScriptValue(QScriptEngine* engine, const HFActionEvent& event) {
QScriptValue obj = engine->newObject();
obj.setProperty("x", event.localPosition.x());
obj.setProperty("y", event.localPosition.y());
obj.setProperty("actionRay", pickRayToScriptValue(engine, event.actionRay));
return obj;
}

View file

@ -12,14 +12,17 @@
#ifndef hifi_HFActionEvent_h
#define hifi_HFActionEvent_h
#include "HFMetaEvent.h"
#include <qscriptengine.h>
#include <RegisteredMetaTypes.h>
#include "HFMetaEvent.h"
class HFActionEvent : public HFMetaEvent {
public:
HFActionEvent() {};
HFActionEvent(QEvent::Type type, const QPointF& localPosition);
HFActionEvent(QEvent::Type type, const PickRay& actionRay);
static QEvent::Type startType();
static QEvent::Type endType();
@ -27,7 +30,7 @@ public:
static QScriptValue toScriptValue(QScriptEngine* engine, const HFActionEvent& event);
static void fromScriptValue(const QScriptValue& object, HFActionEvent& event);
QPointF localPosition;
PickRay actionRay;
};
Q_DECLARE_METATYPE(HFActionEvent)

View file

@ -53,7 +53,8 @@ void qURLFromScriptValue(const QScriptValue& object, QUrl& url);
class PickRay {
public:
PickRay() : origin(0.0f), direction(0.0f) { }
PickRay() : origin(0.0f), direction(0.0f) { }
PickRay(const glm::vec3& origin, const glm::vec3 direction) : origin(origin), direction(direction) {}
glm::vec3 origin;
glm::vec3 direction;
};