From 7517f224a84ee35cc77705722a860597b6fa0732 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 15 Mar 2017 13:49:50 -0700 Subject: [PATCH 1/7] Add MyAvatar drive keys capture capability --- interface/src/Application.cpp | 14 ++++++------- interface/src/avatar/MyAvatar.cpp | 34 +++++++++++++++---------------- interface/src/avatar/MyAvatar.h | 17 +++++++++++++--- 3 files changed, 37 insertions(+), 28 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1bb4c64884..df9d10caa6 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4383,16 +4383,16 @@ void Application::update(float deltaTime) { myAvatar->clearDriveKeys(); if (_myCamera.getMode() != CAMERA_MODE_INDEPENDENT) { if (!_controllerScriptingInterface->areActionsCaptured()) { - myAvatar->setDriveKeys(TRANSLATE_Z, -1.0f * userInputMapper->getActionState(controller::Action::TRANSLATE_Z)); - myAvatar->setDriveKeys(TRANSLATE_Y, userInputMapper->getActionState(controller::Action::TRANSLATE_Y)); - myAvatar->setDriveKeys(TRANSLATE_X, userInputMapper->getActionState(controller::Action::TRANSLATE_X)); + myAvatar->setDriveKey(TRANSLATE_Z, -1.0f * userInputMapper->getActionState(controller::Action::TRANSLATE_Z)); + myAvatar->setDriveKey(TRANSLATE_Y, userInputMapper->getActionState(controller::Action::TRANSLATE_Y)); + myAvatar->setDriveKey(TRANSLATE_X, userInputMapper->getActionState(controller::Action::TRANSLATE_X)); if (deltaTime > FLT_EPSILON) { - myAvatar->setDriveKeys(PITCH, -1.0f * userInputMapper->getActionState(controller::Action::PITCH)); - myAvatar->setDriveKeys(YAW, -1.0f * userInputMapper->getActionState(controller::Action::YAW)); - myAvatar->setDriveKeys(STEP_YAW, -1.0f * userInputMapper->getActionState(controller::Action::STEP_YAW)); + myAvatar->setDriveKey(PITCH, -1.0f * userInputMapper->getActionState(controller::Action::PITCH)); + myAvatar->setDriveKey(YAW, -1.0f * userInputMapper->getActionState(controller::Action::YAW)); + myAvatar->setDriveKey(STEP_YAW, -1.0f * userInputMapper->getActionState(controller::Action::STEP_YAW)); } } - myAvatar->setDriveKeys(ZOOM, userInputMapper->getActionState(controller::Action::TRANSLATE_CAMERA_Z)); + myAvatar->setDriveKey(ZOOM, userInputMapper->getActionState(controller::Action::TRANSLATE_CAMERA_Z)); } controller::Pose leftHandPose = userInputMapper->getPoseState(controller::Action::LEFT_HAND); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 318608e3a8..c38d1ed607 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -119,9 +119,7 @@ MyAvatar::MyAvatar(RigPointer rig) : using namespace recording; _skeletonModel->flagAsCauterized(); - for (int i = 0; i < MAX_DRIVE_KEYS; i++) { - _driveKeys[i] = 0.0f; - } + clearDriveKeys(); // Necessary to select the correct slot using SlotType = void(MyAvatar::*)(const glm::vec3&, bool, const glm::quat&, bool); @@ -462,7 +460,7 @@ void MyAvatar::simulate(float deltaTime) { // When there are no step values, we zero out the last step pulse. // This allows a user to do faster snapping by tapping a control for (int i = STEP_TRANSLATE_X; !stepAction && i <= STEP_YAW; ++i) { - if (_driveKeys[i] != 0.0f) { + if (getDriveKey(i) != 0.0f) { stepAction = true; } } @@ -1655,7 +1653,7 @@ bool MyAvatar::shouldRenderHead(const RenderArgs* renderArgs) const { void MyAvatar::updateOrientation(float deltaTime) { // Smoothly rotate body with arrow keys - float targetSpeed = _driveKeys[YAW] * _yawSpeed; + float targetSpeed = getDriveKey(YAW) * _yawSpeed; if (targetSpeed != 0.0f) { const float ROTATION_RAMP_TIMESCALE = 0.1f; float blend = deltaTime / ROTATION_RAMP_TIMESCALE; @@ -1684,8 +1682,8 @@ void MyAvatar::updateOrientation(float deltaTime) { // Comfort Mode: If you press any of the left/right rotation drive keys or input, you'll // get an instantaneous 15 degree turn. If you keep holding the key down you'll get another // snap turn every half second. - if (_driveKeys[STEP_YAW] != 0.0f) { - totalBodyYaw += _driveKeys[STEP_YAW]; + if (getDriveKey(STEP_YAW) != 0.0f) { + totalBodyYaw += getDriveKey(STEP_YAW); } // use head/HMD orientation to turn while flying @@ -1722,7 +1720,7 @@ void MyAvatar::updateOrientation(float deltaTime) { // update body orientation by movement inputs setOrientation(getOrientation() * glm::quat(glm::radians(glm::vec3(0.0f, totalBodyYaw, 0.0f)))); - getHead()->setBasePitch(getHead()->getBasePitch() + _driveKeys[PITCH] * _pitchSpeed * deltaTime); + getHead()->setBasePitch(getHead()->getBasePitch() + getDriveKey(PITCH) * _pitchSpeed * deltaTime); if (qApp->isHMDMode()) { glm::quat orientation = glm::quat_cast(getSensorToWorldMatrix()) * getHMDSensorOrientation(); @@ -1756,14 +1754,14 @@ void MyAvatar::updateActionMotor(float deltaTime) { } // compute action input - glm::vec3 front = (_driveKeys[TRANSLATE_Z]) * IDENTITY_FRONT; - glm::vec3 right = (_driveKeys[TRANSLATE_X]) * IDENTITY_RIGHT; + glm::vec3 front = (getDriveKey(TRANSLATE_Z)) * IDENTITY_FRONT; + glm::vec3 right = (getDriveKey(TRANSLATE_X)) * IDENTITY_RIGHT; glm::vec3 direction = front + right; CharacterController::State state = _characterController.getState(); if (state == CharacterController::State::Hover) { // we're flying --> support vertical motion - glm::vec3 up = (_driveKeys[TRANSLATE_Y]) * IDENTITY_UP; + glm::vec3 up = (getDriveKey(TRANSLATE_Y)) * IDENTITY_UP; direction += up; } @@ -1802,7 +1800,7 @@ void MyAvatar::updateActionMotor(float deltaTime) { _actionMotorVelocity = MAX_WALKING_SPEED * direction; } - float boomChange = _driveKeys[ZOOM]; + float boomChange = getDriveKey(ZOOM); _boomLength += 2.0f * _boomLength * boomChange + boomChange * boomChange; _boomLength = glm::clamp(_boomLength, ZOOM_MIN, ZOOM_MAX); } @@ -1833,11 +1831,11 @@ void MyAvatar::updatePosition(float deltaTime) { } // capture the head rotation, in sensor space, when the user first indicates they would like to move/fly. - if (!_hoverReferenceCameraFacingIsCaptured && (fabs(_driveKeys[TRANSLATE_Z]) > 0.1f || fabs(_driveKeys[TRANSLATE_X]) > 0.1f)) { + if (!_hoverReferenceCameraFacingIsCaptured && (fabs(getDriveKey(TRANSLATE_Z)) > 0.1f || fabs(getDriveKey(TRANSLATE_X)) > 0.1f)) { _hoverReferenceCameraFacingIsCaptured = true; // transform the camera facing vector into sensor space. _hoverReferenceCameraFacing = transformVectorFast(glm::inverse(_sensorToWorldMatrix), getHead()->getCameraOrientation() * Vectors::UNIT_Z); - } else if (_hoverReferenceCameraFacingIsCaptured && (fabs(_driveKeys[TRANSLATE_Z]) <= 0.1f && fabs(_driveKeys[TRANSLATE_X]) <= 0.1f)) { + } else if (_hoverReferenceCameraFacingIsCaptured && (fabs(getDriveKey(TRANSLATE_Z)) <= 0.1f && fabs(getDriveKey(TRANSLATE_X)) <= 0.1f)) { _hoverReferenceCameraFacingIsCaptured = false; } } @@ -2094,12 +2092,12 @@ bool MyAvatar::getCharacterControllerEnabled() { void MyAvatar::clearDriveKeys() { for (int i = 0; i < MAX_DRIVE_KEYS; ++i) { - _driveKeys[i] = 0.0f; + setDriveKey(i, 0.0f); } } void MyAvatar::relayDriveKeysToCharacterController() { - if (_driveKeys[TRANSLATE_Y] > 0.0f) { + if (getDriveKey(TRANSLATE_Y) > 0.0f) { _characterController.jump(); } } @@ -2382,7 +2380,7 @@ bool MyAvatar::didTeleport() { } bool MyAvatar::hasDriveInput() const { - return fabsf(_driveKeys[TRANSLATE_X]) > 0.0f || fabsf(_driveKeys[TRANSLATE_Y]) > 0.0f || fabsf(_driveKeys[TRANSLATE_Z]) > 0.0f; + return fabsf(getDriveKey(TRANSLATE_X)) > 0.0f || fabsf(getDriveKey(TRANSLATE_Y)) > 0.0f || fabsf(getDriveKey(TRANSLATE_Z)) > 0.0f; } void MyAvatar::setAway(bool value) { @@ -2498,7 +2496,7 @@ bool MyAvatar::pinJoint(int index, const glm::vec3& position, const glm::quat& o return false; } - setPosition(position); + slamPosition(position); setOrientation(orientation); _rig->setMaxHipsOffsetLength(0.05f); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 00923e78cc..731ba89299 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -12,6 +12,8 @@ #ifndef hifi_MyAvatar_h #define hifi_MyAvatar_h +#include + #include #include @@ -87,6 +89,8 @@ class MyAvatar : public Avatar { Q_PROPERTY(bool hmdLeanRecenterEnabled READ getHMDLeanRecenterEnabled WRITE setHMDLeanRecenterEnabled) Q_PROPERTY(bool characterControllerEnabled READ getCharacterControllerEnabled WRITE setCharacterControllerEnabled) + Q_ENUMS(DriveKeys) + public: explicit MyAvatar(RigPointer rig); ~MyAvatar(); @@ -180,9 +184,15 @@ public: // Set what driving keys are being pressed to control thrust levels void clearDriveKeys(); - void setDriveKeys(int key, float val) { _driveKeys[key] = val; }; + void setDriveKey(int key, float val) { _driveKeys[key] = val; }; + float getDriveKey(int key) const { return isDriveKeyCaptured(key) ? 0.0f : _driveKeys[key]; }; + Q_INVOKABLE float getRawDriveKey(int key) const { return _driveKeys[key]; }; void relayDriveKeysToCharacterController(); + Q_INVOKABLE void captureDriveKey(int key) { _capturedDriveKeys.set(key); } + Q_INVOKABLE void releaseDriveKey(int key) { _capturedDriveKeys.reset(key); } + Q_INVOKABLE bool isDriveKeyCaptured(int key) const { return _capturedDriveKeys.test(key); } + eyeContactTarget getEyeContactTarget(); Q_INVOKABLE glm::vec3 getTrackedHeadPosition() const { return _trackedHeadPosition; } @@ -352,7 +362,6 @@ private: virtual bool shouldRenderHead(const RenderArgs* renderArgs) const override; void setShouldRenderLocally(bool shouldRender) { _shouldRender = shouldRender; setEnableMeshVisible(shouldRender); } bool getShouldRenderLocally() const { return _shouldRender; } - bool getDriveKeys(int key) { return _driveKeys[key] != 0.0f; }; bool isMyAvatar() const override { return true; } virtual int parseDataFromBuffer(const QByteArray& buffer) override; virtual glm::vec3 getSkeletonPosition() const override; @@ -388,7 +397,9 @@ private: void clampScaleChangeToDomainLimits(float desiredScale); glm::mat4 computeCameraRelativeHandControllerMatrix(const glm::mat4& controllerSensorMatrix) const; - float _driveKeys[MAX_DRIVE_KEYS]; + std::array _driveKeys; + std::bitset _capturedDriveKeys; + bool _wasPushing; bool _isPushing; bool _isBeingPushed; From 35dd45ddf9f3829bb2707555b5d7805006b7cd81 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 15 Mar 2017 17:39:38 -0700 Subject: [PATCH 2/7] Capture drive keys while avatar is seated --- scripts/tutorials/entity_scripts/sit.js | 99 +++++++++++++------------ 1 file changed, 50 insertions(+), 49 deletions(-) diff --git a/scripts/tutorials/entity_scripts/sit.js b/scripts/tutorials/entity_scripts/sit.js index ffce196572..42cf7685ad 100644 --- a/scripts/tutorials/entity_scripts/sit.js +++ b/scripts/tutorials/entity_scripts/sit.js @@ -6,26 +6,28 @@ var ANIMATION_FPS = 30; var ANIMATION_FIRST_FRAME = 1; var ANIMATION_LAST_FRAME = 10; - var RELEASE_KEYS = ['w', 'a', 's', 'd', 'UP', 'LEFT', 'DOWN', 'RIGHT']; var RELEASE_TIME = 500; // ms var RELEASE_DISTANCE = 0.2; // meters var MAX_IK_ERROR = 30; + var IK_SETTLE_TIME = 250; // ms var DESKTOP_UI_CHECK_INTERVAL = 100; var DESKTOP_MAX_DISTANCE = 5; - var SIT_DELAY = 25 - var MAX_RESET_DISTANCE = 0.5 + var SIT_DELAY = 25; + var MAX_RESET_DISTANCE = 0.5; // meters + var OVERRIDEN_DRIVE_KEYS = [0, 1, 2, 4, 5, 6]; this.entityID = null; - this.timers = {}; this.animStateHandlerID = null; this.interval = null; + this.sitDownTimestamp = null; + this.lastTimeNoDriveKeys = null; this.preload = function(entityID) { this.entityID = entityID; } this.unload = function() { if (Settings.getValue(SETTING_KEY) === this.entityID) { - this.sitUp(); + this.standUp(); } if (this.interval !== null) { Script.clearInterval(this.interval); @@ -96,6 +98,10 @@ print("Someone is already sitting in that chair."); return; } + print("Sitting down (" + this.entityID + ")"); + + this.sitDownTimestamp = Date.now(); + this.lastTimeNoDriveKeys = this.sitDownTimestamp; var previousValue = Settings.getValue(SETTING_KEY); Settings.setValue(SETTING_KEY, this.entityID); @@ -118,20 +124,17 @@ return { headType: 0 }; }, ["headType"]); Script.update.connect(this, this.update); - Controller.keyPressEvent.connect(this, this.keyPressed); - Controller.keyReleaseEvent.connect(this, this.keyReleased); - for (var i in RELEASE_KEYS) { - Controller.captureKeyEvents({ text: RELEASE_KEYS[i] }); + for (var i in OVERRIDEN_DRIVE_KEYS) { + MyAvatar.captureDriveKey(OVERRIDEN_DRIVE_KEYS[i]); } } - this.sitUp = function() { + this.standUp = function() { + print("Standing up (" + this.entityID + ")"); MyAvatar.removeAnimationStateHandler(this.animStateHandlerID); Script.update.disconnect(this, this.update); - Controller.keyPressEvent.disconnect(this, this.keyPressed); - Controller.keyReleaseEvent.disconnect(this, this.keyReleased); - for (var i in RELEASE_KEYS) { - Controller.releaseKeyEvents({ text: RELEASE_KEYS[i] }); + for (var i in OVERRIDEN_DRIVE_KEYS) { + MyAvatar.releaseDriveKey(OVERRIDEN_DRIVE_KEYS[i]); } this.setSeatUser(null); @@ -156,6 +159,7 @@ } } + // function called by teleport.js if it detects the appropriate userData this.sit = function () { this.sitDown(); } @@ -207,7 +211,36 @@ var properties = Entities.getEntityProperties(this.entityID); var avatarDistance = Vec3.distance(MyAvatar.position, properties.position); var ikError = MyAvatar.getIKErrorOnLastSolve(); - if (avatarDistance > RELEASE_DISTANCE || ikError > MAX_IK_ERROR) { + var now = Date.now(); + var shouldStandUp = false; + + // Check if a drive key is pressed + var hasActiveDriveKey = false; + for (var i in OVERRIDEN_DRIVE_KEYS) { + if (MyAvatar.getRawDriveKey(OVERRIDEN_DRIVE_KEYS[i]) != 0.0) { + hasActiveDriveKey = true; + break; + } + } + + // Only standup if user has been pushing a drive key for RELEASE_TIME + if (hasActiveDriveKey) { + var elapsed = now - this.lastTimeNoDriveKeys; + shouldStandUp = elapsed > RELEASE_TIME; + } else { + this.lastTimeNoDriveKeys = Date.now(); + } + + // Allow some time for the IK to settle + if (ikError > MAX_IK_ERROR) { + var elapsed = now - this.sitDownTimestamp; + if (elapsed > IK_SETTLE_TIME) { + shouldStandUp = true; + } + } + + + if (shouldStandUp || avatarDistance > RELEASE_DISTANCE) { print("IK error: " + ikError + ", distance from chair: " + avatarDistance); // Move avatar in front of the chair to avoid getting stuck in collision hulls @@ -215,45 +248,13 @@ var offset = { x: 0, y: 1.0, z: -0.5 - properties.dimensions.z * properties.registrationPoint.z }; var position = Vec3.sum(properties.position, Vec3.multiplyQbyV(properties.rotation, offset)); MyAvatar.position = position; + print("Moving Avatar in front of the chair.") } - this.sitUp(); + this.standUp(); } } } - this.keyPressed = function(event) { - if (isInEditMode()) { - return; - } - - if (RELEASE_KEYS.indexOf(event.text) !== -1) { - var that = this; - this.timers[event.text] = Script.setTimeout(function() { - delete that.timers[event.text]; - - var properties = Entities.getEntityProperties(that.entityID); - var avatarDistance = Vec3.distance(MyAvatar.position, properties.position); - - // Move avatar in front of the chair to avoid getting stuck in collision hulls - if (avatarDistance < MAX_RESET_DISTANCE) { - var offset = { x: 0, y: 1.0, z: -0.5 - properties.dimensions.z * properties.registrationPoint.z }; - var position = Vec3.sum(properties.position, Vec3.multiplyQbyV(properties.rotation, offset)); - MyAvatar.position = position; - } - - that.sitUp(); - }, RELEASE_TIME); - } - } - this.keyReleased = function(event) { - if (RELEASE_KEYS.indexOf(event.text) !== -1) { - if (this.timers[event.text]) { - Script.clearTimeout(this.timers[event.text]); - delete this.timers[event.text]; - } - } - } - this.canSitDesktop = function() { var properties = Entities.getEntityProperties(this.entityID, ["position"]); var distanceFromSeat = Vec3.distance(MyAvatar.position, properties.position); From 3e9474e8784408673f2461886463facfe9c98026 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 16 Mar 2017 14:30:33 -0700 Subject: [PATCH 3/7] CR --- interface/src/avatar/MyAvatar.h | 14 ++++++-------- scripts/tutorials/entity_scripts/sit.js | 18 ++++++++---------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 731ba89299..14142726ea 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -89,8 +89,6 @@ class MyAvatar : public Avatar { Q_PROPERTY(bool hmdLeanRecenterEnabled READ getHMDLeanRecenterEnabled WRITE setHMDLeanRecenterEnabled) Q_PROPERTY(bool characterControllerEnabled READ getCharacterControllerEnabled WRITE setCharacterControllerEnabled) - Q_ENUMS(DriveKeys) - public: explicit MyAvatar(RigPointer rig); ~MyAvatar(); @@ -185,13 +183,13 @@ public: // Set what driving keys are being pressed to control thrust levels void clearDriveKeys(); void setDriveKey(int key, float val) { _driveKeys[key] = val; }; - float getDriveKey(int key) const { return isDriveKeyCaptured(key) ? 0.0f : _driveKeys[key]; }; + float getDriveKey(int key) const { return isDriveKeyDisabled(key) ? 0.0f : _driveKeys[key]; }; Q_INVOKABLE float getRawDriveKey(int key) const { return _driveKeys[key]; }; void relayDriveKeysToCharacterController(); - Q_INVOKABLE void captureDriveKey(int key) { _capturedDriveKeys.set(key); } - Q_INVOKABLE void releaseDriveKey(int key) { _capturedDriveKeys.reset(key); } - Q_INVOKABLE bool isDriveKeyCaptured(int key) const { return _capturedDriveKeys.test(key); } + Q_INVOKABLE void disableDriveKey(int key) { _disabledDriveKeys.set(key); } + Q_INVOKABLE void enableDriveKey(int key) { _disabledDriveKeys.reset(key); } + Q_INVOKABLE bool isDriveKeyDisabled(int key) const { return _disabledDriveKeys.test(key); } eyeContactTarget getEyeContactTarget(); @@ -397,8 +395,8 @@ private: void clampScaleChangeToDomainLimits(float desiredScale); glm::mat4 computeCameraRelativeHandControllerMatrix(const glm::mat4& controllerSensorMatrix) const; - std::array _driveKeys; - std::bitset _capturedDriveKeys; + float _driveKeys[MAX_DRIVE_KEYS]; + std::bitset _disabledDriveKeys; bool _wasPushing; bool _isPushing; diff --git a/scripts/tutorials/entity_scripts/sit.js b/scripts/tutorials/entity_scripts/sit.js index 42cf7685ad..5fff9877b0 100644 --- a/scripts/tutorials/entity_scripts/sit.js +++ b/scripts/tutorials/entity_scripts/sit.js @@ -19,7 +19,7 @@ this.entityID = null; this.animStateHandlerID = null; this.interval = null; - this.sitDownTimestamp = null; + this.sitDownSettlePeriod = null; this.lastTimeNoDriveKeys = null; this.preload = function(entityID) { @@ -100,8 +100,9 @@ } print("Sitting down (" + this.entityID + ")"); - this.sitDownTimestamp = Date.now(); - this.lastTimeNoDriveKeys = this.sitDownTimestamp; + var now = Date.now(); + this.sitDownSettlePeriod = now + IK_SETTLE_TIME; + this.lastTimeNoDriveKeys = now; var previousValue = Settings.getValue(SETTING_KEY); Settings.setValue(SETTING_KEY, this.entityID); @@ -125,7 +126,7 @@ }, ["headType"]); Script.update.connect(this, this.update); for (var i in OVERRIDEN_DRIVE_KEYS) { - MyAvatar.captureDriveKey(OVERRIDEN_DRIVE_KEYS[i]); + MyAvatar.disableDriveKey(OVERRIDEN_DRIVE_KEYS[i]); } } @@ -134,7 +135,7 @@ MyAvatar.removeAnimationStateHandler(this.animStateHandlerID); Script.update.disconnect(this, this.update); for (var i in OVERRIDEN_DRIVE_KEYS) { - MyAvatar.releaseDriveKey(OVERRIDEN_DRIVE_KEYS[i]); + MyAvatar.enableDriveKey(OVERRIDEN_DRIVE_KEYS[i]); } this.setSeatUser(null); @@ -232,11 +233,8 @@ } // Allow some time for the IK to settle - if (ikError > MAX_IK_ERROR) { - var elapsed = now - this.sitDownTimestamp; - if (elapsed > IK_SETTLE_TIME) { - shouldStandUp = true; - } + if (ikError > MAX_IK_ERROR && now > this.sitDownSettlePeriod) { + shouldStandUp = true; } From 42316e713d9330e33d6cf3da4d08d3264cad442a Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 16 Mar 2017 16:24:52 -0700 Subject: [PATCH 4/7] CR drive keys --- interface/src/avatar/MyAvatar.cpp | 68 ++++++++++++++++++++++++- interface/src/avatar/MyAvatar.h | 16 +++--- scripts/tutorials/entity_scripts/sit.js | 8 +-- 3 files changed, 77 insertions(+), 15 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index c38d1ed607..cc40c8eab2 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -2091,8 +2091,27 @@ bool MyAvatar::getCharacterControllerEnabled() { } void MyAvatar::clearDriveKeys() { - for (int i = 0; i < MAX_DRIVE_KEYS; ++i) { - setDriveKey(i, 0.0f); + _driveKeys.fill(0.0f); +} + +void MyAvatar::setDriveKey(int key, float val) { + try { + _driveKeys.at(key) = val; + } catch (const std::exception& exception) { + qCCritical(interfaceapp) << Q_FUNC_INFO << ": Index out of bounds"; + } +} + +float MyAvatar::getDriveKey(int key) const { + return isDriveKeyDisabled(key) ? 0.0f : getRawDriveKey(key); +} + +float MyAvatar::getRawDriveKey(int key) const { + try { + return _driveKeys.at(key); + } catch (const std::exception& exception) { + qCCritical(interfaceapp) << Q_FUNC_INFO << ": Index out of bounds"; + return 0.0f; } } @@ -2102,6 +2121,51 @@ void MyAvatar::relayDriveKeysToCharacterController() { } } +void MyAvatar::disableDriveKey(int key) { + try { + _disabledDriveKeys.set(key); + } catch (const std::exception& exception) { + qCCritical(interfaceapp) << Q_FUNC_INFO << ": Index out of bounds"; + } +} + +void MyAvatar::enableDriveKey(int key) { + try { + _disabledDriveKeys.reset(key); + } catch (const std::exception& exception) { + qCCritical(interfaceapp) << Q_FUNC_INFO << ": Index out of bounds"; + } +} + +void MyAvatar::disableDriveKeys(std::vector key) { + try { + std::for_each(std::begin(key), std::end(key), [&](int val){ + _disabledDriveKeys.set(val); + }); + } catch (const std::exception& exception) { + qCCritical(interfaceapp) << Q_FUNC_INFO << ": Index out of bounds"; + } +} + +void MyAvatar::enableDriveKeys(std::vector key) { + try { + std::for_each(std::begin(key), std::end(key), [&](int val) { + _disabledDriveKeys.reset(val); + }); + } catch (const std::exception& exception) { + qCCritical(interfaceapp) << Q_FUNC_INFO << ": Index out of bounds"; + } +} + +bool MyAvatar::isDriveKeyDisabled(int key) const { + try { + return _disabledDriveKeys.test(key); + } catch (const std::exception& exception) { + qCCritical(interfaceapp) << Q_FUNC_INFO << ": Index out of bounds"; + return false; + } +} + glm::vec3 MyAvatar::getWorldBodyPosition() const { return transformPoint(_sensorToWorldMatrix, extractTranslation(_bodySensorMatrix)); } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 14142726ea..cae445c226 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -182,14 +182,16 @@ public: // Set what driving keys are being pressed to control thrust levels void clearDriveKeys(); - void setDriveKey(int key, float val) { _driveKeys[key] = val; }; - float getDriveKey(int key) const { return isDriveKeyDisabled(key) ? 0.0f : _driveKeys[key]; }; - Q_INVOKABLE float getRawDriveKey(int key) const { return _driveKeys[key]; }; + void setDriveKey(int key, float val); + float getDriveKey(int key) const; + Q_INVOKABLE float getRawDriveKey(int key) const; void relayDriveKeysToCharacterController(); - Q_INVOKABLE void disableDriveKey(int key) { _disabledDriveKeys.set(key); } - Q_INVOKABLE void enableDriveKey(int key) { _disabledDriveKeys.reset(key); } - Q_INVOKABLE bool isDriveKeyDisabled(int key) const { return _disabledDriveKeys.test(key); } + Q_INVOKABLE void disableDriveKey(int key); + Q_INVOKABLE void enableDriveKey(int key); + Q_INVOKABLE void disableDriveKeys(std::vector key); + Q_INVOKABLE void enableDriveKeys(std::vector key); + Q_INVOKABLE bool isDriveKeyDisabled(int key) const; eyeContactTarget getEyeContactTarget(); @@ -395,7 +397,7 @@ private: void clampScaleChangeToDomainLimits(float desiredScale); glm::mat4 computeCameraRelativeHandControllerMatrix(const glm::mat4& controllerSensorMatrix) const; - float _driveKeys[MAX_DRIVE_KEYS]; + std::array _driveKeys; std::bitset _disabledDriveKeys; bool _wasPushing; diff --git a/scripts/tutorials/entity_scripts/sit.js b/scripts/tutorials/entity_scripts/sit.js index 5fff9877b0..420a77e2b8 100644 --- a/scripts/tutorials/entity_scripts/sit.js +++ b/scripts/tutorials/entity_scripts/sit.js @@ -125,18 +125,14 @@ return { headType: 0 }; }, ["headType"]); Script.update.connect(this, this.update); - for (var i in OVERRIDEN_DRIVE_KEYS) { - MyAvatar.disableDriveKey(OVERRIDEN_DRIVE_KEYS[i]); - } + MyAvatar.disableDriveKey(OVERRIDEN_DRIVE_KEYS); } this.standUp = function() { print("Standing up (" + this.entityID + ")"); MyAvatar.removeAnimationStateHandler(this.animStateHandlerID); Script.update.disconnect(this, this.update); - for (var i in OVERRIDEN_DRIVE_KEYS) { - MyAvatar.enableDriveKey(OVERRIDEN_DRIVE_KEYS[i]); - } + MyAvatar.enableDriveKey(OVERRIDEN_DRIVE_KEYS); this.setSeatUser(null); if (Settings.getValue(SETTING_KEY) === this.entityID) { From 9155cc63345fc205200cffffe4db72912a79650d Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 16 Mar 2017 17:44:56 -0700 Subject: [PATCH 5/7] Fix windows warnings --- interface/src/avatar/MyAvatar.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index cc40c8eab2..eb77779691 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -2097,7 +2097,7 @@ void MyAvatar::clearDriveKeys() { void MyAvatar::setDriveKey(int key, float val) { try { _driveKeys.at(key) = val; - } catch (const std::exception& exception) { + } catch (const std::exception&) { qCCritical(interfaceapp) << Q_FUNC_INFO << ": Index out of bounds"; } } @@ -2109,7 +2109,7 @@ float MyAvatar::getDriveKey(int key) const { float MyAvatar::getRawDriveKey(int key) const { try { return _driveKeys.at(key); - } catch (const std::exception& exception) { + } catch (const std::exception&) { qCCritical(interfaceapp) << Q_FUNC_INFO << ": Index out of bounds"; return 0.0f; } @@ -2124,7 +2124,7 @@ void MyAvatar::relayDriveKeysToCharacterController() { void MyAvatar::disableDriveKey(int key) { try { _disabledDriveKeys.set(key); - } catch (const std::exception& exception) { + } catch (const std::exception&) { qCCritical(interfaceapp) << Q_FUNC_INFO << ": Index out of bounds"; } } @@ -2132,7 +2132,7 @@ void MyAvatar::disableDriveKey(int key) { void MyAvatar::enableDriveKey(int key) { try { _disabledDriveKeys.reset(key); - } catch (const std::exception& exception) { + } catch (const std::exception&) { qCCritical(interfaceapp) << Q_FUNC_INFO << ": Index out of bounds"; } } @@ -2142,7 +2142,7 @@ void MyAvatar::disableDriveKeys(std::vector key) { std::for_each(std::begin(key), std::end(key), [&](int val){ _disabledDriveKeys.set(val); }); - } catch (const std::exception& exception) { + } catch (const std::exception&) { qCCritical(interfaceapp) << Q_FUNC_INFO << ": Index out of bounds"; } } @@ -2152,7 +2152,7 @@ void MyAvatar::enableDriveKeys(std::vector key) { std::for_each(std::begin(key), std::end(key), [&](int val) { _disabledDriveKeys.reset(val); }); - } catch (const std::exception& exception) { + } catch (const std::exception&) { qCCritical(interfaceapp) << Q_FUNC_INFO << ": Index out of bounds"; } } @@ -2160,7 +2160,7 @@ void MyAvatar::enableDriveKeys(std::vector key) { bool MyAvatar::isDriveKeyDisabled(int key) const { try { return _disabledDriveKeys.test(key); - } catch (const std::exception& exception) { + } catch (const std::exception&) { qCCritical(interfaceapp) << Q_FUNC_INFO << ": Index out of bounds"; return false; } From 5a1ce4bb05292c80d0453486ff5ba17c563ca40b Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 16 Mar 2017 17:46:47 -0700 Subject: [PATCH 6/7] CR --- interface/src/avatar/MyAvatar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index eb77779691..7b478b3726 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -2162,7 +2162,7 @@ bool MyAvatar::isDriveKeyDisabled(int key) const { return _disabledDriveKeys.test(key); } catch (const std::exception&) { qCCritical(interfaceapp) << Q_FUNC_INFO << ": Index out of bounds"; - return false; + return true; } } From 698791295a6f2b60893619f1555a498084759e45 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 16 Mar 2017 18:37:58 -0700 Subject: [PATCH 7/7] Expose DriveKeys enum to JS --- interface/src/Application.cpp | 17 ++++--- interface/src/avatar/MyAvatar.cpp | 59 +++++++++++++------------ interface/src/avatar/MyAvatar.h | 48 +++++++++++--------- scripts/tutorials/entity_scripts/sit.js | 17 +++++-- 4 files changed, 79 insertions(+), 62 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index df9d10caa6..8cd5a9564a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4383,16 +4383,16 @@ void Application::update(float deltaTime) { myAvatar->clearDriveKeys(); if (_myCamera.getMode() != CAMERA_MODE_INDEPENDENT) { if (!_controllerScriptingInterface->areActionsCaptured()) { - myAvatar->setDriveKey(TRANSLATE_Z, -1.0f * userInputMapper->getActionState(controller::Action::TRANSLATE_Z)); - myAvatar->setDriveKey(TRANSLATE_Y, userInputMapper->getActionState(controller::Action::TRANSLATE_Y)); - myAvatar->setDriveKey(TRANSLATE_X, userInputMapper->getActionState(controller::Action::TRANSLATE_X)); + myAvatar->setDriveKey(MyAvatar::TRANSLATE_Z, -1.0f * userInputMapper->getActionState(controller::Action::TRANSLATE_Z)); + myAvatar->setDriveKey(MyAvatar::TRANSLATE_Y, userInputMapper->getActionState(controller::Action::TRANSLATE_Y)); + myAvatar->setDriveKey(MyAvatar::TRANSLATE_X, userInputMapper->getActionState(controller::Action::TRANSLATE_X)); if (deltaTime > FLT_EPSILON) { - myAvatar->setDriveKey(PITCH, -1.0f * userInputMapper->getActionState(controller::Action::PITCH)); - myAvatar->setDriveKey(YAW, -1.0f * userInputMapper->getActionState(controller::Action::YAW)); - myAvatar->setDriveKey(STEP_YAW, -1.0f * userInputMapper->getActionState(controller::Action::STEP_YAW)); + myAvatar->setDriveKey(MyAvatar::PITCH, -1.0f * userInputMapper->getActionState(controller::Action::PITCH)); + myAvatar->setDriveKey(MyAvatar::YAW, -1.0f * userInputMapper->getActionState(controller::Action::YAW)); + myAvatar->setDriveKey(MyAvatar::STEP_YAW, -1.0f * userInputMapper->getActionState(controller::Action::STEP_YAW)); } } - myAvatar->setDriveKey(ZOOM, userInputMapper->getActionState(controller::Action::TRANSLATE_CAMERA_Z)); + myAvatar->setDriveKey(MyAvatar::ZOOM, userInputMapper->getActionState(controller::Action::TRANSLATE_CAMERA_Z)); } controller::Pose leftHandPose = userInputMapper->getPoseState(controller::Action::LEFT_HAND); @@ -5503,8 +5503,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri scriptEngine->registerGlobalObject("Rates", new RatesScriptingInterface(this)); // hook our avatar and avatar hash map object into this script engine - scriptEngine->registerGlobalObject("MyAvatar", getMyAvatar().get()); - qScriptRegisterMetaType(scriptEngine, audioListenModeToScriptValue, audioListenModeFromScriptValue); + getMyAvatar()->registerMetaTypes(scriptEngine); scriptEngine->registerGlobalObject("AvatarList", DependencyManager::get().data()); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 7b478b3726..401378fff1 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -228,6 +228,21 @@ MyAvatar::~MyAvatar() { _lookAtTargetAvatar.reset(); } +void MyAvatar::registerMetaTypes(QScriptEngine* engine) { + QScriptValue value = engine->newQObject(this, QScriptEngine::QtOwnership, QScriptEngine::ExcludeDeleteLater | QScriptEngine::ExcludeChildObjects); + engine->globalObject().setProperty("MyAvatar", value); + + QScriptValue driveKeys = engine->newObject(); + auto metaEnum = QMetaEnum::fromType(); + for (int i = 0; i < MAX_DRIVE_KEYS; ++i) { + driveKeys.setProperty(metaEnum.key(i), metaEnum.value(i)); + } + engine->globalObject().setProperty("DriveKeys", driveKeys); + + qScriptRegisterMetaType(engine, audioListenModeToScriptValue, audioListenModeFromScriptValue); + qScriptRegisterMetaType(engine, driveKeysToScriptValue, driveKeysFromScriptValue); +} + void MyAvatar::setOrientationVar(const QVariant& newOrientationVar) { Avatar::setOrientation(quatFromVariant(newOrientationVar)); } @@ -460,7 +475,7 @@ void MyAvatar::simulate(float deltaTime) { // When there are no step values, we zero out the last step pulse. // This allows a user to do faster snapping by tapping a control for (int i = STEP_TRANSLATE_X; !stepAction && i <= STEP_YAW; ++i) { - if (getDriveKey(i) != 0.0f) { + if (getDriveKey((DriveKeys)i) != 0.0f) { stepAction = true; } } @@ -2094,7 +2109,7 @@ void MyAvatar::clearDriveKeys() { _driveKeys.fill(0.0f); } -void MyAvatar::setDriveKey(int key, float val) { +void MyAvatar::setDriveKey(DriveKeys key, float val) { try { _driveKeys.at(key) = val; } catch (const std::exception&) { @@ -2102,11 +2117,11 @@ void MyAvatar::setDriveKey(int key, float val) { } } -float MyAvatar::getDriveKey(int key) const { +float MyAvatar::getDriveKey(DriveKeys key) const { return isDriveKeyDisabled(key) ? 0.0f : getRawDriveKey(key); } -float MyAvatar::getRawDriveKey(int key) const { +float MyAvatar::getRawDriveKey(DriveKeys key) const { try { return _driveKeys.at(key); } catch (const std::exception&) { @@ -2121,7 +2136,7 @@ void MyAvatar::relayDriveKeysToCharacterController() { } } -void MyAvatar::disableDriveKey(int key) { +void MyAvatar::disableDriveKey(DriveKeys key) { try { _disabledDriveKeys.set(key); } catch (const std::exception&) { @@ -2129,7 +2144,7 @@ void MyAvatar::disableDriveKey(int key) { } } -void MyAvatar::enableDriveKey(int key) { +void MyAvatar::enableDriveKey(DriveKeys key) { try { _disabledDriveKeys.reset(key); } catch (const std::exception&) { @@ -2137,27 +2152,7 @@ void MyAvatar::enableDriveKey(int key) { } } -void MyAvatar::disableDriveKeys(std::vector key) { - try { - std::for_each(std::begin(key), std::end(key), [&](int val){ - _disabledDriveKeys.set(val); - }); - } catch (const std::exception&) { - qCCritical(interfaceapp) << Q_FUNC_INFO << ": Index out of bounds"; - } -} - -void MyAvatar::enableDriveKeys(std::vector key) { - try { - std::for_each(std::begin(key), std::end(key), [&](int val) { - _disabledDriveKeys.reset(val); - }); - } catch (const std::exception&) { - qCCritical(interfaceapp) << Q_FUNC_INFO << ": Index out of bounds"; - } -} - -bool MyAvatar::isDriveKeyDisabled(int key) const { +bool MyAvatar::isDriveKeyDisabled(DriveKeys key) const { try { return _disabledDriveKeys.test(key); } catch (const std::exception&) { @@ -2251,7 +2246,15 @@ QScriptValue audioListenModeToScriptValue(QScriptEngine* engine, const AudioList } void audioListenModeFromScriptValue(const QScriptValue& object, AudioListenerMode& audioListenerMode) { - audioListenerMode = (AudioListenerMode)object.toUInt16(); + audioListenerMode = static_cast(object.toUInt16()); +} + +QScriptValue driveKeysToScriptValue(QScriptEngine* engine, const MyAvatar::DriveKeys& driveKeys) { + return driveKeys; +} + +void driveKeysFromScriptValue(const QScriptValue& object, MyAvatar::DriveKeys& driveKeys) { + driveKeys = static_cast(object.toUInt16()); } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index cae445c226..9bcec1134f 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -31,20 +31,6 @@ class AvatarActionHold; class ModelItemID; -enum DriveKeys { - TRANSLATE_X = 0, - TRANSLATE_Y, - TRANSLATE_Z, - YAW, - STEP_TRANSLATE_X, - STEP_TRANSLATE_Y, - STEP_TRANSLATE_Z, - STEP_YAW, - PITCH, - ZOOM, - MAX_DRIVE_KEYS -}; - enum eyeContactTarget { LEFT_EYE, RIGHT_EYE, @@ -90,9 +76,26 @@ class MyAvatar : public Avatar { Q_PROPERTY(bool characterControllerEnabled READ getCharacterControllerEnabled WRITE setCharacterControllerEnabled) public: + enum DriveKeys { + TRANSLATE_X = 0, + TRANSLATE_Y, + TRANSLATE_Z, + YAW, + STEP_TRANSLATE_X, + STEP_TRANSLATE_Y, + STEP_TRANSLATE_Z, + STEP_YAW, + PITCH, + ZOOM, + MAX_DRIVE_KEYS + }; + Q_ENUM(DriveKeys) + explicit MyAvatar(RigPointer rig); ~MyAvatar(); + void registerMetaTypes(QScriptEngine* engine); + virtual void simulateAttachments(float deltaTime) override; AudioListenerMode getAudioListenerModeHead() const { return FROM_HEAD; } @@ -182,16 +185,14 @@ public: // Set what driving keys are being pressed to control thrust levels void clearDriveKeys(); - void setDriveKey(int key, float val); - float getDriveKey(int key) const; - Q_INVOKABLE float getRawDriveKey(int key) const; + void setDriveKey(DriveKeys key, float val); + float getDriveKey(DriveKeys key) const; + Q_INVOKABLE float getRawDriveKey(DriveKeys key) const; void relayDriveKeysToCharacterController(); - Q_INVOKABLE void disableDriveKey(int key); - Q_INVOKABLE void enableDriveKey(int key); - Q_INVOKABLE void disableDriveKeys(std::vector key); - Q_INVOKABLE void enableDriveKeys(std::vector key); - Q_INVOKABLE bool isDriveKeyDisabled(int key) const; + Q_INVOKABLE void disableDriveKey(DriveKeys key); + Q_INVOKABLE void enableDriveKey(DriveKeys key); + Q_INVOKABLE bool isDriveKeyDisabled(DriveKeys key) const; eyeContactTarget getEyeContactTarget(); @@ -552,4 +553,7 @@ private: QScriptValue audioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode); void audioListenModeFromScriptValue(const QScriptValue& object, AudioListenerMode& audioListenerMode); +QScriptValue driveKeysToScriptValue(QScriptEngine* engine, const MyAvatar::DriveKeys& driveKeys); +void driveKeysFromScriptValue(const QScriptValue& object, MyAvatar::DriveKeys& driveKeys); + #endif // hifi_MyAvatar_h diff --git a/scripts/tutorials/entity_scripts/sit.js b/scripts/tutorials/entity_scripts/sit.js index 420a77e2b8..82afdc8974 100644 --- a/scripts/tutorials/entity_scripts/sit.js +++ b/scripts/tutorials/entity_scripts/sit.js @@ -14,7 +14,14 @@ var DESKTOP_MAX_DISTANCE = 5; var SIT_DELAY = 25; var MAX_RESET_DISTANCE = 0.5; // meters - var OVERRIDEN_DRIVE_KEYS = [0, 1, 2, 4, 5, 6]; + var OVERRIDEN_DRIVE_KEYS = [ + DriveKeys.TRANSLATE_X, + DriveKeys.TRANSLATE_Y, + DriveKeys.TRANSLATE_Z, + DriveKeys.STEP_TRANSLATE_X, + DriveKeys.STEP_TRANSLATE_Y, + DriveKeys.STEP_TRANSLATE_Z, + ]; this.entityID = null; this.animStateHandlerID = null; @@ -125,14 +132,18 @@ return { headType: 0 }; }, ["headType"]); Script.update.connect(this, this.update); - MyAvatar.disableDriveKey(OVERRIDEN_DRIVE_KEYS); + for (var i in OVERRIDEN_DRIVE_KEYS) { + MyAvatar.disableDriveKey(OVERRIDEN_DRIVE_KEYS[i]); + } } this.standUp = function() { print("Standing up (" + this.entityID + ")"); MyAvatar.removeAnimationStateHandler(this.animStateHandlerID); Script.update.disconnect(this, this.update); - MyAvatar.enableDriveKey(OVERRIDEN_DRIVE_KEYS); + for (var i in OVERRIDEN_DRIVE_KEYS) { + MyAvatar.enableDriveKey(OVERRIDEN_DRIVE_KEYS[i]); + } this.setSeatUser(null); if (Settings.getValue(SETTING_KEY) === this.entityID) {