mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:44:02 +02:00
remove entities from physics before we delete them
This commit is contained in:
parent
b34df211df
commit
f5d24a87ca
5 changed files with 58 additions and 38 deletions
|
@ -337,6 +337,8 @@ public:
|
|||
|
||||
bool isMoving() const;
|
||||
|
||||
bool isSimulated() const { return _simulated; }
|
||||
|
||||
void* getPhysicsInfo() const { return _physicsInfo; }
|
||||
|
||||
void setPhysicsInfo(void* data) { _physicsInfo = data; }
|
||||
|
@ -391,6 +393,8 @@ public:
|
|||
|
||||
protected:
|
||||
|
||||
void setSimulated(bool simulated) { _simulated = simulated; }
|
||||
|
||||
const QByteArray getActionDataInternal() const;
|
||||
void setActionDataInternal(QByteArray actionData);
|
||||
|
||||
|
|
|
@ -53,16 +53,15 @@ void EntitySimulation::removeEntityInternal(EntityItemPointer entity) {
|
|||
_entitiesToSort.remove(entity);
|
||||
_simpleKinematicEntities.remove(entity);
|
||||
_allEntities.remove(entity);
|
||||
entity->_simulated = false;
|
||||
entity->setSimulated(false);
|
||||
}
|
||||
|
||||
void EntitySimulation::prepareEntityForDelete(EntityItemPointer entity) {
|
||||
assert(entity);
|
||||
if (entity->_simulated) {
|
||||
entity->clearActions(this);
|
||||
_entitiesToDelete.insert(entity);
|
||||
removeEntityInternal(entity);
|
||||
}
|
||||
assert(entity->isSimulated());
|
||||
entity->clearActions(this);
|
||||
removeEntityInternal(entity);
|
||||
_entitiesToDelete.insert(entity);
|
||||
}
|
||||
|
||||
void EntitySimulation::addEntityInternal(EntityItemPointer entity) {
|
||||
|
@ -166,7 +165,7 @@ void EntitySimulation::addEntity(EntityItemPointer entity) {
|
|||
addEntityInternal(entity);
|
||||
|
||||
_allEntities.insert(entity);
|
||||
entity->_simulated = true;
|
||||
entity->setSimulated(true);
|
||||
|
||||
// DirtyFlags are used to signal changes to entities that have already been added,
|
||||
// so we can clear them for this entity which has just been added.
|
||||
|
@ -176,7 +175,7 @@ void EntitySimulation::addEntity(EntityItemPointer entity) {
|
|||
void EntitySimulation::changeEntity(EntityItemPointer entity) {
|
||||
QMutexLocker lock(&_mutex);
|
||||
assert(entity);
|
||||
if (!entity->_simulated) {
|
||||
if (!entity->isSimulated()) {
|
||||
// This entity was either never added to the simulation or has been removed
|
||||
// (probably for pending delete), so we don't want to keep a pointer to it
|
||||
// on any internal lists.
|
||||
|
@ -232,7 +231,7 @@ void EntitySimulation::clearEntities() {
|
|||
clearEntitiesInternal();
|
||||
|
||||
for (auto entityItr : _allEntities) {
|
||||
entityItr->_simulated = false;
|
||||
entityItr->setSimulated(false);
|
||||
}
|
||||
_allEntities.clear();
|
||||
}
|
||||
|
|
|
@ -101,6 +101,9 @@ protected:
|
|||
QList<EntityActionPointer> _actionsToAdd;
|
||||
QSet<QUuid> _actionsToRemove;
|
||||
|
||||
protected:
|
||||
SetOfEntities _entitiesToDelete; // entities simulation decided needed to be deleted (EntityTree will actually delete)
|
||||
|
||||
private:
|
||||
void moveSimpleKinematics();
|
||||
|
||||
|
@ -115,7 +118,6 @@ private:
|
|||
|
||||
|
||||
SetOfEntities _entitiesToUpdate; // entities that need to call EntityItem::update()
|
||||
SetOfEntities _entitiesToDelete; // entities simulation decided needed to be deleted (EntityTree will actually delete)
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ void PhysicalEntitySimulation::addEntityInternal(EntityItemPointer entity) {
|
|||
if (entity->shouldBePhysical()) {
|
||||
EntityMotionState* motionState = static_cast<EntityMotionState*>(entity->getPhysicsInfo());
|
||||
if (!motionState) {
|
||||
_pendingAdds.insert(entity);
|
||||
_entitiesToAddToPhysics.insert(entity);
|
||||
}
|
||||
} else if (entity->isMoving()) {
|
||||
_simpleKinematicEntities.insert(entity);
|
||||
|
@ -56,14 +56,17 @@ void PhysicalEntitySimulation::addEntityInternal(EntityItemPointer entity) {
|
|||
|
||||
void PhysicalEntitySimulation::removeEntityInternal(EntityItemPointer entity) {
|
||||
EntitySimulation::removeEntityInternal(entity);
|
||||
_entitiesToAddToPhysics.remove(entity);
|
||||
|
||||
EntityMotionState* motionState = static_cast<EntityMotionState*>(entity->getPhysicsInfo());
|
||||
if (motionState) {
|
||||
motionState->clearObjectBackPointer();
|
||||
entity->setPhysicsInfo(nullptr);
|
||||
_pendingRemoves.insert(motionState);
|
||||
_outgoingChanges.remove(motionState);
|
||||
_entitiesToRemoveFromPhysics.insert(entity);
|
||||
} else {
|
||||
_entitiesToDelete.insert(entity);
|
||||
}
|
||||
_pendingAdds.remove(entity);
|
||||
}
|
||||
|
||||
void PhysicalEntitySimulation::changeEntityInternal(EntityItemPointer entity) {
|
||||
|
@ -75,8 +78,8 @@ void PhysicalEntitySimulation::changeEntityInternal(EntityItemPointer entity) {
|
|||
// the entity should be removed from the physical simulation
|
||||
_pendingChanges.remove(motionState);
|
||||
_physicalObjects.remove(motionState);
|
||||
_pendingRemoves.insert(motionState);
|
||||
_outgoingChanges.remove(motionState);
|
||||
_entitiesToRemoveFromPhysics.insert(entity);
|
||||
if (entity->isMoving()) {
|
||||
_simpleKinematicEntities.insert(entity);
|
||||
}
|
||||
|
@ -86,7 +89,7 @@ void PhysicalEntitySimulation::changeEntityInternal(EntityItemPointer entity) {
|
|||
} else if (entity->shouldBePhysical()) {
|
||||
// The intent is for this object to be in the PhysicsEngine, but it has no MotionState yet.
|
||||
// Perhaps it's shape has changed and it can now be added?
|
||||
_pendingAdds.insert(entity);
|
||||
_entitiesToAddToPhysics.insert(entity);
|
||||
_simpleKinematicEntities.remove(entity); // just in case it's non-physical-kinematic
|
||||
} else if (entity->isMoving()) {
|
||||
_simpleKinematicEntities.insert(entity);
|
||||
|
@ -115,43 +118,53 @@ void PhysicalEntitySimulation::clearEntitiesInternal() {
|
|||
|
||||
// finally clear all lists (which now have only dangling pointers)
|
||||
_physicalObjects.clear();
|
||||
_pendingRemoves.clear();
|
||||
_pendingAdds.clear();
|
||||
_entitiesToRemoveFromPhysics.clear();
|
||||
_entitiesToAddToPhysics.clear();
|
||||
_pendingChanges.clear();
|
||||
_outgoingChanges.clear();
|
||||
}
|
||||
// end EntitySimulation overrides
|
||||
|
||||
// virtual
|
||||
void PhysicalEntitySimulation::prepareEntityForDelete(EntityItemPointer entity) {
|
||||
assert(entity);
|
||||
assert(entity->isSimulated());
|
||||
entity->clearActions(this);
|
||||
removeEntityInternal(entity);
|
||||
|
||||
// the PhysicalEntitySimulation must pull the corresponding object out of the PhysicsEngine
|
||||
// before the Entity is ready to delete so we first put them on this list
|
||||
_entitiesToRemoveFromPhysics.insert(entity);
|
||||
}
|
||||
// end EntitySimulation overrides
|
||||
|
||||
void PhysicalEntitySimulation::getObjectsToDelete(VectorOfMotionStates& result) {
|
||||
result.clear();
|
||||
QMutexLocker lock(&_mutex);
|
||||
for (auto stateItr : _pendingRemoves) {
|
||||
EntityMotionState* motionState = &(*stateItr);
|
||||
_pendingChanges.remove(motionState);
|
||||
_physicalObjects.remove(motionState);
|
||||
|
||||
EntityItemPointer entity = motionState->getEntity();
|
||||
if (entity) {
|
||||
_pendingAdds.remove(entity);
|
||||
entity->setPhysicsInfo(nullptr);
|
||||
for (auto entity: _entitiesToRemoveFromPhysics) {
|
||||
EntityMotionState* motionState = static_cast<EntityMotionState*>(entity->getPhysicsInfo());
|
||||
if (motionState) {
|
||||
_pendingChanges.remove(motionState);
|
||||
_physicalObjects.remove(motionState);
|
||||
motionState->clearObjectBackPointer();
|
||||
result.push_back(motionState);
|
||||
}
|
||||
result.push_back(motionState);
|
||||
_entitiesToAddToPhysics.remove(entity);
|
||||
entity->setPhysicsInfo(nullptr);
|
||||
_entitiesToDelete.insert(entity);
|
||||
}
|
||||
_pendingRemoves.clear();
|
||||
_entitiesToRemoveFromPhysics.clear();
|
||||
}
|
||||
|
||||
void PhysicalEntitySimulation::getObjectsToAdd(VectorOfMotionStates& result) {
|
||||
result.clear();
|
||||
QMutexLocker lock(&_mutex);
|
||||
SetOfEntities::iterator entityItr = _pendingAdds.begin();
|
||||
while (entityItr != _pendingAdds.end()) {
|
||||
SetOfEntities::iterator entityItr = _entitiesToAddToPhysics.begin();
|
||||
while (entityItr != _entitiesToAddToPhysics.end()) {
|
||||
EntityItemPointer entity = *entityItr;
|
||||
assert(!entity->getPhysicsInfo());
|
||||
if (!entity->shouldBePhysical()) {
|
||||
// this entity should no longer be on the internal _pendingAdds
|
||||
entityItr = _pendingAdds.erase(entityItr);
|
||||
// this entity should no longer be on the internal _entitiesToAddToPhysics
|
||||
entityItr = _entitiesToAddToPhysics.erase(entityItr);
|
||||
if (entity->isMoving()) {
|
||||
_simpleKinematicEntities.insert(entity);
|
||||
}
|
||||
|
@ -164,7 +177,7 @@ void PhysicalEntitySimulation::getObjectsToAdd(VectorOfMotionStates& result) {
|
|||
entity->setPhysicsInfo(static_cast<void*>(motionState));
|
||||
_physicalObjects.insert(motionState);
|
||||
result.push_back(motionState);
|
||||
entityItr = _pendingAdds.erase(entityItr);
|
||||
entityItr = _entitiesToAddToPhysics.erase(entityItr);
|
||||
} else {
|
||||
//qDebug() << "Warning! Failed to generate new shape for entity." << entity->getName();
|
||||
++entityItr;
|
||||
|
|
|
@ -44,6 +44,8 @@ protected: // only called by EntitySimulation
|
|||
virtual void clearEntitiesInternal() override;
|
||||
|
||||
public:
|
||||
virtual void prepareEntityForDelete(EntityItemPointer entity) override;
|
||||
|
||||
void getObjectsToDelete(VectorOfMotionStates& result);
|
||||
void getObjectsToAdd(VectorOfMotionStates& result);
|
||||
void setObjectsToChange(const VectorOfMotionStates& objectsToChange);
|
||||
|
@ -55,12 +57,12 @@ public:
|
|||
EntityEditPacketSender* getPacketSender() { return _entityPacketSender; }
|
||||
|
||||
private:
|
||||
// incoming changes
|
||||
SetOfEntityMotionStates _pendingRemoves; // EntityMotionStates to be removed from PhysicsEngine (and deleted)
|
||||
SetOfEntities _pendingAdds; // entities to be be added to PhysicsEngine (and a their EntityMotionState created)
|
||||
// incoming changes to physics simulation
|
||||
SetOfEntities _entitiesToRemoveFromPhysics;
|
||||
SetOfEntities _entitiesToAddToPhysics; // entities to be be added to PhysicsEngine (and a their EntityMotionState created)
|
||||
SetOfEntityMotionStates _pendingChanges; // EntityMotionStates already in PhysicsEngine that need their physics changed
|
||||
|
||||
// outgoing changes
|
||||
// outgoing changes from physics simulation
|
||||
SetOfEntityMotionStates _outgoingChanges; // EntityMotionStates for which we need to send updates to entity-server
|
||||
|
||||
SetOfMotionStates _physicalObjects; // MotionStates of entities in PhysicsEngine
|
||||
|
|
Loading…
Reference in a new issue