mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
Merge pull request #6867 from AndrewMeadows/collision-group-prep
cleanup in preparation for smarter collision grouping
This commit is contained in:
commit
7a3401a8d7
10 changed files with 108 additions and 101 deletions
|
@ -95,6 +95,7 @@
|
|||
#include <PathUtils.h>
|
||||
#include <PerfStat.h>
|
||||
#include <PhysicsEngine.h>
|
||||
#include <PhysicsHelpers.h>
|
||||
#include <plugins/PluginContainer.h>
|
||||
#include <plugins/PluginManager.h>
|
||||
#include <RenderableWebEntityItem.h>
|
||||
|
@ -3125,7 +3126,7 @@ void Application::update(float deltaTime) {
|
|||
PerformanceTimer perfTimer("havestChanges");
|
||||
if (_physicsEngine->hasOutgoingChanges()) {
|
||||
getEntities()->getTree()->withWriteLock([&] {
|
||||
_entitySimulation.handleOutgoingChanges(_physicsEngine->getOutgoingChanges(), _physicsEngine->getSessionID());
|
||||
_entitySimulation.handleOutgoingChanges(_physicsEngine->getOutgoingChanges(), Physics::getSessionUUID());
|
||||
avatarManager->handleOutgoingChanges(_physicsEngine->getOutgoingChanges());
|
||||
});
|
||||
|
||||
|
@ -4225,6 +4226,9 @@ bool Application::acceptURL(const QString& urlString, bool defaultUpload) {
|
|||
}
|
||||
|
||||
void Application::setSessionUUID(const QUuid& sessionUUID) {
|
||||
// HACK: until we swap the library dependency order between physics and entities
|
||||
// we cache the sessionID in two distinct places for physics.
|
||||
Physics::setSessionUUID(sessionUUID); // TODO: remove this one
|
||||
_physicsEngine->setSessionUUID(sessionUUID);
|
||||
}
|
||||
|
||||
|
|
|
@ -146,6 +146,6 @@ QUuid AvatarMotionState::getSimulatorID() const {
|
|||
// virtual
|
||||
void AvatarMotionState::computeCollisionGroupAndMask(int16_t& group, int16_t& mask) const {
|
||||
group = BULLET_COLLISION_GROUP_OTHER_AVATAR;
|
||||
mask = PhysicsEngine::getCollisionMask(group);
|
||||
mask = Physics::getDefaultCollisionMask(group);
|
||||
}
|
||||
|
||||
|
|
|
@ -1507,6 +1507,33 @@ void EntityItem::updateCreated(uint64_t value) {
|
|||
}
|
||||
}
|
||||
|
||||
void EntityItem::computeCollisionGroupAndFinalMask(int16_t& group, int16_t& mask) const {
|
||||
// TODO: detect attachment status and adopt group of wearer
|
||||
if (_collisionless) {
|
||||
group = BULLET_COLLISION_GROUP_COLLISIONLESS;
|
||||
mask = 0;
|
||||
} else {
|
||||
if (_dynamic) {
|
||||
group = BULLET_COLLISION_GROUP_DYNAMIC;
|
||||
} else if (isMoving() || hasActions()) {
|
||||
group = BULLET_COLLISION_GROUP_KINEMATIC;
|
||||
} else {
|
||||
group = BULLET_COLLISION_GROUP_STATIC;
|
||||
}
|
||||
|
||||
uint8_t userMask = getCollisionMask();
|
||||
if ((bool)(userMask & USER_COLLISION_GROUP_MY_AVATAR) !=
|
||||
(bool)(userMask & USER_COLLISION_GROUP_OTHER_AVATAR)) {
|
||||
// asymmetric avatar collision mask bits
|
||||
if (!getSimulatorID().isNull() && (!getSimulatorID().isNull()) && getSimulatorID() != Physics::getSessionUUID()) {
|
||||
// someone else owns the simulation, so we toggle the avatar bits (swap interpretation)
|
||||
userMask ^= USER_COLLISION_MASK_AVATARS | ~userMask;
|
||||
}
|
||||
}
|
||||
mask = Physics::getDefaultCollisionMask(group) & (int16_t)(userMask);
|
||||
}
|
||||
}
|
||||
|
||||
void EntityItem::setSimulationOwner(const QUuid& id, quint8 priority) {
|
||||
if (wantTerseEditLogging() && (id != _simulationOwner.getID() || priority != _simulationOwner.getPriority())) {
|
||||
qCDebug(entities) << "sim ownership for" << getDebugName() << "is now" << id << priority;
|
||||
|
|
|
@ -275,9 +275,10 @@ public:
|
|||
void setCollisionless(bool value) { _collisionless = value; }
|
||||
|
||||
uint8_t getCollisionMask() const { return _collisionMask; }
|
||||
uint8_t getFinalCollisionMask() const { return _collisionless ? 0 : _collisionMask; }
|
||||
void setCollisionMask(uint8_t value) { _collisionMask = value; }
|
||||
|
||||
void computeCollisionGroupAndFinalMask(int16_t& group, int16_t& mask) const;
|
||||
|
||||
bool getDynamic() const { return _dynamic; }
|
||||
void setDynamic(bool value) { _dynamic = value; }
|
||||
|
||||
|
@ -370,8 +371,8 @@ public:
|
|||
bool clearActions(EntitySimulation* simulation);
|
||||
void setActionData(QByteArray actionData);
|
||||
const QByteArray getActionData() const;
|
||||
bool hasActions() { return !_objectActions.empty(); }
|
||||
QList<QUuid> getActionIDs() { return _objectActions.keys(); }
|
||||
bool hasActions() const { return !_objectActions.empty(); }
|
||||
QList<QUuid> getActionIDs() const { return _objectActions.keys(); }
|
||||
QVariantMap getActionArguments(const QUuid& actionID) const;
|
||||
void deserializeActions();
|
||||
|
||||
|
|
|
@ -160,8 +160,8 @@ QString EntityItemProperties::getCollisionMaskAsString() const {
|
|||
void EntityItemProperties::setCollisionMaskFromString(const QString& maskString) {
|
||||
QVector<QStringRef> groups = maskString.splitRef(',');
|
||||
uint8_t mask = 0x00;
|
||||
for (auto group : groups) {
|
||||
mask |= getCollisionGroupAsBitMask(group);
|
||||
for (auto groupName : groups) {
|
||||
mask |= getCollisionGroupAsBitMask(groupName);
|
||||
}
|
||||
_collisionMask = mask;
|
||||
_collisionMaskChanged = true;
|
||||
|
|
|
@ -82,7 +82,7 @@ EntityMotionState::~EntityMotionState() {
|
|||
|
||||
void EntityMotionState::updateServerPhysicsVariables() {
|
||||
assert(entityTreeIsLocked());
|
||||
if (_entity->getSimulatorID() == PhysicsEngine::getSessionID()) {
|
||||
if (_entity->getSimulatorID() == Physics::getSessionUUID()) {
|
||||
// don't slam these values if we are the simulation owner
|
||||
return;
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ bool EntityMotionState::handleEasyChanges(uint32_t& flags) {
|
|||
_outgoingPriority = NO_PRORITY;
|
||||
} else {
|
||||
_nextOwnershipBid = usecTimestampNow() + USECS_BETWEEN_OWNERSHIP_BIDS;
|
||||
if (PhysicsEngine::getSessionID() == _entity->getSimulatorID() || _entity->getSimulationPriority() >= _outgoingPriority) {
|
||||
if (Physics::getSessionUUID() == _entity->getSimulatorID() || _entity->getSimulationPriority() >= _outgoingPriority) {
|
||||
// we own the simulation or our priority looses to (or ties with) remote
|
||||
_outgoingPriority = NO_PRORITY;
|
||||
}
|
||||
|
@ -527,7 +527,7 @@ uint32_t EntityMotionState::getIncomingDirtyFlags() {
|
|||
if (dirtyFlags | Simulation::DIRTY_SIMULATOR_ID) {
|
||||
// when SIMULATOR_ID changes we must check for reinterpretation of asymmetric collision mask
|
||||
// bits for the avatar groups (e.g. MY_AVATAR vs OTHER_AVATAR)
|
||||
uint8_t entityCollisionMask = _entity->getCollisionMask();
|
||||
uint8_t entityCollisionMask = _entity->getCollisionless() ? 0 : _entity->getCollisionMask();
|
||||
if ((bool)(entityCollisionMask & USER_COLLISION_GROUP_MY_AVATAR) !=
|
||||
(bool)(entityCollisionMask & USER_COLLISION_GROUP_OTHER_AVATAR)) {
|
||||
// bits are asymmetric --> flag for reinsertion in physics simulation
|
||||
|
@ -622,39 +622,8 @@ QString EntityMotionState::getName() const {
|
|||
|
||||
// virtual
|
||||
void EntityMotionState::computeCollisionGroupAndMask(int16_t& group, int16_t& mask) const {
|
||||
group = BULLET_COLLISION_GROUP_STATIC;
|
||||
if (_entity) {
|
||||
if (_entity->getCollisionless()) {
|
||||
group = BULLET_COLLISION_GROUP_COLLISIONLESS;
|
||||
}
|
||||
switch (computePhysicsMotionType()){
|
||||
case MOTION_TYPE_STATIC:
|
||||
group = BULLET_COLLISION_GROUP_STATIC;
|
||||
break;
|
||||
case MOTION_TYPE_DYNAMIC:
|
||||
group = BULLET_COLLISION_GROUP_DYNAMIC;
|
||||
break;
|
||||
case MOTION_TYPE_KINEMATIC:
|
||||
group = BULLET_COLLISION_GROUP_KINEMATIC;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mask = PhysicsEngine::getCollisionMask(group);
|
||||
if (_entity) {
|
||||
uint8_t entityCollisionMask = _entity->getFinalCollisionMask();
|
||||
if ((bool)(entityCollisionMask & USER_COLLISION_GROUP_MY_AVATAR) !=
|
||||
(bool)(entityCollisionMask & USER_COLLISION_GROUP_OTHER_AVATAR)) {
|
||||
// asymmetric avatar collision mask bits
|
||||
if (!_entity->getSimulatorID().isNull() && _entity->getSimulatorID() != PhysicsEngine::getSessionID()) {
|
||||
// someone else owns the simulation, so we swap the interpretation of the bits
|
||||
entityCollisionMask ^= USER_COLLISION_MASK_AVATARS | ~entityCollisionMask;
|
||||
}
|
||||
}
|
||||
mask &= (int16_t)(entityCollisionMask);
|
||||
}
|
||||
assert(_entity);
|
||||
_entity->computeCollisionGroupAndFinalMask(group, mask);
|
||||
}
|
||||
|
||||
void EntityMotionState::setOutgoingPriority(quint8 priority) {
|
||||
|
|
|
@ -18,47 +18,10 @@
|
|||
#include "ThreadSafeDynamicsWorld.h"
|
||||
#include "PhysicsLogging.h"
|
||||
|
||||
uint32_t PhysicsEngine::getNumSubsteps() {
|
||||
return _numSubsteps;
|
||||
}
|
||||
|
||||
btHashMap<btHashInt, int16_t> _collisionMasks;
|
||||
|
||||
void initCollisionMaskTable() {
|
||||
if (_collisionMasks.size() == 0) {
|
||||
// build table of masks with their group as the key
|
||||
_collisionMasks.insert(btHashInt((int)BULLET_COLLISION_GROUP_DYNAMIC), BULLET_COLLISION_MASK_DYNAMIC);
|
||||
_collisionMasks.insert(btHashInt((int)BULLET_COLLISION_GROUP_STATIC), BULLET_COLLISION_MASK_STATIC);
|
||||
_collisionMasks.insert(btHashInt((int)BULLET_COLLISION_GROUP_KINEMATIC), BULLET_COLLISION_MASK_KINEMATIC);
|
||||
_collisionMasks.insert(btHashInt((int)BULLET_COLLISION_GROUP_MY_AVATAR), BULLET_COLLISION_MASK_MY_AVATAR);
|
||||
_collisionMasks.insert(btHashInt((int)BULLET_COLLISION_GROUP_OTHER_AVATAR), BULLET_COLLISION_MASK_OTHER_AVATAR);
|
||||
_collisionMasks.insert(btHashInt((int)BULLET_COLLISION_GROUP_COLLISIONLESS), BULLET_COLLISION_MASK_COLLISIONLESS);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
int16_t PhysicsEngine::getCollisionMask(int16_t group) {
|
||||
const int16_t* mask = _collisionMasks.find(btHashInt((int)group));
|
||||
return mask ? *mask : BULLET_COLLISION_MASK_DEFAULT;
|
||||
}
|
||||
|
||||
QUuid _sessionID;
|
||||
|
||||
// static
|
||||
void PhysicsEngine::setSessionUUID(const QUuid& sessionID) {
|
||||
_sessionID = sessionID;
|
||||
}
|
||||
|
||||
// static
|
||||
const QUuid& PhysicsEngine::getSessionID() {
|
||||
return _sessionID;
|
||||
}
|
||||
|
||||
|
||||
PhysicsEngine::PhysicsEngine(const glm::vec3& offset) :
|
||||
_originOffset(offset),
|
||||
_sessionID(),
|
||||
_myAvatarController(nullptr) {
|
||||
initCollisionMaskTable();
|
||||
}
|
||||
|
||||
PhysicsEngine::~PhysicsEngine() {
|
||||
|
@ -90,6 +53,10 @@ void PhysicsEngine::init() {
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t PhysicsEngine::getNumSubsteps() {
|
||||
return _numSubsteps;
|
||||
}
|
||||
|
||||
// private
|
||||
void PhysicsEngine::addObjectToDynamicsWorld(ObjectMotionState* motionState) {
|
||||
assert(motionState);
|
||||
|
|
|
@ -45,16 +45,11 @@ typedef QVector<Collision> CollisionEvents;
|
|||
|
||||
class PhysicsEngine {
|
||||
public:
|
||||
static int16_t getCollisionMask(int16_t group);
|
||||
|
||||
uint32_t getNumSubsteps();
|
||||
|
||||
PhysicsEngine(const glm::vec3& offset);
|
||||
~PhysicsEngine();
|
||||
void init();
|
||||
|
||||
static void setSessionUUID(const QUuid& sessionID);
|
||||
static const QUuid& getSessionID();
|
||||
uint32_t getNumSubsteps();
|
||||
|
||||
void removeObjects(const VectorOfMotionStates& objects);
|
||||
void removeObjects(const SetOfMotionStates& objects); // only called during teardown
|
||||
|
@ -95,6 +90,8 @@ public:
|
|||
void removeAction(const QUuid actionID);
|
||||
void forEachAction(std::function<void(EntityActionPointer)> actor);
|
||||
|
||||
void setSessionUUID(const QUuid& sessionID) { _sessionID = sessionID; }
|
||||
|
||||
private:
|
||||
void addObjectToDynamicsWorld(ObjectMotionState* motionState);
|
||||
void removeObjectFromDynamicsWorld(ObjectMotionState* motionState);
|
||||
|
@ -111,23 +108,21 @@ private:
|
|||
ThreadSafeDynamicsWorld* _dynamicsWorld = NULL;
|
||||
btGhostPairCallback* _ghostPairCallback = NULL;
|
||||
|
||||
glm::vec3 _originOffset;
|
||||
|
||||
ContactMap _contactMap;
|
||||
uint32_t _numContactFrames = 0;
|
||||
CollisionEvents _collisionEvents;
|
||||
QHash<QUuid, EntityActionPointer> _objectActions;
|
||||
|
||||
glm::vec3 _originOffset;
|
||||
QUuid _sessionID;
|
||||
|
||||
/// character collisions
|
||||
CharacterController* _myAvatarController;
|
||||
|
||||
uint32_t _numContactFrames = 0;
|
||||
uint32_t _numSubsteps;
|
||||
|
||||
bool _dumpNextStats = false;
|
||||
bool _hasOutgoingChanges = false;
|
||||
|
||||
CollisionEvents _collisionEvents;
|
||||
|
||||
QHash<QUuid, EntityActionPointer> _objectActions;
|
||||
|
||||
|
||||
uint32_t _numSubsteps;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<PhysicsEngine> PhysicsEnginePointer;
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
|
||||
#include "PhysicsHelpers.h"
|
||||
#include "NumericalConstants.h"
|
||||
#include <QUuid>
|
||||
|
||||
#include "PhysicsCollisionGroups.h"
|
||||
|
||||
// This chunk of code was copied from Bullet-2.82, so we include the Bullet license here:
|
||||
/*
|
||||
|
@ -19,12 +22,12 @@
|
|||
*
|
||||
* This software is provided 'as-is', without any express or implied warranty.
|
||||
* In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it freely,
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it freely,
|
||||
* subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software.
|
||||
* If you use this software in a product, an acknowledgment in the product documentation would be appreciated but
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software.
|
||||
* If you use this software in a product, an acknowledgment in the product documentation would be appreciated but
|
||||
* is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
|
@ -56,3 +59,33 @@ glm::quat computeBulletRotationStep(const glm::vec3& angularVelocity, float time
|
|||
}
|
||||
return glm::quat(cosf(0.5f * speed * timeStep), axis.x, axis.y, axis.z);
|
||||
}
|
||||
/* end Bullet code derivation*/
|
||||
|
||||
int16_t Physics::getDefaultCollisionMask(int16_t group) {
|
||||
switch(group) {
|
||||
case BULLET_COLLISION_GROUP_STATIC:
|
||||
return BULLET_COLLISION_MASK_STATIC;
|
||||
case BULLET_COLLISION_GROUP_DYNAMIC:
|
||||
return BULLET_COLLISION_MASK_DYNAMIC;
|
||||
case BULLET_COLLISION_GROUP_KINEMATIC:
|
||||
return BULLET_COLLISION_MASK_KINEMATIC;
|
||||
case BULLET_COLLISION_GROUP_MY_AVATAR:
|
||||
return BULLET_COLLISION_MASK_MY_AVATAR;
|
||||
case BULLET_COLLISION_GROUP_OTHER_AVATAR:
|
||||
return BULLET_COLLISION_MASK_OTHER_AVATAR;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
return BULLET_COLLISION_MASK_COLLISIONLESS;
|
||||
}
|
||||
|
||||
QUuid _sessionID;
|
||||
|
||||
void Physics::setSessionUUID(const QUuid& sessionID) {
|
||||
_sessionID = sessionID;
|
||||
}
|
||||
|
||||
const QUuid& Physics::getSessionUUID() {
|
||||
return _sessionID;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,10 @@
|
|||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
#include <QUuid>
|
||||
|
||||
// TODO: move everything in here to the physics library after the physics/entities library
|
||||
// dependency order is swapped.
|
||||
|
||||
const int PHYSICS_ENGINE_MAX_NUM_SUBSTEPS = 6; // Bullet will start to "lose time" at 10 FPS.
|
||||
const float PHYSICS_ENGINE_FIXED_SUBSTEP = 1.0f / 90.0f;
|
||||
|
@ -21,4 +25,11 @@ const float PHYSICS_ENGINE_FIXED_SUBSTEP = 1.0f / 90.0f;
|
|||
// return incremental rotation (Bullet-style) caused by angularVelocity over timeStep
|
||||
glm::quat computeBulletRotationStep(const glm::vec3& angularVelocity, float timeStep);
|
||||
|
||||
namespace Physics {
|
||||
int16_t getDefaultCollisionMask(int16_t group);
|
||||
|
||||
void setSessionUUID(const QUuid& sessionID);
|
||||
const QUuid& getSessionUUID();
|
||||
};
|
||||
|
||||
#endif // hifi_PhysicsHelpers_h
|
||||
|
|
Loading…
Reference in a new issue