From 551bfac85e793cc1a0919b4fa74641e288dbc7a2 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 15 Jun 2018 14:30:59 -0700 Subject: [PATCH 1/5] fix crash mode for Animation::_geometry access before ready --- libraries/animation/src/AnimationCache.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/libraries/animation/src/AnimationCache.cpp b/libraries/animation/src/AnimationCache.cpp index 9aa315beb8..f30d5605d7 100644 --- a/libraries/animation/src/AnimationCache.cpp +++ b/libraries/animation/src/AnimationCache.cpp @@ -105,8 +105,10 @@ QStringList Animation::getJointNames() const { return result; } QStringList names; - foreach (const FBXJoint& joint, _geometry->joints) { - names.append(joint.name); + if (_geometry) { + foreach (const FBXJoint& joint, _geometry->joints) { + names.append(joint.name); + } } return names; } @@ -114,11 +116,15 @@ QStringList Animation::getJointNames() const { QVector Animation::getFrames() const { if (QThread::currentThread() != thread()) { QVector result; - BLOCKING_INVOKE_METHOD(const_cast(this), "getFrames", + BLOCKING_INVOKE_METHOD(const_cast(this), "getFrames", Q_RETURN_ARG(QVector, result)); return result; } - return _geometry->animationFrames; + if (_geometry) { + return _geometry->animationFrames; + } else { + return QVector(); + } } const QVector& Animation::getFramesReference() const { From 670e07bbf5ea1e785e5bf68ee683bc1f58887854 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 15 Jun 2018 14:31:51 -0700 Subject: [PATCH 2/5] fix crash for computing inertia for btBvhTriangleMeshShape --- libraries/physics/src/ObjectMotionState.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libraries/physics/src/ObjectMotionState.cpp b/libraries/physics/src/ObjectMotionState.cpp index 64d2368207..161d6bd636 100644 --- a/libraries/physics/src/ObjectMotionState.cpp +++ b/libraries/physics/src/ObjectMotionState.cpp @@ -92,7 +92,7 @@ void ObjectMotionState::setMass(float mass) { } float ObjectMotionState::getMass() const { - if (_shape) { + if (_shape && _shape->getShapeType() != TRIANGLE_MESH_SHAPE_PROXYTYPE) { // scale the density by the current Aabb volume to get mass btTransform transform; transform.setIdentity(); @@ -348,8 +348,10 @@ void ObjectMotionState::updateLastKinematicStep() { void ObjectMotionState::updateBodyMassProperties() { float mass = getMass(); - btVector3 inertia(0.0f, 0.0f, 0.0f); - _body->getCollisionShape()->calculateLocalInertia(mass, inertia); + btVector3 inertia(1.0f, 1.0f, 1.0f); + if (mass > 0.0f) { + _body->getCollisionShape()->calculateLocalInertia(mass, inertia); + } _body->setMassProps(mass, inertia); _body->updateInertiaTensor(); } From cdce598c35bcd61fbeb2098b25474964e889de0d Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 15 Jun 2018 14:49:07 -0700 Subject: [PATCH 3/5] protect against misuse of Sysmem::setSubData() --- libraries/gpu/src/gpu/Sysmem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/gpu/src/gpu/Sysmem.cpp b/libraries/gpu/src/gpu/Sysmem.cpp index a642d40478..d942c3fd27 100644 --- a/libraries/gpu/src/gpu/Sysmem.cpp +++ b/libraries/gpu/src/gpu/Sysmem.cpp @@ -124,7 +124,7 @@ Size Sysmem::setData( Size size, const Byte* bytes ) { } Size Sysmem::setSubData( Size offset, Size size, const Byte* bytes) { - if (size && ((offset + size) <= getSize()) && bytes) { + if (_data && size && ((offset + size) <= getSize()) && bytes) { memcpy( _data + offset, bytes, size ); return size; } From 4880492d058d6ea609c23bf9baf4b7494dd35df3 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 15 Jun 2018 14:49:46 -0700 Subject: [PATCH 4/5] protect against bad menu pointer --- libraries/ui/src/ui/Menu.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libraries/ui/src/ui/Menu.cpp b/libraries/ui/src/ui/Menu.cpp index 16af862324..848b2362ee 100644 --- a/libraries/ui/src/ui/Menu.cpp +++ b/libraries/ui/src/ui/Menu.cpp @@ -402,8 +402,10 @@ MenuWrapper* Menu::addMenu(const QString& menuName, const QString& grouping) { // hook our show/hide for popup menus, so we can keep track of whether or not one // of our submenus is currently showing. - connect(menu->_realMenu, &QMenu::aboutToShow, []() { _isSomeSubmenuShown = true; }); - connect(menu->_realMenu, &QMenu::aboutToHide, []() { _isSomeSubmenuShown = false; }); + if (menu && menu->_realMenu) { + connect(menu->_realMenu, &QMenu::aboutToShow, []() { _isSomeSubmenuShown = true; }); + connect(menu->_realMenu, &QMenu::aboutToHide, []() { _isSomeSubmenuShown = false; }); + } return menu; } From 085130e3c92506eeaba72f60fd4aa76544fee16d Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 18 Jun 2018 13:17:32 -0700 Subject: [PATCH 5/5] avatars collide again again --- interface/src/avatar/AvatarMotionState.cpp | 47 ++++++++++++++----- interface/src/avatar/AvatarMotionState.h | 6 +++ .../src/avatars-renderer/Avatar.cpp | 13 +++-- libraries/physics/src/ObjectMotionState.h | 4 +- libraries/physics/src/PhysicsEngine.cpp | 6 +-- libraries/shared/src/AvatarConstants.h | 1 + 6 files changed, 54 insertions(+), 23 deletions(-) diff --git a/interface/src/avatar/AvatarMotionState.cpp b/interface/src/avatar/AvatarMotionState.cpp index 4c5aaacb95..6fc1bd8196 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; + _diameter = 2.0f * glm::length(halfExtents); return getShapeManager()->getShape(shapeInfo); } @@ -60,25 +74,31 @@ void AvatarMotionState::getWorldTransform(btTransform& worldTrans) const { worldTrans.setRotation(glmToBullet(getObjectRotation())); if (_body) { _body->setLinearVelocity(glmToBullet(getObjectLinearVelocity())); - _body->setAngularVelocity(glmToBullet(getObjectLinearVelocity())); + _body->setAngularVelocity(glmToBullet(getObjectAngularVelocity())); } } // 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 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 distance = offsetToTarget.length(); + if ((1.0f - tau) * distance > _diameter) { + // the avatar body is far from its target --> slam position + btTransform newTransform; + newTransform.setOrigin(currentPosition + offsetToTarget); + newTransform.setRotation(glmToBullet(getObjectRotation())); + _body->setWorldTransform(newTransform); + _body->setLinearVelocity(glmToBullet(getObjectLinearVelocity())); + _body->setAngularVelocity(glmToBullet(getObjectAngularVelocity())); + } else { + // 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())); + } } // These pure virtual methods must be implemented for each MotionState type @@ -145,3 +165,8 @@ void AvatarMotionState::computeCollisionGroupAndMask(int32_t& group, int32_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 07e8102752..2738aba8ee 100644 --- a/interface/src/avatar/AvatarMotionState.h +++ b/interface/src/avatar/AvatarMotionState.h @@ -23,6 +23,9 @@ class AvatarMotionState : public ObjectMotionState { public: AvatarMotionState(AvatarSharedPointer avatar, const btCollisionShape* shape); + virtual void handleEasyChanges(uint32_t& flags) override; + virtual bool handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine) override; + virtual PhysicsMotionType getMotionType() const override { return _motionType; } virtual uint32_t getIncomingDirtyFlags() override; @@ -64,6 +67,8 @@ public: virtual void computeCollisionGroupAndMask(int32_t& group, int32_t& mask) const override; + virtual float getMass() const override; + friend class AvatarManager; friend class Avatar; @@ -76,6 +81,7 @@ protected: virtual const btCollisionShape* computeNewShape() override; AvatarSharedPointer _avatar; + float _diameter { 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 9682c81697..615f11e897 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -861,7 +861,6 @@ bool Avatar::shouldRenderHead(const RenderArgs* renderArgs) const { return true; } -// virtual void Avatar::simulateAttachments(float deltaTime) { assert(_attachmentModels.size() == _attachmentModelsTexturesLoaded.size()); PerformanceTimer perfTimer("attachments"); @@ -1544,12 +1543,13 @@ 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 = glm::max(MIN_AVATAR_RADIUS, uniformScale * _skeletonModel->getBoundingCapsuleRadius()); + float height = glm::max(MIN_AVATAR_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) { @@ -1572,9 +1572,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 0ca28d6b09..4a3b200559 100644 --- a/libraries/physics/src/ObjectMotionState.h +++ b/libraries/physics/src/ObjectMotionState.h @@ -110,8 +110,8 @@ public: MotionStateType getType() const { return _type; } virtual PhysicsMotionType getMotionType() const { return _motionType; } - void setMass(float mass); - float getMass() const; + virtual void setMass(float mass); + virtual float getMass() const; void setBodyLinearVelocity(const glm::vec3& velocity) const; void setBodyAngularVelocity(const glm::vec3& velocity) const; diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index ee87cab8e8..66a4edb486 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -105,9 +105,9 @@ void PhysicsEngine::addObjectToDynamicsWorld(ObjectMotionState* motionState) { } case MOTION_TYPE_DYNAMIC: { mass = motionState->getMass(); - if (mass != mass || mass < 1.0f) { - qCDebug(physics) << "mass is too low, setting to 1.0 Kg --" << mass; - mass = 1.0f; + const float MIN_DYNAMIC_MASS = 0.01f; + if (mass != mass || mass < MIN_DYNAMIC_MASS) { + mass = MIN_DYNAMIC_MASS; } btCollisionShape* shape = const_cast(motionState->getShape()); assert(shape); diff --git a/libraries/shared/src/AvatarConstants.h b/libraries/shared/src/AvatarConstants.h index e90e25d5b0..58cbff6669 100644 --- a/libraries/shared/src/AvatarConstants.h +++ b/libraries/shared/src/AvatarConstants.h @@ -69,6 +69,7 @@ static const float MIN_AVATAR_SCALE = 0.005f; static const float MAX_AVATAR_HEIGHT = 1000.0f * DEFAULT_AVATAR_HEIGHT; // meters static const float MIN_AVATAR_HEIGHT = 0.005f * DEFAULT_AVATAR_HEIGHT; // meters +static const float MIN_AVATAR_RADIUS = 0.5f * MIN_AVATAR_HEIGHT; static const float AVATAR_WALK_SPEED_SCALAR = 1.0f; static const float AVATAR_SPRINT_SPEED_SCALAR = 3.0f;