mirror of
https://github.com/lubosz/overte.git
synced 2025-08-08 03:27:48 +02:00
Merge pull request #7864 from hyperlogic/tony/vive-controller-improvements
Fix for vive controllers sometimes not working
This commit is contained in:
commit
ba357721bf
9 changed files with 178 additions and 34 deletions
|
@ -5,15 +5,17 @@
|
||||||
{ "from": "Vive.LX", "when": "Vive.LS", "filters": [{ "type": "deadZone", "min": 0.6 }], "to": "Standard.LX" },
|
{ "from": "Vive.LX", "when": "Vive.LS", "filters": [{ "type": "deadZone", "min": 0.6 }], "to": "Standard.LX" },
|
||||||
|
|
||||||
{ "from": "Vive.LT", "to": "Standard.LT" },
|
{ "from": "Vive.LT", "to": "Standard.LT" },
|
||||||
{ "from": "Vive.LB", "to": "Standard.LB" },
|
{ "from": "Vive.LeftGrip", "to": "Standard.LB" },
|
||||||
{ "from": "Vive.LS", "to": "Standard.LS" },
|
{ "from": "Vive.LS", "to": "Standard.LS" },
|
||||||
|
{ "from": "Vive.LSTouch", "to": "Standard.LSTouch" },
|
||||||
|
|
||||||
{ "from": "Vive.RY", "when": "Vive.RS", "filters": ["invert", { "type": "deadZone", "min": 0.6 }], "to": "Standard.RY" },
|
{ "from": "Vive.RY", "when": "Vive.RS", "filters": ["invert", { "type": "deadZone", "min": 0.6 }], "to": "Standard.RY" },
|
||||||
{ "from": "Vive.RX", "when": "Vive.RS", "filters": [{ "type": "deadZone", "min": 0.6 }], "to": "Standard.RX" },
|
{ "from": "Vive.RX", "when": "Vive.RS", "filters": [{ "type": "deadZone", "min": 0.6 }], "to": "Standard.RX" },
|
||||||
|
|
||||||
{ "from": "Vive.RT", "to": "Standard.RT" },
|
{ "from": "Vive.RT", "to": "Standard.RT" },
|
||||||
{ "from": "Vive.RB", "to": "Standard.RB" },
|
{ "from": "Vive.RightGrip", "to": "Standard.RB" },
|
||||||
{ "from": "Vive.RS", "to": "Standard.RS" },
|
{ "from": "Vive.RS", "to": "Standard.RS" },
|
||||||
|
{ "from": "Vive.RSTouch", "to": "Standard.RSTouch" },
|
||||||
|
|
||||||
{ "from": "Vive.LeftApplicationMenu", "to": "Standard.Back" },
|
{ "from": "Vive.LeftApplicationMenu", "to": "Standard.Back" },
|
||||||
{ "from": "Vive.RightApplicationMenu", "to": "Standard.Start" },
|
{ "from": "Vive.RightApplicationMenu", "to": "Standard.Start" },
|
||||||
|
|
|
@ -58,7 +58,7 @@ controller::UserInputMapper::UserInputMapper() {
|
||||||
|
|
||||||
namespace controller {
|
namespace controller {
|
||||||
|
|
||||||
|
|
||||||
UserInputMapper::~UserInputMapper() {
|
UserInputMapper::~UserInputMapper() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,6 +80,7 @@ void UserInputMapper::registerDevice(InputDevice::Pointer device) {
|
||||||
recordDeviceOfType(device->getName());
|
recordDeviceOfType(device->getName());
|
||||||
|
|
||||||
qCDebug(controllers) << "Registered input device <" << device->getName() << "> deviceID = " << deviceID;
|
qCDebug(controllers) << "Registered input device <" << device->getName() << "> deviceID = " << deviceID;
|
||||||
|
|
||||||
for (const auto& inputMapping : device->getAvailableInputs()) {
|
for (const auto& inputMapping : device->getAvailableInputs()) {
|
||||||
const auto& input = inputMapping.first;
|
const auto& input = inputMapping.first;
|
||||||
// Ignore aliases
|
// Ignore aliases
|
||||||
|
@ -102,6 +103,7 @@ void UserInputMapper::registerDevice(InputDevice::Pointer device) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_registeredDevices[deviceID] = device;
|
_registeredDevices[deviceID] = device;
|
||||||
|
|
||||||
auto mapping = loadMappings(device->getDefaultMappingConfigs());
|
auto mapping = loadMappings(device->getDefaultMappingConfigs());
|
||||||
if (mapping) {
|
if (mapping) {
|
||||||
_mappingsByDevice[deviceID] = mapping;
|
_mappingsByDevice[deviceID] = mapping;
|
||||||
|
@ -111,15 +113,21 @@ void UserInputMapper::registerDevice(InputDevice::Pointer device) {
|
||||||
emit hardwareChanged();
|
emit hardwareChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME remove the associated device mappings
|
|
||||||
void UserInputMapper::removeDevice(int deviceID) {
|
void UserInputMapper::removeDevice(int deviceID) {
|
||||||
|
|
||||||
Locker locker(_lock);
|
Locker locker(_lock);
|
||||||
auto proxyEntry = _registeredDevices.find(deviceID);
|
auto proxyEntry = _registeredDevices.find(deviceID);
|
||||||
|
|
||||||
if (_registeredDevices.end() == proxyEntry) {
|
if (_registeredDevices.end() == proxyEntry) {
|
||||||
qCWarning(controllers) << "Attempted to remove unknown device " << deviceID;
|
qCWarning(controllers) << "Attempted to remove unknown device " << deviceID;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto proxy = proxyEntry->second;
|
|
||||||
|
auto device = proxyEntry->second;
|
||||||
|
qCDebug(controllers) << "Unregistering input device <" << device->getName() << "> deviceID = " << deviceID;
|
||||||
|
|
||||||
|
unloadMappings(device->getDefaultMappingConfigs());
|
||||||
|
|
||||||
auto mappingsEntry = _mappingsByDevice.find(deviceID);
|
auto mappingsEntry = _mappingsByDevice.find(deviceID);
|
||||||
if (_mappingsByDevice.end() != mappingsEntry) {
|
if (_mappingsByDevice.end() != mappingsEntry) {
|
||||||
disableMapping(mappingsEntry->second);
|
disableMapping(mappingsEntry->second);
|
||||||
|
@ -244,7 +252,7 @@ void UserInputMapper::update(float deltaTime) {
|
||||||
for (auto& channel : _actionStates) {
|
for (auto& channel : _actionStates) {
|
||||||
channel = 0.0f;
|
channel = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& channel : _poseStates) {
|
for (auto& channel : _poseStates) {
|
||||||
channel = Pose();
|
channel = Pose();
|
||||||
}
|
}
|
||||||
|
@ -705,11 +713,10 @@ Mapping::Pointer UserInputMapper::loadMapping(const QString& jsonFile, bool enab
|
||||||
return Mapping::Pointer();
|
return Mapping::Pointer();
|
||||||
}
|
}
|
||||||
// Each mapping only needs to be loaded once
|
// Each mapping only needs to be loaded once
|
||||||
static QSet<QString> loaded;
|
if (_loadedRouteJsonFiles.contains(jsonFile)) {
|
||||||
if (loaded.contains(jsonFile)) {
|
|
||||||
return Mapping::Pointer();
|
return Mapping::Pointer();
|
||||||
}
|
}
|
||||||
loaded.insert(jsonFile);
|
_loadedRouteJsonFiles.insert(jsonFile);
|
||||||
QString json;
|
QString json;
|
||||||
{
|
{
|
||||||
QFile file(jsonFile);
|
QFile file(jsonFile);
|
||||||
|
@ -741,6 +748,18 @@ MappingPointer UserInputMapper::loadMappings(const QStringList& jsonFiles) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UserInputMapper::unloadMappings(const QStringList& jsonFiles) {
|
||||||
|
for (const QString& jsonFile : jsonFiles) {
|
||||||
|
unloadMapping(jsonFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserInputMapper::unloadMapping(const QString& jsonFile) {
|
||||||
|
auto entry = _loadedRouteJsonFiles.find(jsonFile);
|
||||||
|
if (entry != _loadedRouteJsonFiles.end()) {
|
||||||
|
_loadedRouteJsonFiles.erase(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const QString JSON_NAME = QStringLiteral("name");
|
static const QString JSON_NAME = QStringLiteral("name");
|
||||||
static const QString JSON_CHANNELS = QStringLiteral("channels");
|
static const QString JSON_CHANNELS = QStringLiteral("channels");
|
||||||
|
|
|
@ -111,9 +111,18 @@ namespace controller {
|
||||||
|
|
||||||
void loadDefaultMapping(uint16 deviceID);
|
void loadDefaultMapping(uint16 deviceID);
|
||||||
void enableMapping(const QString& mappingName, bool enable = true);
|
void enableMapping(const QString& mappingName, bool enable = true);
|
||||||
|
|
||||||
|
void unloadMappings(const QStringList& jsonFiles);
|
||||||
|
void unloadMapping(const QString& jsonFile);
|
||||||
|
|
||||||
float getValue(const Input& input) const;
|
float getValue(const Input& input) const;
|
||||||
Pose getPose(const Input& input) const;
|
Pose getPose(const Input& input) const;
|
||||||
|
|
||||||
|
// perform an action when the UserInputMapper mutex is acquired.
|
||||||
|
using Locker = std::unique_lock<std::recursive_mutex>;
|
||||||
|
template <typename F>
|
||||||
|
void withLock(F&& f) { Locker locker(_lock); f(); }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void actionEvent(int action, float state);
|
void actionEvent(int action, float state);
|
||||||
void inputEvent(int input, float state);
|
void inputEvent(int input, float state);
|
||||||
|
@ -177,7 +186,7 @@ namespace controller {
|
||||||
RouteList _deviceRoutes;
|
RouteList _deviceRoutes;
|
||||||
RouteList _standardRoutes;
|
RouteList _standardRoutes;
|
||||||
|
|
||||||
using Locker = std::unique_lock<std::recursive_mutex>;
|
QSet<QString> _loadedRouteJsonFiles;
|
||||||
|
|
||||||
mutable std::recursive_mutex _lock;
|
mutable std::recursive_mutex _lock;
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,8 +20,12 @@
|
||||||
|
|
||||||
const QString KeyboardMouseDevice::NAME = "Keyboard/Mouse";
|
const QString KeyboardMouseDevice::NAME = "Keyboard/Mouse";
|
||||||
|
|
||||||
void KeyboardMouseDevice::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
void KeyboardMouseDevice::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
||||||
_inputDevice->update(deltaTime, inputCalibrationData, jointsCaptured);
|
|
||||||
|
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
||||||
|
userInputMapper->withLock([&, this]() {
|
||||||
|
_inputDevice->update(deltaTime, inputCalibrationData, jointsCaptured);
|
||||||
|
});
|
||||||
|
|
||||||
// For touch event, we need to check that the last event is not too long ago
|
// For touch event, we need to check that the last event is not too long ago
|
||||||
// Maybe it's a Qt issue, but the touch event sequence (begin, update, end) is not always called properly
|
// Maybe it's a Qt issue, but the touch event sequence (begin, update, end) is not always called properly
|
||||||
|
|
|
@ -509,7 +509,12 @@ void NeuronPlugin::pluginUpdate(float deltaTime, const controller::InputCalibrat
|
||||||
std::lock_guard<std::mutex> guard(_jointsMutex);
|
std::lock_guard<std::mutex> guard(_jointsMutex);
|
||||||
joints = _joints;
|
joints = _joints;
|
||||||
}
|
}
|
||||||
_inputDevice->update(deltaTime, inputCalibrationData, joints, _prevJoints);
|
|
||||||
|
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
||||||
|
userInputMapper->withLock([&, this]() {
|
||||||
|
_inputDevice->update(deltaTime, inputCalibrationData, joints, _prevJoints);
|
||||||
|
});
|
||||||
|
|
||||||
_prevJoints = joints;
|
_prevJoints = joints;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -136,7 +136,12 @@ void SixenseManager::setSixenseFilter(bool filter) {
|
||||||
|
|
||||||
void SixenseManager::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
void SixenseManager::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
||||||
BAIL_IF_NOT_LOADED
|
BAIL_IF_NOT_LOADED
|
||||||
_inputDevice->update(deltaTime, inputCalibrationData, jointsCaptured);
|
|
||||||
|
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
||||||
|
userInputMapper->withLock([&, this]() {
|
||||||
|
_inputDevice->update(deltaTime, inputCalibrationData, jointsCaptured);
|
||||||
|
});
|
||||||
|
|
||||||
if (_inputDevice->_requestReset) {
|
if (_inputDevice->_requestReset) {
|
||||||
_container->requestReset();
|
_container->requestReset();
|
||||||
_inputDevice->_requestReset = false;
|
_inputDevice->_requestReset = false;
|
||||||
|
|
|
@ -211,9 +211,13 @@ void ViveControllerManager::renderHand(const controller::Pose& pose, gpu::Batch&
|
||||||
|
|
||||||
|
|
||||||
void ViveControllerManager::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
void ViveControllerManager::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
||||||
_inputDevice->update(deltaTime, inputCalibrationData, jointsCaptured);
|
|
||||||
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
||||||
|
|
||||||
|
// because update mutates the internal state we need to lock
|
||||||
|
userInputMapper->withLock([&, this]() {
|
||||||
|
_inputDevice->update(deltaTime, inputCalibrationData, jointsCaptured);
|
||||||
|
});
|
||||||
|
|
||||||
if (_inputDevice->_trackedControllers == 0 && _registeredWithInputMapper) {
|
if (_inputDevice->_trackedControllers == 0 && _registeredWithInputMapper) {
|
||||||
userInputMapper->removeDevice(_inputDevice->_deviceID);
|
userInputMapper->removeDevice(_inputDevice->_deviceID);
|
||||||
_registeredWithInputMapper = false;
|
_registeredWithInputMapper = false;
|
||||||
|
@ -270,7 +274,8 @@ void ViveControllerManager::InputDevice::handleHandController(float deltaTime, u
|
||||||
for (uint32_t i = 0; i < vr::k_EButton_Max; ++i) {
|
for (uint32_t i = 0; i < vr::k_EButton_Max; ++i) {
|
||||||
auto mask = vr::ButtonMaskFromId((vr::EVRButtonId)i);
|
auto mask = vr::ButtonMaskFromId((vr::EVRButtonId)i);
|
||||||
bool pressed = 0 != (controllerState.ulButtonPressed & mask);
|
bool pressed = 0 != (controllerState.ulButtonPressed & mask);
|
||||||
handleButtonEvent(deltaTime, i, pressed, isLeftHand);
|
bool touched = 0 != (controllerState.ulButtonTouched & mask);
|
||||||
|
handleButtonEvent(deltaTime, i, pressed, touched, isLeftHand);
|
||||||
}
|
}
|
||||||
|
|
||||||
// process each axis
|
// process each axis
|
||||||
|
@ -314,20 +319,26 @@ enum ViveButtonChannel {
|
||||||
|
|
||||||
|
|
||||||
// These functions do translation from the Steam IDs to the standard controller IDs
|
// These functions do translation from the Steam IDs to the standard controller IDs
|
||||||
void ViveControllerManager::InputDevice::handleButtonEvent(float deltaTime, uint32_t button, bool pressed, bool isLeftHand) {
|
void ViveControllerManager::InputDevice::handleButtonEvent(float deltaTime, uint32_t button, bool pressed, bool touched, bool isLeftHand) {
|
||||||
if (!pressed) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
using namespace controller;
|
using namespace controller;
|
||||||
if (button == vr::k_EButton_ApplicationMenu) {
|
|
||||||
_buttonPressedMap.insert(isLeftHand ? LEFT_APP_MENU : RIGHT_APP_MENU);
|
if (pressed) {
|
||||||
} else if (button == vr::k_EButton_Grip) {
|
if (button == vr::k_EButton_ApplicationMenu) {
|
||||||
_buttonPressedMap.insert(isLeftHand ? LB : RB);
|
_buttonPressedMap.insert(isLeftHand ? LEFT_APP_MENU : RIGHT_APP_MENU);
|
||||||
} else if (button == vr::k_EButton_SteamVR_Trigger) {
|
} else if (button == vr::k_EButton_Grip) {
|
||||||
_buttonPressedMap.insert(isLeftHand ? LT : RT);
|
_buttonPressedMap.insert(isLeftHand ? LEFT_GRIP : RIGHT_GRIP);
|
||||||
} else if (button == vr::k_EButton_SteamVR_Touchpad) {
|
} else if (button == vr::k_EButton_SteamVR_Trigger) {
|
||||||
_buttonPressedMap.insert(isLeftHand ? LS : RS);
|
_buttonPressedMap.insert(isLeftHand ? LT : RT);
|
||||||
|
} else if (button == vr::k_EButton_SteamVR_Touchpad) {
|
||||||
|
_buttonPressedMap.insert(isLeftHand ? LS : RS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (touched) {
|
||||||
|
if (button == vr::k_EButton_SteamVR_Touchpad) {
|
||||||
|
_buttonPressedMap.insert(isLeftHand ? LS_TOUCH : RS_TOUCH);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -424,18 +435,28 @@ controller::Input::NamedVector ViveControllerManager::InputDevice::getAvailableI
|
||||||
makePair(LY, "LY"),
|
makePair(LY, "LY"),
|
||||||
makePair(RX, "RX"),
|
makePair(RX, "RX"),
|
||||||
makePair(RY, "RY"),
|
makePair(RY, "RY"),
|
||||||
// trigger analogs
|
|
||||||
|
// capacitive touch on the touch pad
|
||||||
|
makePair(LS_TOUCH, "LSTouch"),
|
||||||
|
makePair(RS_TOUCH, "RSTouch"),
|
||||||
|
|
||||||
|
// touch pad press
|
||||||
|
makePair(LS, "LS"),
|
||||||
|
makePair(RS, "RS"),
|
||||||
|
|
||||||
|
// triggers
|
||||||
makePair(LT, "LT"),
|
makePair(LT, "LT"),
|
||||||
makePair(RT, "RT"),
|
makePair(RT, "RT"),
|
||||||
|
|
||||||
makePair(LB, "LB"),
|
// low profile side grip button.
|
||||||
makePair(RB, "RB"),
|
makePair(LEFT_GRIP, "LeftGrip"),
|
||||||
|
makePair(RIGHT_GRIP, "RightGrip"),
|
||||||
|
|
||||||
makePair(LS, "LS"),
|
// 3d location of controller
|
||||||
makePair(RS, "RS"),
|
|
||||||
makePair(LEFT_HAND, "LeftHand"),
|
makePair(LEFT_HAND, "LeftHand"),
|
||||||
makePair(RIGHT_HAND, "RightHand"),
|
makePair(RIGHT_HAND, "RightHand"),
|
||||||
|
|
||||||
|
// app button above trackpad.
|
||||||
Input::NamedPair(Input(_deviceID, LEFT_APP_MENU, ChannelType::BUTTON), "LeftApplicationMenu"),
|
Input::NamedPair(Input(_deviceID, LEFT_APP_MENU, ChannelType::BUTTON), "LeftApplicationMenu"),
|
||||||
Input::NamedPair(Input(_deviceID, RIGHT_APP_MENU, ChannelType::BUTTON), "RightApplicationMenu"),
|
Input::NamedPair(Input(_deviceID, RIGHT_APP_MENU, ChannelType::BUTTON), "RightApplicationMenu"),
|
||||||
};
|
};
|
||||||
|
|
|
@ -59,7 +59,7 @@ private:
|
||||||
virtual void focusOutEvent() override;
|
virtual void focusOutEvent() override;
|
||||||
|
|
||||||
void handleHandController(float deltaTime, uint32_t deviceIndex, const controller::InputCalibrationData& inputCalibrationData, bool isLeftHand);
|
void handleHandController(float deltaTime, uint32_t deviceIndex, const controller::InputCalibrationData& inputCalibrationData, bool isLeftHand);
|
||||||
void handleButtonEvent(float deltaTime, uint32_t button, bool pressed, bool isLeftHand);
|
void handleButtonEvent(float deltaTime, uint32_t button, bool pressed, bool touched, bool isLeftHand);
|
||||||
void handleAxisEvent(float deltaTime, uint32_t axis, float x, float y, bool isLeftHand);
|
void handleAxisEvent(float deltaTime, uint32_t axis, float x, float y, bool isLeftHand);
|
||||||
void handlePoseEvent(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, const mat4& mat,
|
void handlePoseEvent(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, const mat4& mat,
|
||||||
const vec3& linearVelocity, const vec3& angularVelocity, bool isLeftHand);
|
const vec3& linearVelocity, const vec3& angularVelocity, bool isLeftHand);
|
||||||
|
|
79
scripts/developer/tests/viveTouchpadTest.js
Normal file
79
scripts/developer/tests/viveTouchpadTest.js
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
//
|
||||||
|
// viveTouchpadTest.js
|
||||||
|
//
|
||||||
|
// Anthony J. Thibault
|
||||||
|
// Copyright 2016 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// An example of reading touch and move events from the vive controller touch pad.
|
||||||
|
//
|
||||||
|
// It will spawn a gray cube in front of you, then as you use the right touch pad,
|
||||||
|
// the cube should turn green and respond to the motion of your thumb on the pad.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
|
||||||
|
var GRAY = {red: 57, green: 57, blue: 57};
|
||||||
|
var GREEN = {red: 0, green: 255, blue: 0};
|
||||||
|
var ZERO = {x: 0, y: 0, z: 0};
|
||||||
|
var Y_AXIS = {x: 0, y: 1, x: 0};
|
||||||
|
var ROT_Y_90 = Quat.angleAxis(Y_AXIS, 90.0);
|
||||||
|
|
||||||
|
var boxEntity;
|
||||||
|
var boxPosition;
|
||||||
|
var boxZAxis, boxYAxis;
|
||||||
|
var prevThumbDown = false;
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
boxPosition = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getFront(Camera.getOrientation())));
|
||||||
|
var front = Quat.getFront(Camera.getOrientation());
|
||||||
|
boxZAxis = Vec3.normalize(Vec3.cross(front, Y_AXIS));
|
||||||
|
boxYAxis = Vec3.normalize(Vec3.cross(boxZAxis, front));
|
||||||
|
|
||||||
|
boxEntity = Entities.addEntity({
|
||||||
|
type: "Box",
|
||||||
|
position: boxPosition,
|
||||||
|
dimentions: {x: 0.25, y: 0.25, z: 0.25},
|
||||||
|
color: GRAY,
|
||||||
|
gravity: ZERO,
|
||||||
|
visible: true,
|
||||||
|
locked: false,
|
||||||
|
lifetime: 60000
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function shutdown() {
|
||||||
|
Entities.deleteEntity(boxEntity);
|
||||||
|
}
|
||||||
|
Script.scriptEnding.connect(shutdown);
|
||||||
|
|
||||||
|
function viveIsConnected() {
|
||||||
|
return Controller.Hardware.Vive;
|
||||||
|
}
|
||||||
|
|
||||||
|
function update(dt) {
|
||||||
|
if (viveIsConnected()) {
|
||||||
|
var thumbDown = Controller.getValue(Controller.Hardware.Vive.RSTouch);
|
||||||
|
if (thumbDown) {
|
||||||
|
var x = Controller.getValue(Controller.Hardware.Vive.RX);
|
||||||
|
var y = Controller.getValue(Controller.Hardware.Vive.RY);
|
||||||
|
var xOffset = Vec3.multiply(boxZAxis, x);
|
||||||
|
var yOffset = Vec3.multiply(boxYAxis, y);
|
||||||
|
var offset = Vec3.sum(xOffset, yOffset);
|
||||||
|
Entities.editEntity(boxEntity, {position: Vec3.sum(boxPosition, offset)});
|
||||||
|
}
|
||||||
|
if (thumbDown && !prevThumbDown) {
|
||||||
|
Entities.editEntity(boxEntity, {color: GREEN});
|
||||||
|
}
|
||||||
|
if (!thumbDown && prevThumbDown) {
|
||||||
|
Entities.editEntity(boxEntity, {color: GRAY});
|
||||||
|
}
|
||||||
|
prevThumbDown = thumbDown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Script.update.connect(update);
|
||||||
|
|
||||||
|
init();
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue