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 <BulletCollision/BroadphaseCollision/btBroadphaseProxy.h>
#include <NumericalConstants.h>
#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<btCapsuleShape*>(shape)); // KINEMATIC_CONTROLLER_HACK
}
// KINEMATIC_CONTROLLER_HACK
_ghost.setCollisionGroupAndMask(_collisionGroup, BULLET_COLLISION_MASK_MY_AVATAR & (~ _collisionGroup));

View file

@ -13,6 +13,7 @@
#include <assert.h>
#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());
}

View file

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

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