remake foundation for CollisionEvents

This commit is contained in:
Andrew Meadows 2015-05-03 09:27:15 -07:00
parent cb37b884d2
commit fef84730bf
5 changed files with 48 additions and 32 deletions

View file

@ -2386,6 +2386,7 @@ void Application::update(float deltaTime) {
if (_physicsEngine.hasOutgoingChanges()) {
_entitySimulation.handleOutgoingChanges(_physicsEngine.getOutgoingChanges());
_entitySimulation.handleCollisionEvents(_physicsEngine.getCollisionEvents());
_physicsEngine.dumpStatsIfNecessary();
}
}

View file

@ -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
}

View file

@ -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)

View file

@ -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() {

View file

@ -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