From a1f1e504319c49734dcd51cd06277cd747fff87b Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 21 Oct 2015 17:37:26 -0700 Subject: [PATCH 01/10] split CharacterController btw phys and interface --- interface/src/Application.cpp | 5 +- interface/src/avatar/MyAvatar.cpp | 109 +++++++++----- interface/src/avatar/MyAvatar.h | 43 ++++-- .../src/avatar/MyAvatarController.cpp | 137 ++++++++++++------ interface/src/avatar/MyAvatarController.h | 106 ++++++++++++++ libraries/physics/src/CharacterController.cpp | 52 +++++++ libraries/physics/src/CharacterController.h | 60 ++++++++ .../physics/src/DynamicCharacterController.h | 95 ------------ libraries/physics/src/PhysicsEngine.cpp | 43 +++--- libraries/physics/src/PhysicsEngine.h | 7 +- 10 files changed, 437 insertions(+), 220 deletions(-) rename libraries/physics/src/DynamicCharacterController.cpp => interface/src/avatar/MyAvatarController.cpp (81%) create mode 100644 interface/src/avatar/MyAvatarController.h create mode 100644 libraries/physics/src/CharacterController.cpp create mode 100644 libraries/physics/src/CharacterController.h delete mode 100644 libraries/physics/src/DynamicCharacterController.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1b6be53876..79339b03de 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2756,7 +2756,6 @@ void Application::update(float deltaTime) { { PerformanceTimer perfTimer("physics"); - myAvatar->relayDriveKeysToCharacterController(); static VectorOfMotionStates motionStates; _entitySimulation.getObjectsToDelete(motionStates); @@ -2783,6 +2782,8 @@ void Application::update(float deltaTime) { avatarManager->getObjectsToChange(motionStates); _physicsEngine->changeObjects(motionStates); + myAvatar->prepareForPhysicsSimulation(); + _entities.getTree()->withWriteLock([&] { _physicsEngine->stepSimulation(); }); @@ -2807,6 +2808,8 @@ void Application::update(float deltaTime) { // and will simulate entity motion (the EntityTree has been given an EntitySimulation). _entities.update(); // update the models... } + + myAvatar->harvestResultsFromPhysicsSimulation(); } } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 5920543dca..e52e56cd89 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -109,8 +109,13 @@ MyAvatar::MyAvatar(RigPointer rig) : _goToOrientation(), _rig(rig), _prevShouldDrawHead(true), - _audioListenerMode(FROM_HEAD), - _hmdAtRestDetector(glm::vec3(0), glm::quat()) + _audioListenerMode(FROM_HEAD) +#ifdef OLD_HMD_TRACKER + ,_hmdAtRestDetector(glm::vec3(0), glm::quat()) +#else + ,_avatarOffsetFromHMD(0.0f) + ,_hmdVelocity(0.0f) +#endif // OLD_HMD_TRACKER { for (int i = 0; i < MAX_DRIVE_KEYS; i++) { _driveKeys[i] = 0.0f; @@ -154,7 +159,10 @@ void MyAvatar::reset(bool andReload) { } // Reset dynamic state. - _wasPushing = _isPushing = _isBraking = _billboardValid = _straighteningLean = false; + _wasPushing = _isPushing = _isBraking = _billboardValid = false; +#ifdef OLD_HMD_TRACKER + _isFollowingHMD = false; +#endif // OLD_HMD_TRACKER _skeletonModel.reset(); getHead()->reset(); _targetVelocity = glm::vec3(0.0f); @@ -302,9 +310,10 @@ glm::mat4 MyAvatar::getSensorToWorldMatrix() const { return _sensorToWorldMatrix; } +#ifdef OLD_HMD_TRACKER // returns true if pos is OUTSIDE of the vertical capsule // where the middle cylinder length is defined by capsuleLen and the radius by capsuleRad. -static bool capsuleCheck(const glm::vec3& pos, float capsuleLen, float capsuleRad) { +static bool pointIsOutsideCapsule(const glm::vec3& pos, float capsuleLen, float capsuleRad) { const float halfCapsuleLen = capsuleLen / 2.0f; if (fabs(pos.y) <= halfCapsuleLen) { // cylinder check for middle capsule @@ -320,12 +329,18 @@ static bool capsuleCheck(const glm::vec3& pos, float capsuleLen, float capsuleRa return false; } } +#endif // OLD_HMD_TRACKER // Pass a recent sample of the HMD to the avatar. // This can also update the avatar's position to follow the HMD // as it moves through the world. void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { + // update the sensorMatrices based on the new hmd pose + _hmdSensorMatrix = hmdSensorMatrix; + _hmdSensorPosition = extractTranslation(hmdSensorMatrix); + _hmdSensorOrientation = glm::quat_cast(hmdSensorMatrix); +#ifdef OLD_HMD_TRACKER // calc deltaTime auto now = usecTimestampNow(); auto deltaUsecs = now - _lastUpdateFromHMDTime; @@ -334,11 +349,6 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { const float BIGGEST_DELTA_TIME_SECS = 0.25f; float deltaTime = glm::clamp((float)actualDeltaTime, 0.0f, BIGGEST_DELTA_TIME_SECS); - // update the sensorMatrices based on the new hmd pose - _hmdSensorMatrix = hmdSensorMatrix; - _hmdSensorPosition = extractTranslation(hmdSensorMatrix); - _hmdSensorOrientation = glm::quat_cast(hmdSensorMatrix); - bool hmdIsAtRest = _hmdAtRestDetector.update(deltaTime, _hmdSensorPosition, _hmdSensorOrientation); // It can be more accurate/smooth to use velocity rather than position, @@ -360,58 +370,57 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { bool justStartedMoving = (_lastIsMoving != isMoving) && isMoving; _lastIsMoving = isMoving; - if (shouldBeginStraighteningLean() || hmdIsAtRest || justStartedMoving) { - beginStraighteningLean(); + if (shouldFollowHMD() || hmdIsAtRest || justStartedMoving) { + beginFollowingHMD(); } - processStraighteningLean(deltaTime); + followHMD(deltaTime); +#endif // OLD_HMD_TRACKER } -void MyAvatar::beginStraighteningLean() { +#ifdef OLD_HMD_TRACKER +void MyAvatar::beginFollowingHMD() { // begin homing toward derived body position. - if (!_straighteningLean) { - _straighteningLean = true; - _straighteningLeanAlpha = 0.0f; + if (!_isFollowingHMD) { + _isFollowingHMD = true; + _followHMDAlpha = 0.0f; } } -bool MyAvatar::shouldBeginStraighteningLean() const { - // define a vertical capsule - const float STRAIGHTENING_LEAN_CAPSULE_RADIUS = 0.2f; // meters - const float STRAIGHTENING_LEAN_CAPSULE_LENGTH = 0.05f; // length of the cylinder part of the capsule in meters. - - // detect if the derived body position is outside of a capsule around the _bodySensorMatrix - auto newBodySensorMatrix = deriveBodyFromHMDSensor(); - glm::vec3 diff = extractTranslation(newBodySensorMatrix) - extractTranslation(_bodySensorMatrix); - bool isBodyPosOutsideCapsule = capsuleCheck(diff, STRAIGHTENING_LEAN_CAPSULE_LENGTH, STRAIGHTENING_LEAN_CAPSULE_RADIUS); - - if (isBodyPosOutsideCapsule) { - return true; - } else { - return false; +bool MyAvatar::shouldFollowHMD() const { + if (!_isFollowingHMD) { + // define a vertical capsule + const float FOLLOW_HMD_CAPSULE_RADIUS = 0.2f; // meters + const float FOLLOW_HMD_CAPSULE_LENGTH = 0.05f; // length of the cylinder part of the capsule in meters. + + // detect if the derived body position is outside of a capsule around the _bodySensorMatrix + auto newBodySensorMatrix = deriveBodyFromHMDSensor(); + glm::vec3 localPoint = extractTranslation(newBodySensorMatrix) - extractTranslation(_bodySensorMatrix); + return pointIsOutsideCapsule(localPoint, FOLLOW_HMD_CAPSULE_LENGTH, FOLLOW_HMD_CAPSULE_RADIUS); } + return false; } -void MyAvatar::processStraighteningLean(float deltaTime) { - if (_straighteningLean) { +void MyAvatar::followHMD(float deltaTime) { + if (_isFollowingHMD) { - const float STRAIGHTENING_LEAN_DURATION = 0.5f; // seconds + const float FOLLOW_HMD_DURATION = 0.5f; // seconds auto newBodySensorMatrix = deriveBodyFromHMDSensor(); auto worldBodyMatrix = _sensorToWorldMatrix * newBodySensorMatrix; glm::vec3 worldBodyPos = extractTranslation(worldBodyMatrix); glm::quat worldBodyRot = glm::normalize(glm::quat_cast(worldBodyMatrix)); - _straighteningLeanAlpha += (1.0f / STRAIGHTENING_LEAN_DURATION) * deltaTime; + _followHMDAlpha += (1.0f / FOLLOW_HMD_DURATION) * deltaTime; - if (_straighteningLeanAlpha >= 1.0f) { - _straighteningLean = false; + if (_followHMDAlpha >= 1.0f) { + _isFollowingHMD = false; nextAttitude(worldBodyPos, worldBodyRot); _bodySensorMatrix = newBodySensorMatrix; } else { // interp position toward the desired pos - glm::vec3 pos = lerp(getPosition(), worldBodyPos, _straighteningLeanAlpha); - glm::quat rot = glm::normalize(safeMix(getOrientation(), worldBodyRot, _straighteningLeanAlpha)); + glm::vec3 pos = lerp(getPosition(), worldBodyPos, _followHMDAlpha); + glm::quat rot = glm::normalize(safeMix(getOrientation(), worldBodyRot, _followHMDAlpha)); nextAttitude(pos, rot); // interp sensor matrix toward desired @@ -419,12 +428,17 @@ void MyAvatar::processStraighteningLean(float deltaTime) { glm::quat nextBodyRot = glm::normalize(glm::quat_cast(newBodySensorMatrix)); glm::vec3 prevBodyPos = extractTranslation(_bodySensorMatrix); glm::quat prevBodyRot = glm::normalize(glm::quat_cast(_bodySensorMatrix)); - pos = lerp(prevBodyPos, nextBodyPos, _straighteningLeanAlpha); - rot = glm::normalize(safeMix(prevBodyRot, nextBodyRot, _straighteningLeanAlpha)); + pos = lerp(prevBodyPos, nextBodyPos, _followHMDAlpha); + rot = glm::normalize(safeMix(prevBodyRot, nextBodyRot, _followHMDAlpha)); _bodySensorMatrix = createMatFromQuatAndPos(rot, pos); } } } +#else +void MyAvatar::harvestHMDOffset(glm::vec3 offset) { + +} +#endif // USE_OLD // best called at end of main loop, just before rendering. // update sensor to world matrix from current body position and hmd sensor. @@ -1274,6 +1288,21 @@ void MyAvatar::rebuildSkeletonBody() { _characterController.setLocalBoundingBox(corner, scale); } +void MyAvatar::prepareForPhysicsSimulation() { + relayDriveKeysToCharacterController(); + _characterController.setTargetVelocity(getTargetVelocity()); + _characterController.setAvatarPositionAndOrientation(getPosition(), getOrientation()); + //_characterController.setHMDVelocity(hmdVelocity); +} + +void MyAvatar::harvestResultsFromPhysicsSimulation() { + glm::vec3 position = getPosition(); + glm::quat orientation = getOrientation(); + _characterController.getAvatarPositionAndOrientation(position, orientation); + nextAttitude(position, orientation); + setVelocity(_characterController.getLinearVelocity()); +} + QString MyAvatar::getScriptedMotorFrame() const { QString frame = "avatar"; if (_scriptedMotorFrame == SCRIPTED_MOTOR_CAMERA_FRAME) { diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 7347419fee..f3f55f4a7a 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -12,12 +12,16 @@ #ifndef hifi_MyAvatar_h #define hifi_MyAvatar_h +#include + #include -#include #include #include "Avatar.h" -#include "AtRestDetector.h" +//#include "AtRestDetector.h" +#include "MyAvatarController.h" + +//#define OLD_HMD_TRACKER class ModelItemID; @@ -154,8 +158,10 @@ public: virtual void setAttachmentData(const QVector& attachmentData) override; - DynamicCharacterController* getCharacterController() { return &_characterController; } + MyAvatarController* getCharacterController() { return &_characterController; } + void prepareForPhysicsSimulation(); + void harvestResultsFromPhysicsSimulation(); const QString& getCollisionSoundURL() {return _collisionSoundURL; } void setCollisionSoundURL(const QString& url); @@ -262,9 +268,13 @@ private: const RecorderPointer getRecorder() const { return _recorder; } const PlayerPointer getPlayer() const { return _player; } - void beginStraighteningLean(); - bool shouldBeginStraighteningLean() const; - void processStraighteningLean(float deltaTime); +#ifdef OLD_HMD_TRACKER + void beginFollowingHMD(); + bool shouldFollowHMD() const; + void followHMD(float deltaTime); +#else + void harvestHMDOffset(glm::vec3 offset); +#endif bool cameraInsideHead() const; @@ -295,7 +305,7 @@ private: quint32 _motionBehaviors; QString _collisionSoundURL; - DynamicCharacterController _characterController; + MyAvatarController _characterController; AvatarWeakPointer _lookAtTargetAvatar; glm::vec3 _targetAvatarPosition; @@ -348,21 +358,26 @@ private: RigPointer _rig; bool _prevShouldDrawHead; - bool _enableDebugDrawBindPose = false; - bool _enableDebugDrawAnimPose = false; - AnimSkeleton::ConstPointer _debugDrawSkeleton = nullptr; + bool _enableDebugDrawBindPose { false }; + bool _enableDebugDrawAnimPose { false }; + AnimSkeleton::ConstPointer _debugDrawSkeleton { nullptr }; AudioListenerMode _audioListenerMode; glm::vec3 _customListenPosition; glm::quat _customListenOrientation; - bool _straighteningLean = false; - float _straighteningLeanAlpha = 0.0f; +#ifdef OLD_HMD_TRACKER + bool _isFollowingHMD { false }; + float _followHMDAlpha{0.0f}; - quint64 _lastUpdateFromHMDTime = usecTimestampNow(); + quint64 _lastUpdateFromHMDTime{usecTimestampNow()}; AtRestDetector _hmdAtRestDetector; glm::vec3 _lastPosition; - bool _lastIsMoving = false; + bool _lastIsMoving { false }; +#else + glm::vec3 _avatarOffsetFromHMD; + glm::vec3 _hmdVelocity; +#endif // OLD_HMD_TRACKER }; QScriptValue audioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode); diff --git a/libraries/physics/src/DynamicCharacterController.cpp b/interface/src/avatar/MyAvatarController.cpp similarity index 81% rename from libraries/physics/src/DynamicCharacterController.cpp rename to interface/src/avatar/MyAvatarController.cpp index 604326168c..931c8b9b08 100644 --- a/libraries/physics/src/DynamicCharacterController.cpp +++ b/interface/src/avatar/MyAvatarController.cpp @@ -1,13 +1,27 @@ +// +// MyAvatar.h +// interface/src/avatar +// +// Created by AndrewMeadows 2015.10.21 +// Copyright 2015 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 "MyAvatarController.h" + #include #include #include #include +#include +#include +#include #include -#include "BulletUtil.h" -#include "DynamicCharacterController.h" -#include "PhysicsLogging.h" +#include "MyAvatar.h" const btVector3 LOCAL_UP_AXIS(0.0f, 1.0f, 0.0f); const float DEFAULT_GRAVITY = -5.0f; @@ -15,11 +29,6 @@ const float JUMP_SPEED = 3.5f; const float MAX_FALL_HEIGHT = 20.0f; -const uint32_t PENDING_FLAG_ADD_TO_SIMULATION = 1U << 0; -const uint32_t PENDING_FLAG_REMOVE_FROM_SIMULATION = 1U << 1; -const uint32_t PENDING_FLAG_UPDATE_SHAPE = 1U << 2; -const uint32_t PENDING_FLAG_JUMP = 1U << 3; - // TODO: improve walking up steps // TODO: make avatars able to walk up and down steps/slopes // TODO: make avatars stand on steep slope @@ -41,19 +50,19 @@ protected: btRigidBody* _me; }; -DynamicCharacterController::DynamicCharacterController(AvatarData* avatarData) { +MyAvatarController::MyAvatarController(MyAvatar* avatar) { _halfHeight = 1.0f; _shape = nullptr; - _rigidBody = nullptr; - assert(avatarData); - _avatarData = avatarData; + assert(avatar); + _avatar = avatar; _enabled = false; _floorDistance = MAX_FALL_HEIGHT; - _walkVelocity.setValue(0.0f,0.0f,0.0f); + _walkVelocity.setValue(0.0f, 0.0f, 0.0f); + _hmdVelocity.setValue(0.0f, 0.0f, 0.0f); _jumpSpeed = JUMP_SPEED; _isOnGround = false; _isJumping = false; @@ -61,21 +70,16 @@ DynamicCharacterController::DynamicCharacterController(AvatarData* avatarData) { _isHovering = true; _isPushingUp = false; _jumpToHoverStart = 0; + _lastStepDuration = 0.0f; _pendingFlags = PENDING_FLAG_UPDATE_SHAPE; updateShapeIfNecessary(); } -DynamicCharacterController::~DynamicCharacterController() { +MyAvatarController::~MyAvatarController() { } -// virtual -void DynamicCharacterController::setWalkDirection(const btVector3& walkDirection) { - // do nothing -- walkVelocity is upated in preSimulation() - //_walkVelocity = walkDirection; -} - -void DynamicCharacterController::preStep(btCollisionWorld* collisionWorld) { +void MyAvatarController::preStep(btCollisionWorld* collisionWorld) { // trace a ray straight down to see if we're standing on the ground const btTransform& xform = _rigidBody->getWorldTransform(); @@ -96,7 +100,7 @@ void DynamicCharacterController::preStep(btCollisionWorld* collisionWorld) { } } -void DynamicCharacterController::playerStep(btCollisionWorld* dynaWorld, btScalar dt) { +void MyAvatarController::playerStep(btCollisionWorld* dynaWorld, btScalar dt) { btVector3 actualVelocity = _rigidBody->getLinearVelocity(); btScalar actualSpeed = actualVelocity.length(); @@ -160,7 +164,7 @@ void DynamicCharacterController::playerStep(btCollisionWorld* dynaWorld, btScala } } -void DynamicCharacterController::jump() { +void MyAvatarController::jump() { // check for case where user is holding down "jump" key... // we'll eventually tansition to "hover" if (!_isJumping) { @@ -178,12 +182,12 @@ void DynamicCharacterController::jump() { } } -bool DynamicCharacterController::onGround() const { +bool MyAvatarController::onGround() const { const btScalar FLOOR_PROXIMITY_THRESHOLD = 0.3f * _radius; return _floorDistance < FLOOR_PROXIMITY_THRESHOLD; } -void DynamicCharacterController::setHovering(bool hover) { +void MyAvatarController::setHovering(bool hover) { if (hover != _isHovering) { _isHovering = hover; _isJumping = false; @@ -198,7 +202,7 @@ void DynamicCharacterController::setHovering(bool hover) { } } -void DynamicCharacterController::setLocalBoundingBox(const glm::vec3& corner, const glm::vec3& scale) { +void MyAvatarController::setLocalBoundingBox(const glm::vec3& corner, const glm::vec3& scale) { _boxScale = scale; float x = _boxScale.x; @@ -231,15 +235,17 @@ void DynamicCharacterController::setLocalBoundingBox(const glm::vec3& corner, co _shapeLocalOffset = corner + 0.5f * _boxScale; } -bool DynamicCharacterController::needsRemoval() const { +/* moved to base class +bool MyAvatarController::needsRemoval() const { return (bool)(_pendingFlags & PENDING_FLAG_REMOVE_FROM_SIMULATION); } -bool DynamicCharacterController::needsAddition() const { +bool MyAvatarController::needsAddition() const { return (bool)(_pendingFlags & PENDING_FLAG_ADD_TO_SIMULATION); } +*/ -void DynamicCharacterController::setEnabled(bool enabled) { +void MyAvatarController::setEnabled(bool enabled) { if (enabled != _enabled) { if (enabled) { // Don't bother clearing REMOVE bit since it might be paired with an UPDATE_SHAPE bit. @@ -257,7 +263,8 @@ void DynamicCharacterController::setEnabled(bool enabled) { } } -void DynamicCharacterController::setDynamicsWorld(btDynamicsWorld* world) { +/* moved to base class +void MyAvatarController::setDynamicsWorld(btDynamicsWorld* world) { if (_dynamicsWorld != world) { if (_dynamicsWorld) { if (_rigidBody) { @@ -284,9 +291,9 @@ void DynamicCharacterController::setDynamicsWorld(btDynamicsWorld* world) { } else { _pendingFlags &= ~ PENDING_FLAG_REMOVE_FROM_SIMULATION; } -} +}*/ -void DynamicCharacterController::updateShapeIfNecessary() { +void MyAvatarController::updateShapeIfNecessary() { if (_pendingFlags & PENDING_FLAG_UPDATE_SHAPE) { // make sure there is NO pending removal from simulation at this point // (don't want to delete _rigidBody out from under the simulation) @@ -321,8 +328,8 @@ void DynamicCharacterController::updateShapeIfNecessary() { _rigidBody = new btRigidBody(mass, nullptr, _shape, inertia); _rigidBody->setSleepingThresholds(0.0f, 0.0f); _rigidBody->setAngularFactor(0.0f); - _rigidBody->setWorldTransform(btTransform(glmToBullet(_avatarData->getOrientation()), - glmToBullet(_avatarData->getPosition()))); + _rigidBody->setWorldTransform(btTransform(glmToBullet(_avatar->getOrientation()), + glmToBullet(_avatar->getPosition()))); if (_isHovering) { _rigidBody->setGravity(btVector3(0.0f, 0.0f, 0.0f)); } else { @@ -335,7 +342,7 @@ void DynamicCharacterController::updateShapeIfNecessary() { } } -void DynamicCharacterController::updateUpAxis(const glm::quat& rotation) { +void MyAvatarController::updateUpAxis(const glm::quat& rotation) { btVector3 oldUp = _currentUp; _currentUp = quatRotate(glmToBullet(rotation), LOCAL_UP_AXIS); if (!_isHovering) { @@ -346,24 +353,57 @@ void DynamicCharacterController::updateUpAxis(const glm::quat& rotation) { } } -void DynamicCharacterController::preSimulation(btScalar timeStep) { - if (_enabled && _dynamicsWorld) { - glm::quat rotation = _avatarData->getOrientation(); +void MyAvatarController::setAvatarPositionAndOrientation( + const glm::vec3& position, + const glm::quat& orientation) { + // TODO: update gravity if up has changed + updateUpAxis(orientation); + btQuaternion bodyOrientation = glmToBullet(orientation); + btVector3 bodyPosition = glmToBullet(position + orientation * _shapeLocalOffset); + _avatarBodyTransform = btTransform(bodyOrientation, bodyPosition); +} + +void MyAvatarController::getAvatarPositionAndOrientation(glm::vec3& position, glm::quat& rotation) const { + if (_enabled && _rigidBody) { + const btTransform& avatarTransform = _rigidBody->getWorldTransform(); + rotation = bulletToGLM(avatarTransform.getRotation()); + position = bulletToGLM(avatarTransform.getOrigin()) - rotation * _shapeLocalOffset; + } +} + +void MyAvatarController::setTargetVelocity(const glm::vec3& velocity) { + //_walkVelocity = glmToBullet(_avatarData->getTargetVelocity()); + _walkVelocity = glmToBullet(velocity); +} + +void MyAvatarController::setHMDVelocity(const glm::vec3& velocity) { + _hmdVelocity = glmToBullet(velocity); +} + +glm::vec3 MyAvatarController::getLinearVelocity() const { + glm::vec3 velocity(0.0f); + if (_rigidBody) { + velocity = bulletToGLM(_rigidBody->getLinearVelocity()); + } + return velocity; +} + +void MyAvatarController::preSimulation() { + if (_enabled && _dynamicsWorld) { + /* + glm::quat rotation = _avatarData->getOrientation(); // TODO: update gravity if up has changed updateUpAxis(rotation); - glm::vec3 position = _avatarData->getPosition() + rotation * _shapeLocalOffset; _rigidBody->setWorldTransform(btTransform(glmToBullet(rotation), glmToBullet(position))); + */ - // the rotation is dictated by AvatarData - btTransform xform = _rigidBody->getWorldTransform(); - xform.setRotation(glmToBullet(rotation)); - _rigidBody->setWorldTransform(xform); + _rigidBody->setWorldTransform(_avatarBodyTransform); // scan for distant floor // rayStart is at center of bottom sphere - btVector3 rayStart = xform.getOrigin() - _halfHeight * _currentUp; + btVector3 rayStart = _avatarBodyTransform.getOrigin() - _halfHeight * _currentUp; // rayEnd is straight down MAX_FALL_HEIGHT btScalar rayLength = _radius + MAX_FALL_HEIGHT; @@ -388,8 +428,6 @@ void DynamicCharacterController::preSimulation(btScalar timeStep) { setHovering(true); } - _walkVelocity = glmToBullet(_avatarData->getTargetVelocity()); - if (_pendingFlags & PENDING_FLAG_JUMP) { _pendingFlags &= ~ PENDING_FLAG_JUMP; if (onGround()) { @@ -402,7 +440,9 @@ void DynamicCharacterController::preSimulation(btScalar timeStep) { } } -void DynamicCharacterController::postSimulation() { +void MyAvatarController::postSimulation() { + /* + _lastStepDuration += timeStep; if (_enabled && _rigidBody) { const btTransform& avatarTransform = _rigidBody->getWorldTransform(); glm::quat rotation = bulletToGLM(avatarTransform.getRotation()); @@ -410,5 +450,8 @@ void DynamicCharacterController::postSimulation() { _avatarData->nextAttitude(position - rotation * _shapeLocalOffset, rotation); _avatarData->setVelocity(bulletToGLM(_rigidBody->getLinearVelocity())); + _avatarData->applySimulationTime(_lastStepDuration); } + _lastStepDuration = 0.0f; + */ } diff --git a/interface/src/avatar/MyAvatarController.h b/interface/src/avatar/MyAvatarController.h new file mode 100644 index 0000000000..a973905653 --- /dev/null +++ b/interface/src/avatar/MyAvatarController.h @@ -0,0 +1,106 @@ +// +// MyAvatar.h +// interface/src/avatar +// +// Created by AndrewMeadows 2015.10.21 +// Copyright 2015 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_MyAvatarController_h +#define hifi_MyAvatarController_h + +#include +#include + +#include +#include + +class btCollisionShape; +class MyAvatar; + +class MyAvatarController : public CharacterController { +public: + MyAvatarController(MyAvatar* avatar); + ~MyAvatarController (); + + // TODO: implement these when needed + virtual void setVelocityForTimeInterval(const btVector3 &velocity, btScalar timeInterval) override { assert(false); } + virtual void reset(btCollisionWorld* collisionWorld) override { } + virtual void warp(const btVector3& origin) override { } + virtual void debugDraw(btIDebugDraw* debugDrawer) override { } + virtual void setUpInterpolate(bool value) override { } + + // overrides from btCharacterControllerInterface + virtual void updateAction(btCollisionWorld* collisionWorld, btScalar deltaTime) override { + preStep(collisionWorld); + playerStep(collisionWorld, deltaTime); + } + virtual void preStep(btCollisionWorld* collisionWorld) override; + virtual void playerStep(btCollisionWorld* collisionWorld, btScalar dt) override; + virtual bool canJump() const override { assert(false); return false; } // never call this + virtual void jump() override; // call this every frame the jump button is pressed + virtual bool onGround() const override; + + // overrides from CharacterController + virtual void preSimulation() override; + virtual void postSimulation() override; + virtual void incrementSimulationTime(btScalar timeStep) override { _lastStepDuration += timeStep; } + + bool isHovering() const { return _isHovering; } + void setHovering(bool enabled); + + void setEnabled(bool enabled); + bool isEnabled() const { return _enabled && _dynamicsWorld; } + + void setLocalBoundingBox(const glm::vec3& corner, const glm::vec3& scale); + + virtual void updateShapeIfNecessary() override; + + void setAvatarPositionAndOrientation( const glm::vec3& position, const glm::quat& orientation); + void getAvatarPositionAndOrientation(glm::vec3& position, glm::quat& rotation) const; + + void setTargetVelocity(const glm::vec3& velocity); + void setHMDVelocity(const glm::vec3& velocity); + + glm::vec3 getLinearVelocity() const; + +protected: + void updateUpAxis(const glm::quat& rotation); + +protected: + btVector3 _currentUp; + btVector3 _walkVelocity; + btVector3 _hmdVelocity; + btTransform _avatarBodyTransform; + + glm::vec3 _shapeLocalOffset; + glm::vec3 _boxScale; // used to compute capsule shape + + quint64 _jumpToHoverStart; + + btCollisionShape* _shape { nullptr }; + MyAvatar* _avatar { nullptr }; + + btScalar _halfHeight; + btScalar _radius; + + btScalar _floorDistance; + + btScalar _gravity; + + btScalar _jumpSpeed; + btScalar _lastStepDuration; + + bool _enabled; + bool _isOnGround; + bool _isJumping; + bool _isFalling; + bool _isHovering; + bool _isPushingUp; +}; + +#endif // hifi_MyAvatarController_h diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp new file mode 100644 index 0000000000..9ba22cf2db --- /dev/null +++ b/libraries/physics/src/CharacterController.cpp @@ -0,0 +1,52 @@ +// +// CharacterControllerInterface.cpp +// libraries/physcis/src +// +// Created by Andrew Meadows 2015.10.21 +// Copyright 2015 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 "CharacterController.h" + +#include "PhysicsCollisionGroups.h" + +bool CharacterController::needsRemoval() const { + return (bool)(_pendingFlags & PENDING_FLAG_REMOVE_FROM_SIMULATION); +} + +bool CharacterController::needsAddition() const { + return (bool)(_pendingFlags & PENDING_FLAG_ADD_TO_SIMULATION); +} + +void CharacterController::setDynamicsWorld(btDynamicsWorld* world) { + if (_dynamicsWorld != world) { + if (_dynamicsWorld) { + if (_rigidBody) { + _dynamicsWorld->removeRigidBody(_rigidBody); + _dynamicsWorld->removeAction(this); + } + _dynamicsWorld = nullptr; + } + if (world && _rigidBody) { + _dynamicsWorld = world; + _pendingFlags &= ~ PENDING_FLAG_JUMP; + _dynamicsWorld->addRigidBody(_rigidBody, COLLISION_GROUP_MY_AVATAR, COLLISION_MASK_MY_AVATAR); + _dynamicsWorld->addAction(this); + //reset(_dynamicsWorld); + } + } + if (_dynamicsWorld) { + if (_pendingFlags & PENDING_FLAG_UPDATE_SHAPE) { + // shouldn't fall in here, but if we do make sure both ADD and REMOVE bits are still set + _pendingFlags |= PENDING_FLAG_ADD_TO_SIMULATION | PENDING_FLAG_REMOVE_FROM_SIMULATION; + } else { + _pendingFlags &= ~PENDING_FLAG_ADD_TO_SIMULATION; + } + } else { + _pendingFlags &= ~ PENDING_FLAG_REMOVE_FROM_SIMULATION; + } +} + diff --git a/libraries/physics/src/CharacterController.h b/libraries/physics/src/CharacterController.h new file mode 100644 index 0000000000..cff257a790 --- /dev/null +++ b/libraries/physics/src/CharacterController.h @@ -0,0 +1,60 @@ +// +// CharacterControllerInterface.h +// libraries/physcis/src +// +// Created by Andrew Meadows 2015.10.21 +// Copyright 2015 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_CharacterControllerInterface_h +#define hifi_CharacterControllerInterface_h + +#include +#include +#include +#include + +const uint32_t PENDING_FLAG_ADD_TO_SIMULATION = 1U << 0; +const uint32_t PENDING_FLAG_REMOVE_FROM_SIMULATION = 1U << 1; +const uint32_t PENDING_FLAG_UPDATE_SHAPE = 1U << 2; +const uint32_t PENDING_FLAG_JUMP = 1U << 3; + + +class btRigidBody; +class btCollisionWorld; +class btDynamicsWorld; + +class CharacterController : public btCharacterControllerInterface { +public: + bool needsRemoval() const; + bool needsAddition() const; + void setDynamicsWorld(btDynamicsWorld* world); + btCollisionObject* getCollisionObject() { return _rigidBody; } + + virtual void updateShapeIfNecessary() = 0; + virtual void preSimulation() = 0; + virtual void incrementSimulationTime(btScalar stepTime) = 0; + virtual void postSimulation() = 0; + + virtual void setWalkDirection(const btVector3 &walkDirection) { assert(false); } + + /* these from btCharacterControllerInterface remain to be overridden + virtual void setVelocityForTimeInterval(const btVector3 &velocity, btScalar timeInterval) = 0; + virtual void reset() = 0; + virtual void warp(const btVector3 &origin) = 0; + virtual void preStep(btCollisionWorld *collisionWorld) = 0; + virtual void playerStep(btCollisionWorld *collisionWorld, btScalar dt) = 0; + virtual bool canJump() const = 0; + virtual void jump() = 0; + virtual bool onGround() const = 0; + */ +protected: + btDynamicsWorld* _dynamicsWorld { nullptr }; + btRigidBody* _rigidBody { nullptr }; + uint32_t _pendingFlags { 0 }; +}; + +#endif // hifi_CharacterControllerInterface_h diff --git a/libraries/physics/src/DynamicCharacterController.h b/libraries/physics/src/DynamicCharacterController.h deleted file mode 100644 index d26c69c5a5..0000000000 --- a/libraries/physics/src/DynamicCharacterController.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef hifi_DynamicCharacterController_h -#define hifi_DynamicCharacterController_h - -#include -#include - -#include - -class btCollisionShape; -class btRigidBody; -class btCollisionWorld; - -const int NUM_CHARACTER_CONTROLLER_RAYS = 2; - -class DynamicCharacterController : public btCharacterControllerInterface -{ -protected: - btScalar _halfHeight; - btScalar _radius; - btCollisionShape* _shape; - btRigidBody* _rigidBody; - - btVector3 _currentUp; - - btScalar _floorDistance; - - btVector3 _walkVelocity; - btScalar _gravity; - - glm::vec3 _shapeLocalOffset; - glm::vec3 _boxScale; // used to compute capsule shape - AvatarData* _avatarData = nullptr; - - bool _enabled; - bool _isOnGround; - bool _isJumping; - bool _isFalling; - bool _isHovering; - bool _isPushingUp; - quint64 _jumpToHoverStart; - uint32_t _pendingFlags; - - btDynamicsWorld* _dynamicsWorld = nullptr; - - btScalar _jumpSpeed; - -public: - DynamicCharacterController(AvatarData* avatarData); - ~DynamicCharacterController (); - - virtual void setWalkDirection(const btVector3& walkDirection); - virtual void setVelocityForTimeInterval(const btVector3 &velocity, btScalar timeInterval) { assert(false); } - - // TODO: implement these when needed - virtual void reset(btCollisionWorld* collisionWorld) { } - virtual void warp(const btVector3& origin) { } - virtual void debugDraw(btIDebugDraw* debugDrawer) { } - virtual void setUpInterpolate(bool value) { } - - btCollisionObject* getCollisionObject() { return _rigidBody; } - - ///btActionInterface interface - virtual void updateAction(btCollisionWorld* collisionWorld, btScalar deltaTime) { - preStep(collisionWorld); - playerStep(collisionWorld, deltaTime); - } - - virtual void preStep(btCollisionWorld* collisionWorld); - virtual void playerStep(btCollisionWorld* collisionWorld, btScalar dt); - - virtual bool canJump() const { assert(false); return false; } // never call this - virtual void jump(); // call this every frame the jump button is pressed - virtual bool onGround() const; - bool isHovering() const { return _isHovering; } - void setHovering(bool enabled); - - bool needsRemoval() const; - bool needsAddition() const; - void setEnabled(bool enabled); - bool isEnabled() const { return _enabled && _dynamicsWorld; } - - void setDynamicsWorld(btDynamicsWorld* world); - - void setLocalBoundingBox(const glm::vec3& corner, const glm::vec3& scale); - bool needsShapeUpdate() const; - void updateShapeIfNecessary(); - - void preSimulation(btScalar timeStep); - void postSimulation(); - -protected: - void updateUpAxis(const glm::quat& rotation); -}; - -#endif // hifi_DynamicCharacterController_h diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 75273e62ba..a6b8dbe959 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -11,6 +11,7 @@ #include +#include "CharacterController.h" #include "ObjectMotionState.h" #include "PhysicsEngine.h" #include "PhysicsHelpers.h" @@ -23,7 +24,7 @@ uint32_t PhysicsEngine::getNumSubsteps() { PhysicsEngine::PhysicsEngine(const glm::vec3& offset) : _originOffset(offset), - _characterController(nullptr) { + _myAvatarController(nullptr) { // build table of masks with their group as the key _collisionMasks.insert(btHashInt((int)COLLISION_GROUP_DEFAULT), COLLISION_MASK_DEFAULT); _collisionMasks.insert(btHashInt((int)COLLISION_GROUP_STATIC), COLLISION_MASK_STATIC); @@ -38,8 +39,8 @@ PhysicsEngine::PhysicsEngine(const glm::vec3& offset) : } PhysicsEngine::~PhysicsEngine() { - if (_characterController) { - _characterController->setDynamicsWorld(nullptr); + if (_myAvatarController) { + _myAvatarController->setDynamicsWorld(nullptr); } delete _collisionConfig; delete _collisionDispatcher; @@ -239,16 +240,18 @@ void PhysicsEngine::stepSimulation() { _clock.reset(); float timeStep = btMin(dt, MAX_TIMESTEP); - // TODO: move character->preSimulation() into relayIncomingChanges - if (_characterController) { - if (_characterController->needsRemoval()) { - _characterController->setDynamicsWorld(nullptr); + if (_myAvatarController) { + // ADEBUG TODO: move this stuff outside and in front of stepSimulation, because + // the updateShapeIfNecessary() call needs info from MyAvatar and should + // be done on the main thread during the pre-simulation stuff + if (_myAvatarController->needsRemoval()) { + _myAvatarController->setDynamicsWorld(nullptr); } - _characterController->updateShapeIfNecessary(); - if (_characterController->needsAddition()) { - _characterController->setDynamicsWorld(_dynamicsWorld); + _myAvatarController->updateShapeIfNecessary(); + if (_myAvatarController->needsAddition()) { + _myAvatarController->setDynamicsWorld(_dynamicsWorld); } - _characterController->preSimulation(timeStep); + _myAvatarController->preSimulation(); } int numSubsteps = _dynamicsWorld->stepSimulation(timeStep, PHYSICS_ENGINE_MAX_NUM_SUBSTEPS, PHYSICS_ENGINE_FIXED_SUBSTEP); @@ -257,8 +260,8 @@ void PhysicsEngine::stepSimulation() { _numSubsteps += (uint32_t)numSubsteps; ObjectMotionState::setWorldSimulationStep(_numSubsteps); - if (_characterController) { - _characterController->postSimulation(); + if (_myAvatarController) { + _myAvatarController->postSimulation(); } updateContactMap(); _hasOutgoingChanges = true; @@ -268,7 +271,7 @@ void PhysicsEngine::stepSimulation() { void PhysicsEngine::doOwnershipInfection(const btCollisionObject* objectA, const btCollisionObject* objectB) { BT_PROFILE("ownershipInfection"); - const btCollisionObject* characterObject = _characterController ? _characterController->getCollisionObject() : nullptr; + const btCollisionObject* characterObject = _myAvatarController ? _myAvatarController->getCollisionObject() : nullptr; ObjectMotionState* motionStateA = static_cast(objectA->getUserPointer()); ObjectMotionState* motionStateB = static_cast(objectB->getUserPointer()); @@ -431,15 +434,15 @@ void PhysicsEngine::bump(ObjectMotionState* motionState) { } } -void PhysicsEngine::setCharacterController(DynamicCharacterController* character) { - if (_characterController != character) { - if (_characterController) { +void PhysicsEngine::setCharacterController(CharacterController* character) { + if (_myAvatarController != character) { + if (_myAvatarController) { // remove the character from the DynamicsWorld immediately - _characterController->setDynamicsWorld(nullptr); - _characterController = nullptr; + _myAvatarController->setDynamicsWorld(nullptr); + _myAvatarController = nullptr; } // the character will be added to the DynamicsWorld later - _characterController = character; + _myAvatarController = character; } } diff --git a/libraries/physics/src/PhysicsEngine.h b/libraries/physics/src/PhysicsEngine.h index 0a317652da..e7b5fd79d4 100644 --- a/libraries/physics/src/PhysicsEngine.h +++ b/libraries/physics/src/PhysicsEngine.h @@ -21,13 +21,14 @@ #include "BulletUtil.h" #include "ContactInfo.h" -#include "DynamicCharacterController.h" #include "ObjectMotionState.h" #include "ThreadSafeDynamicsWorld.h" #include "ObjectAction.h" const float HALF_SIMULATION_EXTENT = 512.0f; // meters +class CharacterController; + // simple class for keeping track of contacts class ContactKey { public: @@ -87,7 +88,7 @@ public: void removeRigidBody(btRigidBody* body); - void setCharacterController(DynamicCharacterController* character); + void setCharacterController(CharacterController* character); void dumpNextStats() { _dumpNextStats = true; } @@ -117,7 +118,7 @@ private: uint32_t _lastNumSubstepsAtUpdateInternal = 0; /// character collisions - DynamicCharacterController* _characterController = NULL; + CharacterController* _myAvatarController; bool _dumpNextStats = false; bool _hasOutgoingChanges = false; From 5f278f90246004dc0bbafe69d3e2082766bae4c6 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 22 Oct 2015 09:44:22 -0700 Subject: [PATCH 02/10] name change --- interface/src/avatar/MyAvatar.h | 6 +-- ...ntroller.cpp => MyCharacterController.cpp} | 44 +++++++++---------- ...arController.h => MyCharacterController.h} | 14 +++--- 3 files changed, 32 insertions(+), 32 deletions(-) rename interface/src/avatar/{MyAvatarController.cpp => MyCharacterController.cpp} (91%) rename interface/src/avatar/{MyAvatarController.h => MyCharacterController.h} (91%) diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index f3f55f4a7a..2f2b8ca3b5 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -19,7 +19,7 @@ #include "Avatar.h" //#include "AtRestDetector.h" -#include "MyAvatarController.h" +#include "MyCharacterController.h" //#define OLD_HMD_TRACKER @@ -158,7 +158,7 @@ public: virtual void setAttachmentData(const QVector& attachmentData) override; - MyAvatarController* getCharacterController() { return &_characterController; } + MyCharacterController* getCharacterController() { return &_characterController; } void prepareForPhysicsSimulation(); void harvestResultsFromPhysicsSimulation(); @@ -305,7 +305,7 @@ private: quint32 _motionBehaviors; QString _collisionSoundURL; - MyAvatarController _characterController; + MyCharacterController _characterController; AvatarWeakPointer _lookAtTargetAvatar; glm::vec3 _targetAvatarPosition; diff --git a/interface/src/avatar/MyAvatarController.cpp b/interface/src/avatar/MyCharacterController.cpp similarity index 91% rename from interface/src/avatar/MyAvatarController.cpp rename to interface/src/avatar/MyCharacterController.cpp index 931c8b9b08..05d6c57bb8 100644 --- a/interface/src/avatar/MyAvatarController.cpp +++ b/interface/src/avatar/MyCharacterController.cpp @@ -9,7 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include "MyAvatarController.h" +#include "MyCharacterController.h" #include #include @@ -50,7 +50,7 @@ protected: btRigidBody* _me; }; -MyAvatarController::MyAvatarController(MyAvatar* avatar) { +MyCharacterController::MyCharacterController(MyAvatar* avatar) { _halfHeight = 1.0f; _shape = nullptr; @@ -76,10 +76,10 @@ MyAvatarController::MyAvatarController(MyAvatar* avatar) { updateShapeIfNecessary(); } -MyAvatarController::~MyAvatarController() { +MyCharacterController::~MyCharacterController() { } -void MyAvatarController::preStep(btCollisionWorld* collisionWorld) { +void MyCharacterController::preStep(btCollisionWorld* collisionWorld) { // trace a ray straight down to see if we're standing on the ground const btTransform& xform = _rigidBody->getWorldTransform(); @@ -100,7 +100,7 @@ void MyAvatarController::preStep(btCollisionWorld* collisionWorld) { } } -void MyAvatarController::playerStep(btCollisionWorld* dynaWorld, btScalar dt) { +void MyCharacterController::playerStep(btCollisionWorld* dynaWorld, btScalar dt) { btVector3 actualVelocity = _rigidBody->getLinearVelocity(); btScalar actualSpeed = actualVelocity.length(); @@ -164,7 +164,7 @@ void MyAvatarController::playerStep(btCollisionWorld* dynaWorld, btScalar dt) { } } -void MyAvatarController::jump() { +void MyCharacterController::jump() { // check for case where user is holding down "jump" key... // we'll eventually tansition to "hover" if (!_isJumping) { @@ -182,12 +182,12 @@ void MyAvatarController::jump() { } } -bool MyAvatarController::onGround() const { +bool MyCharacterController::onGround() const { const btScalar FLOOR_PROXIMITY_THRESHOLD = 0.3f * _radius; return _floorDistance < FLOOR_PROXIMITY_THRESHOLD; } -void MyAvatarController::setHovering(bool hover) { +void MyCharacterController::setHovering(bool hover) { if (hover != _isHovering) { _isHovering = hover; _isJumping = false; @@ -202,7 +202,7 @@ void MyAvatarController::setHovering(bool hover) { } } -void MyAvatarController::setLocalBoundingBox(const glm::vec3& corner, const glm::vec3& scale) { +void MyCharacterController::setLocalBoundingBox(const glm::vec3& corner, const glm::vec3& scale) { _boxScale = scale; float x = _boxScale.x; @@ -236,16 +236,16 @@ void MyAvatarController::setLocalBoundingBox(const glm::vec3& corner, const glm: } /* moved to base class -bool MyAvatarController::needsRemoval() const { +bool MyCharacterController::needsRemoval() const { return (bool)(_pendingFlags & PENDING_FLAG_REMOVE_FROM_SIMULATION); } -bool MyAvatarController::needsAddition() const { +bool MyCharacterController::needsAddition() const { return (bool)(_pendingFlags & PENDING_FLAG_ADD_TO_SIMULATION); } */ -void MyAvatarController::setEnabled(bool enabled) { +void MyCharacterController::setEnabled(bool enabled) { if (enabled != _enabled) { if (enabled) { // Don't bother clearing REMOVE bit since it might be paired with an UPDATE_SHAPE bit. @@ -264,7 +264,7 @@ void MyAvatarController::setEnabled(bool enabled) { } /* moved to base class -void MyAvatarController::setDynamicsWorld(btDynamicsWorld* world) { +void MyCharacterController::setDynamicsWorld(btDynamicsWorld* world) { if (_dynamicsWorld != world) { if (_dynamicsWorld) { if (_rigidBody) { @@ -293,7 +293,7 @@ void MyAvatarController::setDynamicsWorld(btDynamicsWorld* world) { } }*/ -void MyAvatarController::updateShapeIfNecessary() { +void MyCharacterController::updateShapeIfNecessary() { if (_pendingFlags & PENDING_FLAG_UPDATE_SHAPE) { // make sure there is NO pending removal from simulation at this point // (don't want to delete _rigidBody out from under the simulation) @@ -342,7 +342,7 @@ void MyAvatarController::updateShapeIfNecessary() { } } -void MyAvatarController::updateUpAxis(const glm::quat& rotation) { +void MyCharacterController::updateUpAxis(const glm::quat& rotation) { btVector3 oldUp = _currentUp; _currentUp = quatRotate(glmToBullet(rotation), LOCAL_UP_AXIS); if (!_isHovering) { @@ -353,7 +353,7 @@ void MyAvatarController::updateUpAxis(const glm::quat& rotation) { } } -void MyAvatarController::setAvatarPositionAndOrientation( +void MyCharacterController::setAvatarPositionAndOrientation( const glm::vec3& position, const glm::quat& orientation) { // TODO: update gravity if up has changed @@ -364,7 +364,7 @@ void MyAvatarController::setAvatarPositionAndOrientation( _avatarBodyTransform = btTransform(bodyOrientation, bodyPosition); } -void MyAvatarController::getAvatarPositionAndOrientation(glm::vec3& position, glm::quat& rotation) const { +void MyCharacterController::getAvatarPositionAndOrientation(glm::vec3& position, glm::quat& rotation) const { if (_enabled && _rigidBody) { const btTransform& avatarTransform = _rigidBody->getWorldTransform(); rotation = bulletToGLM(avatarTransform.getRotation()); @@ -372,16 +372,16 @@ void MyAvatarController::getAvatarPositionAndOrientation(glm::vec3& position, gl } } -void MyAvatarController::setTargetVelocity(const glm::vec3& velocity) { +void MyCharacterController::setTargetVelocity(const glm::vec3& velocity) { //_walkVelocity = glmToBullet(_avatarData->getTargetVelocity()); _walkVelocity = glmToBullet(velocity); } -void MyAvatarController::setHMDVelocity(const glm::vec3& velocity) { +void MyCharacterController::setHMDVelocity(const glm::vec3& velocity) { _hmdVelocity = glmToBullet(velocity); } -glm::vec3 MyAvatarController::getLinearVelocity() const { +glm::vec3 MyCharacterController::getLinearVelocity() const { glm::vec3 velocity(0.0f); if (_rigidBody) { velocity = bulletToGLM(_rigidBody->getLinearVelocity()); @@ -389,7 +389,7 @@ glm::vec3 MyAvatarController::getLinearVelocity() const { return velocity; } -void MyAvatarController::preSimulation() { +void MyCharacterController::preSimulation() { if (_enabled && _dynamicsWorld) { /* glm::quat rotation = _avatarData->getOrientation(); @@ -440,7 +440,7 @@ void MyAvatarController::preSimulation() { } } -void MyAvatarController::postSimulation() { +void MyCharacterController::postSimulation() { /* _lastStepDuration += timeStep; if (_enabled && _rigidBody) { diff --git a/interface/src/avatar/MyAvatarController.h b/interface/src/avatar/MyCharacterController.h similarity index 91% rename from interface/src/avatar/MyAvatarController.h rename to interface/src/avatar/MyCharacterController.h index a973905653..2533ec2680 100644 --- a/interface/src/avatar/MyAvatarController.h +++ b/interface/src/avatar/MyCharacterController.h @@ -1,5 +1,5 @@ // -// MyAvatar.h +// MyCharacterController.h // interface/src/avatar // // Created by AndrewMeadows 2015.10.21 @@ -10,8 +10,8 @@ // -#ifndef hifi_MyAvatarController_h -#define hifi_MyAvatarController_h +#ifndef hifi_MyCharacterController_h +#define hifi_MyCharacterController_h #include #include @@ -22,10 +22,10 @@ class btCollisionShape; class MyAvatar; -class MyAvatarController : public CharacterController { +class MyCharacterController : public CharacterController { public: - MyAvatarController(MyAvatar* avatar); - ~MyAvatarController (); + MyCharacterController(MyAvatar* avatar); + ~MyCharacterController (); // TODO: implement these when needed virtual void setVelocityForTimeInterval(const btVector3 &velocity, btScalar timeInterval) override { assert(false); } @@ -103,4 +103,4 @@ protected: bool _isPushingUp; }; -#endif // hifi_MyAvatarController_h +#endif // hifi_MyCharacterController_h From 5e59e9595b1f2bded6021189ca44355acf0f6fb5 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 22 Oct 2015 09:45:47 -0700 Subject: [PATCH 03/10] fix typo in comments --- interface/src/avatar/MyCharacterController.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/MyCharacterController.cpp b/interface/src/avatar/MyCharacterController.cpp index 05d6c57bb8..4c77384e88 100644 --- a/interface/src/avatar/MyCharacterController.cpp +++ b/interface/src/avatar/MyCharacterController.cpp @@ -1,5 +1,5 @@ // -// MyAvatar.h +// MyCharacterController.h // interface/src/avatar // // Created by AndrewMeadows 2015.10.21 From 355ebe923dd94b879cf9cbc0c1400768fe1eb551 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 22 Oct 2015 09:51:36 -0700 Subject: [PATCH 04/10] cleanup and comments --- .../src/avatar/MyCharacterController.cpp | 63 +------------------ 1 file changed, 2 insertions(+), 61 deletions(-) diff --git a/interface/src/avatar/MyCharacterController.cpp b/interface/src/avatar/MyCharacterController.cpp index 4c77384e88..0ae4b240a2 100644 --- a/interface/src/avatar/MyCharacterController.cpp +++ b/interface/src/avatar/MyCharacterController.cpp @@ -235,16 +235,6 @@ void MyCharacterController::setLocalBoundingBox(const glm::vec3& corner, const g _shapeLocalOffset = corner + 0.5f * _boxScale; } -/* moved to base class -bool MyCharacterController::needsRemoval() const { - return (bool)(_pendingFlags & PENDING_FLAG_REMOVE_FROM_SIMULATION); -} - -bool MyCharacterController::needsAddition() const { - return (bool)(_pendingFlags & PENDING_FLAG_ADD_TO_SIMULATION); -} -*/ - void MyCharacterController::setEnabled(bool enabled) { if (enabled != _enabled) { if (enabled) { @@ -263,36 +253,6 @@ void MyCharacterController::setEnabled(bool enabled) { } } -/* moved to base class -void MyCharacterController::setDynamicsWorld(btDynamicsWorld* world) { - if (_dynamicsWorld != world) { - if (_dynamicsWorld) { - if (_rigidBody) { - _dynamicsWorld->removeRigidBody(_rigidBody); - _dynamicsWorld->removeAction(this); - } - _dynamicsWorld = nullptr; - } - if (world && _rigidBody) { - _dynamicsWorld = world; - _pendingFlags &= ~ PENDING_FLAG_JUMP; - _dynamicsWorld->addRigidBody(_rigidBody, COLLISION_GROUP_MY_AVATAR, COLLISION_MASK_MY_AVATAR); - _dynamicsWorld->addAction(this); - //reset(_dynamicsWorld); - } - } - if (_dynamicsWorld) { - if (_pendingFlags & PENDING_FLAG_UPDATE_SHAPE) { - // shouldn't fall in here, but if we do make sure both ADD and REMOVE bits are still set - _pendingFlags |= PENDING_FLAG_ADD_TO_SIMULATION | PENDING_FLAG_REMOVE_FROM_SIMULATION; - } else { - _pendingFlags &= ~PENDING_FLAG_ADD_TO_SIMULATION; - } - } else { - _pendingFlags &= ~ PENDING_FLAG_REMOVE_FROM_SIMULATION; - } -}*/ - void MyCharacterController::updateShapeIfNecessary() { if (_pendingFlags & PENDING_FLAG_UPDATE_SHAPE) { // make sure there is NO pending removal from simulation at this point @@ -391,14 +351,7 @@ glm::vec3 MyCharacterController::getLinearVelocity() const { void MyCharacterController::preSimulation() { if (_enabled && _dynamicsWorld) { - /* - glm::quat rotation = _avatarData->getOrientation(); - // TODO: update gravity if up has changed - updateUpAxis(rotation); - glm::vec3 position = _avatarData->getPosition() + rotation * _shapeLocalOffset; - _rigidBody->setWorldTransform(btTransform(glmToBullet(rotation), glmToBullet(position))); - */ - + // slam body to where it is supposed to be _rigidBody->setWorldTransform(_avatarBodyTransform); // scan for distant floor @@ -441,17 +394,5 @@ void MyCharacterController::preSimulation() { } void MyCharacterController::postSimulation() { - /* - _lastStepDuration += timeStep; - if (_enabled && _rigidBody) { - const btTransform& avatarTransform = _rigidBody->getWorldTransform(); - glm::quat rotation = bulletToGLM(avatarTransform.getRotation()); - glm::vec3 position = bulletToGLM(avatarTransform.getOrigin()); - - _avatarData->nextAttitude(position - rotation * _shapeLocalOffset, rotation); - _avatarData->setVelocity(bulletToGLM(_rigidBody->getLinearVelocity())); - _avatarData->applySimulationTime(_lastStepDuration); - } - _lastStepDuration = 0.0f; - */ + // postSimulation() exists for symmetry and just in case we need to do something here later } From 24c2f538a42bb34780b5a9310e44fdf59c504b35 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 22 Oct 2015 10:52:49 -0700 Subject: [PATCH 05/10] keep MyAvatar RigidBody on shape changes --- .../src/avatar/MyCharacterController.cpp | 27 +++++++++---------- interface/src/avatar/MyCharacterController.h | 1 - 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/interface/src/avatar/MyCharacterController.cpp b/interface/src/avatar/MyCharacterController.cpp index 0ae4b240a2..3e9755c6ca 100644 --- a/interface/src/avatar/MyCharacterController.cpp +++ b/interface/src/avatar/MyCharacterController.cpp @@ -52,7 +52,6 @@ protected: MyCharacterController::MyCharacterController(MyAvatar* avatar) { _halfHeight = 1.0f; - _shape = nullptr; assert(avatar); _avatar = avatar; @@ -255,15 +254,7 @@ void MyCharacterController::setEnabled(bool enabled) { void MyCharacterController::updateShapeIfNecessary() { if (_pendingFlags & PENDING_FLAG_UPDATE_SHAPE) { - // make sure there is NO pending removal from simulation at this point - // (don't want to delete _rigidBody out from under the simulation) - assert(!(_pendingFlags & PENDING_FLAG_REMOVE_FROM_SIMULATION)); _pendingFlags &= ~ PENDING_FLAG_UPDATE_SHAPE; - // delete shape and RigidBody - delete _rigidBody; - _rigidBody = nullptr; - delete _shape; - _shape = nullptr; // compute new dimensions from avatar's bounding box float x = _boxScale.x; @@ -277,15 +268,23 @@ void MyCharacterController::updateShapeIfNecessary() { // NOTE: _shapeLocalOffset is already computed if (_radius > 0.0f) { - // create new shape - _shape = new btCapsuleShape(_radius, 2.0f * _halfHeight); - // HACK: use some simple mass property defaults for now float mass = 100.0f; btVector3 inertia(30.0f, 8.0f, 30.0f); - // create new body - _rigidBody = new btRigidBody(mass, nullptr, _shape, inertia); + // create RigidBody if it doesn't exist + if (!_rigidBody) { + btCollisionShape* shape = new btCapsuleShape(_radius, 2.0f * _halfHeight); + _rigidBody = new btRigidBody(mass, nullptr, shape, inertia); + } else { + btCollisionShape* shape = _rigidBody->getCollisionShape(); + if (shape) { + delete shape; + } + shape = new btCapsuleShape(_radius, 2.0f * _halfHeight); + _rigidBody->setCollisionShape(shape); + } + _rigidBody->setSleepingThresholds(0.0f, 0.0f); _rigidBody->setAngularFactor(0.0f); _rigidBody->setWorldTransform(btTransform(glmToBullet(_avatar->getOrientation()), diff --git a/interface/src/avatar/MyCharacterController.h b/interface/src/avatar/MyCharacterController.h index 2533ec2680..5ee9f50f7e 100644 --- a/interface/src/avatar/MyCharacterController.h +++ b/interface/src/avatar/MyCharacterController.h @@ -82,7 +82,6 @@ protected: quint64 _jumpToHoverStart; - btCollisionShape* _shape { nullptr }; MyAvatar* _avatar { nullptr }; btScalar _halfHeight; From 43aac813daab023eeb5003ed3d0db072f104cf7d Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 22 Oct 2015 11:46:55 -0700 Subject: [PATCH 06/10] more prep for shifting avatar during HMD motion --- interface/src/avatar/MyAvatar.cpp | 17 +++++++++++------ interface/src/avatar/MyAvatar.h | 5 ++--- interface/src/avatar/MyCharacterController.cpp | 13 ++++++++++++- interface/src/avatar/MyCharacterController.h | 3 ++- libraries/physics/src/CharacterController.h | 1 - 5 files changed, 27 insertions(+), 12 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index e52e56cd89..cfcd7a69f9 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -114,7 +114,6 @@ MyAvatar::MyAvatar(RigPointer rig) : ,_hmdAtRestDetector(glm::vec3(0), glm::quat()) #else ,_avatarOffsetFromHMD(0.0f) - ,_hmdVelocity(0.0f) #endif // OLD_HMD_TRACKER { for (int i = 0; i < MAX_DRIVE_KEYS; i++) { @@ -375,9 +374,16 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { } followHMD(deltaTime); +#else + // TODO adebug BOOKMARK -- this is where we need to add the new code for HMD_TRACKER #endif // OLD_HMD_TRACKER } +glm::vec3 MyAvatar::getHMDCorrectionVelocity() const { + // TODO: impelement this + return Vectors::ZERO; +} + #ifdef OLD_HMD_TRACKER void MyAvatar::beginFollowingHMD() { // begin homing toward derived body position. @@ -433,10 +439,6 @@ void MyAvatar::followHMD(float deltaTime) { _bodySensorMatrix = createMatFromQuatAndPos(rot, pos); } } -} -#else -void MyAvatar::harvestHMDOffset(glm::vec3 offset) { - } #endif // USE_OLD @@ -1292,7 +1294,7 @@ void MyAvatar::prepareForPhysicsSimulation() { relayDriveKeysToCharacterController(); _characterController.setTargetVelocity(getTargetVelocity()); _characterController.setAvatarPositionAndOrientation(getPosition(), getOrientation()); - //_characterController.setHMDVelocity(hmdVelocity); + _characterController.setHMDVelocity(getHMDCorrectionVelocity()); } void MyAvatar::harvestResultsFromPhysicsSimulation() { @@ -1301,6 +1303,9 @@ void MyAvatar::harvestResultsFromPhysicsSimulation() { _characterController.getAvatarPositionAndOrientation(position, orientation); nextAttitude(position, orientation); setVelocity(_characterController.getLinearVelocity()); + + // adebug TODO: harvest HMD shift here + //glm::vec3 hmdShift = _characterController.getHMDShift(); } QString MyAvatar::getScriptedMotorFrame() const { diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 2f2b8ca3b5..36c73d672d 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -76,6 +76,8 @@ public: // as it moves through the world. void updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix); + glm::vec3 getHMDCorrectionVelocity() const; + // best called at end of main loop, just before rendering. // update sensor to world matrix from current body position and hmd sensor. // This is so the correct camera can be used for rendering. @@ -272,8 +274,6 @@ private: void beginFollowingHMD(); bool shouldFollowHMD() const; void followHMD(float deltaTime); -#else - void harvestHMDOffset(glm::vec3 offset); #endif bool cameraInsideHead() const; @@ -376,7 +376,6 @@ private: bool _lastIsMoving { false }; #else glm::vec3 _avatarOffsetFromHMD; - glm::vec3 _hmdVelocity; #endif // OLD_HMD_TRACKER }; diff --git a/interface/src/avatar/MyCharacterController.cpp b/interface/src/avatar/MyCharacterController.cpp index 3e9755c6ca..ad2ca32b05 100644 --- a/interface/src/avatar/MyCharacterController.cpp +++ b/interface/src/avatar/MyCharacterController.cpp @@ -16,7 +16,6 @@ #include #include -#include #include #include #include @@ -161,6 +160,17 @@ void MyCharacterController::playerStep(btCollisionWorld* dynaWorld, btScalar dt) _rigidBody->setLinearVelocity(actualVelocity + tau * velocityCorrection); } } + + // Rather than add _hmdVelocity to the velocity of the RigidBody, we explicitly teleport + // the RigidBody forward according to the formula: distance = rate * time + if (_hmdVelocity.length2() > 0.0f) { + btTransform bodyTransform = _rigidBody->getWorldTransform(); + bodyTransform.setOrigin(bodyTransform.getOrigin() + dt * _hmdVelocity); + _rigidBody->setWorldTransform(bodyTransform); + } + // MyAvatar will ask us how far we stepped for HMD motion, which will depend on how + // much time has accumulated in _lastStepDuration. + _lastStepDuration += dt; } void MyCharacterController::jump() { @@ -390,6 +400,7 @@ void MyCharacterController::preSimulation() { } } } + _lastStepDuration = 0.0f; } void MyCharacterController::postSimulation() { diff --git a/interface/src/avatar/MyCharacterController.h b/interface/src/avatar/MyCharacterController.h index 5ee9f50f7e..de711c84f4 100644 --- a/interface/src/avatar/MyCharacterController.h +++ b/interface/src/avatar/MyCharacterController.h @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -48,7 +49,6 @@ public: // overrides from CharacterController virtual void preSimulation() override; virtual void postSimulation() override; - virtual void incrementSimulationTime(btScalar timeStep) override { _lastStepDuration += timeStep; } bool isHovering() const { return _isHovering; } void setHovering(bool enabled); @@ -65,6 +65,7 @@ public: void setTargetVelocity(const glm::vec3& velocity); void setHMDVelocity(const glm::vec3& velocity); + glm::vec3 getHMDShift() const { return _lastStepDuration * bulletToGLM(_hmdVelocity); } glm::vec3 getLinearVelocity() const; diff --git a/libraries/physics/src/CharacterController.h b/libraries/physics/src/CharacterController.h index cff257a790..e9e6f1328e 100644 --- a/libraries/physics/src/CharacterController.h +++ b/libraries/physics/src/CharacterController.h @@ -36,7 +36,6 @@ public: virtual void updateShapeIfNecessary() = 0; virtual void preSimulation() = 0; - virtual void incrementSimulationTime(btScalar stepTime) = 0; virtual void postSimulation() = 0; virtual void setWalkDirection(const btVector3 &walkDirection) { assert(false); } From 8b285fd2287a3a6a02567208303f6f3e34693580 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 27 Oct 2015 13:51:40 -0700 Subject: [PATCH 07/10] recover follow HMD behavior --- interface/src/avatar/MyAvatar.cpp | 18 ++---------------- interface/src/avatar/MyAvatar.h | 9 +-------- 2 files changed, 3 insertions(+), 24 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index cfcd7a69f9..acde1dc599 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -109,12 +109,8 @@ MyAvatar::MyAvatar(RigPointer rig) : _goToOrientation(), _rig(rig), _prevShouldDrawHead(true), - _audioListenerMode(FROM_HEAD) -#ifdef OLD_HMD_TRACKER - ,_hmdAtRestDetector(glm::vec3(0), glm::quat()) -#else - ,_avatarOffsetFromHMD(0.0f) -#endif // OLD_HMD_TRACKER + _audioListenerMode(FROM_HEAD), + _hmdAtRestDetector(glm::vec3(0), glm::quat()) { for (int i = 0; i < MAX_DRIVE_KEYS; i++) { _driveKeys[i] = 0.0f; @@ -159,9 +155,7 @@ void MyAvatar::reset(bool andReload) { // Reset dynamic state. _wasPushing = _isPushing = _isBraking = _billboardValid = false; -#ifdef OLD_HMD_TRACKER _isFollowingHMD = false; -#endif // OLD_HMD_TRACKER _skeletonModel.reset(); getHead()->reset(); _targetVelocity = glm::vec3(0.0f); @@ -309,7 +303,6 @@ glm::mat4 MyAvatar::getSensorToWorldMatrix() const { return _sensorToWorldMatrix; } -#ifdef OLD_HMD_TRACKER // returns true if pos is OUTSIDE of the vertical capsule // where the middle cylinder length is defined by capsuleLen and the radius by capsuleRad. static bool pointIsOutsideCapsule(const glm::vec3& pos, float capsuleLen, float capsuleRad) { @@ -328,7 +321,6 @@ static bool pointIsOutsideCapsule(const glm::vec3& pos, float capsuleLen, float return false; } } -#endif // OLD_HMD_TRACKER // Pass a recent sample of the HMD to the avatar. // This can also update the avatar's position to follow the HMD @@ -339,7 +331,6 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { _hmdSensorPosition = extractTranslation(hmdSensorMatrix); _hmdSensorOrientation = glm::quat_cast(hmdSensorMatrix); -#ifdef OLD_HMD_TRACKER // calc deltaTime auto now = usecTimestampNow(); auto deltaUsecs = now - _lastUpdateFromHMDTime; @@ -374,9 +365,6 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { } followHMD(deltaTime); -#else - // TODO adebug BOOKMARK -- this is where we need to add the new code for HMD_TRACKER -#endif // OLD_HMD_TRACKER } glm::vec3 MyAvatar::getHMDCorrectionVelocity() const { @@ -384,7 +372,6 @@ glm::vec3 MyAvatar::getHMDCorrectionVelocity() const { return Vectors::ZERO; } -#ifdef OLD_HMD_TRACKER void MyAvatar::beginFollowingHMD() { // begin homing toward derived body position. if (!_isFollowingHMD) { @@ -440,7 +427,6 @@ void MyAvatar::followHMD(float deltaTime) { } } } -#endif // USE_OLD // best called at end of main loop, just before rendering. // update sensor to world matrix from current body position and hmd sensor. diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 36c73d672d..9e66472328 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -18,10 +18,9 @@ #include #include "Avatar.h" -//#include "AtRestDetector.h" +#include "AtRestDetector.h" #include "MyCharacterController.h" -//#define OLD_HMD_TRACKER class ModelItemID; @@ -270,11 +269,9 @@ private: const RecorderPointer getRecorder() const { return _recorder; } const PlayerPointer getPlayer() const { return _player; } -#ifdef OLD_HMD_TRACKER void beginFollowingHMD(); bool shouldFollowHMD() const; void followHMD(float deltaTime); -#endif bool cameraInsideHead() const; @@ -366,7 +363,6 @@ private: glm::vec3 _customListenPosition; glm::quat _customListenOrientation; -#ifdef OLD_HMD_TRACKER bool _isFollowingHMD { false }; float _followHMDAlpha{0.0f}; @@ -374,9 +370,6 @@ private: AtRestDetector _hmdAtRestDetector; glm::vec3 _lastPosition; bool _lastIsMoving { false }; -#else - glm::vec3 _avatarOffsetFromHMD; -#endif // OLD_HMD_TRACKER }; QScriptValue audioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode); From e35596428c7e9445036131326122a5efc3d59cd4 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 27 Oct 2015 14:43:18 -0700 Subject: [PATCH 08/10] cleanup comment --- interface/src/avatar/MyAvatar.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index acde1dc599..f7fad2bd2b 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1289,8 +1289,7 @@ void MyAvatar::harvestResultsFromPhysicsSimulation() { _characterController.getAvatarPositionAndOrientation(position, orientation); nextAttitude(position, orientation); setVelocity(_characterController.getLinearVelocity()); - - // adebug TODO: harvest HMD shift here + // TODO: harvest HMD shift here //glm::vec3 hmdShift = _characterController.getHMDShift(); } From c9cd3364005f29368c5412560adb86fea0fc381d Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 27 Oct 2015 15:01:48 -0700 Subject: [PATCH 09/10] fix for bad contacts after changing avatar models --- libraries/physics/src/PhysicsEngine.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index a6b8dbe959..d6772f8d36 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -246,6 +246,11 @@ void PhysicsEngine::stepSimulation() { // be done on the main thread during the pre-simulation stuff if (_myAvatarController->needsRemoval()) { _myAvatarController->setDynamicsWorld(nullptr); + + // We must remove any existing contacts for the avatar so that any new contacts will have + // valid data. MyAvatar's RigidBody is the ONLY one in the simulation that does not yet + // have a MotionState so we pass nullptr to removeContacts(). + removeContacts(nullptr); } _myAvatarController->updateShapeIfNecessary(); if (_myAvatarController->needsAddition()) { From afec2a9771cadd729f21aca42020fada86e898cd Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 28 Oct 2015 09:42:55 -0700 Subject: [PATCH 10/10] fix whitespace --- interface/src/avatar/MyAvatar.h | 6 +++--- libraries/physics/src/CharacterController.cpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 9e66472328..5f75b7cf14 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -164,7 +164,7 @@ public: void prepareForPhysicsSimulation(); void harvestResultsFromPhysicsSimulation(); - const QString& getCollisionSoundURL() {return _collisionSoundURL; } + const QString& getCollisionSoundURL() { return _collisionSoundURL; } void setCollisionSoundURL(const QString& url); void clearScriptableSettings(); @@ -364,9 +364,9 @@ private: glm::quat _customListenOrientation; bool _isFollowingHMD { false }; - float _followHMDAlpha{0.0f}; + float _followHMDAlpha { 0.0f }; - quint64 _lastUpdateFromHMDTime{usecTimestampNow()}; + quint64 _lastUpdateFromHMDTime { usecTimestampNow() }; AtRestDetector _hmdAtRestDetector; glm::vec3 _lastPosition; bool _lastIsMoving { false }; diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index 9ba22cf2db..aadf9b16ea 100644 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -32,7 +32,7 @@ void CharacterController::setDynamicsWorld(btDynamicsWorld* world) { } if (world && _rigidBody) { _dynamicsWorld = world; - _pendingFlags &= ~ PENDING_FLAG_JUMP; + _pendingFlags &= ~PENDING_FLAG_JUMP; _dynamicsWorld->addRigidBody(_rigidBody, COLLISION_GROUP_MY_AVATAR, COLLISION_MASK_MY_AVATAR); _dynamicsWorld->addAction(this); //reset(_dynamicsWorld); @@ -46,7 +46,7 @@ void CharacterController::setDynamicsWorld(btDynamicsWorld* world) { _pendingFlags &= ~PENDING_FLAG_ADD_TO_SIMULATION; } } else { - _pendingFlags &= ~ PENDING_FLAG_REMOVE_FROM_SIMULATION; + _pendingFlags &= ~PENDING_FLAG_REMOVE_FROM_SIMULATION; } }