From 0d92e2de0ac3dfe2cc75ac2b74950431e21af1e2 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 1 Aug 2018 11:21:54 -0700 Subject: [PATCH 1/4] remove bits from other-avatar collision mask --- libraries/shared/src/PhysicsCollisionGroups.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libraries/shared/src/PhysicsCollisionGroups.h b/libraries/shared/src/PhysicsCollisionGroups.h index 9d99ec3532..ef18cb0b0e 100644 --- a/libraries/shared/src/PhysicsCollisionGroups.h +++ b/libraries/shared/src/PhysicsCollisionGroups.h @@ -59,7 +59,11 @@ const int32_t BULLET_COLLISION_MASK_KINEMATIC = BULLET_COLLISION_MASK_STATIC; // MY_AVATAR does not collide with itself const int32_t BULLET_COLLISION_MASK_MY_AVATAR = ~(BULLET_COLLISION_GROUP_COLLISIONLESS | BULLET_COLLISION_GROUP_MY_AVATAR); -const int32_t BULLET_COLLISION_MASK_OTHER_AVATAR = BULLET_COLLISION_MASK_DEFAULT; +// OTHER_AVATARs are dynamic, but are slammed to whatever the avatar-mixer says, which means +// their motion can't actually be affected by the local physics simulation -- we rely on the remote simulation +// to move its avatar around correctly and to communicate its motion through the avatar-mixer. +// Therefore, they only need to collide against things that can be affected by their motion: dynamic and MyAvatar +const int32_t BULLET_COLLISION_MASK_OTHER_AVATAR = BULLET_COLLISION_GROUP_DYNAMIC | BULLET_COLLISION_GROUP_MY_AVATAR; // COLLISIONLESS gets an empty mask. const int32_t BULLET_COLLISION_MASK_COLLISIONLESS = 0; From c9396998796d10768bdac8e43ea70a6ff66e73c8 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 1 Aug 2018 11:22:58 -0700 Subject: [PATCH 2/4] ignore other-avatar angularVelocity in physics simulation --- interface/src/avatar/AvatarMotionState.cpp | 29 ++++++++++++++++++--- interface/src/avatar/AvatarMotionState.h | 3 +++ libraries/physics/src/ObjectMotionState.cpp | 2 +- libraries/physics/src/ObjectMotionState.h | 2 +- 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/interface/src/avatar/AvatarMotionState.cpp b/interface/src/avatar/AvatarMotionState.cpp index 50c715b14a..298701ca5d 100644 --- a/interface/src/avatar/AvatarMotionState.cpp +++ b/interface/src/avatar/AvatarMotionState.cpp @@ -19,6 +19,7 @@ AvatarMotionState::AvatarMotionState(AvatarSharedPointer avatar, const btCollisionShape* shape) : ObjectMotionState(shape), _avatar(avatar) { assert(_avatar); _type = MOTIONSTATE_TYPE_AVATAR; + cacheShapeDiameter(); } void AvatarMotionState::handleEasyChanges(uint32_t& flags) { @@ -57,9 +58,6 @@ 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); } @@ -141,7 +139,10 @@ glm::vec3 AvatarMotionState::getObjectLinearVelocity() const { // virtual glm::vec3 AvatarMotionState::getObjectAngularVelocity() const { - return _avatar->getWorldAngularVelocity(); + // HACK: avatars use a capusle collision shape and their angularVelocity in the local simulation is unimportant. + // Therefore, as optimization toward support for larger crowds we ignore it and return zero. + //return _avatar->getWorldAngularVelocity(); + return glm::vec3(0.0f); } // virtual @@ -174,3 +175,23 @@ float AvatarMotionState::getMass() const { return std::static_pointer_cast(_avatar)->computeMass(); } +void AvatarMotionState::cacheShapeDiameter() { + if (_shape) { + // measure XZ diameter of capsule shape + btVector3 aabbMin, aabbMax; + btTransform transform; + transform.setIdentity(); + _shape->getAabb(transform, aabbMin, aabbMax); + aabbMax -= aabbMin; + aabbMax.setY(0.0f); + const float SQRT_TWO = 1.414213562f; + _diameter = SQRT_TWO * aabbMax.length(); + } else { + _diameter = 0.0f; + } +} + +void AvatarMotionState::setShape(const btCollisionShape* shape) { + cacheShapeDiameter(); + ObjectMotionState::setShape(shape); +} diff --git a/interface/src/avatar/AvatarMotionState.h b/interface/src/avatar/AvatarMotionState.h index 9228641b25..62fbc566f3 100644 --- a/interface/src/avatar/AvatarMotionState.h +++ b/interface/src/avatar/AvatarMotionState.h @@ -74,6 +74,9 @@ public: friend class Avatar; protected: + void setShape(const btCollisionShape* shape) override; + void cacheShapeDiameter(); + // the dtor had been made protected to force the compiler to verify that it is only // ever called by the Avatar class dtor. ~AvatarMotionState(); diff --git a/libraries/physics/src/ObjectMotionState.cpp b/libraries/physics/src/ObjectMotionState.cpp index 310cf7cec1..c814140930 100644 --- a/libraries/physics/src/ObjectMotionState.cpp +++ b/libraries/physics/src/ObjectMotionState.cpp @@ -64,9 +64,9 @@ ShapeManager* ObjectMotionState::getShapeManager() { } ObjectMotionState::ObjectMotionState(const btCollisionShape* shape) : - _shape(shape), _lastKinematicStep(worldSimulationStep) { + setShape(shape); } ObjectMotionState::~ObjectMotionState() { diff --git a/libraries/physics/src/ObjectMotionState.h b/libraries/physics/src/ObjectMotionState.h index 7439c1c38d..269117b28c 100644 --- a/libraries/physics/src/ObjectMotionState.h +++ b/libraries/physics/src/ObjectMotionState.h @@ -181,7 +181,7 @@ protected: MotionStateType _type { MOTIONSTATE_TYPE_INVALID }; // type of MotionState PhysicsMotionType _motionType { MOTION_TYPE_STATIC }; // type of motion: KINEMATIC, DYNAMIC, or STATIC - const btCollisionShape* _shape; + const btCollisionShape* _shape { nullptr }; btRigidBody* _body { nullptr }; float _density { 1.0f }; From bd6f00e707c4df82b8b9c26db4f2297f4c3bb919 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 1 Aug 2018 11:58:52 -0700 Subject: [PATCH 3/4] eliminate angular dynamics of other-avatars --- interface/src/avatar/AvatarMotionState.cpp | 12 ++++++++++++ interface/src/avatar/AvatarMotionState.h | 1 + libraries/physics/src/ObjectMotionState.h | 2 +- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/interface/src/avatar/AvatarMotionState.cpp b/interface/src/avatar/AvatarMotionState.cpp index 298701ca5d..bff5233f1d 100644 --- a/interface/src/avatar/AvatarMotionState.cpp +++ b/interface/src/avatar/AvatarMotionState.cpp @@ -96,6 +96,10 @@ void AvatarMotionState::setWorldTransform(const btTransform& worldTrans) { btVector3 velocity = glmToBullet(getObjectLinearVelocity()) + (1.0f / SPRING_TIMESCALE) * offsetToTarget; _body->setLinearVelocity(velocity); _body->setAngularVelocity(glmToBullet(getObjectAngularVelocity())); + // slam its rotation + btTransform newTransform = worldTrans; + newTransform.setRotation(glmToBullet(getObjectRotation())); + _body->setWorldTransform(newTransform); } } @@ -191,6 +195,14 @@ void AvatarMotionState::cacheShapeDiameter() { } } +void AvatarMotionState::setRigidBody(btRigidBody* body) { + ObjectMotionState::setRigidBody(body); + if (_body) { + // remove angular dynamics from this body + _body->setAngularFactor(0.0f); + } +} + void AvatarMotionState::setShape(const btCollisionShape* shape) { cacheShapeDiameter(); ObjectMotionState::setShape(shape); diff --git a/interface/src/avatar/AvatarMotionState.h b/interface/src/avatar/AvatarMotionState.h index 62fbc566f3..a458704b1a 100644 --- a/interface/src/avatar/AvatarMotionState.h +++ b/interface/src/avatar/AvatarMotionState.h @@ -74,6 +74,7 @@ public: friend class Avatar; protected: + void setRigidBody(btRigidBody* body) override; void setShape(const btCollisionShape* shape) override; void cacheShapeDiameter(); diff --git a/libraries/physics/src/ObjectMotionState.h b/libraries/physics/src/ObjectMotionState.h index 269117b28c..74173c3f47 100644 --- a/libraries/physics/src/ObjectMotionState.h +++ b/libraries/physics/src/ObjectMotionState.h @@ -175,7 +175,7 @@ protected: virtual void setMotionType(PhysicsMotionType motionType); void updateCCDConfiguration(); - void setRigidBody(btRigidBody* body); + virtual void setRigidBody(btRigidBody* body); virtual void setShape(const btCollisionShape* shape); MotionStateType _type { MOTIONSTATE_TYPE_INVALID }; // type of MotionState From e336c9276dde27f5e3f6ca73f4e08d6f3c37c508 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 1 Aug 2018 17:39:57 -0700 Subject: [PATCH 4/4] first set shape THEN use it --- interface/src/avatar/AvatarMotionState.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/interface/src/avatar/AvatarMotionState.cpp b/interface/src/avatar/AvatarMotionState.cpp index bff5233f1d..07e6b3f6b0 100644 --- a/interface/src/avatar/AvatarMotionState.cpp +++ b/interface/src/avatar/AvatarMotionState.cpp @@ -181,15 +181,12 @@ float AvatarMotionState::getMass() const { void AvatarMotionState::cacheShapeDiameter() { if (_shape) { - // measure XZ diameter of capsule shape + // shape is capsuleY btVector3 aabbMin, aabbMax; btTransform transform; transform.setIdentity(); _shape->getAabb(transform, aabbMin, aabbMax); - aabbMax -= aabbMin; - aabbMax.setY(0.0f); - const float SQRT_TWO = 1.414213562f; - _diameter = SQRT_TWO * aabbMax.length(); + _diameter = (aabbMax - aabbMin).getX(); } else { _diameter = 0.0f; } @@ -204,6 +201,6 @@ void AvatarMotionState::setRigidBody(btRigidBody* body) { } void AvatarMotionState::setShape(const btCollisionShape* shape) { - cacheShapeDiameter(); ObjectMotionState::setShape(shape); + cacheShapeDiameter(); }