diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index f7116a60db..e508c972c6 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -2196,6 +2196,14 @@ float MyAvatar::getDomainMaxScale() { return _domainMaximumScale; } +void MyAvatar::setGravity(float gravity) { + _characterController.setGravity(gravity); +} + +float MyAvatar::getGravity() { + return _characterController.getGravity(); +} + void MyAvatar::increaseSize() { // make sure we're starting from an allowable scale clampTargetScaleToDomainLimits(); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index c9d073cfd9..9620d61a49 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -152,7 +152,7 @@ class MyAvatar : public Avatar { Q_PROPERTY(float userHeight READ getUserHeight WRITE setUserHeight) Q_PROPERTY(float userEyeHeight READ getUserEyeHeight) - + const QString DOMINANT_LEFT_HAND = "left"; const QString DOMINANT_RIGHT_HAND = "right"; @@ -551,6 +551,9 @@ public slots: float getDomainMinScale(); float getDomainMaxScale(); + void setGravity(float gravity); + float getGravity(); + void goToLocation(const glm::vec3& newPosition, bool hasOrientation = false, const glm::quat& newOrientation = glm::quat(), bool shouldFaceLocation = false); diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index d2da521768..32e764bd10 100755 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -120,7 +120,7 @@ void CharacterController::setDynamicsWorld(btDynamicsWorld* world) { _dynamicsWorld->addRigidBody(_rigidBody, collisionGroup, BULLET_COLLISION_MASK_MY_AVATAR); _dynamicsWorld->addAction(this); // restore gravity settings because adding an object to the world overwrites its gravity setting - _rigidBody->setGravity(_gravity * _currentUp); + _rigidBody->setGravity(_currentGravity * _currentUp); btCollisionShape* shape = _rigidBody->getCollisionShape(); assert(shape && shape->getShapeType() == CONVEX_HULL_SHAPE_PROXYTYPE); _ghost.setCharacterShape(static_cast(shape)); @@ -302,7 +302,7 @@ void CharacterController::playerStep(btCollisionWorld* collisionWorld, btScalar // add minimum velocity to counteract gravity's displacement during one step // Note: the 0.5 factor comes from the fact that we really want the // average velocity contribution from gravity during the step - stepUpSpeed -= 0.5f * _gravity * timeToStep; // remember: _gravity is negative scalar + stepUpSpeed -= 0.5f * _currentGravity * timeToStep; // remember: _gravity is negative scalar btScalar vDotUp = velocity.dot(_currentUp); if (vDotUp < stepUpSpeed) { @@ -351,6 +351,28 @@ static const char* stateToStr(CharacterController::State state) { } #endif // #ifdef DEBUG_STATE_CHANGE +void CharacterController::updateCurrentGravity() { + int16_t collisionGroup = computeCollisionGroup(); + if (_state == State::Hover || collisionGroup == BULLET_COLLISION_GROUP_COLLISIONLESS) { + _currentGravity = 0.0f; + } else { + _currentGravity = _gravity; + } + if (_rigidBody) { + _rigidBody->setGravity(_currentGravity * _currentUp); + } +} + + +void CharacterController::setGravity(float gravity) { + _gravity = gravity; + updateCurrentGravity(); +} + +float CharacterController::getGravity() { + return _gravity; +} + #ifdef DEBUG_STATE_CHANGE void CharacterController::setState(State desiredState, const char* reason) { #else @@ -365,19 +387,7 @@ void CharacterController::setState(State desiredState) { qCDebug(physics) << "CharacterController::setState" << stateToStr(desiredState) << "from" << stateToStr(_state) << "," << reason; #endif _state = desiredState; - updateGravity(); - } -} - -void CharacterController::updateGravity() { - int16_t collisionGroup = computeCollisionGroup(); - if (_state == State::Hover || collisionGroup == BULLET_COLLISION_GROUP_COLLISIONLESS) { - _gravity = 0.0f; - } else { - _gravity = DEFAULT_AVATAR_GRAVITY; - } - if (_rigidBody) { - _rigidBody->setGravity(_gravity * _currentUp); + updateCurrentGravity(); } } @@ -436,14 +446,14 @@ void CharacterController::handleChangedCollisionGroup() { _dynamicsWorld->addRigidBody(_rigidBody, collisionGroup, BULLET_COLLISION_MASK_MY_AVATAR); } _pendingFlags &= ~PENDING_FLAG_UPDATE_COLLISION_GROUP; - updateGravity(); + updateCurrentGravity(); } } void CharacterController::updateUpAxis(const glm::quat& rotation) { _currentUp = quatRotate(glmToBullet(rotation), LOCAL_UP_AXIS); if (_rigidBody) { - _rigidBody->setGravity(_gravity * _currentUp); + _rigidBody->setGravity(_currentGravity * _currentUp); } } diff --git a/libraries/physics/src/CharacterController.h b/libraries/physics/src/CharacterController.h index 585eb7d3ed..0f97cc7c16 100644 --- a/libraries/physics/src/CharacterController.h +++ b/libraries/physics/src/CharacterController.h @@ -24,6 +24,7 @@ #include "BulletUtil.h" #include "CharacterGhostObject.h" +#include "AvatarConstants.h" const uint32_t PENDING_FLAG_ADD_TO_SIMULATION = 1U << 0; const uint32_t PENDING_FLAG_REMOVE_FROM_SIMULATION = 1U << 1; @@ -42,15 +43,18 @@ const btScalar MAX_CHARACTER_MOTOR_TIMESCALE = 60.0f; // one minute const btScalar MIN_CHARACTER_MOTOR_TIMESCALE = 0.05f; class CharacterController : public btCharacterControllerInterface { + public: CharacterController(); virtual ~CharacterController(); - bool needsRemoval() const; bool needsAddition() const; virtual void setDynamicsWorld(btDynamicsWorld* world); btCollisionObject* getCollisionObject() { return _rigidBody; } + void setGravity(float gravity); + float getGravity(); + virtual void updateShapeIfNecessary() = 0; // overrides from btCharacterControllerInterface @@ -131,7 +135,7 @@ protected: #endif virtual void updateMassProperties() = 0; - void updateGravity(); + void updateCurrentGravity(); void updateUpAxis(const glm::quat& rotation); bool checkForSupport(btCollisionWorld* collisionWorld); @@ -184,7 +188,8 @@ protected: bool _stepUpEnabled { true }; bool _hasSupport; - btScalar _gravity { 0.0f }; + btScalar _currentGravity { 0.0f }; + btScalar _gravity { DEFAULT_AVATAR_GRAVITY }; btScalar _followTime; btVector3 _followLinearDisplacement; diff --git a/scripts/developer/tests/gravityScript.js b/scripts/developer/tests/gravityScript.js new file mode 100644 index 0000000000..3468de72c3 --- /dev/null +++ b/scripts/developer/tests/gravityScript.js @@ -0,0 +1,45 @@ +// +// Gravity Script 1.0 +// ************ +// +// Created by Cain Kilgore on 9/14/2017 + +// Javascript for the Gravity Modifier Implementation to test +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + + +function menuParameters(menuNameSelection, menuItemNameSelection) { + Menu.addMenuItem({ + menuName: menuNameSelection, + menuItemName: menuItemNameSelection, + isCheckable: false + }); +} + +function setupMenu() { + if (!Menu.menuExists("Gravity")) { + Menu.addMenu("Gravity"); + for (var i = -5; i <= 5; i++) { + menuParameters("Gravity", i); + } + } +} + +function menuItemEvent(menuItem) { + for (var i = -5; i <= 5; i++) { + if (menuItem == i) { + MyAvatar.setGravity(i); + } + } +} + +function onScriptEnding() { + Menu.removeMenu("Gravity"); +} + +setupMenu(); +Menu.menuItemEvent.connect(menuItemEvent); +Script.scriptEnding.connect(onScriptEnding);