From 6de175e794146c9f521275a7da45335b8fef6388 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 11 May 2018 17:01:48 -0700 Subject: [PATCH 1/3] avatars collide again --- interface/src/avatar/AvatarMotionState.cpp | 45 +++++++++++++---- interface/src/avatar/AvatarMotionState.h | 48 +++++++++++-------- .../src/avatars-renderer/Avatar.cpp | 14 +++--- libraries/physics/src/ObjectMotionState.h | 2 +- 4 files changed, 72 insertions(+), 37 deletions(-) diff --git a/interface/src/avatar/AvatarMotionState.cpp b/interface/src/avatar/AvatarMotionState.cpp index 900c1c0a11..ac52a6e485 100644 --- a/interface/src/avatar/AvatarMotionState.cpp +++ b/interface/src/avatar/AvatarMotionState.cpp @@ -21,6 +21,17 @@ AvatarMotionState::AvatarMotionState(AvatarSharedPointer avatar, const btCollisi _type = MOTIONSTATE_TYPE_AVATAR; } +void AvatarMotionState::handleEasyChanges(uint32_t& flags) { + ObjectMotionState::handleEasyChanges(flags); + if (flags & Simulation::DIRTY_PHYSICS_ACTIVATION && !_body->isActive()) { + _body->activate(); + } +} + +bool AvatarMotionState::handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine) { + return ObjectMotionState::handleHardAndEasyChanges(flags, engine); +} + AvatarMotionState::~AvatarMotionState() { assert(_avatar); _avatar = nullptr; @@ -46,6 +57,9 @@ PhysicsMotionType AvatarMotionState::computePhysicsMotionType() const { const btCollisionShape* AvatarMotionState::computeNewShape() { ShapeInfo shapeInfo; std::static_pointer_cast(_avatar)->computeShapeInfo(shapeInfo); + glm::vec3 halfExtents = shapeInfo.getHalfExtents(); + halfExtents.y = 0.0f; + _radius2 = glm::length2(halfExtents); return getShapeManager()->getShape(shapeInfo); } @@ -60,7 +74,7 @@ void AvatarMotionState::getWorldTransform(btTransform& worldTrans) const { worldTrans.setRotation(glmToBullet(getObjectRotation())); if (_body) { _body->setLinearVelocity(glmToBullet(getObjectLinearVelocity())); - _body->setAngularVelocity(glmToBullet(getObjectLinearVelocity())); + _body->setAngularVelocity(glmToBullet(getObjectAngularVelocity())); } } @@ -72,13 +86,23 @@ void AvatarMotionState::setWorldTransform(const btTransform& worldTrans) { const float SPRING_TIMESCALE = 0.5f; float tau = PHYSICS_ENGINE_FIXED_SUBSTEP / SPRING_TIMESCALE; btVector3 currentPosition = worldTrans.getOrigin(); - btVector3 targetPosition = glmToBullet(getObjectPosition()); - btTransform newTransform; - newTransform.setOrigin((1.0f - tau) * currentPosition + tau * targetPosition); - newTransform.setRotation(glmToBullet(getObjectRotation())); - _body->setWorldTransform(newTransform); - _body->setLinearVelocity(glmToBullet(getObjectLinearVelocity())); - _body->setAngularVelocity(glmToBullet(getObjectLinearVelocity())); + btVector3 offsetToTarget = glmToBullet(getObjectPosition()) - currentPosition; + float distance2 = offsetToTarget.length2(); + const float TWO_SQUARED = 4.0f; + if (distance2 > TWO_SQUARED * _radius2) { + // reduce the offsetToTarget by slamming the position + btTransform newTransform; + newTransform.setOrigin(currentPosition + tau * offsetToTarget); + newTransform.setRotation(glmToBullet(getObjectRotation())); + _body->setWorldTransform(newTransform); + _body->setLinearVelocity(glmToBullet(getObjectLinearVelocity())); + _body->setAngularVelocity(glmToBullet(getObjectAngularVelocity())); + } else { + // reduce the offsetToTarget by slamming the velocity + btVector3 velocity = glmToBullet(getObjectLinearVelocity()) + (1.0f / SPRING_TIMESCALE) * offsetToTarget; + _body->setLinearVelocity(velocity); + _body->setAngularVelocity(glmToBullet(getObjectAngularVelocity())); + } } // These pure virtual methods must be implemented for each MotionState type @@ -145,3 +169,8 @@ void AvatarMotionState::computeCollisionGroupAndMask(int16_t& group, int16_t& ma mask = Physics::getDefaultCollisionMask(group); } +// virtual +float AvatarMotionState::getMass() const { + return std::static_pointer_cast(_avatar)->computeMass(); +} + diff --git a/interface/src/avatar/AvatarMotionState.h b/interface/src/avatar/AvatarMotionState.h index 90bd2a60ac..cfddab90ce 100644 --- a/interface/src/avatar/AvatarMotionState.h +++ b/interface/src/avatar/AvatarMotionState.h @@ -23,46 +23,51 @@ class AvatarMotionState : public ObjectMotionState { public: AvatarMotionState(AvatarSharedPointer avatar, const btCollisionShape* shape); - virtual PhysicsMotionType getMotionType() const override { return _motionType; } + void handleEasyChanges(uint32_t& flags) override; + bool handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine) override; - virtual uint32_t getIncomingDirtyFlags() override; - virtual void clearIncomingDirtyFlags() override; + PhysicsMotionType getMotionType() const override { return _motionType; } - virtual PhysicsMotionType computePhysicsMotionType() const override; + uint32_t getIncomingDirtyFlags() override; + void clearIncomingDirtyFlags() override; - virtual bool isMoving() const override; + PhysicsMotionType computePhysicsMotionType() const override; + + bool isMoving() const override; // this relays incoming position/rotation to the RigidBody - virtual void getWorldTransform(btTransform& worldTrans) const override; + void getWorldTransform(btTransform& worldTrans) const override; // this relays outgoing position/rotation to the EntityItem - virtual void setWorldTransform(const btTransform& worldTrans) override; + void setWorldTransform(const btTransform& worldTrans) override; // These pure virtual methods must be implemented for each MotionState type // and make it possible to implement more complicated methods in this base class. // pure virtual overrides from ObjectMotionState - virtual float getObjectRestitution() const override; - virtual float getObjectFriction() const override; - virtual float getObjectLinearDamping() const override; - virtual float getObjectAngularDamping() const override; + float getObjectRestitution() const override; + float getObjectFriction() const override; + float getObjectLinearDamping() const override; + float getObjectAngularDamping() const override; - virtual glm::vec3 getObjectPosition() const override; - virtual glm::quat getObjectRotation() const override; - virtual glm::vec3 getObjectLinearVelocity() const override; - virtual glm::vec3 getObjectAngularVelocity() const override; - virtual glm::vec3 getObjectGravity() const override; + glm::vec3 getObjectPosition() const override; + glm::quat getObjectRotation() const override; + glm::vec3 getObjectLinearVelocity() const override; + glm::vec3 getObjectAngularVelocity() const override; + glm::vec3 getObjectGravity() const override; - virtual const QUuid getObjectID() const override; + const QUuid getObjectID() const override; - virtual QUuid getSimulatorID() const override; + QUuid getSimulatorID() const override; void setBoundingBox(const glm::vec3& corner, const glm::vec3& diagonal); void addDirtyFlags(uint32_t flags) { _dirtyFlags |= flags; } - virtual void computeCollisionGroupAndMask(int16_t& group, int16_t& mask) const override; + void computeCollisionGroupAndMask(int16_t& group, int16_t& mask) const override; + + float getMass() const override; friend class AvatarManager; friend class Avatar; @@ -72,10 +77,11 @@ protected: // ever called by the Avatar class dtor. ~AvatarMotionState(); - virtual bool isReadyToComputeShape() const override { return true; } - virtual const btCollisionShape* computeNewShape() override; + bool isReadyToComputeShape() const override { return true; } + const btCollisionShape* computeNewShape() override; AvatarSharedPointer _avatar; + float _radius2 { 0.0f }; uint32_t _dirtyFlags; }; diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index 048b8b1633..da829b23e4 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -799,7 +799,6 @@ bool Avatar::shouldRenderHead(const RenderArgs* renderArgs) const { return true; } -// virtual void Avatar::simulateAttachments(float deltaTime) { assert(_attachmentModels.size() == _attachmentModelsTexturesLoaded.size()); PerformanceTimer perfTimer("attachments"); @@ -1482,12 +1481,14 @@ void Avatar::updateDisplayNameAlpha(bool showDisplayName) { } } -// virtual void Avatar::computeShapeInfo(ShapeInfo& shapeInfo) { float uniformScale = getModelScale(); - shapeInfo.setCapsuleY(uniformScale * _skeletonModel->getBoundingCapsuleRadius(), - 0.5f * uniformScale * _skeletonModel->getBoundingCapsuleHeight()); - shapeInfo.setOffset(uniformScale * _skeletonModel->getBoundingCapsuleOffset()); + float radius = uniformScale * _skeletonModel->getBoundingCapsuleRadius(); + float height = uniformScale * _skeletonModel->getBoundingCapsuleHeight(); + shapeInfo.setCapsuleY(radius, 0.5f * height); + + glm::vec3 offset = uniformScale * _skeletonModel->getBoundingCapsuleOffset(); + shapeInfo.setOffset(offset); } void Avatar::getCapsule(glm::vec3& start, glm::vec3& end, float& radius) { @@ -1510,9 +1511,8 @@ float Avatar::computeMass() { return _density * TWO_PI * radius * radius * (glm::length(end - start) + 2.0f * radius / 3.0f); } -// virtual void Avatar::rebuildCollisionShape() { - addPhysicsFlags(Simulation::DIRTY_SHAPE); + addPhysicsFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS); } void Avatar::setPhysicsCallback(AvatarPhysicsCallback cb) { diff --git a/libraries/physics/src/ObjectMotionState.h b/libraries/physics/src/ObjectMotionState.h index fbda9366fc..e1cf5a4285 100644 --- a/libraries/physics/src/ObjectMotionState.h +++ b/libraries/physics/src/ObjectMotionState.h @@ -111,7 +111,7 @@ public: virtual PhysicsMotionType getMotionType() const { return _motionType; } void setMass(float mass); - float getMass() const; + virtual float getMass() const; void setBodyLinearVelocity(const glm::vec3& velocity) const; void setBodyAngularVelocity(const glm::vec3& velocity) const; From a30e06d5949d36bc6742200d9042fa0496f5dfc4 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 14 May 2018 09:58:16 -0700 Subject: [PATCH 2/3] don't blend avatar position when far from target --- interface/src/avatar/AvatarMotionState.cpp | 16 ++++++---------- interface/src/avatar/AvatarMotionState.h | 2 +- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/interface/src/avatar/AvatarMotionState.cpp b/interface/src/avatar/AvatarMotionState.cpp index ac52a6e485..beb7e34439 100644 --- a/interface/src/avatar/AvatarMotionState.cpp +++ b/interface/src/avatar/AvatarMotionState.cpp @@ -59,7 +59,7 @@ const btCollisionShape* AvatarMotionState::computeNewShape() { std::static_pointer_cast(_avatar)->computeShapeInfo(shapeInfo); glm::vec3 halfExtents = shapeInfo.getHalfExtents(); halfExtents.y = 0.0f; - _radius2 = glm::length2(halfExtents); + _diameter = 2.0f * glm::length(halfExtents); return getShapeManager()->getShape(shapeInfo); } @@ -80,25 +80,21 @@ void AvatarMotionState::getWorldTransform(btTransform& worldTrans) const { // virtual void AvatarMotionState::setWorldTransform(const btTransform& worldTrans) { - // HACK: The PhysicsEngine does not actually move OTHER avatars -- instead it slaves their local RigidBody to the transform - // as specified by a remote simulation. However, to give the remote simulation time to respond to our own objects we tie - // the other avatar's body to its true position with a simple spring. This is a HACK that will have to be improved later. const float SPRING_TIMESCALE = 0.5f; float tau = PHYSICS_ENGINE_FIXED_SUBSTEP / SPRING_TIMESCALE; btVector3 currentPosition = worldTrans.getOrigin(); btVector3 offsetToTarget = glmToBullet(getObjectPosition()) - currentPosition; - float distance2 = offsetToTarget.length2(); - const float TWO_SQUARED = 4.0f; - if (distance2 > TWO_SQUARED * _radius2) { - // reduce the offsetToTarget by slamming the position + float distance = offsetToTarget.length(); + if ((1.0f - tau) * distance > _diameter) { + // the avatar body is far from its target --> slam position btTransform newTransform; - newTransform.setOrigin(currentPosition + tau * offsetToTarget); + newTransform.setOrigin(currentPosition + offsetToTarget); newTransform.setRotation(glmToBullet(getObjectRotation())); _body->setWorldTransform(newTransform); _body->setLinearVelocity(glmToBullet(getObjectLinearVelocity())); _body->setAngularVelocity(glmToBullet(getObjectAngularVelocity())); } else { - // reduce the offsetToTarget by slamming the velocity + // the avatar body is near its target --> slam velocity btVector3 velocity = glmToBullet(getObjectLinearVelocity()) + (1.0f / SPRING_TIMESCALE) * offsetToTarget; _body->setLinearVelocity(velocity); _body->setAngularVelocity(glmToBullet(getObjectAngularVelocity())); diff --git a/interface/src/avatar/AvatarMotionState.h b/interface/src/avatar/AvatarMotionState.h index cfddab90ce..b0f7f29e37 100644 --- a/interface/src/avatar/AvatarMotionState.h +++ b/interface/src/avatar/AvatarMotionState.h @@ -81,7 +81,7 @@ protected: const btCollisionShape* computeNewShape() override; AvatarSharedPointer _avatar; - float _radius2 { 0.0f }; + float _diameter { 0.0f }; uint32_t _dirtyFlags; }; From c5773cbe84374a3932a7ee9228cb731e2aab1992 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 15 May 2018 13:59:22 -0700 Subject: [PATCH 3/3] restore 'virtual' keyword for overrides --- interface/src/avatar/AvatarMotionState.h | 48 ++++++++++++------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/interface/src/avatar/AvatarMotionState.h b/interface/src/avatar/AvatarMotionState.h index b0f7f29e37..73fb853312 100644 --- a/interface/src/avatar/AvatarMotionState.h +++ b/interface/src/avatar/AvatarMotionState.h @@ -23,51 +23,51 @@ class AvatarMotionState : public ObjectMotionState { public: AvatarMotionState(AvatarSharedPointer avatar, const btCollisionShape* shape); - void handleEasyChanges(uint32_t& flags) override; - bool handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine) override; + virtual void handleEasyChanges(uint32_t& flags) override; + virtual bool handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine) override; - PhysicsMotionType getMotionType() const override { return _motionType; } + virtual PhysicsMotionType getMotionType() const override { return _motionType; } - uint32_t getIncomingDirtyFlags() override; - void clearIncomingDirtyFlags() override; + virtual uint32_t getIncomingDirtyFlags() override; + virtual void clearIncomingDirtyFlags() override; - PhysicsMotionType computePhysicsMotionType() const override; + virtual PhysicsMotionType computePhysicsMotionType() const override; - bool isMoving() const override; + virtual bool isMoving() const override; // this relays incoming position/rotation to the RigidBody - void getWorldTransform(btTransform& worldTrans) const override; + virtual void getWorldTransform(btTransform& worldTrans) const override; // this relays outgoing position/rotation to the EntityItem - void setWorldTransform(const btTransform& worldTrans) override; + virtual void setWorldTransform(const btTransform& worldTrans) override; // These pure virtual methods must be implemented for each MotionState type // and make it possible to implement more complicated methods in this base class. // pure virtual overrides from ObjectMotionState - float getObjectRestitution() const override; - float getObjectFriction() const override; - float getObjectLinearDamping() const override; - float getObjectAngularDamping() const override; + virtual float getObjectRestitution() const override; + virtual float getObjectFriction() const override; + virtual float getObjectLinearDamping() const override; + virtual float getObjectAngularDamping() const override; - glm::vec3 getObjectPosition() const override; - glm::quat getObjectRotation() const override; - glm::vec3 getObjectLinearVelocity() const override; - glm::vec3 getObjectAngularVelocity() const override; - glm::vec3 getObjectGravity() const override; + virtual glm::vec3 getObjectPosition() const override; + virtual glm::quat getObjectRotation() const override; + virtual glm::vec3 getObjectLinearVelocity() const override; + virtual glm::vec3 getObjectAngularVelocity() const override; + virtual glm::vec3 getObjectGravity() const override; - const QUuid getObjectID() const override; + virtual const QUuid getObjectID() const override; - QUuid getSimulatorID() const override; + virtual QUuid getSimulatorID() const override; void setBoundingBox(const glm::vec3& corner, const glm::vec3& diagonal); void addDirtyFlags(uint32_t flags) { _dirtyFlags |= flags; } - void computeCollisionGroupAndMask(int16_t& group, int16_t& mask) const override; + virtual void computeCollisionGroupAndMask(int16_t& group, int16_t& mask) const override; - float getMass() const override; + virtual float getMass() const override; friend class AvatarManager; friend class Avatar; @@ -77,8 +77,8 @@ protected: // ever called by the Avatar class dtor. ~AvatarMotionState(); - bool isReadyToComputeShape() const override { return true; } - const btCollisionShape* computeNewShape() override; + virtual bool isReadyToComputeShape() const override { return true; } + virtual const btCollisionShape* computeNewShape() override; AvatarSharedPointer _avatar; float _diameter { 0.0f };