This commit is contained in:
Andrzej Kapolka 2014-02-07 11:26:55 -08:00
commit 3e2ba9fb7e
20 changed files with 529 additions and 148 deletions

135
examples/cameraExample.js Normal file
View file

@ -0,0 +1,135 @@
//
// cameraExample.js
// hifi
//
// Created by Brad Hefta-Gaub on 2/6/14.
// Copyright (c) 2014 HighFidelity, Inc. All rights reserved.
//
// This is an example script that demonstrates use of the Camera class
//
//
var damping = 0.9;
var yaw = 0.0;
var pitch = 0.0;
var roll = 0.0;
var thrust = { x: 0, y: 0, z: 0 };
var velocity = { x: 0, y: 0, z: 0 };
var position = { x: MyAvatar.position.x, y: MyAvatar.position.y + 1, z: MyAvatar.position.z };
var joysticksCaptured = false;
var THRUST_CONTROLLER = 0;
var VIEW_CONTROLLER = 1;
function checkCamera() {
if (Camera.getMode() == "independent") {
var deltaTime = 1/60; // approximately our FPS - maybe better to be elapsed time since last call
var THRUST_MAG_UP = 800.0;
var THRUST_MAG_DOWN = 300.0;
var THRUST_MAG_FWD = 500.0;
var THRUST_MAG_BACK = 300.0;
var THRUST_MAG_LATERAL = 250.0;
var THRUST_JUMP = 120.0;
var scale = 1.0;
var thrustMultiplier = 1.0; // maybe increase this as you hold it down?
var YAW_MAG = 500.0;
var PITCH_MAG = 100.0;
var THRUST_MAG_HAND_JETS = THRUST_MAG_FWD;
var JOYSTICK_YAW_MAG = YAW_MAG;
var JOYSTICK_PITCH_MAG = PITCH_MAG * 0.5;
var thrustJoystickPosition = Controller.getJoystickPosition(THRUST_CONTROLLER);
var currentOrientation = Camera.getOrientation();
var front = Quat.getFront(currentOrientation);
var right = Quat.getRight(currentOrientation);
var up = Quat.getUp(currentOrientation);
var thrustFront = Vec3.multiply(front, scale * THRUST_MAG_HAND_JETS * thrustJoystickPosition.y * thrustMultiplier * deltaTime);
var thrustRight = Vec3.multiply(right, scale * THRUST_MAG_HAND_JETS * thrustJoystickPosition.x * thrustMultiplier * deltaTime);
thrust = Vec3.sum(thrust, thrustFront);
thrust = Vec3.sum(thrust, thrustRight);
// add thrust to velocity
velocity = Vec3.sum(velocity, Vec3.multiply(thrust, deltaTime));
// add velocity to position
position = Vec3.sum(position, Vec3.multiply(velocity, deltaTime));
Camera.setPosition(position);
// reset thrust
thrust = { x: 0, y: 0, z: 0 };
// damp velocity
velocity = Vec3.multiply(velocity, damping);
// View Controller
var viewJoystickPosition = Controller.getJoystickPosition(VIEW_CONTROLLER);
yaw -= viewJoystickPosition.x * JOYSTICK_YAW_MAG * deltaTime;
pitch += viewJoystickPosition.y * JOYSTICK_PITCH_MAG * deltaTime;
var orientation = Quat.fromPitchYawRoll(pitch, yaw, roll);
Camera.setOrientation(orientation);
}
}
Script.willSendVisualDataCallback.connect(checkCamera);
function mouseMoveEvent(event) {
print("mouseMoveEvent event.x,y=" + event.x + ", " + event.y);
var pickRay = Camera.computePickRay(event.x, event.y);
print("called Camera.computePickRay()");
print("computePickRay origin=" + pickRay.origin.x + ", " + pickRay.origin.y + ", " + pickRay.origin.z);
print("computePickRay direction=" + pickRay.direction.x + ", " + pickRay.direction.y + ", " + pickRay.direction.z);
}
Controller.mouseMoveEvent.connect(mouseMoveEvent);
function keyPressEvent(event) {
if (joysticksCaptured) {
Controller.releaseJoystick(THRUST_CONTROLLER);
Controller.releaseJoystick(VIEW_CONTROLLER);
joysticksCaptured = false;
}
if (event.text == "1") {
Camera.setMode("first person");
}
if (event.text == "2") {
Camera.setMode("mirror");
}
if (event.text == "3") {
Camera.setMode("third person");
}
if (event.text == "4") {
Camera.setMode("independent");
joysticksCaptured = true;
Controller.captureJoystick(THRUST_CONTROLLER);
Controller.captureJoystick(VIEW_CONTROLLER);
position = { x: MyAvatar.position.x, y: MyAvatar.position.y + 1, z: MyAvatar.position.z };
}
}
// Map keyPress and mouse move events to our callbacks
Controller.keyPressEvent.connect(keyPressEvent);
Controller.captureKeyEvents({ text: "1" });
Controller.captureKeyEvents({ text: "2" });
Controller.captureKeyEvents({ text: "3" });
Controller.captureKeyEvents({ text: "4" });
function scriptEnding() {
// re-enabled the standard application for touch events
Controller.releaseKeyEvents({ text: "1" });
Controller.releaseKeyEvents({ text: "2" });
Controller.releaseKeyEvents({ text: "3" });
Controller.releaseKeyEvents({ text: "4" });
Controller.releaseJoystick(THRUST_CONTROLLER);
Controller.releaseJoystick(VIEW_CONTROLLER);
}
Script.scriptEnding.connect(scriptEnding);

View file

@ -434,9 +434,9 @@ void Application::paintGL() {
glEnable(GL_LINE_SMOOTH);
if (OculusManager::isConnected()) {
_myCamera.setUpShift (0.0f);
_myCamera.setDistance (0.0f);
_myCamera.setTightness (0.0f); // Camera is directly connected to head without smoothing
_myCamera.setUpShift(0.0f);
_myCamera.setDistance(0.0f);
_myCamera.setTightness(0.0f); // Camera is directly connected to head without smoothing
_myCamera.setTargetPosition(_myAvatar->getHead().calculateAverageEyePosition());
_myCamera.setTargetRotation(_myAvatar->getHead().getOrientation());
@ -446,7 +446,7 @@ void Application::paintGL() {
_myCamera.setTargetRotation(_myAvatar->getHead().getCameraOrientation());
} else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
_myCamera.setTightness (0.0f); // Camera is directly connected to head without smoothing
_myCamera.setTightness(0.0f); // Camera is directly connected to head without smoothing
_myCamera.setTargetPosition(_myAvatar->getUprightHeadPosition());
_myCamera.setTargetRotation(_myAvatar->getHead().getCameraOrientation());
@ -2227,28 +2227,30 @@ void Application::updateMetavoxels(float deltaTime) {
}
}
void Application::cameraMenuChanged() {
if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) {
if (_myCamera.getMode() != CAMERA_MODE_MIRROR) {
_myCamera.setMode(CAMERA_MODE_MIRROR);
_myCamera.setModeShiftRate(100.0f);
}
} else if (Menu::getInstance()->isOptionChecked(MenuOption::FirstPerson)) {
if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON) {
_myCamera.setMode(CAMERA_MODE_FIRST_PERSON);
_myCamera.setModeShiftRate(1.0f);
}
} else {
if (_myCamera.getMode() != CAMERA_MODE_THIRD_PERSON) {
_myCamera.setMode(CAMERA_MODE_THIRD_PERSON);
_myCamera.setModeShiftRate(1.0f);
}
}
}
void Application::updateCamera(float deltaTime) {
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
PerformanceWarning warn(showWarnings, "Application::updateCamera()");
if (!OculusManager::isConnected() && !TV3DManager::isConnected()) {
if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) {
if (_myCamera.getMode() != CAMERA_MODE_MIRROR) {
_myCamera.setMode(CAMERA_MODE_MIRROR);
_myCamera.setModeShiftRate(100.0f);
}
} else if (Menu::getInstance()->isOptionChecked(MenuOption::FirstPerson)) {
if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON) {
_myCamera.setMode(CAMERA_MODE_FIRST_PERSON);
_myCamera.setModeShiftRate(1.0f);
}
} else {
if (_myCamera.getMode() != CAMERA_MODE_THIRD_PERSON) {
_myCamera.setMode(CAMERA_MODE_THIRD_PERSON);
_myCamera.setModeShiftRate(1.0f);
}
}
if (Menu::getInstance()->isOptionChecked(MenuOption::OffAxisProjection)) {
float xSign = _myCamera.getMode() == CAMERA_MODE_MIRROR ? 1.0f : -1.0f;
if (_faceshift.isActive()) {
@ -4102,6 +4104,10 @@ void Application::loadScript(const QString& fileNameString) {
// hook our avatar object into this script engine
scriptEngine->setAvatarData( static_cast<Avatar*>(_myAvatar), "MyAvatar");
CameraScriptableObject* cameraScriptable = new CameraScriptableObject(&_myCamera, &_viewFrustum);
scriptEngine->registerGlobalObject("Camera", cameraScriptable);
connect(scriptEngine, SIGNAL(finished(const QString&)), cameraScriptable, SLOT(deleteLater()));
QThread* workerThread = new QThread(this);
// when the worker thread is started, call our engine's run..

View file

@ -170,6 +170,7 @@ public:
GeometryCache* getGeometryCache() { return &_geometryCache; }
TextureCache* getTextureCache() { return &_textureCache; }
GlowEffect* getGlowEffect() { return &_glowEffect; }
ControllerScriptingInterface* getControllerScriptingInterface() { return &_controllerScriptingInterface; }
AvatarManager& getAvatarManager() { return _avatarManager; }
Profile* getProfile() { return &_profile; }
@ -238,6 +239,7 @@ private slots:
void setFullscreen(bool fullscreen);
void setEnable3DTVMode(bool enable3DTVMode);
void cameraMenuChanged();
void renderThrustAtVoxel(const glm::vec3& thrust);

View file

@ -8,8 +8,11 @@
#include <SharedUtil.h>
#include <VoxelConstants.h>
#include <EventTypes.h>
#include "Application.h"
#include "Camera.h"
#include "Menu.h"
#include "Util.h"
const float CAMERA_MINIMUM_MODE_SHIFT_RATE = 0.5f;
@ -18,6 +21,10 @@ const float CAMERA_FIRST_PERSON_MODE_UP_SHIFT = 0.0f;
const float CAMERA_FIRST_PERSON_MODE_DISTANCE = 0.0f;
const float CAMERA_FIRST_PERSON_MODE_TIGHTNESS = 100.0f;
const float CAMERA_INDEPENDENT_MODE_UP_SHIFT = 0.0f;
const float CAMERA_INDEPENDENT_MODE_DISTANCE = 0.0f;
const float CAMERA_INDEPENDENT_MODE_TIGHTNESS = 100.0f;
const float CAMERA_THIRD_PERSON_MODE_UP_SHIFT = -0.2f;
const float CAMERA_THIRD_PERSON_MODE_DISTANCE = 1.5f;
const float CAMERA_THIRD_PERSON_MODE_TIGHTNESS = 8.0f;
@ -27,33 +34,32 @@ const float CAMERA_MIRROR_MODE_DISTANCE = 0.17f;
const float CAMERA_MIRROR_MODE_TIGHTNESS = 100.0f;
Camera::Camera() {
_needsToInitialize = true;
_frustumNeedsReshape = true;
_modeShift = 1.0f;
_modeShiftRate = 1.0f;
_linearModeShift = 0.0f;
_mode = CAMERA_MODE_THIRD_PERSON;
_prevMode = CAMERA_MODE_THIRD_PERSON;
_tightness = 10.0f; // default
_fieldOfView = DEFAULT_FIELD_OF_VIEW_DEGREES;
_aspectRatio = 16.f/9.f;
_nearClip = 0.08f; // default
_farClip = 50.0f * TREE_SCALE; // default
_upShift = 0.0f;
_distance = 0.0f;
_previousUpShift = 0.0f;
_previousDistance = 0.0f;
_previousTightness = 0.0f;
_newUpShift = 0.0f;
_newDistance = 0.0f;
_newTightness = 0.0f;
_targetPosition = glm::vec3(0.0f, 0.0f, 0.0f);
_position = glm::vec3(0.0f, 0.0f, 0.0f);
_idealPosition = glm::vec3(0.0f, 0.0f, 0.0f);
_scale = 1.0f;
Camera::Camera() :
_needsToInitialize(true),
_mode(CAMERA_MODE_THIRD_PERSON),
_prevMode(CAMERA_MODE_THIRD_PERSON),
_frustumNeedsReshape(true),
_position(0.0f, 0.0f, 0.0f),
_idealPosition(0.0f, 0.0f, 0.0f),
_targetPosition(0.0f, 0.0f, 0.0f),
_fieldOfView(DEFAULT_FIELD_OF_VIEW_DEGREES),
_aspectRatio(16.f/9.f),
_nearClip(0.08f), // default
_farClip(50.0f * TREE_SCALE), // default
_upShift(0.0f),
_distance(0.0f),
_tightness(10.0f), // default
_previousUpShift(0.0f),
_previousDistance(0.0f),
_previousTightness(0.0f),
_newUpShift(0.0f),
_newDistance(0.0f),
_newTightness(0.0f),
_modeShift(1.0f),
_linearModeShift(0.0f),
_modeShiftRate(1.0f),
_scale(1.0f)
{
}
void Camera::update(float deltaTime) {
@ -66,12 +72,9 @@ void Camera::update(float deltaTime) {
// use iterative forces to keep the camera at the desired position and angle
void Camera::updateFollowMode(float deltaTime) {
if (_linearModeShift < 1.0f) {
_linearModeShift += _modeShiftRate * deltaTime;
_modeShift = ONE_HALF - ONE_HALF * cosf(_linearModeShift * PIE );
_upShift = _previousUpShift * (1.0f - _modeShift) + _newUpShift * _modeShift;
_distance = _previousDistance * (1.0f - _modeShift) + _newDistance * _modeShift;
_tightness = _previousTightness * (1.0f - _modeShift) + _newTightness * _modeShift;
@ -98,7 +101,6 @@ void Camera::updateFollowMode(float deltaTime) {
_idealPosition = _targetPosition + _scale * (_rotation * glm::vec3(0.0f, _upShift, _distance));
_position = _idealPosition;
_needsToInitialize = false;
} else {
// pull rotation towards ideal
_rotation = safeMix(_rotation, _targetRotation, t);
@ -137,16 +139,19 @@ void Camera::setMode(CameraMode m) {
_newUpShift = CAMERA_THIRD_PERSON_MODE_UP_SHIFT;
_newDistance = CAMERA_THIRD_PERSON_MODE_DISTANCE;
_newTightness = CAMERA_THIRD_PERSON_MODE_TIGHTNESS;
} else if (_mode == CAMERA_MODE_FIRST_PERSON) {
_newUpShift = CAMERA_FIRST_PERSON_MODE_UP_SHIFT;
_newDistance = CAMERA_FIRST_PERSON_MODE_DISTANCE;
_newTightness = CAMERA_FIRST_PERSON_MODE_TIGHTNESS;
} else if (_mode == CAMERA_MODE_MIRROR) {
_newUpShift = CAMERA_MIRROR_MODE_UP_SHIFT;
_newDistance = CAMERA_MIRROR_MODE_DISTANCE;
_newTightness = CAMERA_MIRROR_MODE_TIGHTNESS;
} else if (_mode == CAMERA_MODE_INDEPENDENT) {
_newUpShift = CAMERA_INDEPENDENT_MODE_UP_SHIFT;
_newDistance = CAMERA_INDEPENDENT_MODE_DISTANCE;
_newTightness = CAMERA_INDEPENDENT_MODE_TIGHTNESS;
}
}
@ -165,22 +170,22 @@ void Camera::setAspectRatio(float a) {
_frustumNeedsReshape = true;
}
void Camera::setNearClip (float n) {
void Camera::setNearClip(float n) {
_nearClip = n;
_frustumNeedsReshape = true;
}
void Camera::setFarClip (float f) {
void Camera::setFarClip(float f) {
_farClip = f;
_frustumNeedsReshape = true;
}
void Camera::setEyeOffsetPosition (const glm::vec3& p) {
void Camera::setEyeOffsetPosition(const glm::vec3& p) {
_eyeOffsetPosition = p;
_frustumNeedsReshape = true;
}
void Camera::setEyeOffsetOrientation (const glm::quat& o) {
void Camera::setEyeOffsetOrientation(const glm::quat& o) {
_eyeOffsetOrientation = o;
_frustumNeedsReshape = true;
}
@ -218,4 +223,65 @@ void Camera::setFrustumWasReshaped() {
}
CameraScriptableObject::CameraScriptableObject(Camera* camera, ViewFrustum* viewFrustum) :
_camera(camera), _viewFrustum(viewFrustum)
{
}
PickRay CameraScriptableObject::computePickRay(float x, float y) {
float screenWidth = Application::getInstance()->getGLWidget()->width();
float screenHeight = Application::getInstance()->getGLWidget()->height();
PickRay result;
_viewFrustum->computePickRay(x / screenWidth, y / screenHeight, result.origin, result.direction);
return result;
}
QString CameraScriptableObject::getMode() const {
QString mode("unknown");
switch(_camera->getMode()) {
case CAMERA_MODE_THIRD_PERSON:
mode = "third person";
break;
case CAMERA_MODE_FIRST_PERSON:
mode = "first person";
break;
case CAMERA_MODE_MIRROR:
mode = "mirror";
break;
case CAMERA_MODE_INDEPENDENT:
mode = "independent";
break;
default:
break;
}
return mode;
}
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);
}
if (currentMode != targetMode) {
_camera->setMode(targetMode);
_camera->setModeShiftRate(10.0f);
}
}

View file

@ -10,8 +10,10 @@
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
#include <RegisteredMetaTypes.h>
#include <ViewFrustum.h>
const float DEFAULT_FIELD_OF_VIEW_DEGREES = 90.0f;
const float DEFAULT_FIELD_OF_VIEW_DEGREES = 90.0f;
enum CameraMode
{
@ -19,11 +21,12 @@ enum CameraMode
CAMERA_MODE_THIRD_PERSON,
CAMERA_MODE_FIRST_PERSON,
CAMERA_MODE_MIRROR,
CAMERA_MODE_INDEPENDENT,
NUM_CAMERA_MODES
};
class Camera
{
class Camera {
public:
Camera();
@ -31,73 +34,95 @@ public:
void update( float deltaTime );
void setUpShift ( float u ) { _upShift = u; }
void setDistance ( float d ) { _distance = d; }
void setTargetPosition( const glm::vec3& t ) { _targetPosition = t; }
void setPosition ( const glm::vec3& p ) { _position = p; }
void setTightness ( float t ) { _tightness = t; }
void setTargetRotation( const glm::quat& rotation );
void setUpShift(float u) { _upShift = u; }
void setDistance(float d) { _distance = d; }
void setPosition(const glm::vec3& p) { _position = p; }
void setTargetPosition(const glm::vec3& t) { _targetPosition = t; }
void setTightness(float t) { _tightness = t; }
void setTargetRotation(const glm::quat& rotation);
void setMode ( CameraMode m );
void setModeShiftRate ( float r );
void setFieldOfView ( float f );
void setAspectRatio ( float a );
void setNearClip ( float n );
void setFarClip ( float f );
void setEyeOffsetPosition ( const glm::vec3& p );
void setEyeOffsetOrientation( const glm::quat& o );
void setScale ( const float s );
void setMode(CameraMode m);
void setModeShiftRate(float r);
void setFieldOfView(float f);
void setAspectRatio(float a);
void setNearClip(float n);
void setFarClip(float f);
void setEyeOffsetPosition(const glm::vec3& p);
void setEyeOffsetOrientation(const glm::quat& o);
void setScale(const float s);
const glm::vec3& getTargetPosition () const { return _targetPosition; }
const glm::vec3& getPosition () const { return _position; }
const glm::quat& getTargetRotation () const { return _targetRotation; }
const glm::quat& getRotation () const { return _rotation; }
CameraMode getMode () const { return _mode; }
float getFieldOfView () const { return _fieldOfView; }
float getAspectRatio () const { return _aspectRatio; }
float getNearClip () const { return _scale * _nearClip; }
float getFarClip () const;
const glm::vec3& getEyeOffsetPosition () const { return _eyeOffsetPosition; }
const glm::quat& getEyeOffsetOrientation () const { return _eyeOffsetOrientation; }
float getScale () const { return _scale; }
const glm::vec3& getPosition() const { return _position; }
const glm::quat& getRotation() const { return _rotation; }
CameraMode getMode() const { return _mode; }
const glm::vec3& getTargetPosition() const { return _targetPosition; }
const glm::quat& getTargetRotation() const { return _targetRotation; }
float getFieldOfView() const { return _fieldOfView; }
float getAspectRatio() const { return _aspectRatio; }
float getNearClip() const { return _scale * _nearClip; }
float getFarClip() const;
const glm::vec3& getEyeOffsetPosition() const { return _eyeOffsetPosition; }
const glm::quat& getEyeOffsetOrientation() const { return _eyeOffsetOrientation; }
float getScale() const { return _scale; }
CameraMode getInterpolatedMode() const;
bool getFrustumNeedsReshape() const; // call to find out if the view frustum needs to be reshaped
void setFrustumWasReshaped(); // call this after reshaping the view frustum.
private:
bool _needsToInitialize;
CameraMode _mode;
CameraMode _prevMode;
bool _frustumNeedsReshape;
glm::vec3 _position;
glm::vec3 _idealPosition;
glm::vec3 _targetPosition;
float _fieldOfView;
float _aspectRatio;
float _nearClip;
float _farClip;
glm::vec3 _eyeOffsetPosition;
glm::quat _eyeOffsetOrientation;
glm::quat _rotation;
glm::quat _targetRotation;
float _upShift;
float _distance;
float _tightness;
float _previousUpShift;
float _previousDistance;
float _previousTightness;
float _newUpShift;
float _newDistance;
float _newTightness;
float _modeShift;
float _linearModeShift;
float _modeShiftRate;
float _scale;
void updateFollowMode( float deltaTime );
bool _needsToInitialize;
CameraMode _mode;
CameraMode _prevMode;
bool _frustumNeedsReshape;
glm::vec3 _position;
glm::vec3 _idealPosition;
glm::vec3 _targetPosition;
float _fieldOfView;
float _aspectRatio;
float _nearClip;
float _farClip;
glm::vec3 _eyeOffsetPosition;
glm::quat _eyeOffsetOrientation;
glm::quat _rotation;
glm::quat _targetRotation;
float _upShift;
float _distance;
float _tightness;
float _previousUpShift;
float _previousDistance;
float _previousTightness;
float _newUpShift;
float _newDistance;
float _newTightness;
float _modeShift;
float _linearModeShift;
float _modeShiftRate;
float _scale;
void updateFollowMode(float deltaTime);
};
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->setTargetPosition(value);}
glm::vec3 getPosition() const { return _camera->getPosition(); }
void setOrientation(const glm::quat& value) { _camera->setTargetRotation(value); }
glm::quat getOrientation() const { return _camera->getRotation(); }
PickRay computePickRay(float x, float y);
private:
Camera* _camera;
ViewFrustum* _viewFrustum;
};
#endif

View file

@ -219,3 +219,19 @@ void ControllerScriptingInterface::releaseKeyEvents(const KeyEvent& event) {
}
}
bool ControllerScriptingInterface::isJoystickCaptured(int joystickIndex) const {
return _capturedJoysticks.contains(joystickIndex);
}
void ControllerScriptingInterface::captureJoystick(int joystickIndex) {
if (!isJoystickCaptured(joystickIndex)) {
_capturedJoysticks.insert(joystickIndex);
}
}
void ControllerScriptingInterface::releaseJoystick(int joystickIndex) {
if (isJoystickCaptured(joystickIndex)) {
_capturedJoysticks.remove(joystickIndex);
}
}

View file

@ -38,7 +38,7 @@ public:
bool isMouseCaptured() const { return _mouseCaptured; }
bool isTouchCaptured() const { return _touchCaptured; }
bool isWheelCaptured() const { return _wheelCaptured; }
bool isJoystickCaptured(int joystickIndex) const;
public slots:
virtual bool isPrimaryButtonPressed() const;
@ -70,6 +70,9 @@ public slots:
virtual void captureWheelEvents() { _wheelCaptured = true; }
virtual void releaseWheelEvents() { _wheelCaptured = false; }
virtual void captureJoystick(int joystickIndex);
virtual void releaseJoystick(int joystickIndex);
private:
const PalmData* getPrimaryPalm() const;
const PalmData* getPalm(int palmIndex) const;
@ -80,6 +83,7 @@ private:
bool _touchCaptured;
bool _wheelCaptured;
QMultiMap<int,KeyEvent> _capturedKeys;
QSet<int> _capturedJoysticks;
};
const int NUMBER_OF_SPATIALCONTROLS_PER_PALM = 2; // the hand and the tip

View file

@ -232,9 +232,12 @@ Menu::Menu() :
false,
appInstance,
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);
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FullscreenMirror, Qt::Key_H);
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FullscreenMirror, Qt::Key_H,false,
appInstance,SLOT(cameraMenuChanged()));
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Enable3DTVMode, 0,
false,
appInstance,
@ -690,6 +693,9 @@ void Menu::removeAction(QMenu* menu, const QString& actionName) {
menu->removeAction(_actionHash.value(actionName));
}
void Menu::setIsOptionChecked(const QString& menuOption, bool isChecked) {
return _actionHash.value(menuOption)->setChecked(isChecked);
}
bool Menu::isOptionChecked(const QString& menuOption) {
return _actionHash.value(menuOption)->isChecked();

View file

@ -48,6 +48,7 @@ public:
~Menu();
bool isOptionChecked(const QString& menuOption);
void setIsOptionChecked(const QString& menuOption, bool isChecked);
void triggerOption(const QString& menuOption);
QAction* getActionForOption(const QString& menuOption);
bool isVoxelModeActionChecked();

View file

@ -792,23 +792,27 @@ void MyAvatar::updateThrust(float deltaTime) {
const int VIEW_CONTROLLER = 1;
for (size_t i = 0; i < getHand().getPalms().size(); ++i) {
PalmData& palm = getHand().getPalms()[i];
if (palm.isActive() && (palm.getSixenseID() == THRUST_CONTROLLER)) {
if (palm.getJoystickY() != 0.f) {
FingerData& finger = palm.getFingers()[0];
if (finger.isActive()) {
// If the script hasn't captured this joystick, then let the default behavior work
if (!Application::getInstance()->getControllerScriptingInterface()->isJoystickCaptured(palm.getSixenseID())) {
if (palm.isActive() && (palm.getSixenseID() == THRUST_CONTROLLER)) {
if (palm.getJoystickY() != 0.f) {
FingerData& finger = palm.getFingers()[0];
if (finger.isActive()) {
}
_thrust += front * _scale * THRUST_MAG_HAND_JETS * palm.getJoystickY() * _thrustMultiplier * deltaTime;
}
if (palm.getJoystickX() != 0.f) {
_thrust += right * _scale * THRUST_MAG_HAND_JETS * palm.getJoystickX() * _thrustMultiplier * deltaTime;
}
} else if (palm.isActive() && (palm.getSixenseID() == VIEW_CONTROLLER)) {
if (palm.getJoystickX() != 0.f) {
_bodyYawDelta -= palm.getJoystickX() * JOYSTICK_YAW_MAG * deltaTime;
}
if (palm.getJoystickY() != 0.f) {
getHand().setPitchUpdate(getHand().getPitchUpdate() +
(palm.getJoystickY() * JOYSTICK_PITCH_MAG * deltaTime));
}
_thrust += front * _scale * THRUST_MAG_HAND_JETS * palm.getJoystickY() * _thrustMultiplier * deltaTime;
}
if (palm.getJoystickX() != 0.f) {
_thrust += right * _scale * THRUST_MAG_HAND_JETS * palm.getJoystickX() * _thrustMultiplier * deltaTime;
}
} else if (palm.isActive() && (palm.getSixenseID() == VIEW_CONTROLLER)) {
if (palm.getJoystickX() != 0.f) {
_bodyYawDelta -= palm.getJoystickX() * JOYSTICK_YAW_MAG * deltaTime;
}
if (palm.getJoystickY() != 0.f) {
getHand().setPitchUpdate(getHand().getPitchUpdate() +
(palm.getJoystickY() * JOYSTICK_PITCH_MAG * deltaTime));
}
}

View file

@ -124,7 +124,7 @@ QScriptValue keyEventToScriptValue(QScriptEngine* engine, const KeyEvent& event)
return obj;
}
void keyEventFromScriptValue(const QScriptValue &object, KeyEvent& event) {
void keyEventFromScriptValue(const QScriptValue& object, KeyEvent& event) {
event.isValid = false; // assume the worst
event.isMeta = object.property("isMeta").toVariant().toBool();
@ -231,7 +231,7 @@ QScriptValue mouseEventToScriptValue(QScriptEngine* engine, const MouseEvent& ev
return obj;
}
void mouseEventFromScriptValue(const QScriptValue &object, MouseEvent& event) {
void mouseEventFromScriptValue(const QScriptValue& object, MouseEvent& event) {
// nothing for now...
}
@ -242,7 +242,7 @@ QScriptValue touchEventToScriptValue(QScriptEngine* engine, const TouchEvent& ev
return obj;
}
void touchEventFromScriptValue(const QScriptValue &object, TouchEvent& event) {
void touchEventFromScriptValue(const QScriptValue& object, TouchEvent& event) {
// nothing for now...
}
@ -253,6 +253,8 @@ QScriptValue wheelEventToScriptValue(QScriptEngine* engine, const WheelEvent& ev
return obj;
}
void wheelEventFromScriptValue(const QScriptValue &object, WheelEvent& event) {
void wheelEventFromScriptValue(const QScriptValue& object, WheelEvent& event) {
// nothing for now...
}

View file

@ -65,7 +65,6 @@ public:
int y;
};
Q_DECLARE_METATYPE(KeyEvent)
Q_DECLARE_METATYPE(MouseEvent)
Q_DECLARE_METATYPE(TouchEvent)
@ -74,15 +73,15 @@ Q_DECLARE_METATYPE(WheelEvent)
void registerEventTypes(QScriptEngine* engine);
QScriptValue keyEventToScriptValue(QScriptEngine* engine, const KeyEvent& event);
void keyEventFromScriptValue(const QScriptValue &object, KeyEvent& event);
void keyEventFromScriptValue(const QScriptValue& object, KeyEvent& event);
QScriptValue mouseEventToScriptValue(QScriptEngine* engine, const MouseEvent& event);
void mouseEventFromScriptValue(const QScriptValue &object, MouseEvent& event);
void mouseEventFromScriptValue(const QScriptValue& object, MouseEvent& event);
QScriptValue touchEventToScriptValue(QScriptEngine* engine, const TouchEvent& event);
void touchEventFromScriptValue(const QScriptValue &object, TouchEvent& event);
void touchEventFromScriptValue(const QScriptValue& object, TouchEvent& event);
QScriptValue wheelEventToScriptValue(QScriptEngine* engine, const WheelEvent& event);
void wheelEventFromScriptValue(const QScriptValue &object, WheelEvent& event);
void wheelEventFromScriptValue(const QScriptValue& object, WheelEvent& event);
#endif // __hifi_EventTypes_h__

View file

@ -9,6 +9,7 @@
//
//
#include <OctreeConstants.h>
#include "Quat.h"
glm::quat Quat::multiply(const glm::quat& q1, const glm::quat& q2) {
@ -18,3 +19,19 @@ glm::quat Quat::multiply(const glm::quat& q1, const glm::quat& q2) {
glm::quat Quat::fromVec3(const glm::vec3& vec3) {
return glm::quat(vec3);
}
glm::quat Quat::fromPitchYawRoll(float pitch, float yaw, float roll) {
return glm::quat(glm::radians(glm::vec3(pitch, yaw, roll)));
}
glm::vec3 Quat::getFront(const glm::quat& orientation) {
return orientation * IDENTITY_FRONT;
}
glm::vec3 Quat::getRight(const glm::quat& orientation) {
return orientation * IDENTITY_RIGHT;
}
glm::vec3 Quat::getUp(const glm::quat& orientation) {
return orientation * IDENTITY_UP;
}

View file

@ -22,6 +22,10 @@ class Quat : public QObject {
public slots:
glm::quat multiply(const glm::quat& q1, const glm::quat& q2);
glm::quat fromVec3(const glm::vec3& vec3);
glm::quat fromPitchYawRoll(float pitch, float yaw, float roll);
glm::vec3 getFront(const glm::quat& orientation);
glm::vec3 getRight(const glm::quat& orientation);
glm::vec3 getUp(const glm::quat& orientation);
};

View file

@ -140,6 +140,7 @@ void ScriptEngine::init() {
registerGlobalObject("Data", &_dataServerScriptingInterface);
registerGlobalObject("Particles", &_particlesScriptingInterface);
registerGlobalObject("Quat", &_quatLibrary);
registerGlobalObject("Vec3", &_vec3Library);
registerGlobalObject("Voxels", &_voxelsScriptingInterface);

View file

@ -26,6 +26,7 @@ class ParticlesScriptingInterface;
#include "AbstractControllerScriptingInterface.h"
#include "DataServerScriptingInterface.h"
#include "Quat.h"
#include "Vec3.h"
const QString NO_SCRIPT("");
@ -105,6 +106,7 @@ private:
AbstractMenuInterface* _menu;
static int _scriptNumber;
Quat _quatLibrary;
Vec3 _vec3Library;
};
#endif /* defined(__hifi__ScriptEngine__) */

View file

@ -0,0 +1,24 @@
//
// Vec3.cpp
// hifi
//
// Created by Brad Hefta-Gaub on 1/29/14
// Copyright (c) 2014 High Fidelity, Inc. All rights reserved.
//
// Scriptable Vec3 class library.
//
//
#include "Vec3.h"
glm::vec3 Vec3::multiply(const glm::vec3& v1, const glm::vec3& v2) {
return v1 * v2;
}
glm::vec3 Vec3::multiply(const glm::vec3& v1, float f) {
return v1 * f;
}
glm::vec3 Vec3::sum(const glm::vec3& v1, const glm::vec3& v2) {
return v1 + v2;
}

View file

@ -0,0 +1,31 @@
//
// Vec3.h
// hifi
//
// Created by Brad Hefta-Gaub on 1/29/14
// Copyright (c) 2014 High Fidelity, Inc. All rights reserved.
//
// Scriptable Vec3 class library.
//
//
#ifndef __hifi__Vec3__
#define __hifi__Vec3__
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
#include <QtCore/QObject>
/// Scriptable interface a Vec3ernion helper class object. Used exclusively in the JavaScript API
class Vec3 : public QObject {
Q_OBJECT
public slots:
glm::vec3 multiply(const glm::vec3& v1, const glm::vec3& v2);
glm::vec3 multiply(const glm::vec3& v1, float f);
glm::vec3 sum(const glm::vec3& v1, const glm::vec3& v2);
};
#endif /* defined(__hifi__Vec3__) */

View file

@ -15,6 +15,7 @@ void registerMetaTypes(QScriptEngine* engine) {
qScriptRegisterMetaType(engine, vec2toScriptValue, vec2FromScriptValue);
qScriptRegisterMetaType(engine, quatToScriptValue, quatFromScriptValue);
qScriptRegisterMetaType(engine, xColorToScriptValue, xColorFromScriptValue);
qScriptRegisterMetaType(engine, pickRayToScriptValue, pickRayFromScriptValue);
}
QScriptValue vec3toScriptValue(QScriptEngine* engine, const glm::vec3 &vec3) {
@ -73,3 +74,28 @@ void xColorFromScriptValue(const QScriptValue &object, xColor& color) {
color.blue = object.property("blue").toVariant().toInt();
}
QScriptValue pickRayToScriptValue(QScriptEngine* engine, const PickRay& pickRay) {
QScriptValue obj = engine->newObject();
QScriptValue origin = vec3toScriptValue(engine, pickRay.origin);
obj.setProperty("origin", origin);
QScriptValue direction = vec3toScriptValue(engine, pickRay.direction);
obj.setProperty("direction", direction);
return obj;
}
void pickRayFromScriptValue(const QScriptValue& object, PickRay& pickRay) {
QScriptValue originValue = object.property("origin");
if (originValue.isValid()) {
pickRay.origin.x = originValue.property("x").toVariant().toFloat();
pickRay.origin.y = originValue.property("y").toVariant().toFloat();
pickRay.origin.z = originValue.property("z").toVariant().toFloat();
}
QScriptValue directionValue = object.property("direction");
if (directionValue.isValid()) {
pickRay.direction.x = directionValue.property("x").toVariant().toFloat();
pickRay.direction.y = directionValue.property("y").toVariant().toFloat();
pickRay.direction.z = directionValue.property("z").toVariant().toFloat();
}
}

View file

@ -22,7 +22,6 @@ Q_DECLARE_METATYPE(glm::vec2)
Q_DECLARE_METATYPE(glm::quat)
Q_DECLARE_METATYPE(xColor)
void registerMetaTypes(QScriptEngine* engine);
QScriptValue vec3toScriptValue(QScriptEngine* engine, const glm::vec3 &vec3);
@ -37,4 +36,15 @@ void quatFromScriptValue(const QScriptValue &object, glm::quat& quat);
QScriptValue xColorToScriptValue(QScriptEngine* engine, const xColor& color);
void xColorFromScriptValue(const QScriptValue &object, xColor& color);
class PickRay {
public:
PickRay() : origin(0), direction(0) { };
glm::vec3 origin;
glm::vec3 direction;
};
Q_DECLARE_METATYPE(PickRay)
QScriptValue pickRayToScriptValue(QScriptEngine* engine, const PickRay& pickRay);
void pickRayFromScriptValue(const QScriptValue& object, PickRay& pickRay);
#endif