mirror of
https://github.com/overte-org/overte.git
synced 2025-06-02 08:42:03 +02:00
remake foundation for CollisionEvents
This commit is contained in:
parent
cb37b884d2
commit
fef84730bf
5 changed files with 48 additions and 32 deletions
|
@ -2386,6 +2386,7 @@ void Application::update(float deltaTime) {
|
||||||
|
|
||||||
if (_physicsEngine.hasOutgoingChanges()) {
|
if (_physicsEngine.hasOutgoingChanges()) {
|
||||||
_entitySimulation.handleOutgoingChanges(_physicsEngine.getOutgoingChanges());
|
_entitySimulation.handleOutgoingChanges(_physicsEngine.getOutgoingChanges());
|
||||||
|
_entitySimulation.handleCollisionEvents(_physicsEngine.getCollisionEvents());
|
||||||
_physicsEngine.dumpStatsIfNecessary();
|
_physicsEngine.dumpStatsIfNecessary();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
|
|
||||||
#include "EntityMotionState.h"
|
#include "EntityMotionState.h"
|
||||||
#include "PhysicalEntitySimulation.h"
|
#include "PhysicalEntitySimulation.h"
|
||||||
#include "PhysicsEngine.h"
|
|
||||||
#include "PhysicsHelpers.h"
|
#include "PhysicsHelpers.h"
|
||||||
#include "PhysicsLogging.h"
|
#include "PhysicsLogging.h"
|
||||||
#include "ShapeInfoUtil.h"
|
#include "ShapeInfoUtil.h"
|
||||||
|
@ -189,6 +188,7 @@ void PhysicalEntitySimulation::handleOutgoingChanges(VectorOfMotionStates& motio
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicalEntitySimulation::bump(EntityItem* bumpEntity) {
|
void PhysicalEntitySimulation::handleCollisionEvents(CollisionEvents& collisionEvents) {
|
||||||
|
// BOOKMARK TODO: emit events
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,10 +20,10 @@
|
||||||
#include <EntityItem.h>
|
#include <EntityItem.h>
|
||||||
#include <EntitySimulation.h>
|
#include <EntitySimulation.h>
|
||||||
|
|
||||||
|
#include "PhysicsEngine.h"
|
||||||
#include "PhysicsTypedefs.h"
|
#include "PhysicsTypedefs.h"
|
||||||
|
|
||||||
class EntityMotionState;
|
class EntityMotionState;
|
||||||
class PhysicsEngine;
|
|
||||||
class ShapeManager;
|
class ShapeManager;
|
||||||
|
|
||||||
class PhysicalEntitySimulation :public EntitySimulation {
|
class PhysicalEntitySimulation :public EntitySimulation {
|
||||||
|
@ -47,10 +47,9 @@ public:
|
||||||
VectorOfMotionStates& getObjectsToChange();
|
VectorOfMotionStates& getObjectsToChange();
|
||||||
|
|
||||||
void handleOutgoingChanges(VectorOfMotionStates& motionStates);
|
void handleOutgoingChanges(VectorOfMotionStates& motionStates);
|
||||||
|
void handleCollisionEvents(CollisionEvents& collisionEvents);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void bump(EntityItem* bumpEntity);
|
|
||||||
|
|
||||||
// incoming changes
|
// incoming changes
|
||||||
SetOfEntities _pendingRemoves; // entities to be removed from PhysicsEngine (and their MotionState deleted)
|
SetOfEntities _pendingRemoves; // entities to be removed from PhysicsEngine (and their MotionState deleted)
|
||||||
SetOfEntities _pendingAdds; // entities to be be added to PhysicsEngine (and a their MotionState created)
|
SetOfEntities _pendingAdds; // entities to be be added to PhysicsEngine (and a their MotionState created)
|
||||||
|
|
|
@ -237,12 +237,13 @@ void PhysicsEngine::stepSimulation() {
|
||||||
if (_characterController) {
|
if (_characterController) {
|
||||||
_characterController->postSimulation();
|
_characterController->postSimulation();
|
||||||
}
|
}
|
||||||
computeCollisionEvents();
|
updateContactMap();
|
||||||
_hasOutgoingChanges = true;
|
_hasOutgoingChanges = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsEngine::doOwnershipInfection(const btCollisionObject* objectA, const btCollisionObject* objectB) {
|
void PhysicsEngine::doOwnershipInfection(const btCollisionObject* objectA, const btCollisionObject* objectB) {
|
||||||
|
// BOOKMARK TODO: move this to PhysicalEntitySimulation
|
||||||
BT_PROFILE("ownershipInfection");
|
BT_PROFILE("ownershipInfection");
|
||||||
if (_sessionID.isNull()) {
|
if (_sessionID.isNull()) {
|
||||||
return;
|
return;
|
||||||
|
@ -263,8 +264,9 @@ void PhysicsEngine::doOwnershipInfection(const btCollisionObject* objectA, const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsEngine::computeCollisionEvents() {
|
void PhysicsEngine::updateContactMap() {
|
||||||
BT_PROFILE("computeCollisionEvents");
|
BT_PROFILE("updateContactMap");
|
||||||
|
++_numContactFrames;
|
||||||
|
|
||||||
// update all contacts every frame
|
// update all contacts every frame
|
||||||
int numManifolds = _collisionDispatcher->getNumManifolds();
|
int numManifolds = _collisionDispatcher->getNumManifolds();
|
||||||
|
@ -292,39 +294,31 @@ void PhysicsEngine::computeCollisionEvents() {
|
||||||
doOwnershipInfection(objectA, objectB);
|
doOwnershipInfection(objectA, objectB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fireCollisionEvents();
|
|
||||||
++_numContactFrames;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsEngine::fireCollisionEvents() {
|
CollisionEvents& PhysicsEngine::getCollisionEvents() {
|
||||||
/* TODO: Andrew to make this work for ObjectMotionStates
|
|
||||||
const uint32_t CONTINUE_EVENT_FILTER_FREQUENCY = 10;
|
const uint32_t CONTINUE_EVENT_FILTER_FREQUENCY = 10;
|
||||||
|
_collisionEvents.clear();
|
||||||
|
|
||||||
// scan known contacts and trigger events
|
// scan known contacts and trigger events
|
||||||
ContactMap::iterator contactItr = _contactMap.begin();
|
ContactMap::iterator contactItr = _contactMap.begin();
|
||||||
|
|
||||||
while (contactItr != _contactMap.end()) {
|
while (contactItr != _contactMap.end()) {
|
||||||
ObjectMotionState* A = static_cast<ObjectMotionState*>(contactItr->first._a);
|
|
||||||
ObjectMotionState* B = static_cast<ObjectMotionState*>(contactItr->first._b);
|
|
||||||
|
|
||||||
// TODO: make triggering these events clean and efficient. The code at this context shouldn't
|
|
||||||
// have to figure out what kind of object (entity, avatar, etc) these are in order to properly
|
|
||||||
// emit a collision event.
|
|
||||||
// TODO: enable scripts to filter based on contact event type
|
|
||||||
ContactEventType type = contactItr->second.computeType(_numContactFrames);
|
ContactEventType type = contactItr->second.computeType(_numContactFrames);
|
||||||
if(type != CONTACT_EVENT_TYPE_CONTINUE || _numSubsteps % CONTINUE_EVENT_FILTER_FREQUENCY == 0){
|
if(type != CONTACT_EVENT_TYPE_CONTINUE || _numSubsteps % CONTINUE_EVENT_FILTER_FREQUENCY == 0) {
|
||||||
|
ObjectMotionState* A = static_cast<ObjectMotionState*>(contactItr->first._a);
|
||||||
|
ObjectMotionState* B = static_cast<ObjectMotionState*>(contactItr->first._b);
|
||||||
|
|
||||||
if (A && A->getType() == MOTION_STATE_TYPE_ENTITY) {
|
if (A && A->getType() == MOTION_STATE_TYPE_ENTITY) {
|
||||||
EntityItemID idA = static_cast<EntityMotionState*>(A)->getEntity()->getEntityItemID();
|
QUuid idA = A->getObjectID();
|
||||||
EntityItemID idB;
|
QUuid idB;
|
||||||
if (B && B->getType() == MOTION_STATE_TYPE_ENTITY) {
|
if (B && B->getType() == MOTION_STATE_TYPE_ENTITY) {
|
||||||
idB = static_cast<EntityMotionState*>(B)->getEntity()->getEntityItemID();
|
idB = B->getObjectID();
|
||||||
}
|
}
|
||||||
emit entityCollisionWithEntity(idA, idB, contactItr->second);
|
_collisionEvents.push_back(CollisionEvent(type, idA, idB));
|
||||||
} else if (B && B->getType() == MOTION_STATE_TYPE_ENTITY) {
|
} else if (B && B->getType() == MOTION_STATE_TYPE_ENTITY) {
|
||||||
EntityItemID idA;
|
QUuid idB = B->getObjectID();
|
||||||
EntityItemID idB = static_cast<EntityMotionState*>(B)->getEntity()->getEntityItemID();
|
_collisionEvents.push_back(CollisionEvent(type, idB, QUuid()));
|
||||||
emit entityCollisionWithEntity(idA, idB, contactItr->second);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,7 +330,7 @@ void PhysicsEngine::fireCollisionEvents() {
|
||||||
++contactItr;
|
++contactItr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
return _collisionEvents;
|
||||||
}
|
}
|
||||||
|
|
||||||
VectorOfMotionStates& PhysicsEngine::getOutgoingChanges() {
|
VectorOfMotionStates& PhysicsEngine::getOutgoingChanges() {
|
||||||
|
|
|
@ -41,7 +41,21 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<ContactKey, ContactInfo> ContactMap;
|
typedef std::map<ContactKey, ContactInfo> ContactMap;
|
||||||
typedef std::pair<ContactKey, ContactInfo> ContactMapElement;
|
|
||||||
|
class CollisionEvent {
|
||||||
|
public:
|
||||||
|
CollisionEvent() : _type(CONTACT_EVENT_TYPE_START), _idA(), _idB() {}
|
||||||
|
CollisionEvent(ContactEventType type, const QUuid& idA, const QUuid& idB) : _type(type), _idA(idA), _idB(idB) {}
|
||||||
|
|
||||||
|
ContactEventType _type; // START, CONTINUE, or END
|
||||||
|
QUuid _idA;
|
||||||
|
QUuid _idB;
|
||||||
|
// TODO: add is info to contact callback
|
||||||
|
//glm::vec3 _position; // world-frame
|
||||||
|
//glm::vec3 _normal; // world-frame
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef QVector<CollisionEvent> CollisionEvents;
|
||||||
|
|
||||||
class PhysicsEngine {
|
class PhysicsEngine {
|
||||||
public:
|
public:
|
||||||
|
@ -64,11 +78,17 @@ public:
|
||||||
void reinsertObject(ObjectMotionState* object);
|
void reinsertObject(ObjectMotionState* object);
|
||||||
|
|
||||||
void stepSimulation();
|
void stepSimulation();
|
||||||
void computeCollisionEvents();
|
void updateContactMap();
|
||||||
void fireCollisionEvents();
|
|
||||||
|
|
||||||
bool hasOutgoingChanges() const { return _hasOutgoingChanges; }
|
bool hasOutgoingChanges() const { return _hasOutgoingChanges; }
|
||||||
|
|
||||||
|
/// \return reference to list of changed MotionStates. The list is only valid until beginning of next simulation loop.
|
||||||
VectorOfMotionStates& getOutgoingChanges();
|
VectorOfMotionStates& getOutgoingChanges();
|
||||||
|
|
||||||
|
/// \return reference to list of CollisionEvent's. The list is only valid until beginning of next simulation loop.
|
||||||
|
CollisionEvents& getCollisionEvents();
|
||||||
|
|
||||||
|
/// \brief prints timings for last frame if stats have been requested.
|
||||||
void dumpStatsIfNecessary();
|
void dumpStatsIfNecessary();
|
||||||
|
|
||||||
/// \param offset position of simulation origin in domain-frame
|
/// \param offset position of simulation origin in domain-frame
|
||||||
|
@ -77,6 +97,7 @@ public:
|
||||||
/// \return position of simulation origin in domain-frame
|
/// \return position of simulation origin in domain-frame
|
||||||
const glm::vec3& getOriginOffset() const { return _originOffset; }
|
const glm::vec3& getOriginOffset() const { return _originOffset; }
|
||||||
|
|
||||||
|
/// \brief call bump on any objects that touch the object corresponding to motionState
|
||||||
void bump(ObjectMotionState* motionState);
|
void bump(ObjectMotionState* motionState);
|
||||||
|
|
||||||
void removeRigidBody(btRigidBody* body);
|
void removeRigidBody(btRigidBody* body);
|
||||||
|
@ -111,6 +132,7 @@ private:
|
||||||
bool _hasOutgoingChanges = false;
|
bool _hasOutgoingChanges = false;
|
||||||
|
|
||||||
QUuid _sessionID;
|
QUuid _sessionID;
|
||||||
|
CollisionEvents _collisionEvents;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_PhysicsEngine_h
|
#endif // hifi_PhysicsEngine_h
|
||||||
|
|
Loading…
Reference in a new issue