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