From d444603a54003e8720c7a85c880b24e1a07928fd Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 14 Sep 2016 14:57:47 -0700 Subject: [PATCH] simplified Aabb management for GhostObject --- libraries/physics/src/CharacterController.cpp | 6 ++- .../physics/src/CharacterGhostObject.cpp | 39 +++++++------------ libraries/physics/src/CharacterGhostObject.h | 7 +++- libraries/physics/src/CharacterGhostShape.cpp | 20 ++++++++++ libraries/physics/src/CharacterGhostShape.h | 26 +++++++++++++ 5 files changed, 69 insertions(+), 29 deletions(-) create mode 100644 libraries/physics/src/CharacterGhostShape.cpp create mode 100644 libraries/physics/src/CharacterGhostShape.h diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index 7cab21e7e2..16f447f790 100644 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -11,6 +11,8 @@ #include "CharacterController.h" +//#include + #include #include "ObjectMotionState.h" @@ -121,7 +123,9 @@ void CharacterController::setDynamicsWorld(btDynamicsWorld* world) { _dynamicsWorld->addAction(this); // restore gravity settings _rigidBody->setGravity(oldGravity); - _ghost.setCollisionShape(_rigidBody->getCollisionShape()); // KINEMATIC_CONTROLLER_HACK + btCollisionShape* shape = _rigidBody->getCollisionShape(); + assert(shape && shape->getShapeType() == CAPSULE_SHAPE_PROXYTYPE); + _ghost.setCharacterShape(static_cast(shape)); // KINEMATIC_CONTROLLER_HACK } // KINEMATIC_CONTROLLER_HACK _ghost.setCollisionGroupAndMask(_collisionGroup, BULLET_COLLISION_MASK_MY_AVATAR & (~ _collisionGroup)); diff --git a/libraries/physics/src/CharacterGhostObject.cpp b/libraries/physics/src/CharacterGhostObject.cpp index f3e1da3585..250ff39e98 100644 --- a/libraries/physics/src/CharacterGhostObject.cpp +++ b/libraries/physics/src/CharacterGhostObject.cpp @@ -13,6 +13,7 @@ #include +#include "CharacterGhostShape.h" #include "CharacterRayResult.h" const btScalar DEFAULT_STEP_UP_HEIGHT = 0.5f; @@ -20,7 +21,11 @@ const btScalar DEFAULT_STEP_UP_HEIGHT = 0.5f; CharacterGhostObject::~CharacterGhostObject() { removeFromWorld(); - setCollisionShape(nullptr); + if (_ghostShape) { + delete _ghostShape; + _ghostShape = nullptr; + setCollisionShape(nullptr); + } } void CharacterGhostObject::setCollisionGroupAndMask(int16_t group, int16_t mask) { @@ -50,17 +55,14 @@ void CharacterGhostObject::setMotorVelocity(const btVector3& velocity) { } // override of btCollisionObject::setCollisionShape() -void CharacterGhostObject::setCollisionShape(btCollisionShape* shape) { - assert(!shape || shape->isConvex()); // if shape is valid then please make it convex - if (shape != getCollisionShape()) { - bool wasInWorld = _inWorld; - removeFromWorld(); - btCollisionObject::setCollisionShape(shape); - if (wasInWorld) { - assert(shape); // please remove from world before setting null shape - addToWorld(); - } +void CharacterGhostObject::setCharacterShape(btCapsuleShape* capsule) { + assert(capsule); + // we create our own CharacterGhostShape which has a larger Aabb for more reliable sweep tests + if (_ghostShape) { + delete _ghostShape; } + _ghostShape = new CharacterGhostShape(capsule->getRadius(), 2.0f * capsule->getHalfHeight()); + setCollisionShape(_ghostShape); } void CharacterGhostObject::setCollisionWorld(btCollisionWorld* world) { @@ -125,20 +127,6 @@ void CharacterGhostObject::move(btScalar dt, btScalar overshoot) { btScalar longSweepDistance = stepDistance + overshoot; forwardSweep *= longSweepDistance / stepDistance; - // expand this object's Aabb in the broadphase and - // update the pairCache for the sweepTests we intend to do - btVector3 minAabb, maxAabb; - getCollisionShape()->getAabb(getWorldTransform(), minAabb, maxAabb); - minAabb.setMin(minAabb - btVector3(margin, margin, margin)); - maxAabb.setMax(maxAabb + btVector3(margin, margin, margin)); - minAabb.setMin(minAabb + forwardSweep); - maxAabb.setMax(maxAabb + forwardSweep); - minAabb.setMin(minAabb + _maxStepHeight * _upDirection); - maxAabb.setMax(maxAabb + _maxStepHeight * _upDirection); - - // this updates both pairCaches: world broadphase and ghostobject - _world->getBroadphase()->setAabb(getBroadphaseHandle(), minAabb, maxAabb, _world->getDispatcher()); - // step forward CharacterSweepResult result(this); btTransform startTransform = getWorldTransform(); @@ -338,7 +326,6 @@ void CharacterGhostObject::refreshOverlappingPairCache() { assert(_world && _inWorld); btVector3 minAabb, maxAabb; getCollisionShape()->getAabb(getWorldTransform(), minAabb, maxAabb); - // this updates both pairCaches: world broadphase and ghostobject _world->getBroadphase()->setAabb(getBroadphaseHandle(), minAabb, maxAabb, _world->getDispatcher()); } diff --git a/libraries/physics/src/CharacterGhostObject.h b/libraries/physics/src/CharacterGhostObject.h index df569181b9..be8a68594e 100644 --- a/libraries/physics/src/CharacterGhostObject.h +++ b/libraries/physics/src/CharacterGhostObject.h @@ -18,6 +18,7 @@ #include "CharacterSweepResult.h" #include "CharacterRayResult.h" +class CharacterGhostShape; class CharacterGhostObject : public btPairCachingGhostObject { public: @@ -36,7 +37,7 @@ public: const btVector3& getLinearVelocity() const { return _linearVelocity; } - void setCollisionShape(btCollisionShape* shape) override; + void setCharacterShape(btCapsuleShape* capsule); void setCollisionWorld(btCollisionWorld* world); @@ -72,10 +73,12 @@ protected: btScalar _gravity { 0.0f }; // input, amplitude of gravity along _upDirection (should be negative) btScalar _maxWallNormalUpComponent { 0.0f }; // input: max vertical component of wall normal btScalar _maxStepHeight { 0.0f }; // input, max step height the character can climb + btCapsuleShape* _characterShape { nullptr }; // input, shape of character + CharacterGhostShape* _ghostShape{ nullptr }; // internal, shape whose Aabb is used for overlap cache int16_t _collisionFilterGroup { 0 }; int16_t _collisionFilterMask { 0 }; bool _inWorld { false }; // internal, was added to world - bool _hovering { false }; // internal, + bool _hovering { false }; // internal, bool _onFloor { false }; // output, is actually standing on floor bool _hasFloor { false }; // output, has floor underneath to fall on }; diff --git a/libraries/physics/src/CharacterGhostShape.cpp b/libraries/physics/src/CharacterGhostShape.cpp new file mode 100644 index 0000000000..bf031ec569 --- /dev/null +++ b/libraries/physics/src/CharacterGhostShape.cpp @@ -0,0 +1,20 @@ +// +// CharacterGhostShape.cpp +// libraries/physcis/src +// +// Created by Andrew Meadows 2016.09.14 +// Copyright 2016 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 "CharacterGhostShape.h" + +void CharacterGhostShape::getAabb (const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const { + btCapsuleShape::getAabb(t, aabbMin, aabbMax); + // double the size of the Aabb by expanding both corners by half the extent + btVector3 expansion = 0.5f * (aabbMax - aabbMin); + aabbMin -= expansion; + aabbMax += expansion; +} diff --git a/libraries/physics/src/CharacterGhostShape.h b/libraries/physics/src/CharacterGhostShape.h new file mode 100644 index 0000000000..9c9efded34 --- /dev/null +++ b/libraries/physics/src/CharacterGhostShape.h @@ -0,0 +1,26 @@ +// +// CharacterGhostShape.h +// libraries/physcis/src +// +// Created by Andrew Meadows 2016.09.14 +// Copyright 2016 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_CharacterGhostShape_h +#define hifi_CharacterGhostShape_h + +#include + +class CharacterGhostShape : public btCapsuleShape { + // Same as btCapsuleShape but reports an expanded Aabb for larger ghost overlap cache +public: + CharacterGhostShape(btScalar radius, btScalar height) : btCapsuleShape(radius, height) { + } + + virtual void getAabb (const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const override; +}; + +#endif // hifi_CharacterGhostShape_h