mirror of
https://github.com/overte-org/overte.git
synced 2025-06-05 18:51:13 +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()) {
|
||||
_entitySimulation.handleOutgoingChanges(_physicsEngine.getOutgoingChanges());
|
||||
_entitySimulation.handleCollisionEvents(_physicsEngine.getCollisionEvents());
|
||||
_physicsEngine.dumpStatsIfNecessary();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
|
||||
#include "EntityMotionState.h"
|
||||
#include "PhysicalEntitySimulation.h"
|
||||
#include "PhysicsEngine.h"
|
||||
#include "PhysicsHelpers.h"
|
||||
#include "PhysicsLogging.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 <EntitySimulation.h>
|
||||
|
||||
#include "PhysicsEngine.h"
|
||||
#include "PhysicsTypedefs.h"
|
||||
|
||||
class EntityMotionState;
|
||||
class PhysicsEngine;
|
||||
class ShapeManager;
|
||||
|
||||
class PhysicalEntitySimulation :public EntitySimulation {
|
||||
|
@ -47,10 +47,9 @@ public:
|
|||
VectorOfMotionStates& getObjectsToChange();
|
||||
|
||||
void handleOutgoingChanges(VectorOfMotionStates& motionStates);
|
||||
void handleCollisionEvents(CollisionEvents& collisionEvents);
|
||||
|
||||
private:
|
||||
void bump(EntityItem* bumpEntity);
|
||||
|
||||
// incoming changes
|
||||
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)
|
||||
|
|
|
@ -237,12 +237,13 @@ void PhysicsEngine::stepSimulation() {
|
|||
if (_characterController) {
|
||||
_characterController->postSimulation();
|
||||
}
|
||||
computeCollisionEvents();
|
||||
updateContactMap();
|
||||
_hasOutgoingChanges = true;
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsEngine::doOwnershipInfection(const btCollisionObject* objectA, const btCollisionObject* objectB) {
|
||||
// BOOKMARK TODO: move this to PhysicalEntitySimulation
|
||||
BT_PROFILE("ownershipInfection");
|
||||
if (_sessionID.isNull()) {
|
||||
return;
|
||||
|
@ -263,8 +264,9 @@ void PhysicsEngine::doOwnershipInfection(const btCollisionObject* objectA, const
|
|||
}
|
||||
}
|
||||
|
||||
void PhysicsEngine::computeCollisionEvents() {
|
||||
BT_PROFILE("computeCollisionEvents");
|
||||
void PhysicsEngine::updateContactMap() {
|
||||
BT_PROFILE("updateContactMap");
|
||||
++_numContactFrames;
|
||||
|
||||
// update all contacts every frame
|
||||
int numManifolds = _collisionDispatcher->getNumManifolds();
|
||||
|
@ -292,39 +294,31 @@ void PhysicsEngine::computeCollisionEvents() {
|
|||
doOwnershipInfection(objectA, objectB);
|
||||
}
|
||||
}
|
||||
|
||||
fireCollisionEvents();
|
||||
++_numContactFrames;
|
||||
}
|
||||
|
||||
void PhysicsEngine::fireCollisionEvents() {
|
||||
/* TODO: Andrew to make this work for ObjectMotionStates
|
||||
CollisionEvents& PhysicsEngine::getCollisionEvents() {
|
||||
const uint32_t CONTINUE_EVENT_FILTER_FREQUENCY = 10;
|
||||
_collisionEvents.clear();
|
||||
|
||||
// scan known contacts and trigger events
|
||||
ContactMap::iterator contactItr = _contactMap.begin();
|
||||
|
||||
while (contactItr != _contactMap.end()) {
|
||||
ContactEventType type = contactItr->second.computeType(_numContactFrames);
|
||||
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);
|
||||
|
||||
// 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);
|
||||
if(type != CONTACT_EVENT_TYPE_CONTINUE || _numSubsteps % CONTINUE_EVENT_FILTER_FREQUENCY == 0){
|
||||
if (A && A->getType() == MOTION_STATE_TYPE_ENTITY) {
|
||||
EntityItemID idA = static_cast<EntityMotionState*>(A)->getEntity()->getEntityItemID();
|
||||
EntityItemID idB;
|
||||
QUuid idA = A->getObjectID();
|
||||
QUuid idB;
|
||||
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) {
|
||||
EntityItemID idA;
|
||||
EntityItemID idB = static_cast<EntityMotionState*>(B)->getEntity()->getEntityItemID();
|
||||
emit entityCollisionWithEntity(idA, idB, contactItr->second);
|
||||
QUuid idB = B->getObjectID();
|
||||
_collisionEvents.push_back(CollisionEvent(type, idB, QUuid()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -336,7 +330,7 @@ void PhysicsEngine::fireCollisionEvents() {
|
|||
++contactItr;
|
||||
}
|
||||
}
|
||||
*/
|
||||
return _collisionEvents;
|
||||
}
|
||||
|
||||
VectorOfMotionStates& PhysicsEngine::getOutgoingChanges() {
|
||||
|
|
|
@ -41,7 +41,21 @@ public:
|
|||
};
|
||||
|
||||
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 {
|
||||
public:
|
||||
|
@ -64,11 +78,17 @@ public:
|
|||
void reinsertObject(ObjectMotionState* object);
|
||||
|
||||
void stepSimulation();
|
||||
void computeCollisionEvents();
|
||||
void fireCollisionEvents();
|
||||
void updateContactMap();
|
||||
|
||||
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();
|
||||
|
||||
/// \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();
|
||||
|
||||
/// \param offset position of simulation origin in domain-frame
|
||||
|
@ -77,6 +97,7 @@ public:
|
|||
/// \return position of simulation origin in domain-frame
|
||||
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 removeRigidBody(btRigidBody* body);
|
||||
|
@ -111,6 +132,7 @@ private:
|
|||
bool _hasOutgoingChanges = false;
|
||||
|
||||
QUuid _sessionID;
|
||||
CollisionEvents _collisionEvents;
|
||||
};
|
||||
|
||||
#endif // hifi_PhysicsEngine_h
|
||||
|
|
Loading…
Reference in a new issue