simplified Aabb management for GhostObject

This commit is contained in:
Andrew Meadows 2016-09-14 14:57:47 -07:00
parent 418271e06b
commit d444603a54
5 changed files with 69 additions and 29 deletions

View file

@ -11,6 +11,8 @@
#include "CharacterController.h" #include "CharacterController.h"
//#include <BulletCollision/BroadphaseCollision/btBroadphaseProxy.h>
#include <NumericalConstants.h> #include <NumericalConstants.h>
#include "ObjectMotionState.h" #include "ObjectMotionState.h"
@ -121,7 +123,9 @@ void CharacterController::setDynamicsWorld(btDynamicsWorld* world) {
_dynamicsWorld->addAction(this); _dynamicsWorld->addAction(this);
// restore gravity settings // restore gravity settings
_rigidBody->setGravity(oldGravity); _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<btCapsuleShape*>(shape)); // KINEMATIC_CONTROLLER_HACK
} }
// KINEMATIC_CONTROLLER_HACK // KINEMATIC_CONTROLLER_HACK
_ghost.setCollisionGroupAndMask(_collisionGroup, BULLET_COLLISION_MASK_MY_AVATAR & (~ _collisionGroup)); _ghost.setCollisionGroupAndMask(_collisionGroup, BULLET_COLLISION_MASK_MY_AVATAR & (~ _collisionGroup));

View file

@ -13,6 +13,7 @@
#include <assert.h> #include <assert.h>
#include "CharacterGhostShape.h"
#include "CharacterRayResult.h" #include "CharacterRayResult.h"
const btScalar DEFAULT_STEP_UP_HEIGHT = 0.5f; const btScalar DEFAULT_STEP_UP_HEIGHT = 0.5f;
@ -20,7 +21,11 @@ const btScalar DEFAULT_STEP_UP_HEIGHT = 0.5f;
CharacterGhostObject::~CharacterGhostObject() { CharacterGhostObject::~CharacterGhostObject() {
removeFromWorld(); removeFromWorld();
setCollisionShape(nullptr); if (_ghostShape) {
delete _ghostShape;
_ghostShape = nullptr;
setCollisionShape(nullptr);
}
} }
void CharacterGhostObject::setCollisionGroupAndMask(int16_t group, int16_t mask) { void CharacterGhostObject::setCollisionGroupAndMask(int16_t group, int16_t mask) {
@ -50,17 +55,14 @@ void CharacterGhostObject::setMotorVelocity(const btVector3& velocity) {
} }
// override of btCollisionObject::setCollisionShape() // override of btCollisionObject::setCollisionShape()
void CharacterGhostObject::setCollisionShape(btCollisionShape* shape) { void CharacterGhostObject::setCharacterShape(btCapsuleShape* capsule) {
assert(!shape || shape->isConvex()); // if shape is valid then please make it convex assert(capsule);
if (shape != getCollisionShape()) { // we create our own CharacterGhostShape which has a larger Aabb for more reliable sweep tests
bool wasInWorld = _inWorld; if (_ghostShape) {
removeFromWorld(); delete _ghostShape;
btCollisionObject::setCollisionShape(shape);
if (wasInWorld) {
assert(shape); // please remove from world before setting null shape
addToWorld();
}
} }
_ghostShape = new CharacterGhostShape(capsule->getRadius(), 2.0f * capsule->getHalfHeight());
setCollisionShape(_ghostShape);
} }
void CharacterGhostObject::setCollisionWorld(btCollisionWorld* world) { void CharacterGhostObject::setCollisionWorld(btCollisionWorld* world) {
@ -125,20 +127,6 @@ void CharacterGhostObject::move(btScalar dt, btScalar overshoot) {
btScalar longSweepDistance = stepDistance + overshoot; btScalar longSweepDistance = stepDistance + overshoot;
forwardSweep *= longSweepDistance / stepDistance; 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 // step forward
CharacterSweepResult result(this); CharacterSweepResult result(this);
btTransform startTransform = getWorldTransform(); btTransform startTransform = getWorldTransform();
@ -338,7 +326,6 @@ void CharacterGhostObject::refreshOverlappingPairCache() {
assert(_world && _inWorld); assert(_world && _inWorld);
btVector3 minAabb, maxAabb; btVector3 minAabb, maxAabb;
getCollisionShape()->getAabb(getWorldTransform(), minAabb, maxAabb); getCollisionShape()->getAabb(getWorldTransform(), minAabb, maxAabb);
// this updates both pairCaches: world broadphase and ghostobject // this updates both pairCaches: world broadphase and ghostobject
_world->getBroadphase()->setAabb(getBroadphaseHandle(), minAabb, maxAabb, _world->getDispatcher()); _world->getBroadphase()->setAabb(getBroadphaseHandle(), minAabb, maxAabb, _world->getDispatcher());
} }

View file

@ -18,6 +18,7 @@
#include "CharacterSweepResult.h" #include "CharacterSweepResult.h"
#include "CharacterRayResult.h" #include "CharacterRayResult.h"
class CharacterGhostShape;
class CharacterGhostObject : public btPairCachingGhostObject { class CharacterGhostObject : public btPairCachingGhostObject {
public: public:
@ -36,7 +37,7 @@ public:
const btVector3& getLinearVelocity() const { return _linearVelocity; } const btVector3& getLinearVelocity() const { return _linearVelocity; }
void setCollisionShape(btCollisionShape* shape) override; void setCharacterShape(btCapsuleShape* capsule);
void setCollisionWorld(btCollisionWorld* world); void setCollisionWorld(btCollisionWorld* world);
@ -72,10 +73,12 @@ protected:
btScalar _gravity { 0.0f }; // input, amplitude of gravity along _upDirection (should be negative) 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 _maxWallNormalUpComponent { 0.0f }; // input: max vertical component of wall normal
btScalar _maxStepHeight { 0.0f }; // input, max step height the character can climb 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 _collisionFilterGroup { 0 };
int16_t _collisionFilterMask { 0 }; int16_t _collisionFilterMask { 0 };
bool _inWorld { false }; // internal, was added to world 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 _onFloor { false }; // output, is actually standing on floor
bool _hasFloor { false }; // output, has floor underneath to fall on bool _hasFloor { false }; // output, has floor underneath to fall on
}; };

View file

@ -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;
}

View file

@ -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 <BulletCollision/CollisionShapes/btCapsuleShape.h>
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