From 08b525ef91e3301069cc414085bc2a1e2435311b Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 22 May 2014 17:54:32 -0700 Subject: [PATCH 1/5] prevent walking avatar from bouncing on floor --- interface/src/avatar/MyAvatar.cpp | 113 ++++++++++++++++++------------ interface/src/avatar/MyAvatar.h | 2 +- 2 files changed, 71 insertions(+), 44 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 85c1734e56..6a4ababa25 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -134,45 +134,7 @@ void MyAvatar::simulate(float deltaTime) { _handState = HAND_STATE_NULL; updateOrientation(deltaTime); - - float keyboardInput = fabsf(_driveKeys[FWD] - _driveKeys[BACK]) + - fabsf(_driveKeys[RIGHT] - _driveKeys[LEFT]) + - fabsf(_driveKeys[UP] - _driveKeys[DOWN]); - - bool walkingOnFloor = false; - float gravityLength = glm::length(_gravity); - if (gravityLength > EPSILON) { - const CapsuleShape& boundingShape = _skeletonModel.getBoundingShape(); - glm::vec3 startCap; - boundingShape.getStartPoint(startCap); - glm::vec3 bottomOfBoundingCapsule = startCap + (boundingShape.getRadius() / gravityLength) * _gravity; - - float fallThreshold = 2.0f * deltaTime * gravityLength; - walkingOnFloor = (glm::distance(bottomOfBoundingCapsule, _lastFloorContactPoint) < fallThreshold); - } - - if (keyboardInput > 0.0f || glm::length2(_velocity) > 0.0f || glm::length2(_thrust) > 0.0f || - ! walkingOnFloor) { - // apply gravity - _velocity += _scale * _gravity * (GRAVITY_EARTH * deltaTime); - - // update motor and thrust - updateMotorFromKeyboard(deltaTime, walkingOnFloor); - applyMotor(deltaTime); - applyThrust(deltaTime); - - // update position - if (glm::length2(_velocity) < EPSILON) { - _velocity = glm::vec3(0.0f); - } else { - _position += _velocity * deltaTime; - } - } - - // update moving flag based on speed - const float MOVING_SPEED_THRESHOLD = 0.01f; - _moving = glm::length(_velocity) > MOVING_SPEED_THRESHOLD; - updateChatCircle(deltaTime); + updatePosition(deltaTime); // update avatar skeleton and simulate hand and head getHand()->collideAgainstOurself(); @@ -833,8 +795,7 @@ void MyAvatar::updateOrientation(float deltaTime) { // We must adjust the body orientation using a delta rotation (rather than // doing yaw math) because the body's yaw ranges are not the same // as what the Oculus API provides. - glm::vec3 UP_AXIS = glm::vec3(0.0f, 1.0f, 0.0f); - glm::quat bodyCorrection = glm::angleAxis(glm::radians(delta), UP_AXIS); + glm::quat bodyCorrection = glm::angleAxis(glm::radians(delta), _worldUpDirection); orientation = orientation * bodyCorrection; } Head* head = getHead(); @@ -848,6 +809,62 @@ void MyAvatar::updateOrientation(float deltaTime) { setOrientation(orientation); } +void MyAvatar::updatePosition(float deltaTime) { + float keyboardInput = fabsf(_driveKeys[FWD] - _driveKeys[BACK]) + + fabsf(_driveKeys[RIGHT] - _driveKeys[LEFT]) + + fabsf(_driveKeys[UP] - _driveKeys[DOWN]); + + bool walkingOnFloor = false; + float gravityLength = glm::length(_gravity) * GRAVITY_EARTH; + if (gravityLength > EPSILON) { + const CapsuleShape& boundingShape = _skeletonModel.getBoundingShape(); + glm::vec3 startCap; + boundingShape.getStartPoint(startCap); + glm::vec3 bottomOfBoundingCapsule = startCap - boundingShape.getRadius() * _worldUpDirection; + + float speedFromGravity = _scale * deltaTime * gravityLength; + float distanceToFall = glm::distance(bottomOfBoundingCapsule, _lastFloorContactPoint); + walkingOnFloor = (distanceToFall < 2.0f * deltaTime * speedFromGravity); + + if (walkingOnFloor) { + // BEGIN HACK: to prevent the avatar from bouncing on a floor surface + if (distanceToFall < deltaTime * speedFromGravity) { + float verticalSpeed = glm::dot(_velocity, _worldUpDirection); + if (fabs(verticalSpeed) < speedFromGravity) { + // we're standing on a floor, and nearly at rest so we zero the vertical velocity component + _velocity -= verticalSpeed * _worldUpDirection; + } + } else { + // fall with gravity against floor + _velocity -= speedFromGravity * _worldUpDirection; + } + // END HACK + } else { + _velocity -= speedFromGravity * _worldUpDirection; + } + } + + if (keyboardInput > 0.0f || glm::length2(_velocity) > 0.0f || glm::length2(_thrust) > 0.0f || ! walkingOnFloor) { + // update motor and thrust + updateMotorFromKeyboard(deltaTime, walkingOnFloor); + applyMotor(deltaTime); + applyThrust(deltaTime); + + // update position + if (glm::length2(_velocity) < EPSILON) { + _velocity = glm::vec3(0.0f); + } else { + _position += _velocity * deltaTime; + } + } + + // update moving flag based on speed + const float MOVING_SPEED_THRESHOLD = 0.01f; + _moving = glm::length(_velocity) > MOVING_SPEED_THRESHOLD; + + updateChatCircle(deltaTime); +} + void MyAvatar::updateMotorFromKeyboard(float deltaTime, bool walking) { // Increase motor velocity until its length is equal to _maxMotorSpeed. if (!(_motionBehaviors & AVATAR_MOTION_MOTOR_KEYBOARD_ENABLED)) { @@ -1121,6 +1138,8 @@ void MyAvatar::updateCollisionWithVoxels(float deltaTime, float radius) { const float MIN_STEP_HEIGHT = 0.0f; glm::vec3 footBase = boundingShape.getPosition() - (capsuleRadius + capsuleHalfHeight) * _worldUpDirection; float highestStep = 0.0f; + float lowestStep = MAX_STEP_HEIGHT; + glm::vec3 floorPoint; glm::vec3 stepPenetration(0.0f); glm::vec3 totalPenetration(0.0f); @@ -1154,8 +1173,15 @@ void MyAvatar::updateCollisionWithVoxels(float deltaTime, float radius) { highestStep = stepHeight; stepPenetration = collision->_penetration; } + if (stepHeight < lowestStep) { + lowestStep = stepHeight; + floorPoint = collision->_contactPoint - collision->_penetration; + } } } + if (lowestStep < MAX_STEP_HEIGHT) { + _lastFloorContactPoint = floorPoint; + } float penetrationLength = glm::length(totalPenetration); if (penetrationLength < EPSILON) { @@ -1194,8 +1220,9 @@ void MyAvatar::updateCollisionWithVoxels(float deltaTime, float radius) { applyHardCollision(totalPenetration, VOXEL_ELASTICITY, VOXEL_DAMPING); } - const float VOXEL_COLLISION_FREQUENCY = 0.5f; - updateCollisionSound(myCollisions[0]->_penetration, deltaTime, VOXEL_COLLISION_FREQUENCY); + // Don't make a collision sound against voxlels by default -- too annoying when walking + //const float VOXEL_COLLISION_FREQUENCY = 0.5f; + //updateCollisionSound(myCollisions[0]->_penetration, deltaTime, VOXEL_COLLISION_FREQUENCY); } _trapDuration = isTrapped ? _trapDuration + deltaTime : 0.0f; } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 9d6f22264f..89606858e6 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -141,7 +141,6 @@ private: bool _shouldJump; float _driveKeys[MAX_DRIVE_KEYS]; glm::vec3 _gravity; - glm::vec3 _environmentGravity; float _distanceToNearestAvatar; // How close is the nearest avatar? bool _wasPushing; @@ -166,6 +165,7 @@ private: // private methods void updateOrientation(float deltaTime); + void updatePosition(float deltaTime); void updateMotorFromKeyboard(float deltaTime, bool walking); float computeMotorTimescale(); void applyMotor(float deltaTime); From b875144e2d4cb68581a75b02c1d39e2b06e2cd21 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 23 May 2014 09:55:45 -0700 Subject: [PATCH 2/5] Don't repeat check for non-zero collision groups --- interface/src/avatar/MyAvatar.cpp | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 6a4ababa25..43f577d878 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -168,19 +168,17 @@ void MyAvatar::simulate(float deltaTime) { radius = myCamera->getAspectRatio() * (myCamera->getNearClip() / cos(myCamera->getFieldOfView() / 2.0f)); radius *= COLLISION_RADIUS_SCALAR; } - if (_collisionGroups) { - updateShapePositions(); - if (_collisionGroups & COLLISION_GROUP_ENVIRONMENT) { - updateCollisionWithEnvironment(deltaTime, radius); - } - if (_collisionGroups & COLLISION_GROUP_VOXELS) { - updateCollisionWithVoxels(deltaTime, radius); - } else { - _trapDuration = 0.0f; - } - if (_collisionGroups & COLLISION_GROUP_AVATARS) { - updateCollisionWithAvatars(deltaTime); - } + updateShapePositions(); + if (_collisionGroups & COLLISION_GROUP_ENVIRONMENT) { + updateCollisionWithEnvironment(deltaTime, radius); + } + if (_collisionGroups & COLLISION_GROUP_VOXELS) { + updateCollisionWithVoxels(deltaTime, radius); + } else { + _trapDuration = 0.0f; + } + if (_collisionGroups & COLLISION_GROUP_AVATARS) { + updateCollisionWithAvatars(deltaTime); } } From be9aac08ee5635b7e58728756ff127ff049e11d1 Mon Sep 17 00:00:00 2001 From: Stojce Slavkovski Date: Fri, 23 May 2014 20:49:48 +0200 Subject: [PATCH 3/5] add `disabled` state to Share button on click --- interface/src/ui/SnapshotShareDialog.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/interface/src/ui/SnapshotShareDialog.cpp b/interface/src/ui/SnapshotShareDialog.cpp index b5694b3e48..617d5e7101 100644 --- a/interface/src/ui/SnapshotShareDialog.cpp +++ b/interface/src/ui/SnapshotShareDialog.cpp @@ -31,6 +31,10 @@ const QString FORUM_REPLY_TO_TOPIC = "244"; const QString FORUM_POST_TEMPLATE = "

%2

"; const QString SHARE_DEFAULT_ERROR = "The server isn't responding. Please try again in a few minutes."; const QString SUCCESS_LABEL_TEMPLATE = "Success!!! Go check out your image ...
%1"; +const QString SHARE_BUTTON_STYLE = "border-width:0;border-radius:9px;border-radius:9px;font-family:Arial;font-size:18px;" + "font-weight:100;color:#FFFFFF;width: 120px;height: 50px;"; +const QString SHARE_BUTTON_ENABLED_STYLE = "background-color: #333;"; +const QString SHARE_BUTTON_DISABLED_STYLE = "background-color: #999;"; Q_DECLARE_METATYPE(QNetworkAccessManager::Operation) @@ -73,6 +77,10 @@ SnapshotShareDialog::SnapshotShareDialog(QString fileName, QWidget* parent) : } void SnapshotShareDialog::accept() { + // prevent multiple clicks on share button + _ui.shareButton->setEnabled(false); + // gray out share button + _ui.shareButton->setStyleSheet(SHARE_BUTTON_STYLE + SHARE_BUTTON_DISABLED_STYLE); uploadSnapshot(); } @@ -179,6 +187,8 @@ void SnapshotShareDialog::postRequestFinished() { } } QMessageBox::warning(this, "", errorMessage); + _ui.shareButton->setEnabled(true); + _ui.shareButton->setStyleSheet(SHARE_BUTTON_STYLE + SHARE_BUTTON_ENABLED_STYLE); } } @@ -192,6 +202,8 @@ void SnapshotShareDialog::uploadRequestFinished() { sendForumPost(responseObject["url"].toString()); } else { QMessageBox::warning(this, "", SHARE_DEFAULT_ERROR); + _ui.shareButton->setEnabled(true); + _ui.shareButton->setStyleSheet(SHARE_BUTTON_STYLE + SHARE_BUTTON_ENABLED_STYLE); } delete requestReply; From d425b5b322bbc5140652606394d66e472fc220ea Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 23 May 2014 15:59:27 -0700 Subject: [PATCH 4/5] Enable local gravity when there is a floor nearby. --- interface/src/Menu.cpp | 3 +- interface/src/Menu.h | 1 + interface/src/avatar/MyAvatar.cpp | 63 ++++++++++++++++++++++++------ libraries/avatars/src/AvatarData.h | 20 ++++++---- 4 files changed, 67 insertions(+), 20 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 96bfa106f4..856e1efae7 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -200,7 +200,8 @@ Menu::Menu() : QObject* avatar = appInstance->getAvatar(); addCheckableActionToQMenuAndActionHash(editMenu, MenuOption::ObeyEnvironmentalGravity, Qt::SHIFT | Qt::Key_G, false, avatar, SLOT(updateMotionBehaviorsFromMenu())); - + addCheckableActionToQMenuAndActionHash(editMenu, MenuOption::StandOnNearbyFloors, 0, true, + avatar, SLOT(updateMotionBehaviorsFromMenu())); addAvatarCollisionSubMenu(editMenu); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index b12f989ed6..279d2151c9 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -376,6 +376,7 @@ namespace MenuOption { const QString ShowBordersModelNodes = "Show Model Nodes"; const QString ShowBordersParticleNodes = "Show Particle Nodes"; const QString ShowIKConstraints = "Show IK Constraints"; + const QString StandOnNearbyFloors = "Stand on nearby floors"; const QString Stars = "Stars"; const QString Stats = "Stats"; const QString StopAllScripts = "Stop All Scripts"; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 43f577d878..79c721e896 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -383,9 +383,9 @@ void MyAvatar::setGravity(const glm::vec3& gravity) { float gravityLength = glm::length(gravity); if (gravityLength > EPSILON) { _worldUpDirection = _gravity / -gravityLength; - } else { - _worldUpDirection = DEFAULT_UP_DIRECTION; } + // NOTE: the else case here it to leave _worldUpDirection unchanged + // so it continues to point opposite to the previous gravity setting. } AnimationHandlePointer MyAvatar::addAnimationHandle() { @@ -814,12 +814,13 @@ void MyAvatar::updatePosition(float deltaTime) { bool walkingOnFloor = false; float gravityLength = glm::length(_gravity) * GRAVITY_EARTH; - if (gravityLength > EPSILON) { - const CapsuleShape& boundingShape = _skeletonModel.getBoundingShape(); - glm::vec3 startCap; - boundingShape.getStartPoint(startCap); - glm::vec3 bottomOfBoundingCapsule = startCap - boundingShape.getRadius() * _worldUpDirection; + const CapsuleShape& boundingShape = _skeletonModel.getBoundingShape(); + glm::vec3 startCap; + boundingShape.getStartPoint(startCap); + glm::vec3 bottomOfBoundingCapsule = startCap - boundingShape.getRadius() * _worldUpDirection; + + if (gravityLength > EPSILON) { float speedFromGravity = _scale * deltaTime * gravityLength; float distanceToFall = glm::distance(bottomOfBoundingCapsule, _lastFloorContactPoint); walkingOnFloor = (distanceToFall < 2.0f * deltaTime * speedFromGravity); @@ -840,6 +841,32 @@ void MyAvatar::updatePosition(float deltaTime) { } else { _velocity -= speedFromGravity * _worldUpDirection; } + if (_motionBehaviors & AVATAR_MOTION_STAND_ON_NEARBY_FLOORS) { + const float MAX_VERTICAL_FLOOR_DETECTION_SPEED = _scale * MAX_WALKING_SPEED; + if (keyboardInput && glm::dot(_motorVelocity, _worldUpDirection) > 0.0f && + glm::dot(_velocity, _worldUpDirection) > MAX_VERTICAL_FLOOR_DETECTION_SPEED) { + // disable gravity because we're pushing with keyboard + setLocalGravity(glm::vec3(0.0f)); + } + } + } else { + if ((_collisionGroups & COLLISION_GROUP_VOXELS) && + _motionBehaviors & AVATAR_MOTION_STAND_ON_NEARBY_FLOORS) { + const float MIN_FLOOR_DETECTION_SPEED = _scale * 1.0f; + if (glm::length(_velocity) < MIN_FLOOR_DETECTION_SPEED ) { + // scan for floor + glm::vec3 direction = -_worldUpDirection; + OctreeElement* elementHit; // output from findRayIntersection + float distance; // output from findRayIntersection + BoxFace face; // output from findRayIntersection + Application::getInstance()->getVoxelTree()->findRayIntersection(bottomOfBoundingCapsule, direction, elementHit, distance, face); + const float NEARBY_FLOOR_THRESHOLD = _scale * 2.0f; + if (elementHit && distance < NEARBY_FLOOR_THRESHOLD) { + // turn on local gravity + setLocalGravity(-_worldUpDirection); + } + } + } } if (keyboardInput > 0.0f || glm::length2(_velocity) > 0.0f || glm::length2(_thrust) > 0.0f || ! walkingOnFloor) { @@ -888,12 +915,12 @@ void MyAvatar::updateMotorFromKeyboard(float deltaTime, bool walking) { if (directionLength > EPSILON) { direction /= directionLength; // the finalMotorSpeed depends on whether we are walking or not - float finalMaxMotorSpeed = walking ? MAX_WALKING_SPEED : _maxMotorSpeed; + float finalMaxMotorSpeed = walking ? _scale * MAX_WALKING_SPEED : _scale * _maxMotorSpeed; float motorLength = glm::length(_motorVelocity); - if (motorLength < MIN_KEYBOARD_CONTROL_SPEED) { + if (motorLength < _scale * MIN_KEYBOARD_CONTROL_SPEED) { // an active keyboard motor should never be slower than this - _motorVelocity = MIN_KEYBOARD_CONTROL_SPEED * direction; + _motorVelocity = _scale * MIN_KEYBOARD_CONTROL_SPEED * direction; } else { float MOTOR_LENGTH_TIMESCALE = 1.5f; float tau = glm::clamp(deltaTime / MOTOR_LENGTH_TIMESCALE, 0.0f, 1.0f); @@ -1566,7 +1593,8 @@ void MyAvatar::goToLocationFromResponse(const QJsonObject& jsonObject) { } void MyAvatar::updateMotionBehaviorsFromMenu() { - if (Menu::getInstance()->isOptionChecked(MenuOption::ObeyEnvironmentalGravity)) { + Menu* menu = Menu::getInstance(); + if (menu->isOptionChecked(MenuOption::ObeyEnvironmentalGravity)) { _motionBehaviors |= AVATAR_MOTION_OBEY_ENVIRONMENTAL_GRAVITY; // Environmental and Local gravities are incompatible. Environmental setting trumps local. _motionBehaviors &= ~AVATAR_MOTION_OBEY_LOCAL_GRAVITY; @@ -1576,6 +1604,14 @@ void MyAvatar::updateMotionBehaviorsFromMenu() { if (! (_motionBehaviors & (AVATAR_MOTION_OBEY_ENVIRONMENTAL_GRAVITY | AVATAR_MOTION_OBEY_LOCAL_GRAVITY))) { setGravity(glm::vec3(0.0f)); } + if (menu->isOptionChecked(MenuOption::StandOnNearbyFloors)) { + _motionBehaviors |= AVATAR_MOTION_STAND_ON_NEARBY_FLOORS; + // standing on floors requires collision with voxels + _collisionGroups |= COLLISION_GROUP_VOXELS; + menu->setIsOptionChecked(MenuOption::CollideWithVoxels, true); + } else { + _motionBehaviors &= ~AVATAR_MOTION_STAND_ON_NEARBY_FLOORS; + } } void MyAvatar::renderAttachments(RenderMode renderMode) { @@ -1602,6 +1638,11 @@ void MyAvatar::setCollisionGroups(quint32 collisionGroups) { menu->setIsOptionChecked(MenuOption::CollideWithAvatars, (bool)(_collisionGroups & COLLISION_GROUP_AVATARS)); menu->setIsOptionChecked(MenuOption::CollideWithVoxels, (bool)(_collisionGroups & COLLISION_GROUP_VOXELS)); menu->setIsOptionChecked(MenuOption::CollideWithParticles, (bool)(_collisionGroups & COLLISION_GROUP_PARTICLES)); + if (! (_collisionGroups & COLLISION_GROUP_VOXELS)) { + // no collision with voxels --> disable standing on floors + _motionBehaviors &= ~AVATAR_MOTION_STAND_ON_NEARBY_FLOORS; + menu->setIsOptionChecked(MenuOption::StandOnNearbyFloors, false); + } } void MyAvatar::setMotionBehaviorsByScript(quint32 flags) { diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 072070e98c..8f658678b5 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -53,23 +53,27 @@ typedef unsigned long long quint64; #include "HandData.h" // avatar motion behaviors -const quint32 AVATAR_MOTION_MOTOR_ENABLED = 1U << 0; -const quint32 AVATAR_MOTION_MOTOR_KEYBOARD_ENABLED = 1U << 1; -const quint32 AVATAR_MOTION_MOTOR_USE_LOCAL_FRAME = 1U << 2; -const quint32 AVATAR_MOTION_MOTOR_COLLISION_SURFACE_ONLY = 1U << 3; +const quint32 AVATAR_MOTION_MOTOR_ENABLED = 1U << 0; +const quint32 AVATAR_MOTION_MOTOR_KEYBOARD_ENABLED = 1U << 1; +const quint32 AVATAR_MOTION_MOTOR_USE_LOCAL_FRAME = 1U << 2; +const quint32 AVATAR_MOTION_MOTOR_COLLISION_SURFACE_ONLY = 1U << 3; -const quint32 AVATAR_MOTION_OBEY_ENVIRONMENTAL_GRAVITY = 1U << 4; -const quint32 AVATAR_MOTION_OBEY_LOCAL_GRAVITY = 1U << 5; +const quint32 AVATAR_MOTION_OBEY_ENVIRONMENTAL_GRAVITY = 1U << 4; +const quint32 AVATAR_MOTION_OBEY_LOCAL_GRAVITY = 1U << 5; + +const quint32 AVATAR_MOTION_STAND_ON_NEARBY_FLOORS = 1U << 6; const quint32 AVATAR_MOTION_DEFAULTS = AVATAR_MOTION_MOTOR_ENABLED | AVATAR_MOTION_MOTOR_KEYBOARD_ENABLED | - AVATAR_MOTION_MOTOR_USE_LOCAL_FRAME; + AVATAR_MOTION_MOTOR_USE_LOCAL_FRAME | + AVATAR_MOTION_STAND_ON_NEARBY_FLOORS; // these bits will be expanded as features are exposed const quint32 AVATAR_MOTION_SCRIPTABLE_BITS = AVATAR_MOTION_OBEY_ENVIRONMENTAL_GRAVITY | - AVATAR_MOTION_OBEY_LOCAL_GRAVITY; + AVATAR_MOTION_OBEY_LOCAL_GRAVITY | + AVATAR_MOTION_STAND_ON_NEARBY_FLOORS; // First bitset From d341e7314defd042622ef1fc6a4e05ee3b1e1099 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 23 May 2014 16:25:19 -0700 Subject: [PATCH 5/5] squared force on thrust controller --- examples/hydraMove.js | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/examples/hydraMove.js b/examples/hydraMove.js index ed6a5a4f44..f211a450a3 100644 --- a/examples/hydraMove.js +++ b/examples/hydraMove.js @@ -78,7 +78,7 @@ function createDebugOverlay() { position: defaultPosition, size: RADIUS, color: GRAY_COLOR, - alpha: 1, + alpha: 0.75, visible: true, solid: true, anchor: "MyAvatar" @@ -87,7 +87,7 @@ function createDebugOverlay() { position: defaultPosition, size: RADIUS, color: RED_COLOR, - alpha: 1, + alpha: 0.5, visible: true, solid: true, anchor: "MyAvatar" @@ -111,7 +111,7 @@ function displayDebug() { } } else { // update debug indicator - if (greenSphere == -1) { + if (greenSphere == -1) { createDebugOverlay(); } @@ -149,8 +149,8 @@ function getGrabRotation() { // When move button is pressed, process results function handleGrabBehavior(deltaTime) { // check for and handle grab behaviors - grabbingWithRightHand = Controller.isButtonPressed(RIGHT_BUTTON_FWD) || Controller.isButtonPressed(RIGHT_BUTTON_4); - grabbingWithLeftHand = Controller.isButtonPressed(LEFT_BUTTON_FWD) || Controller.isButtonPressed(LEFT_BUTTON_4); + grabbingWithRightHand = Controller.isButtonPressed(RIGHT_BUTTON_4); + grabbingWithLeftHand = Controller.isButtonPressed(LEFT_BUTTON_4); stoppedGrabbingWithLeftHand = false; stoppedGrabbingWithRightHand = false; @@ -201,20 +201,22 @@ function handleGrabBehavior(deltaTime) { printVector("grabDelta: ", grabDelta, 3); } - var THRUST_GRAB_SCALING = 300000.0; + var thrust = Vec3.multiply(grabDelta, Math.abs(Vec3.length(grabDelta))); + + var THRUST_GRAB_SCALING = 100000.0; - var thrustFront = Vec3.multiply(front, MyAvatar.scale * -grabDelta.z * THRUST_GRAB_SCALING * deltaTime); + var thrustFront = Vec3.multiply(front, MyAvatar.scale * -thrust.z * THRUST_GRAB_SCALING * deltaTime); MyAvatar.addThrust(thrustFront); - var thrustRight = Vec3.multiply(right, MyAvatar.scale * grabDelta.x * THRUST_GRAB_SCALING * deltaTime); + var thrustRight = Vec3.multiply(right, MyAvatar.scale * thrust.x * THRUST_GRAB_SCALING * deltaTime); MyAvatar.addThrust(thrustRight); - var thrustUp = Vec3.multiply(up, MyAvatar.scale * grabDelta.y * THRUST_GRAB_SCALING * deltaTime); + var thrustUp = Vec3.multiply(up, MyAvatar.scale * thrust.y * THRUST_GRAB_SCALING * deltaTime); MyAvatar.addThrust(thrustUp); // add some rotation... var deltaRotation = getGrabRotation(); - var PITCH_SCALING = 2.0; + var PITCH_SCALING = 2.5; var PITCH_DEAD_ZONE = 2.0; - var YAW_SCALING = 2.0; + var YAW_SCALING = 2.5; var ROLL_SCALING = 2.0; var euler = Quat.safeEulerAngles(deltaRotation);