mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 05:17:24 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi
This commit is contained in:
commit
e5c0d712c4
13 changed files with 292 additions and 65 deletions
|
@ -21,9 +21,9 @@ var roll = 0.0;
|
||||||
var rotation = Quat.fromPitchYawRollDegrees(pitch, yaw, roll)
|
var rotation = Quat.fromPitchYawRollDegrees(pitch, yaw, roll)
|
||||||
|
|
||||||
var originalProperties = {
|
var originalProperties = {
|
||||||
position: { x: 10,
|
position: { x: MyAvatar.position.x,
|
||||||
y: 0,
|
y: MyAvatar.position.y,
|
||||||
z: 0 },
|
z: MyAvatar.position.z },
|
||||||
|
|
||||||
radius : 1,
|
radius : 1,
|
||||||
|
|
||||||
|
@ -56,11 +56,11 @@ function moveModel(deltaTime) {
|
||||||
|
|
||||||
if (count % adjustFPSEveryWhile == 0) {
|
if (count % adjustFPSEveryWhile == 0) {
|
||||||
if (animationFPS == 30) {
|
if (animationFPS == 30) {
|
||||||
animationFPS = 10;
|
|
||||||
} else if (animationFPS == 10) {
|
|
||||||
animationFPS = 60;
|
|
||||||
} else if (animationFPS == 60) {
|
|
||||||
animationFPS = 30;
|
animationFPS = 30;
|
||||||
|
} else if (animationFPS == 10) {
|
||||||
|
animationFPS = 10;
|
||||||
|
} else if (animationFPS == 60) {
|
||||||
|
animationFPS = 60;
|
||||||
}
|
}
|
||||||
print("animationFPS=" + animationFPS);
|
print("animationFPS=" + animationFPS);
|
||||||
isPlaying = true;
|
isPlaying = true;
|
||||||
|
|
|
@ -25,7 +25,7 @@ function printVector(string, vector) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var CHANCE_OF_MOVING = 0.005;
|
var CHANCE_OF_MOVING = 0.005;
|
||||||
var CHANCE_OF_SOUND = 0.000;
|
var CHANCE_OF_SOUND = 0.005;
|
||||||
var CHANCE_OF_HEAD_TURNING = 0.05;
|
var CHANCE_OF_HEAD_TURNING = 0.05;
|
||||||
var CHANCE_OF_BIG_MOVE = 0.1;
|
var CHANCE_OF_BIG_MOVE = 0.1;
|
||||||
var CHANCE_OF_WAVING = 0.009;
|
var CHANCE_OF_WAVING = 0.009;
|
||||||
|
@ -41,11 +41,11 @@ var isWaving = false;
|
||||||
var waveFrequency = 0.0;
|
var waveFrequency = 0.0;
|
||||||
var waveAmplitude = 0.0;
|
var waveAmplitude = 0.0;
|
||||||
|
|
||||||
var X_MIN = 20.0;
|
var X_MIN = 5.0;
|
||||||
var X_MAX = 25.0;
|
var X_MAX = 15.0;
|
||||||
var Z_MIN = 20.0;
|
var Z_MIN = 5.0;
|
||||||
var Z_MAX = 25.0;
|
var Z_MAX = 15.0;
|
||||||
var Y_PELVIS = 2.5;
|
var Y_PELVIS = 1.0;
|
||||||
var SPINE_JOINT_NUMBER = 13;
|
var SPINE_JOINT_NUMBER = 13;
|
||||||
var SHOULDER_JOINT_NUMBER = 17;
|
var SHOULDER_JOINT_NUMBER = 17;
|
||||||
var ELBOW_JOINT_NUMBER = 18;
|
var ELBOW_JOINT_NUMBER = 18;
|
||||||
|
|
|
@ -39,7 +39,7 @@ var impactSound = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-pub
|
||||||
var targetHitSound = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Space%20Invaders/hit.raw");
|
var targetHitSound = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Space%20Invaders/hit.raw");
|
||||||
var targetLaunchSound = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Space%20Invaders/shoot.raw");
|
var targetLaunchSound = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Space%20Invaders/shoot.raw");
|
||||||
|
|
||||||
var gunModel = "http://highfidelity-public.s3-us-west-1.amazonaws.com/models/attachments/Raygun2.fst";
|
var gunModel = "http://public.highfidelity.io/models/attachments/HaloGun.fst";
|
||||||
|
|
||||||
var audioOptions = new AudioInjectionOptions();
|
var audioOptions = new AudioInjectionOptions();
|
||||||
audioOptions.volume = 0.9;
|
audioOptions.volume = 0.9;
|
||||||
|
@ -199,7 +199,7 @@ function playLoadSound() {
|
||||||
Audio.playSound(loadSound, audioOptions);
|
Audio.playSound(loadSound, audioOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
MyAvatar.attach(gunModel, "RightHand", {x: -0.02, y: -.14, z: 0.07}, Quat.fromPitchYawRollDegrees(-70, -151, 72), 0.20);
|
//MyAvatar.attach(gunModel, "RightHand", {x: -0.02, y: -.14, z: 0.07}, Quat.fromPitchYawRollDegrees(-70, -151, 72), 0.20);
|
||||||
MyAvatar.attach(gunModel, "LeftHand", {x: -0.02, y: -.14, z: 0.07}, Quat.fromPitchYawRollDegrees(-70, -151, 72), 0.20);
|
MyAvatar.attach(gunModel, "LeftHand", {x: -0.02, y: -.14, z: 0.07}, Quat.fromPitchYawRollDegrees(-70, -151, 72), 0.20);
|
||||||
|
|
||||||
// Give a bit of time to load before playing sound
|
// Give a bit of time to load before playing sound
|
||||||
|
@ -320,7 +320,6 @@ function scriptEnding() {
|
||||||
Overlays.deleteOverlay(reticle);
|
Overlays.deleteOverlay(reticle);
|
||||||
Overlays.deleteOverlay(text);
|
Overlays.deleteOverlay(text);
|
||||||
MyAvatar.detachOne(gunModel);
|
MyAvatar.detachOne(gunModel);
|
||||||
MyAvatar.detachOne(gunModel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Particles.particleCollisionWithVoxel.connect(particleCollisionWithVoxel);
|
Particles.particleCollisionWithVoxel.connect(particleCollisionWithVoxel);
|
||||||
|
|
|
@ -50,6 +50,13 @@ var LEFT_BUTTON_4 = 4;
|
||||||
var RIGHT_PALM = 2;
|
var RIGHT_PALM = 2;
|
||||||
var RIGHT_BUTTON_4 = 10;
|
var RIGHT_BUTTON_4 = 10;
|
||||||
|
|
||||||
|
|
||||||
|
function printVector(text, v, decimals) {
|
||||||
|
print(text + " " + v.x.toFixed(decimals) + ", " + v.y.toFixed(decimals) + ", " + v.z.toFixed(decimals));
|
||||||
|
}
|
||||||
|
|
||||||
|
var debug = false;
|
||||||
|
|
||||||
// Used by handleGrabBehavior() for managing the grab position changes
|
// Used by handleGrabBehavior() for managing the grab position changes
|
||||||
function getAndResetGrabDelta() {
|
function getAndResetGrabDelta() {
|
||||||
var HAND_GRAB_SCALE_DISTANCE = 2.0;
|
var HAND_GRAB_SCALE_DISTANCE = 2.0;
|
||||||
|
@ -60,24 +67,12 @@ function getAndResetGrabDelta() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used by handleGrabBehavior() for managing the grab velocity feature
|
function getGrabRotation() {
|
||||||
function getAndResetGrabDeltaVelocity() {
|
|
||||||
var HAND_GRAB_SCALE_VELOCITY = 50.0;
|
|
||||||
var delta = Vec3.multiply(grabDeltaVelocity, (MyAvatar.scale * HAND_GRAB_SCALE_VELOCITY));
|
|
||||||
grabDeltaVelocity = { x: 0, y: 0, z: 0};
|
|
||||||
var avatarRotation = MyAvatar.orientation;
|
|
||||||
var result = Quat.multiply(avatarRotation, Vec3.multiply(delta, -1));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Used by handleGrabBehavior() for managing the grab rotation feature
|
|
||||||
function getAndResetGrabRotation() {
|
|
||||||
var quatDiff = Quat.multiply(grabCurrentRotation, Quat.inverse(grabStartRotation));
|
var quatDiff = Quat.multiply(grabCurrentRotation, Quat.inverse(grabStartRotation));
|
||||||
grabStartRotation = grabCurrentRotation;
|
|
||||||
return quatDiff;
|
return quatDiff;
|
||||||
}
|
}
|
||||||
|
|
||||||
// handles all the grab related behavior: position (crawl), velocity (flick), and rotate (twist)
|
// When move button is pressed, process results
|
||||||
function handleGrabBehavior(deltaTime) {
|
function handleGrabBehavior(deltaTime) {
|
||||||
// check for and handle grab behaviors
|
// check for and handle grab behaviors
|
||||||
grabbingWithRightHand = Controller.isButtonPressed(RIGHT_BUTTON_4);
|
grabbingWithRightHand = Controller.isButtonPressed(RIGHT_BUTTON_4);
|
||||||
|
@ -88,9 +83,11 @@ function handleGrabBehavior(deltaTime) {
|
||||||
if (grabbingWithRightHand && !wasGrabbingWithRightHand) {
|
if (grabbingWithRightHand && !wasGrabbingWithRightHand) {
|
||||||
// Just starting grab, capture starting rotation
|
// Just starting grab, capture starting rotation
|
||||||
grabStartRotation = Controller.getSpatialControlRawRotation(RIGHT_PALM);
|
grabStartRotation = Controller.getSpatialControlRawRotation(RIGHT_PALM);
|
||||||
|
grabStartPosition = Controller.getSpatialControlPosition(RIGHT_PALM);
|
||||||
|
if (debug) printVector("start position", grabStartPosition, 3);
|
||||||
}
|
}
|
||||||
if (grabbingWithRightHand) {
|
if (grabbingWithRightHand) {
|
||||||
grabDelta = Vec3.sum(grabDelta, Vec3.multiply(Controller.getSpatialControlVelocity(RIGHT_PALM), deltaTime));
|
grabDelta = Vec3.subtract(Controller.getSpatialControlPosition(RIGHT_PALM), grabStartPosition);
|
||||||
grabCurrentRotation = Controller.getSpatialControlRawRotation(RIGHT_PALM);
|
grabCurrentRotation = Controller.getSpatialControlRawRotation(RIGHT_PALM);
|
||||||
}
|
}
|
||||||
if (!grabbingWithRightHand && wasGrabbingWithRightHand) {
|
if (!grabbingWithRightHand && wasGrabbingWithRightHand) {
|
||||||
|
@ -102,10 +99,12 @@ function handleGrabBehavior(deltaTime) {
|
||||||
if (grabbingWithLeftHand && !wasGrabbingWithLeftHand) {
|
if (grabbingWithLeftHand && !wasGrabbingWithLeftHand) {
|
||||||
// Just starting grab, capture starting rotation
|
// Just starting grab, capture starting rotation
|
||||||
grabStartRotation = Controller.getSpatialControlRawRotation(LEFT_PALM);
|
grabStartRotation = Controller.getSpatialControlRawRotation(LEFT_PALM);
|
||||||
|
grabStartPosition = Controller.getSpatialControlPosition(LEFT_PALM);
|
||||||
|
if (debug) printVector("start position", grabStartPosition, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (grabbingWithLeftHand) {
|
if (grabbingWithLeftHand) {
|
||||||
grabDelta = Vec3.sum(grabDelta, Vec3.multiply(Controller.getSpatialControlVelocity(LEFT_PALM), deltaTime));
|
grabDelta = Vec3.subtract(Controller.getSpatialControlPosition(LEFT_PALM), grabStartPosition);
|
||||||
grabCurrentRotation = Controller.getSpatialControlRawRotation(LEFT_PALM);
|
grabCurrentRotation = Controller.getSpatialControlRawRotation(LEFT_PALM);
|
||||||
}
|
}
|
||||||
if (!grabbingWithLeftHand && wasGrabbingWithLeftHand) {
|
if (!grabbingWithLeftHand && wasGrabbingWithLeftHand) {
|
||||||
|
@ -119,44 +118,57 @@ function handleGrabBehavior(deltaTime) {
|
||||||
|
|
||||||
if (grabbing) {
|
if (grabbing) {
|
||||||
|
|
||||||
// move position
|
var headOrientation = MyAvatar.headOrientation;
|
||||||
var moveFromGrab = getAndResetGrabDelta();
|
var front = Quat.getFront(headOrientation);
|
||||||
if (Vec3.length(moveFromGrab) > EPSILON) {
|
var right = Quat.getRight(headOrientation);
|
||||||
MyAvatar.position = Vec3.sum(MyAvatar.position, moveFromGrab);
|
var up = Quat.getUp(headOrientation);
|
||||||
velocity = { x: 0, y: 0, z: 0};
|
|
||||||
}
|
|
||||||
|
|
||||||
// add some rotation...
|
|
||||||
var deltaRotation = getAndResetGrabRotation();
|
|
||||||
var GRAB_CONTROLLER_TURN_SCALING = 0.5;
|
|
||||||
var euler = Vec3.multiply(Quat.safeEulerAngles(deltaRotation), GRAB_CONTROLLER_TURN_SCALING);
|
|
||||||
|
|
||||||
// Adjust body yaw by yaw from controller
|
grabDelta = Vec3.multiplyQbyV(MyAvatar.orientation, Vec3.multiply(grabDelta, -1));
|
||||||
var orientation = Quat.multiply(Quat.angleAxis(-euler.y, {x:0, y: 1, z:0}), MyAvatar.orientation);
|
|
||||||
|
if (debug) {
|
||||||
|
printVector("grabDelta: ", grabDelta, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
var THRUST_GRAB_SCALING = 0.0;
|
||||||
|
|
||||||
|
var thrustFront = Vec3.multiply(front, MyAvatar.scale * grabDelta.z * THRUST_GRAB_SCALING * deltaTime);
|
||||||
|
MyAvatar.addThrust(thrustFront);
|
||||||
|
var thrustRight = Vec3.multiply(right, MyAvatar.scale * grabDelta.x * THRUST_GRAB_SCALING * deltaTime);
|
||||||
|
MyAvatar.addThrust(thrustRight);
|
||||||
|
var thrustUp = Vec3.multiply(up, MyAvatar.scale * grabDelta.y * THRUST_GRAB_SCALING * deltaTime);
|
||||||
|
MyAvatar.addThrust(thrustUp);
|
||||||
|
|
||||||
|
|
||||||
|
// add some rotation...
|
||||||
|
var deltaRotation = getGrabRotation();
|
||||||
|
var PITCH_SCALING = 2.0;
|
||||||
|
var PITCH_DEAD_ZONE = 2.0;
|
||||||
|
var YAW_SCALING = 2.0;
|
||||||
|
var ROLL_SCALING = 2.0;
|
||||||
|
|
||||||
|
var euler = Quat.safeEulerAngles(deltaRotation);
|
||||||
|
|
||||||
|
// Adjust body yaw by roll from controller
|
||||||
|
var orientation = Quat.multiply(Quat.angleAxis(((euler.y * YAW_SCALING) +
|
||||||
|
(euler.z * ROLL_SCALING)) * deltaTime, {x:0, y: 1, z:0}), MyAvatar.orientation);
|
||||||
MyAvatar.orientation = orientation;
|
MyAvatar.orientation = orientation;
|
||||||
|
|
||||||
// Adjust head pitch from controller
|
// Adjust head pitch from controller
|
||||||
MyAvatar.headPitch = MyAvatar.headPitch - euler.x;
|
var pitch = 0.0;
|
||||||
|
if (Math.abs(euler.x) > PITCH_DEAD_ZONE) {
|
||||||
|
pitch = (euler.x < 0.0) ? (euler.x + PITCH_DEAD_ZONE) : (euler.x - PITCH_DEAD_ZONE);
|
||||||
|
}
|
||||||
|
MyAvatar.headPitch = MyAvatar.headPitch + (pitch * PITCH_SCALING * deltaTime);
|
||||||
|
|
||||||
|
// TODO: Add some camera roll proportional to the rate of turn (so it feels like an airplane or roller coaster)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// add some velocity...
|
|
||||||
if (stoppedGrabbing) {
|
|
||||||
velocity = Vec3.sum(velocity, getAndResetGrabDeltaVelocity());
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle residual velocity
|
|
||||||
if(Vec3.length(velocity) > EPSILON) {
|
|
||||||
MyAvatar.position = Vec3.sum(MyAvatar.position, Vec3.multiply(velocity, deltaTime));
|
|
||||||
// damp velocity
|
|
||||||
velocity = Vec3.multiply(velocity, damping);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
wasGrabbingWithRightHand = grabbingWithRightHand;
|
wasGrabbingWithRightHand = grabbingWithRightHand;
|
||||||
wasGrabbingWithLeftHand = grabbingWithLeftHand;
|
wasGrabbingWithLeftHand = grabbingWithLeftHand;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main update function that handles flying and grabbing behaviort
|
// Update for joysticks and move button
|
||||||
function flyWithHydra(deltaTime) {
|
function flyWithHydra(deltaTime) {
|
||||||
var thrustJoystickPosition = Controller.getJoystickPosition(THRUST_CONTROLLER);
|
var thrustJoystickPosition = Controller.getJoystickPosition(THRUST_CONTROLLER);
|
||||||
|
|
||||||
|
|
|
@ -136,6 +136,7 @@ find_package(Faceplus)
|
||||||
find_package(Faceshift)
|
find_package(Faceshift)
|
||||||
find_package(LibOVR)
|
find_package(LibOVR)
|
||||||
find_package(PrioVR)
|
find_package(PrioVR)
|
||||||
|
find_package(SDL)
|
||||||
find_package(Sixense)
|
find_package(Sixense)
|
||||||
find_package(Visage)
|
find_package(Visage)
|
||||||
find_package(ZLIB)
|
find_package(ZLIB)
|
||||||
|
@ -193,6 +194,13 @@ if (PRIOVR_FOUND AND NOT DISABLE_PRIOVR)
|
||||||
target_link_libraries(${TARGET_NAME} "${PRIOVR_LIBRARIES}")
|
target_link_libraries(${TARGET_NAME} "${PRIOVR_LIBRARIES}")
|
||||||
endif (PRIOVR_FOUND AND NOT DISABLE_PRIOVR)
|
endif (PRIOVR_FOUND AND NOT DISABLE_PRIOVR)
|
||||||
|
|
||||||
|
# and with SDL for joysticks
|
||||||
|
if (SDL_FOUND AND NOT DISABLE_SDL)
|
||||||
|
add_definitions(-DHAVE_SDL)
|
||||||
|
include_directories(SYSTEM "${SDL_INCLUDE_DIR}")
|
||||||
|
target_link_libraries(${TARGET_NAME} "${SDL_LIBRARY}")
|
||||||
|
endif (SDL_FOUND AND NOT DISABLE_SDL)
|
||||||
|
|
||||||
# and with qxmpp for chat
|
# and with qxmpp for chat
|
||||||
if (QXMPP_FOUND AND NOT DISABLE_QXMPP)
|
if (QXMPP_FOUND AND NOT DISABLE_QXMPP)
|
||||||
add_definitions(-DHAVE_QXMPP -DQXMPP_STATIC)
|
add_definitions(-DHAVE_QXMPP -DQXMPP_STATIC)
|
||||||
|
|
|
@ -1990,7 +1990,8 @@ void Application::update(float deltaTime) {
|
||||||
_myAvatar->updateLookAtTargetAvatar();
|
_myAvatar->updateLookAtTargetAvatar();
|
||||||
updateMyAvatarLookAtPosition();
|
updateMyAvatarLookAtPosition();
|
||||||
_sixenseManager.update(deltaTime);
|
_sixenseManager.update(deltaTime);
|
||||||
_prioVR.update();
|
_joystickManager.update();
|
||||||
|
_prioVR.update(deltaTime);
|
||||||
updateMyAvatar(deltaTime); // Sample hardware, update view frustum if needed, and send avatar data to mixer/nodes
|
updateMyAvatar(deltaTime); // Sample hardware, update view frustum if needed, and send avatar data to mixer/nodes
|
||||||
updateThreads(deltaTime); // If running non-threaded, then give the threads some time to process...
|
updateThreads(deltaTime); // If running non-threaded, then give the threads some time to process...
|
||||||
_avatarManager.updateOtherAvatars(deltaTime); //loop through all the other avatars and simulate them...
|
_avatarManager.updateOtherAvatars(deltaTime); //loop through all the other avatars and simulate them...
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
#include "avatar/MyAvatar.h"
|
#include "avatar/MyAvatar.h"
|
||||||
#include "devices/Faceplus.h"
|
#include "devices/Faceplus.h"
|
||||||
#include "devices/Faceshift.h"
|
#include "devices/Faceshift.h"
|
||||||
|
#include "devices/JoystickManager.h"
|
||||||
#include "devices/PrioVR.h"
|
#include "devices/PrioVR.h"
|
||||||
#include "devices/SixenseManager.h"
|
#include "devices/SixenseManager.h"
|
||||||
#include "devices/Visage.h"
|
#include "devices/Visage.h"
|
||||||
|
@ -196,6 +197,7 @@ public:
|
||||||
FaceTracker* getActiveFaceTracker();
|
FaceTracker* getActiveFaceTracker();
|
||||||
SixenseManager* getSixenseManager() { return &_sixenseManager; }
|
SixenseManager* getSixenseManager() { return &_sixenseManager; }
|
||||||
PrioVR* getPrioVR() { return &_prioVR; }
|
PrioVR* getPrioVR() { return &_prioVR; }
|
||||||
|
JoystickManager* getJoystickManager() { return &_joystickManager; }
|
||||||
BandwidthMeter* getBandwidthMeter() { return &_bandwidthMeter; }
|
BandwidthMeter* getBandwidthMeter() { return &_bandwidthMeter; }
|
||||||
QUndoStack* getUndoStack() { return &_undoStack; }
|
QUndoStack* getUndoStack() { return &_undoStack; }
|
||||||
|
|
||||||
|
@ -449,6 +451,7 @@ private:
|
||||||
|
|
||||||
SixenseManager _sixenseManager;
|
SixenseManager _sixenseManager;
|
||||||
PrioVR _prioVR;
|
PrioVR _prioVR;
|
||||||
|
JoystickManager _joystickManager;
|
||||||
|
|
||||||
Camera _myCamera; // My view onto the world
|
Camera _myCamera; // My view onto the world
|
||||||
Camera _viewFrustumOffsetCamera; // The camera we use to sometimes show the view frustum from an offset mode
|
Camera _viewFrustumOffsetCamera; // The camera we use to sometimes show the view frustum from an offset mode
|
||||||
|
|
64
interface/src/devices/JoystickManager.cpp
Normal file
64
interface/src/devices/JoystickManager.cpp
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
//
|
||||||
|
// JoystickManager.cpp
|
||||||
|
// interface/src/devices
|
||||||
|
//
|
||||||
|
// Created by Andrzej Kapolka on 5/15/14.
|
||||||
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
#include <QtDebug>
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
#include "JoystickManager.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
JoystickManager::JoystickManager() {
|
||||||
|
#ifdef HAVE_SDL
|
||||||
|
SDL_Init(SDL_INIT_JOYSTICK);
|
||||||
|
int joystickCount = SDL_NumJoysticks();
|
||||||
|
for (int i = 0; i < joystickCount; i++) {
|
||||||
|
SDL_Joystick* joystick = SDL_JoystickOpen(i);
|
||||||
|
if (joystick) {
|
||||||
|
JoystickState state = { SDL_JoystickName(i), QVector<float>(SDL_JoystickNumAxes(joystick)),
|
||||||
|
QVector<bool>(SDL_JoystickNumButtons(joystick)) };
|
||||||
|
_joystickStates.append(state);
|
||||||
|
_joysticks.append(joystick);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
JoystickManager::~JoystickManager() {
|
||||||
|
#ifdef HAVE_SDL
|
||||||
|
foreach (SDL_Joystick* joystick, _joysticks) {
|
||||||
|
SDL_JoystickClose(joystick);
|
||||||
|
}
|
||||||
|
SDL_Quit();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void JoystickManager::update() {
|
||||||
|
#ifdef HAVE_SDL
|
||||||
|
SDL_JoystickUpdate();
|
||||||
|
|
||||||
|
for (int i = 0; i < _joystickStates.size(); i++) {
|
||||||
|
SDL_Joystick* joystick = _joysticks.at(i);
|
||||||
|
JoystickState& state = _joystickStates[i];
|
||||||
|
for (int j = 0; j < state.axes.size(); j++) {
|
||||||
|
float value = glm::round(SDL_JoystickGetAxis(joystick, j) + 0.5f) / numeric_limits<short>::max();
|
||||||
|
const float DEAD_ZONE = 0.1f;
|
||||||
|
state.axes[j] = glm::abs(value) < DEAD_ZONE ? 0.0f : value;
|
||||||
|
}
|
||||||
|
for (int j = 0; j < state.buttons.size(); j++) {
|
||||||
|
state.buttons[j] = SDL_JoystickGetButton(joystick, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
53
interface/src/devices/JoystickManager.h
Normal file
53
interface/src/devices/JoystickManager.h
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
//
|
||||||
|
// JoystickManager.h
|
||||||
|
// interface/src/devices
|
||||||
|
//
|
||||||
|
// Created by Andrzej Kapolka on 5/15/14.
|
||||||
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_JoystickManager_h
|
||||||
|
#define hifi_JoystickManager_h
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QVector>
|
||||||
|
|
||||||
|
#ifdef HAVE_SDL
|
||||||
|
#include <SDL.h>
|
||||||
|
#undef main
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class JoystickState;
|
||||||
|
|
||||||
|
/// Handles joystick input through SDL.
|
||||||
|
class JoystickManager : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
JoystickManager();
|
||||||
|
virtual ~JoystickManager();
|
||||||
|
|
||||||
|
const QVector<JoystickState>& getJoystickStates() const { return _joystickStates; }
|
||||||
|
|
||||||
|
void update();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QVector<JoystickState> _joystickStates;
|
||||||
|
|
||||||
|
#ifdef HAVE_SDL
|
||||||
|
QVector<SDL_Joystick*> _joysticks;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
class JoystickState {
|
||||||
|
public:
|
||||||
|
QString name;
|
||||||
|
QVector<float> axes;
|
||||||
|
QVector<bool> buttons;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // hifi_JoystickManager_h
|
|
@ -9,6 +9,7 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <QTimer>
|
||||||
#include <QtDebug>
|
#include <QtDebug>
|
||||||
|
|
||||||
#include <FBXReader.h>
|
#include <FBXReader.h>
|
||||||
|
@ -17,6 +18,7 @@
|
||||||
#include "PrioVR.h"
|
#include "PrioVR.h"
|
||||||
#include "ui/TextRenderer.h"
|
#include "ui/TextRenderer.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_PRIOVR
|
||||||
const unsigned int SERIAL_LIST[] = { 0x00000001, 0x00000000, 0x00000008, 0x00000009, 0x0000000A,
|
const unsigned int SERIAL_LIST[] = { 0x00000001, 0x00000000, 0x00000008, 0x00000009, 0x0000000A,
|
||||||
0x0000000C, 0x0000000D, 0x0000000E, 0x00000004, 0x00000005, 0x00000010, 0x00000011 };
|
0x0000000C, 0x0000000D, 0x0000000E, 0x00000004, 0x00000005, 0x00000010, 0x00000011 };
|
||||||
const unsigned char AXIS_LIST[] = { 9, 43, 37, 37, 37, 13, 13, 13, 52, 52, 28, 28 };
|
const unsigned char AXIS_LIST[] = { 9, 43, 37, 37, 37, 13, 13, 13, 52, 52, 28, 28 };
|
||||||
|
@ -25,7 +27,6 @@ const int LIST_LENGTH = sizeof(SERIAL_LIST) / sizeof(SERIAL_LIST[0]);
|
||||||
const char* JOINT_NAMES[] = { "Neck", "Spine", "LeftArm", "LeftForeArm", "LeftHand", "RightArm",
|
const char* JOINT_NAMES[] = { "Neck", "Spine", "LeftArm", "LeftForeArm", "LeftHand", "RightArm",
|
||||||
"RightForeArm", "RightHand", "LeftUpLeg", "LeftLeg", "RightUpLeg", "RightLeg" };
|
"RightForeArm", "RightHand", "LeftUpLeg", "LeftLeg", "RightUpLeg", "RightLeg" };
|
||||||
|
|
||||||
#ifdef HAVE_PRIOVR
|
|
||||||
static int indexOfHumanIKJoint(const char* jointName) {
|
static int indexOfHumanIKJoint(const char* jointName) {
|
||||||
for (int i = 0;; i++) {
|
for (int i = 0;; i++) {
|
||||||
QByteArray humanIKJoint = HUMANIK_JOINTS[i];
|
QByteArray humanIKJoint = HUMANIK_JOINTS[i];
|
||||||
|
@ -37,6 +38,87 @@ static int indexOfHumanIKJoint(const char* jointName) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void setPalm(float deltaTime, int index) {
|
||||||
|
MyAvatar* avatar = Application::getInstance()->getAvatar();
|
||||||
|
Hand* hand = avatar->getHand();
|
||||||
|
PalmData* palm;
|
||||||
|
bool foundHand = false;
|
||||||
|
for (size_t j = 0; j < hand->getNumPalms(); j++) {
|
||||||
|
if (hand->getPalms()[j].getSixenseID() == index) {
|
||||||
|
palm = &(hand->getPalms()[j]);
|
||||||
|
foundHand = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!foundHand) {
|
||||||
|
PalmData newPalm(hand);
|
||||||
|
hand->getPalms().push_back(newPalm);
|
||||||
|
palm = &(hand->getPalms()[hand->getNumPalms() - 1]);
|
||||||
|
palm->setSixenseID(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
palm->setActive(true);
|
||||||
|
|
||||||
|
// Read controller buttons and joystick into the hand
|
||||||
|
if (!Application::getInstance()->getJoystickManager()->getJoystickStates().isEmpty()) {
|
||||||
|
const JoystickState& state = Application::getInstance()->getJoystickManager()->getJoystickStates().at(0);
|
||||||
|
if (state.axes.size() >= 4 && state.buttons.size() >= 4) {
|
||||||
|
if (index == SIXENSE_CONTROLLER_ID_LEFT_HAND) {
|
||||||
|
palm->setControllerButtons(state.buttons.at(1) ? BUTTON_FWD : 0);
|
||||||
|
palm->setTrigger(state.buttons.at(0) ? 1.0f : 0.0f);
|
||||||
|
palm->setJoystick(state.axes.at(0), -state.axes.at(1));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
palm->setControllerButtons(state.buttons.at(3) ? BUTTON_FWD : 0);
|
||||||
|
palm->setTrigger(state.buttons.at(2) ? 1.0f : 0.0f);
|
||||||
|
palm->setJoystick(state.axes.at(2), -state.axes.at(3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 position;
|
||||||
|
glm::quat rotation;
|
||||||
|
|
||||||
|
Model* skeletonModel = &Application::getInstance()->getAvatar()->getSkeletonModel();
|
||||||
|
int jointIndex;
|
||||||
|
glm::quat inverseRotation = glm::inverse(Application::getInstance()->getAvatar()->getOrientation());
|
||||||
|
if (index == SIXENSE_CONTROLLER_ID_LEFT_HAND) {
|
||||||
|
jointIndex = skeletonModel->getLeftHandJointIndex();
|
||||||
|
skeletonModel->getJointRotation(jointIndex, rotation, true);
|
||||||
|
rotation = inverseRotation * rotation * glm::quat(glm::vec3(0.0f, PI_OVER_TWO, 0.0f));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
jointIndex = skeletonModel->getRightHandJointIndex();
|
||||||
|
skeletonModel->getJointRotation(jointIndex, rotation, true);
|
||||||
|
rotation = inverseRotation * rotation * glm::quat(glm::vec3(0.0f, -PI_OVER_TWO, 0.0f));
|
||||||
|
}
|
||||||
|
skeletonModel->getJointPosition(jointIndex, position);
|
||||||
|
position = inverseRotation * (position - skeletonModel->getTranslation());
|
||||||
|
|
||||||
|
palm->setRawRotation(rotation);
|
||||||
|
|
||||||
|
// Compute current velocity from position change
|
||||||
|
glm::vec3 rawVelocity;
|
||||||
|
if (deltaTime > 0.f) {
|
||||||
|
rawVelocity = (position - palm->getRawPosition()) / deltaTime;
|
||||||
|
} else {
|
||||||
|
rawVelocity = glm::vec3(0.0f);
|
||||||
|
}
|
||||||
|
palm->setRawVelocity(rawVelocity);
|
||||||
|
palm->setRawPosition(position);
|
||||||
|
|
||||||
|
// Store the one fingertip in the palm structure so we can track velocity
|
||||||
|
const float FINGER_LENGTH = 0.3f; // meters
|
||||||
|
const glm::vec3 FINGER_VECTOR(0.0f, 0.0f, FINGER_LENGTH);
|
||||||
|
const glm::vec3 newTipPosition = position + rotation * FINGER_VECTOR;
|
||||||
|
glm::vec3 oldTipPosition = palm->getTipRawPosition();
|
||||||
|
if (deltaTime > 0.f) {
|
||||||
|
palm->setTipVelocity((newTipPosition - oldTipPosition) / deltaTime);
|
||||||
|
} else {
|
||||||
|
palm->setTipVelocity(glm::vec3(0.f));
|
||||||
|
}
|
||||||
|
palm->setTipPosition(newTipPosition);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PrioVR::PrioVR() {
|
PrioVR::PrioVR() {
|
||||||
|
@ -78,7 +160,7 @@ glm::quat PrioVR::getTorsoRotation() const {
|
||||||
return _jointRotations.size() > TORSO_ROTATION_INDEX ? _jointRotations.at(TORSO_ROTATION_INDEX) : glm::quat();
|
return _jointRotations.size() > TORSO_ROTATION_INDEX ? _jointRotations.at(TORSO_ROTATION_INDEX) : glm::quat();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrioVR::update() {
|
void PrioVR::update(float deltaTime) {
|
||||||
#ifdef HAVE_PRIOVR
|
#ifdef HAVE_PRIOVR
|
||||||
if (!_skeletalDevice) {
|
if (!_skeletalDevice) {
|
||||||
return;
|
return;
|
||||||
|
@ -96,6 +178,10 @@ void PrioVR::update() {
|
||||||
_lastJointRotations[i] = _jointRotations.at(i);
|
_lastJointRotations[i] = _jointRotations.at(i);
|
||||||
_jointRotations[i] = safeMix(lastRotation, _jointRotations.at(i), 0.5f);
|
_jointRotations[i] = safeMix(lastRotation, _jointRotations.at(i), 0.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// convert the joysticks into palm data
|
||||||
|
setPalm(deltaTime, SIXENSE_CONTROLLER_ID_LEFT_HAND);
|
||||||
|
setPalm(deltaTime, SIXENSE_CONTROLLER_ID_RIGHT_HAND);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ public:
|
||||||
const QVector<int>& getHumanIKJointIndices() const { return _humanIKJointIndices; }
|
const QVector<int>& getHumanIKJointIndices() const { return _humanIKJointIndices; }
|
||||||
const QVector<glm::quat>& getJointRotations() const { return _jointRotations; }
|
const QVector<glm::quat>& getJointRotations() const { return _jointRotations; }
|
||||||
|
|
||||||
void update();
|
void update(float deltaTime);
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
|
@ -74,7 +74,7 @@ bool ControllerScriptingInterface::isPrimaryButtonPressed() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -585,6 +585,7 @@ const char* HUMANIK_JOINTS[] = {
|
||||||
"LeftArm",
|
"LeftArm",
|
||||||
"LeftForeArm",
|
"LeftForeArm",
|
||||||
"LeftHand",
|
"LeftHand",
|
||||||
|
"Neck",
|
||||||
"Spine",
|
"Spine",
|
||||||
"Hips",
|
"Hips",
|
||||||
"RightUpLeg",
|
"RightUpLeg",
|
||||||
|
|
Loading…
Reference in a new issue