mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-04 21:53:12 +02:00
basic support for collision groups
This commit is contained in:
parent
b0fdb0413c
commit
7b6cc59d30
8 changed files with 100 additions and 4 deletions
|
@ -10,6 +10,7 @@
|
|||
//
|
||||
|
||||
#include <PhysicsHelpers.h>
|
||||
#include <PhysicsEngine.h>
|
||||
|
||||
#include "Avatar.h"
|
||||
#include "AvatarMotionState.h"
|
||||
|
@ -151,6 +152,11 @@ QUuid AvatarMotionState::getSimulatorID() const {
|
|||
void AvatarMotionState::bump() {
|
||||
}
|
||||
|
||||
// virtual
|
||||
int16_t AvatarMotionState::computeCollisionGroup() {
|
||||
return COLLISION_GROUP_OTHER_AVATAR;
|
||||
}
|
||||
|
||||
// virtual
|
||||
void AvatarMotionState::clearObjectBackPointer() {
|
||||
ObjectMotionState::clearObjectBackPointer();
|
||||
|
|
|
@ -61,6 +61,8 @@ public:
|
|||
|
||||
void addDirtyFlags(uint32_t flags) { _dirtyFlags |= flags; }
|
||||
|
||||
virtual int16_t computeCollisionGroup();
|
||||
|
||||
friend class AvatarManager;
|
||||
|
||||
protected:
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "BulletUtil.h"
|
||||
#include "DynamicCharacterController.h"
|
||||
#include "PhysicsEngine.h"
|
||||
|
||||
const btVector3 LOCAL_UP_AXIS(0.0f, 1.0f, 0.0f);
|
||||
const float DEFAULT_GRAVITY = -5.0f;
|
||||
|
@ -267,7 +268,7 @@ void DynamicCharacterController::setDynamicsWorld(btDynamicsWorld* world) {
|
|||
if (world && _rigidBody) {
|
||||
_dynamicsWorld = world;
|
||||
_pendingFlags &= ~ PENDING_FLAG_JUMP;
|
||||
_dynamicsWorld->addRigidBody(_rigidBody);
|
||||
_dynamicsWorld->addRigidBody(_rigidBody, COLLISION_GROUP_MY_AVATAR, COLLISION_MASK_MY_AVATAR);
|
||||
_dynamicsWorld->addAction(this);
|
||||
//reset(_dynamicsWorld);
|
||||
}
|
||||
|
|
|
@ -517,3 +517,8 @@ QString EntityMotionState::getName() {
|
|||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// virtual
|
||||
int16_t EntityMotionState::computeCollisionGroup() {
|
||||
return COLLISION_GROUP_DEFAULT;
|
||||
}
|
||||
|
|
|
@ -77,6 +77,8 @@ public:
|
|||
|
||||
virtual QString getName();
|
||||
|
||||
virtual int16_t computeCollisionGroup();
|
||||
|
||||
friend class PhysicalEntitySimulation;
|
||||
|
||||
protected:
|
||||
|
|
|
@ -123,6 +123,8 @@ public:
|
|||
|
||||
virtual QString getName() { return ""; }
|
||||
|
||||
virtual int16_t computeCollisionGroup() = 0;
|
||||
|
||||
friend class PhysicsEngine;
|
||||
|
||||
protected:
|
||||
|
|
|
@ -23,8 +23,19 @@ uint32_t PhysicsEngine::getNumSubsteps() {
|
|||
}
|
||||
|
||||
PhysicsEngine::PhysicsEngine(const glm::vec3& offset) :
|
||||
_originOffset(offset),
|
||||
_characterController(nullptr) {
|
||||
_originOffset(offset),
|
||||
_characterController(nullptr) {
|
||||
// build table of masks with their group as the key
|
||||
_collisionMasks.insert(btHashInt((int)COLLISION_GROUP_DEFAULT), COLLISION_MASK_DEFAULT);
|
||||
_collisionMasks.insert(btHashInt((int)COLLISION_GROUP_STATIC), COLLISION_MASK_STATIC);
|
||||
_collisionMasks.insert(btHashInt((int)COLLISION_GROUP_KINEMATIC), COLLISION_MASK_KINEMATIC);
|
||||
_collisionMasks.insert(btHashInt((int)COLLISION_GROUP_DEBRIS), COLLISION_MASK_DEBRIS);
|
||||
_collisionMasks.insert(btHashInt((int)COLLISION_GROUP_TRIGGER), COLLISION_MASK_TRIGGER);
|
||||
_collisionMasks.insert(btHashInt((int)COLLISION_GROUP_MY_AVATAR), COLLISION_MASK_MY_AVATAR);
|
||||
_collisionMasks.insert(btHashInt((int)COLLISION_GROUP_MY_ATTACHMENT), COLLISION_MASK_MY_ATTACHMENT);
|
||||
_collisionMasks.insert(btHashInt((int)COLLISION_GROUP_OTHER_AVATAR), COLLISION_MASK_OTHER_AVATAR);
|
||||
_collisionMasks.insert(btHashInt((int)COLLISION_GROUP_OTHER_ATTACHMENT), COLLISION_MASK_OTHER_ATTACHMENT);
|
||||
_collisionMasks.insert(btHashInt((int)COLLISION_GROUP_COLLISIONLESS), COLLISION_MASK_COLLISIONLESS);
|
||||
}
|
||||
|
||||
PhysicsEngine::~PhysicsEngine() {
|
||||
|
@ -125,7 +136,8 @@ void PhysicsEngine::addObject(ObjectMotionState* motionState) {
|
|||
body->setFlags(BT_DISABLE_WORLD_GRAVITY);
|
||||
motionState->updateBodyMaterialProperties();
|
||||
|
||||
_dynamicsWorld->addRigidBody(body);
|
||||
int16_t group = motionState->computeCollisionGroup();
|
||||
_dynamicsWorld->addRigidBody(body, group, getCollisionMask(group));
|
||||
|
||||
motionState->getAndClearIncomingDirtyFlags();
|
||||
}
|
||||
|
@ -417,6 +429,7 @@ void PhysicsEngine::setCharacterController(DynamicCharacterController* character
|
|||
}
|
||||
}
|
||||
|
||||
// static
|
||||
bool PhysicsEngine::physicsInfoIsActive(void* physicsInfo) {
|
||||
if (!physicsInfo) {
|
||||
return false;
|
||||
|
@ -431,6 +444,7 @@ bool PhysicsEngine::physicsInfoIsActive(void* physicsInfo) {
|
|||
return body->isActive();
|
||||
}
|
||||
|
||||
// static
|
||||
bool PhysicsEngine::getBodyLocation(void* physicsInfo, glm::vec3& positionReturn, glm::quat& rotationReturn) {
|
||||
if (!physicsInfo) {
|
||||
return false;
|
||||
|
@ -448,3 +462,8 @@ bool PhysicsEngine::getBodyLocation(void* physicsInfo, glm::vec3& positionReturn
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
int16_t PhysicsEngine::getCollisionMask(int16_t group) const {
|
||||
const int16_t* mask = _collisionMasks.find(btHashInt((int)group));
|
||||
return mask ? *mask : COLLISION_MASK_DEFAULT;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,61 @@
|
|||
#include "ObjectMotionState.h"
|
||||
#include "ThreadSafeDynamicsWorld.h"
|
||||
|
||||
/* Note: These are the collision groups defined in btBroadphaseProxy. Only
|
||||
* DefaultFilter and StaticFilter are explicitly used by Bullet (when the
|
||||
* collision filter of an object is not manually specified), the rest are
|
||||
* merely suggestions.
|
||||
*
|
||||
enum CollisionFilterGroups {
|
||||
DefaultFilter = 1,
|
||||
StaticFilter = 2,
|
||||
KinematicFilter = 4,
|
||||
DebrisFilter = 8,
|
||||
SensorTrigger = 16,
|
||||
CharacterFilter = 32,
|
||||
AllFilter = -1
|
||||
}
|
||||
*
|
||||
* When using custom collision filters we pretty much need to do all or nothing.
|
||||
* We'll be doing it all which means we define our own groups and build custom masks
|
||||
* for everything.
|
||||
*
|
||||
*/
|
||||
|
||||
const int16_t COLLISION_GROUP_DEFAULT = 1 << 0;
|
||||
const int16_t COLLISION_GROUP_STATIC = 1 << 1;
|
||||
const int16_t COLLISION_GROUP_KINEMATIC = 1 << 2;
|
||||
const int16_t COLLISION_GROUP_DEBRIS = 1 << 3;
|
||||
const int16_t COLLISION_GROUP_TRIGGER = 1 << 4;
|
||||
const int16_t COLLISION_GROUP_MY_AVATAR = 1 << 5;
|
||||
const int16_t COLLISION_GROUP_OTHER_AVATAR = 1 << 6;
|
||||
const int16_t COLLISION_GROUP_MY_ATTACHMENT = 1 << 7;
|
||||
const int16_t COLLISION_GROUP_OTHER_ATTACHMENT = 1 << 8;
|
||||
// ...
|
||||
const int16_t COLLISION_GROUP_COLLISIONLESS = 1 << 15;
|
||||
|
||||
|
||||
/* Note: In order for objectA to collide with objectB at the filter stage
|
||||
* both (groupA & maskB) and (groupB & maskA) must be non-zero.
|
||||
*/
|
||||
// DEFAULT collides with everything except COLLISIONLESS
|
||||
const int16_t COLLISION_MASK_DEFAULT = ~ COLLISION_GROUP_COLLISIONLESS;
|
||||
const int16_t COLLISION_MASK_STATIC = COLLISION_MASK_DEFAULT;
|
||||
const int16_t COLLISION_MASK_KINEMATIC = COLLISION_MASK_DEFAULT;
|
||||
// DEBRIS also doesn't collide with: other DEBRIS, and TRIGGER
|
||||
const int16_t COLLISION_MASK_DEBRIS = ~ (COLLISION_GROUP_COLLISIONLESS
|
||||
| COLLISION_GROUP_DEBRIS
|
||||
| COLLISION_GROUP_TRIGGER);
|
||||
// TRIGGER also doesn't collide with: DEBRIS, TRIGGER, and STATIC (TRIGGER only detects moveable things that matter)
|
||||
const int16_t COLLISION_MASK_TRIGGER = COLLISION_MASK_DEBRIS & ~(COLLISION_GROUP_STATIC);
|
||||
// AVATAR also doesn't collide with: corresponding ATTACHMENT
|
||||
const int16_t COLLISION_MASK_MY_AVATAR = ~(COLLISION_GROUP_COLLISIONLESS | COLLISION_GROUP_MY_ATTACHMENT);
|
||||
const int16_t COLLISION_MASK_MY_ATTACHMENT = ~(COLLISION_GROUP_COLLISIONLESS | COLLISION_GROUP_MY_AVATAR);
|
||||
const int16_t COLLISION_MASK_OTHER_AVATAR = ~(COLLISION_GROUP_COLLISIONLESS | COLLISION_GROUP_OTHER_ATTACHMENT);
|
||||
const int16_t COLLISION_MASK_OTHER_ATTACHMENT = ~(COLLISION_GROUP_COLLISIONLESS | COLLISION_GROUP_OTHER_AVATAR);
|
||||
// ...
|
||||
const int16_t COLLISION_MASK_COLLISIONLESS = 0;
|
||||
|
||||
const float HALF_SIMULATION_EXTENT = 512.0f; // meters
|
||||
|
||||
// simple class for keeping track of contacts
|
||||
|
@ -91,9 +146,12 @@ public:
|
|||
|
||||
void dumpNextStats() { _dumpNextStats = true; }
|
||||
|
||||
// TODO: Andrew to move these to ObjectMotionState
|
||||
static bool physicsInfoIsActive(void* physicsInfo);
|
||||
static bool getBodyLocation(void* physicsInfo, glm::vec3& positionReturn, glm::quat& rotationReturn);
|
||||
|
||||
int16_t getCollisionMask(int16_t group) const;
|
||||
|
||||
private:
|
||||
void removeContacts(ObjectMotionState* motionState);
|
||||
|
||||
|
@ -121,6 +179,7 @@ private:
|
|||
|
||||
QUuid _sessionID;
|
||||
CollisionEvents _collisionEvents;
|
||||
btHashMap<btHashInt, int16_t> _collisionMasks;
|
||||
};
|
||||
|
||||
#endif // hifi_PhysicsEngine_h
|
||||
|
|
Loading…
Reference in a new issue