Merge pull request #5037 from AndrewMeadows/inertia

collision groups for physical objects
This commit is contained in:
Seth Alves 2015-06-05 10:26:28 -07:00
commit edb3622c85
12 changed files with 136 additions and 38 deletions

View file

@ -10,6 +10,7 @@
//
#include <PhysicsHelpers.h>
#include <PhysicsCollisionGroups.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();

View file

@ -61,6 +61,8 @@ public:
void addDirtyFlags(uint32_t flags) { _dirtyFlags |= flags; }
virtual int16_t computeCollisionGroup();
friend class AvatarManager;
protected:

View file

@ -80,7 +80,8 @@ void RenderableDebugableEntityItem::render(EntityItem* entity, RenderArgs* args)
renderBoundingBox(entity, args, 0.3f, yellowColor);
}
if (PhysicsEngine::physicsInfoIsActive(entity->getPhysicsInfo())) {
ObjectMotionState* motionState = static_cast<ObjectMotionState*>(entity->getPhysicsInfo());
if (motionState && motionState->isActive()) {
renderHoverDot(entity, args);
}
}

View file

@ -3,6 +3,8 @@
#include <BulletCollision/CollisionDispatch/btCollisionWorld.h>
#include <LinearMath/btDefaultMotionState.h>
#include <PhysicsCollisionGroups.h>
#include "BulletUtil.h"
#include "DynamicCharacterController.h"
@ -267,7 +269,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);
}

View file

@ -11,6 +11,7 @@
#include <EntityItem.h>
#include <EntityEditPacketSender.h>
#include <PhysicsCollisionGroups.h>
#include "BulletUtil.h"
#include "EntityMotionState.h"
@ -524,3 +525,16 @@ QString EntityMotionState::getName() {
}
return "";
}
// virtual
int16_t EntityMotionState::computeCollisionGroup() {
switch (computeObjectMotionType()){
case MOTION_TYPE_STATIC:
return COLLISION_GROUP_STATIC;
case MOTION_TYPE_KINEMATIC:
return COLLISION_GROUP_KINEMATIC;
default:
break;
}
return COLLISION_GROUP_DEFAULT;
}

View file

@ -78,6 +78,8 @@ public:
virtual QString getName();
virtual int16_t computeCollisionGroup();
friend class PhysicalEntitySimulation;
protected:

View file

@ -203,3 +203,4 @@ void ObjectMotionState::updateBodyMassProperties() {
_body->setMassProps(mass, inertia);
_body->updateInertiaTensor();
}

View file

@ -124,6 +124,10 @@ public:
virtual QString getName() { return ""; }
virtual int16_t computeCollisionGroup() = 0;
bool isActive() const { return _body ? _body->isActive() : false; }
friend class PhysicsEngine;
protected:

View file

@ -9,6 +9,8 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <PhysicsCollisionGroups.h>
#include "ObjectMotionState.h"
#include "PhysicsEngine.h"
#include "PhysicsHelpers.h"
@ -23,8 +25,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 +138,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();
}
@ -419,34 +433,7 @@ void PhysicsEngine::setCharacterController(DynamicCharacterController* character
}
}
bool PhysicsEngine::physicsInfoIsActive(void* physicsInfo) {
if (!physicsInfo) {
return false;
}
ObjectMotionState* motionState = static_cast<ObjectMotionState*>(physicsInfo);
btRigidBody* body = motionState->getRigidBody();
if (!body) {
return false;
}
return body->isActive();
}
bool PhysicsEngine::getBodyLocation(void* physicsInfo, glm::vec3& positionReturn, glm::quat& rotationReturn) {
if (!physicsInfo) {
return false;
}
ObjectMotionState* motionState = static_cast<ObjectMotionState*>(physicsInfo);
btRigidBody* body = motionState->getRigidBody();
if (!body) {
return false;
}
const btTransform& worldTrans = body->getCenterOfMassTransform();
positionReturn = bulletToGLM(worldTrans.getOrigin()) + ObjectMotionState::getWorldOffset();
rotationReturn = bulletToGLM(worldTrans.getRotation());
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;
}

View file

@ -91,8 +91,7 @@ public:
void dumpNextStats() { _dumpNextStats = true; }
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 +120,7 @@ private:
QUuid _sessionID;
CollisionEvents _collisionEvents;
btHashMap<btHashInt, int16_t> _collisionMasks;
};
#endif // hifi_PhysicsEngine_h

View file

@ -0,0 +1,79 @@
//
// PhysicsCollisionGroups.h
// libraries/shared/src
//
// Created by Andrew Meadows 2015.06.03
// Copyright 2015 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_PhysicsCollisionGroups_h
#define hifi_PhysicsCollisionGroups_h
#include <stdint.h>
/* Note: These are the Bullet 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;
// STATIC also doesn't collide with other STATIC
const int16_t COLLISION_MASK_STATIC = ~ (COLLISION_GROUP_COLLISIONLESS | COLLISION_MASK_STATIC);
const int16_t COLLISION_MASK_KINEMATIC = COLLISION_MASK_DEFAULT;
// DEBRIS also doesn't collide with other DEBRIS, or TRIGGER
const int16_t COLLISION_MASK_DEBRIS = ~ (COLLISION_GROUP_COLLISIONLESS
| COLLISION_GROUP_DEBRIS
| COLLISION_GROUP_TRIGGER);
// TRIGGER also doesn't collide with DEBRIS, TRIGGER, or 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 ATTACHMENTs
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);
// COLLISIONLESS gets an empty mask.
const int16_t COLLISION_MASK_COLLISIONLESS = 0;
#endif // hifi_PhysicsCollisionGroups_h

View file

@ -5,7 +5,7 @@
// Created by Andrew Meadows 2015.01.27
// Unless otherwise copyrighted: Copyright 2015 High Fidelity, Inc.
//
// Unless otherwise licensced: Distributed under the Apache License, Version 2.0.
// Unless otherwise licensed: Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//