diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index d48ed1af92..616a660d43 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -70,6 +70,7 @@ #include #include #include +#include #include #include #include @@ -2069,11 +2070,11 @@ void Application::init() { auto entityScriptingInterface = DependencyManager::get(); - connect(&_physicsEngine, &EntitySimulation::entityCollisionWithEntity, + connect(&_entitySimulation, &EntitySimulation::entityCollisionWithEntity, entityScriptingInterface.data(), &EntityScriptingInterface::entityCollisionWithEntity); // connect the _entityCollisionSystem to our EntityTreeRenderer since that's what handles running entity scripts - connect(&_physicsEngine, &EntitySimulation::entityCollisionWithEntity, + connect(&_entitySimulation, &EntitySimulation::entityCollisionWithEntity, &_entities, &EntityTreeRenderer::entityCollisionWithEntity); // connect the _entities (EntityTreeRenderer) to our script engine's EntityScriptingInterface for firing @@ -2355,7 +2356,7 @@ void Application::update(float deltaTime) { PerformanceTimer perfTimer("physics"); _myAvatar->relayDriveKeysToCharacterController(); - _physicsEngine.deleteObjects(_entitySimulation.getObjectsToRemove()); + _physicsEngine.deleteObjects(_entitySimulation.getObjectsToDelete()); _physicsEngine.addObjects(_entitySimulation.getObjectsToAdd()); _physicsEngine.changeObjects(_entitySimulation.getObjectsToChange()); diff --git a/libraries/entities/src/EntitySimulation.cpp b/libraries/entities/src/EntitySimulation.cpp index 1cf3ba42e6..7ea8c0a330 100644 --- a/libraries/entities/src/EntitySimulation.cpp +++ b/libraries/entities/src/EntitySimulation.cpp @@ -70,7 +70,7 @@ void EntitySimulation::expireMortalEntities(const quint64& now) { itemItr = _mortalEntities.erase(itemItr); _entitiesToUpdate.remove(entity); _entitiesToSort.remove(entity); - deleteEntityInternal(entity); + removeEntityInternal(entity); } else { if (expiry < _nextExpiry) { // remeber the smallest _nextExpiry so we know when to start the next search @@ -116,7 +116,7 @@ void EntitySimulation::sortEntitiesThatMoved() { _entitiesToDelete.insert(entity); _mortalEntities.remove(entity); _entitiesToUpdate.remove(entity); - deleteEntityInternal(entity); + removeEntityInternal(entity); itemItr = _entitiesToSort.erase(itemItr); } else { moveOperator.addEntityToMoveList(entity, newCube); @@ -160,36 +160,7 @@ void EntitySimulation::removeEntity(EntityItem* entity) { _entitiesToUpdate.remove(entity); _mortalEntities.remove(entity); _entitiesToSort.remove(entity); - if (entity->_element) { - // some EntityTreeElement still references this entity, but it's being removed from this simulation - _entitiesToDelete.remove(entity); - removeEntityInternal(entity); - } else { - // we're the last to reference this entity, so we really need to delete it - deleteEntityInternal(entity); - } - } else if (!entity->_element) { - // nothing else is referencing this entity, so we delete it now - delete entity; - } -} - -void EntitySimulation::deleteEntity(EntityItem* entity) { - assert(entity); - if (entity->_simulation == this) { - _entitiesToUpdate.remove(entity); - _mortalEntities.remove(entity); - _entitiesToSort.remove(entity); - deleteEntityInternal(entity); - } else { - if (entity->_element) { - // some EntityTreeElement still references this entity, so we put it on the list - // which will be harvested by the tree later - _entitiesToDelete.insert(entity); - } else { - // nothing else is referencing this entity, so we delete it now - delete entity; - } + removeEntityInternal(entity); } } @@ -209,7 +180,8 @@ void EntitySimulation::changeEntity(EntityItem* entity) { _entitiesToDelete.insert(entity); _mortalEntities.remove(entity); _entitiesToUpdate.remove(entity); - deleteEntityInternal(entity); + _entitiesToSort.remove(entity); + removeEntityInternal(entity); wasRemoved = true; } } diff --git a/libraries/entities/src/EntitySimulation.h b/libraries/entities/src/EntitySimulation.h index b975207f87..03db85e399 100644 --- a/libraries/entities/src/EntitySimulation.h +++ b/libraries/entities/src/EntitySimulation.h @@ -20,8 +20,6 @@ #include "EntityItem.h" #include "EntityTree.h" -typedef QSet SetOfEntities; - // the EntitySimulation needs to know when these things change on an entity, // so it can sort EntityItem or relay its state to the PhysicsEngine. const int DIRTY_SIMULATION_FLAGS = @@ -51,6 +49,9 @@ public: void updateEntities(); + friend EntityTree; + +protected: // these only called by the EntityTree? /// \param entity pointer to EntityItem to be added /// \sideeffect sets relevant backpointers in entity, but maybe later when appropriate data structures are locked void addEntity(EntityItem* entity); @@ -60,17 +61,14 @@ public: /// \sideeffect nulls relevant backpointers in entity void removeEntity(EntityItem* entity); - /// \param pointer to EntityItem to be removed from simulation, and deleted if possible - /// \brief actual removal/delete may happen later when appropriate data structures are locked - /// \sideeffect nulls relevant backpointers in entity - void deleteEntity(EntityItem* entity); - /// \param entity pointer to EntityItem to that may have changed in a way that would affect its simulation /// call this whenever an entity was changed from some EXTERNAL event (NOT by the EntitySimulation itself) void changeEntity(EntityItem* entity); void clearEntities(); +public: + EntityTree* getEntityTree() { return _entityTree; } void getEntitiesToDelete(SetOfEntities& entitiesToDelete); @@ -84,20 +82,11 @@ protected: // These pure virtual methods are protected because they are not to be called will-nilly. The base class // calls them in the right places. - - // NOTE: updateEntitiesInternal() should clear all dirty flags on each changed entity as side effect virtual void updateEntitiesInternal(const quint64& now) = 0; - virtual void addEntityInternal(EntityItem* entity) = 0; - virtual void removeEntityInternal(EntityItem* entity) = 0; - - virtual void deleteEntityInternal(EntityItem* entity) = 0; - virtual void changeEntityInternal(EntityItem* entity) = 0; - virtual void sortEntitiesThatMovedInternal() {} - virtual void clearEntitiesInternal() = 0; void expireMortalEntities(const quint64& now); diff --git a/libraries/entities/src/SimpleEntitySimulation.cpp b/libraries/entities/src/SimpleEntitySimulation.cpp index 7739a9a28c..b6e444a0a9 100644 --- a/libraries/entities/src/SimpleEntitySimulation.cpp +++ b/libraries/entities/src/SimpleEntitySimulation.cpp @@ -68,17 +68,6 @@ void SimpleEntitySimulation::removeEntityInternal(EntityItem* entity) { clearEntitySimulation(entity); } -void SimpleEntitySimulation::deleteEntityInternal(EntityItem* entity) { - _movingEntities.remove(entity); - _movableButStoppedEntities.remove(entity); - _hasSimulationOwnerEntities.remove(entity); - clearEntitySimulation(entity); - if (!entity->getElement()) { - // we held the last reference to this entity, so delete it - delete entity; - } -} - const int SIMPLE_SIMULATION_DIRTY_FLAGS = EntityItem::DIRTY_VELOCITIES | EntityItem::DIRTY_MOTION_TYPE; void SimpleEntitySimulation::changeEntityInternal(EntityItem* entity) { diff --git a/libraries/entities/src/SimpleEntitySimulation.h b/libraries/entities/src/SimpleEntitySimulation.h index fa625e4783..b63047ef0e 100644 --- a/libraries/entities/src/SimpleEntitySimulation.h +++ b/libraries/entities/src/SimpleEntitySimulation.h @@ -25,7 +25,6 @@ protected: virtual void updateEntitiesInternal(const quint64& now); virtual void addEntityInternal(EntityItem* entity); virtual void removeEntityInternal(EntityItem* entity); - virtual void deleteEntityInternal(EntityItem* entity); virtual void changeEntityInternal(EntityItem* entity); virtual void clearEntitiesInternal(); diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index fd1a53a0ce..d8fcc47b60 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -111,6 +111,10 @@ void EntityMotionState::setWorldTransform(const btTransform& worldTrans) { #endif } +void EntityMotionState::computeObjectShapeInfo(ShapeInfo& shapeInfo) { + _entity->computeShapeInfo(shapeInfo); +} + // RELIABLE_SEND_HACK: until we have truly reliable resends of non-moving updates // we alwasy resend packets for objects that have stopped moving up to some max limit. const int MAX_NUM_NON_MOVING_UPDATES = 5; diff --git a/libraries/physics/src/ObjectMotionState.cpp b/libraries/physics/src/ObjectMotionState.cpp index 9486b4a8a1..47e8e7d861 100644 --- a/libraries/physics/src/ObjectMotionState.cpp +++ b/libraries/physics/src/ObjectMotionState.cpp @@ -67,6 +67,11 @@ ObjectMotionState::ObjectMotionState(btCollisionShape* shape) : { } +ObjectMotionState::~ObjectMotionState() { + assert(!_body); + assert(!_shape); +} + void ObjectMotionState::setBodyLinearVelocity(const glm::vec3& velocity) const { _body->setLinearVelocity(glmToBullet(velocity)); } @@ -190,8 +195,8 @@ void ObjectMotionState::updateBodyMaterialProperties() { } void ObjectMotionState::updateBodyVelocities() { - setBodyVelocity(getObjectLinearVelocity()); - setBodyAngularVelocity(getObjectAngularVelocity(); - setBodyGravity(getObjectGravity(); + setBodyLinearVelocity(getObjectLinearVelocity()); + setBodyAngularVelocity(getObjectAngularVelocity()); + setBodyGravity(getObjectGravity()); _body->setActivationState(ACTIVE_TAG); } diff --git a/libraries/physics/src/ObjectMotionState.h b/libraries/physics/src/ObjectMotionState.h index 0d82395c76..253ce57847 100644 --- a/libraries/physics/src/ObjectMotionState.h +++ b/libraries/physics/src/ObjectMotionState.h @@ -90,7 +90,7 @@ public: virtual void clearIncomingDirtyFlags(uint32_t flags) = 0; virtual MotionType computeObjectMotionType() const = 0; - virtual void computeObjectShapeInfo(ShapeInfo& shapeInfo); + virtual void computeObjectShapeInfo(ShapeInfo& shapeInfo) = 0; btCollisionShape* getShape() const { return _shape; } diff --git a/libraries/physics/src/PhysicalEntitySimulation.cpp b/libraries/physics/src/PhysicalEntitySimulation.cpp index f117ed4c1c..fe104e82ec 100644 --- a/libraries/physics/src/PhysicalEntitySimulation.cpp +++ b/libraries/physics/src/PhysicalEntitySimulation.cpp @@ -55,22 +55,12 @@ void PhysicalEntitySimulation::addEntityInternal(EntityItem* entity) { } void PhysicalEntitySimulation::removeEntityInternal(EntityItem* entity) { - assert(entity); - void* physicsInfo = entity->getPhysicsInfo(); - if (physicsInfo) { + if (entity->getPhysicsInfo()) { _pendingRemoves.insert(entity); } } -void PhysicalEntitySimulation::deleteEntityInternal(EntityItem* entity) { - assert(entity); - void* physicsInfo = entity->getPhysicsInfo(); - if (physicsInfo) { - _pendingRemoves.insert(entity); - } -} - -void PhysicalEntitySimulation::entityChangedInternal(EntityItem* entity) { +void PhysicalEntitySimulation::changeEntityInternal(EntityItem* entity) { // queue incoming changes: from external sources (script, EntityServer, etc) to physics engine assert(entity); void* physicsInfo = entity->getPhysicsInfo(); diff --git a/libraries/physics/src/PhysicalEntitySimulation.h b/libraries/physics/src/PhysicalEntitySimulation.h index 523121cefe..3cbebadd12 100644 --- a/libraries/physics/src/PhysicalEntitySimulation.h +++ b/libraries/physics/src/PhysicalEntitySimulation.h @@ -33,15 +33,16 @@ public: void init(EntityTree* tree, PhysicsEngine* engine, ShapeManager* shapeManager, EntityEditPacketSender* packetSender); +protected: // only called by EntitySimulation // overrides for EntitySimulation void updateEntitiesInternal(const quint64& now); void addEntityInternal(EntityItem* entity); void removeEntityInternal(EntityItem* entity); - void deleteEntityInternal(EntityItem* entity); - void entityChangedInternal(EntityItem* entity); + void changeEntityInternal(EntityItem* entity); void sortEntitiesThatMovedInternal(); void clearEntitiesInternal(); +public: VectorOfMotionStates& getObjectsToDelete(); VectorOfMotionStates& getObjectsToAdd(); VectorOfMotionStates& getObjectsToChange(); diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 7b9a534cac..1029dc064f 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -113,7 +113,8 @@ void PhysicsEngine::addObject(ObjectMotionState* motionState) { case MOTION_TYPE_STATIC: default: { if (!body) { - body = new btRigidBody(mass, motionState, shape, inertia); + assert(motionState->getShape()); + body = new btRigidBody(mass, motionState, motionState->getShape(), inertia); } else { body->setMassProps(mass, inertia); } @@ -144,6 +145,7 @@ void PhysicsEngine::deleteObjects(VectorOfMotionStates& objects) { removeObject(object); // NOTE: setRigidBody() modifies body->m_userPointer so we should clear the MotionState's body BEFORE deleting it. + btRigidBody* body = object->getRigidBody(); object->setRigidBody(nullptr); delete body; object->releaseShape(); @@ -151,9 +153,10 @@ void PhysicsEngine::deleteObjects(VectorOfMotionStates& objects) { } } -// Same as above, but takes a Set instead of a Vector. Only called during teardown. +// Same as above, but takes a Set instead of a Vector and ommits some cleanup operations. Only called during teardown. void PhysicsEngine::deleteObjects(SetOfMotionStates& objects) { for (auto object : objects) { + btRigidBody* body = object->getRigidBody(); _dynamicsWorld->removeRigidBody(body); // NOTE: setRigidBody() modifies body->m_userPointer so we should clear the MotionState's body BEFORE deleting it. @@ -181,6 +184,11 @@ void PhysicsEngine::changeObjects(VectorOfMotionStates& objects) { } } +void PhysicsEngine::reinsertObject(ObjectMotionState* object) { + removeObject(object); + addObject(object); +} + void PhysicsEngine::removeContacts(ObjectMotionState* motionState) { // trigger events for new/existing/old contacts ContactMap::iterator contactItr = _contactMap.begin(); @@ -373,11 +381,6 @@ void PhysicsEngine::dumpStatsIfNecessary() { // CF_DISABLE_VISUALIZE_OBJECT = 32, //disable debug drawing // CF_DISABLE_SPU_COLLISION_PROCESSING = 64//disable parallel/SPU processing -void PhysicsEngine::reinsertObject(ObjectMotionState* object) { - removeObject(object); - addObject(object); -} - void PhysicsEngine::bump(ObjectMotionState* object) { assert(object); /* TODO: Andrew to implement this diff --git a/libraries/physics/src/PhysicsEngine.h b/libraries/physics/src/PhysicsEngine.h index 416ceee3e5..b05ebd05db 100644 --- a/libraries/physics/src/PhysicsEngine.h +++ b/libraries/physics/src/PhysicsEngine.h @@ -58,6 +58,7 @@ public: void deleteObjects(SetOfMotionStates& objects); // only called during teardown void addObjects(VectorOfMotionStates& objects); void changeObjects(VectorOfMotionStates& objects); + void reinsertObject(ObjectMotionState* object); void stepSimulation(); void computeCollisionEvents();