Remove Changing state, now keep QSet of changes

This commit is contained in:
Andrew Meadows 2014-11-17 15:53:03 -08:00
parent 2cf93697cb
commit ac87c90d62
3 changed files with 31 additions and 55 deletions

View file

@ -42,8 +42,8 @@ void EntityTree::eraseAllOctreeElements(bool createNewRoot) {
_entityToElementMap.clear(); _entityToElementMap.clear();
Octree::eraseAllOctreeElements(createNewRoot); Octree::eraseAllOctreeElements(createNewRoot);
_movingEntities.clear(); _movingEntities.clear();
_changingEntities.clear();
_mortalEntities.clear(); _mortalEntities.clear();
_changedEntities.clear();
} }
bool EntityTree::handlesEditPacketType(PacketType packetType) const { bool EntityTree::handlesEditPacketType(PacketType packetType) const {
@ -91,7 +91,7 @@ void EntityTree::addEntityItem(EntityItem* entity) {
recurseTreeWithOperator(&theOperator); recurseTreeWithOperator(&theOperator);
// check to see if we need to simulate this entity.. // check to see if we need to simulate this entity..
changeEntityState(entity, EntityItem::Static, entity->getSimulationState()); changeEntityState(entity, EntityItem::Static, entity->computeSimulationState());
if (_physicsWorld && !entity->getMotionState()) { if (_physicsWorld && !entity->getMotionState()) {
addEntityToPhysicsWorld(entity); addEntityToPhysicsWorld(entity);
@ -129,14 +129,14 @@ bool EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProp
} }
} else { } else {
// check to see if we need to simulate this entity... // check to see if we need to simulate this entity...
EntityItem::SimulationState oldState = existingEntity->getSimulationState(); EntityItem::SimulationState oldState = existingEntity->computeSimulationState();
QString entityScriptBefore = existingEntity->getScript(); QString entityScriptBefore = existingEntity->getScript();
UpdateEntityOperator theOperator(this, containingElement, existingEntity, properties); UpdateEntityOperator theOperator(this, containingElement, existingEntity, properties);
recurseTreeWithOperator(&theOperator); recurseTreeWithOperator(&theOperator);
_isDirty = true; _isDirty = true;
EntityItem::SimulationState newState = existingEntity->getSimulationState(); EntityItem::SimulationState newState = existingEntity->computeSimulationState();
if (newState != oldState) { if (newState != oldState) {
changeEntityState(existingEntity, oldState, newState); changeEntityState(existingEntity, oldState, newState);
} }
@ -242,12 +242,8 @@ void EntityTree::removeEntityFromSimulationLists(const EntityItemID& entityID) {
if (theEntity) { if (theEntity) {
// make sure to remove it from any of our simulation lists // make sure to remove it from any of our simulation lists
EntityItem::SimulationState theState = theEntity->getSimulationState(); EntityItem::SimulationState theState = theEntity->computeSimulationState();
switch (theState) { switch (theState) {
case EntityItem::Changing:
_changingEntities.removeAll(theEntity);
break;
case EntityItem::Moving: case EntityItem::Moving:
_movingEntities.removeAll(theEntity); _movingEntities.removeAll(theEntity);
break; break;
@ -259,6 +255,7 @@ void EntityTree::removeEntityFromSimulationLists(const EntityItemID& entityID) {
default: default:
break; break;
} }
_changedEntities.remove(theEntity);
} }
} }
@ -600,10 +597,6 @@ void EntityTree::changeEntityState(EntityItem* const entity,
// TODO: can we short circuit this if the state isn't changing? // TODO: can we short circuit this if the state isn't changing?
switch (oldState) { switch (oldState) {
case EntityItem::Changing:
_changingEntities.removeAll(entity);
break;
case EntityItem::Moving: case EntityItem::Moving:
_movingEntities.removeAll(entity); _movingEntities.removeAll(entity);
break; break;
@ -618,10 +611,6 @@ void EntityTree::changeEntityState(EntityItem* const entity,
switch (newState) { switch (newState) {
case EntityItem::Changing:
_changingEntities.push_back(entity);
break;
case EntityItem::Moving: case EntityItem::Moving:
_movingEntities.push_back(entity); _movingEntities.push_back(entity);
break; break;
@ -635,6 +624,10 @@ void EntityTree::changeEntityState(EntityItem* const entity,
} }
} }
void EntityTree::entityChanged(EntityItem* entity) {
_changedEntities.insert(entity);
}
void EntityTree::addEntityToPhysicsWorld(EntityItem* entity) { void EntityTree::addEntityToPhysicsWorld(EntityItem* entity) {
EntityMotionState* motionState = entity->createMotionState(); EntityMotionState* motionState = entity->createMotionState();
if (!_physicsWorld->addEntity(static_cast<CustomMotionState*>(motionState))) { if (!_physicsWorld->addEntity(static_cast<CustomMotionState*>(motionState))) {
@ -665,7 +658,7 @@ void EntityTree::update() {
lockForWrite(); lockForWrite();
quint64 now = usecTimestampNow(); quint64 now = usecTimestampNow();
QSet<EntityItemID> entitiesToDelete; QSet<EntityItemID> entitiesToDelete;
updateChangingEntities(now, entitiesToDelete); updateChangedEntities(now, entitiesToDelete);
updateMovingEntities(now, entitiesToDelete); updateMovingEntities(now, entitiesToDelete);
updateMortalEntities(now, entitiesToDelete); updateMortalEntities(now, entitiesToDelete);
@ -675,27 +668,21 @@ void EntityTree::update() {
unlock(); unlock();
} }
void EntityTree::updateChangingEntities(quint64 now, QSet<EntityItemID>& entitiesToDelete) { void EntityTree::updateChangedEntities(quint64 now, QSet<EntityItemID>& entitiesToDelete) {
QSet<EntityItem*> entitiesBecomingStatic; QSet<EntityItem*> entitiesBecomingStatic;
QSet<EntityItem*> entitiesBecomingMortal; QSet<EntityItem*> entitiesBecomingMortal;
QSet<EntityItem*> entitiesBecomingMoving; QSet<EntityItem*> entitiesBecomingMoving;
// TODO: switch these to iterators so we can remove items that get deleted // TODO: switch these to iterators so we can remove items that get deleted
for (int i = 0; i < _changingEntities.size(); i++) { foreach (EntityItem* thisEntity, _changedEntities) {
EntityItem* thisEntity = _changingEntities[i]; // check to see if the lifetime has expired, for immortal entities this is always false
EntityMotionState* motionState = thisEntity->getMotionState();
if (!motionState) {
thisEntity->update(now);
}
// always check to see if the lifetime has expired, for immortal entities this is always false
if (thisEntity->lifetimeHasExpired()) { if (thisEntity->lifetimeHasExpired()) {
qDebug() << "Lifetime has expired for entity:" << thisEntity->getEntityItemID(); qDebug() << "Lifetime has expired for entity:" << thisEntity->getEntityItemID();
entitiesToDelete << thisEntity->getEntityItemID(); entitiesToDelete << thisEntity->getEntityItemID();
entitiesBecomingStatic << thisEntity; entitiesBecomingStatic << thisEntity;
} else { } else {
// check to see if this entity is no longer moving // TODO: Andrew to push changes to physics engine (when we know how to sort the changes)
EntityItem::SimulationState newState = thisEntity->getSimulationState(); EntityItem::SimulationState newState = thisEntity->computeSimulationState();
if (newState == EntityItem::Static) { if (newState == EntityItem::Static) {
entitiesBecomingStatic << thisEntity; entitiesBecomingStatic << thisEntity;
@ -706,6 +693,7 @@ void EntityTree::updateChangingEntities(quint64 now, QSet<EntityItemID>& entitie
} }
} }
} }
_changedEntities.clear();
// change state for any entities that were changing but are now either static, mortal, or moving // change state for any entities that were changing but are now either static, mortal, or moving
foreach(EntityItem* entity, entitiesBecomingStatic) { foreach(EntityItem* entity, entitiesBecomingStatic) {
@ -726,7 +714,6 @@ void EntityTree::updateMovingEntities(quint64 now, QSet<EntityItemID>& entitiesT
QSet<EntityItem*> entitiesBecomingStatic; QSet<EntityItem*> entitiesBecomingStatic;
QSet<EntityItem*> entitiesBecomingMortal; QSet<EntityItem*> entitiesBecomingMortal;
QSet<EntityItem*> entitiesBecomingChanging;
{ {
PerformanceTimer perfTimer("_movingEntities"); PerformanceTimer perfTimer("_movingEntities");
@ -761,10 +748,8 @@ void EntityTree::updateMovingEntities(quint64 now, QSet<EntityItemID>& entitiesT
moveOperator.addEntityToMoveList(thisEntity, oldCube, newCube); moveOperator.addEntityToMoveList(thisEntity, oldCube, newCube);
// check to see if this entity is no longer moving // check to see if this entity is no longer moving
EntityItem::SimulationState newState = thisEntity->getSimulationState(); EntityItem::SimulationState newState = thisEntity->computeSimulationState();
if (newState == EntityItem::Changing) { if (newState == EntityItem::Mortal) {
entitiesBecomingChanging << thisEntity;
} else if (newState == EntityItem::Mortal) {
entitiesBecomingMortal << thisEntity; entitiesBecomingMortal << thisEntity;
} else if (newState == EntityItem::Static) { } else if (newState == EntityItem::Static) {
entitiesBecomingStatic << thisEntity; entitiesBecomingStatic << thisEntity;
@ -785,15 +770,11 @@ void EntityTree::updateMovingEntities(quint64 now, QSet<EntityItemID>& entitiesT
foreach(EntityItem* entity, entitiesBecomingMortal) { foreach(EntityItem* entity, entitiesBecomingMortal) {
changeEntityState(entity, EntityItem::Moving, EntityItem::Mortal); changeEntityState(entity, EntityItem::Moving, EntityItem::Mortal);
} }
foreach(EntityItem* entity, entitiesBecomingChanging) {
changeEntityState(entity, EntityItem::Moving, EntityItem::Changing);
}
} }
} }
void EntityTree::updateMortalEntities(quint64 now, QSet<EntityItemID>& entitiesToDelete) { void EntityTree::updateMortalEntities(quint64 now, QSet<EntityItemID>& entitiesToDelete) {
QSet<EntityItem*> entitiesBecomingStatic; QSet<EntityItem*> entitiesBecomingStatic;
QSet<EntityItem*> entitiesBecomingChanging;
QSet<EntityItem*> entitiesBecomingMoving; QSet<EntityItem*> entitiesBecomingMoving;
// TODO: switch these to iterators so we can remove items that get deleted // TODO: switch these to iterators so we can remove items that get deleted
@ -807,12 +788,10 @@ void EntityTree::updateMortalEntities(quint64 now, QSet<EntityItemID>& entitiesT
entitiesBecomingStatic << thisEntity; entitiesBecomingStatic << thisEntity;
} else { } else {
// check to see if this entity is no longer moving // check to see if this entity is no longer moving
EntityItem::SimulationState newState = thisEntity->getSimulationState(); EntityItem::SimulationState newState = thisEntity->computeSimulationState();
if (newState == EntityItem::Static) { if (newState == EntityItem::Static) {
entitiesBecomingStatic << thisEntity; entitiesBecomingStatic << thisEntity;
} else if (newState == EntityItem::Changing) {
entitiesBecomingChanging << thisEntity;
} else if (newState == EntityItem::Moving) { } else if (newState == EntityItem::Moving) {
entitiesBecomingMoving << thisEntity; entitiesBecomingMoving << thisEntity;
} }
@ -823,9 +802,6 @@ void EntityTree::updateMortalEntities(quint64 now, QSet<EntityItemID>& entitiesT
foreach(EntityItem* entity, entitiesBecomingStatic) { foreach(EntityItem* entity, entitiesBecomingStatic) {
changeEntityState(entity, EntityItem::Mortal, EntityItem::Static); changeEntityState(entity, EntityItem::Mortal, EntityItem::Static);
} }
foreach(EntityItem* entity, entitiesBecomingChanging) {
changeEntityState(entity, EntityItem::Mortal, EntityItem::Changing);
}
foreach(EntityItem* entity, entitiesBecomingMoving) { foreach(EntityItem* entity, entitiesBecomingMoving) {
changeEntityState(entity, EntityItem::Mortal, EntityItem::Moving); changeEntityState(entity, EntityItem::Mortal, EntityItem::Moving);
} }

View file

@ -12,6 +12,8 @@
#ifndef hifi_EntityTree_h #ifndef hifi_EntityTree_h
#define hifi_EntityTree_h #define hifi_EntityTree_h
#include <QSet>
#include <Octree.h> #include <Octree.h>
#include "EntityTreeElement.h" #include "EntityTreeElement.h"
@ -139,6 +141,7 @@ public:
void changeEntityState(EntityItem* const entity, void changeEntityState(EntityItem* const entity,
EntityItem::SimulationState oldState, EntityItem::SimulationState newState); EntityItem::SimulationState oldState, EntityItem::SimulationState newState);
void entityChanged(EntityItem* entity);
void addEntityToPhysicsWorld(EntityItem* entity); void addEntityToPhysicsWorld(EntityItem* entity);
void removeEntityFromPhysicsWorld(EntityItem* entity); void removeEntityFromPhysicsWorld(EntityItem* entity);
@ -159,7 +162,7 @@ signals:
private: private:
void updateChangingEntities(quint64 now, QSet<EntityItemID>& entitiesToDelete); void updateChangedEntities(quint64 now, QSet<EntityItemID>& entitiesToDelete);
void updateMovingEntities(quint64 now, QSet<EntityItemID>& entitiesToDelete); void updateMovingEntities(quint64 now, QSet<EntityItemID>& entitiesToDelete);
void updateMortalEntities(quint64 now, QSet<EntityItemID>& entitiesToDelete); void updateMortalEntities(quint64 now, QSet<EntityItemID>& entitiesToDelete);
@ -179,9 +182,10 @@ private:
QHash<EntityItemID, EntityTreeElement*> _entityToElementMap; QHash<EntityItemID, EntityTreeElement*> _entityToElementMap;
QList<EntityItem*> _movingEntities; // entities that are moving as part of update QList<EntityItem*> _movingEntities; // entities that need to be updated
QList<EntityItem*> _changingEntities; // entities that are changing (like animating), but not moving QList<EntityItem*> _mortalEntities; // entities that need to be checked for expiry
QList<EntityItem*> _mortalEntities; // entities that are mortal (have lifetime), but not moving or changing
QSet<EntityItem*> _changedEntities; // entities that have changed in the last frame
PhysicsWorld* _physicsWorld; PhysicsWorld* _physicsWorld;
}; };

View file

@ -745,14 +745,10 @@ int EntityTreeElement::readElementDataFromBuffer(const unsigned char* data, int
QString entityScriptBefore = entityItem->getScript(); QString entityScriptBefore = entityItem->getScript();
bool bestFitBefore = bestFitEntityBounds(entityItem); bool bestFitBefore = bestFitEntityBounds(entityItem);
EntityTreeElement* currentContainingElement = _myTree->getContainingElement(entityItemID); EntityTreeElement* currentContainingElement = _myTree->getContainingElement(entityItemID);
EntityItem::SimulationState oldState = entityItem->getSimulationState();
bytesForThisEntity = entityItem->readEntityDataFromBuffer(dataAt, bytesLeftToRead, args); bytesForThisEntity = entityItem->readEntityDataFromBuffer(dataAt, bytesLeftToRead, args);
// TODO: Andrew to only set changed if something has actually changed
EntityItem::SimulationState newState = entityItem->getSimulationState(); _myTree->entityChanged(entityItem);
if (oldState != newState) {
_myTree->changeEntityState(entityItem, oldState, newState);
}
bool bestFitAfter = bestFitEntityBounds(entityItem); bool bestFitAfter = bestFitEntityBounds(entityItem);
if (bestFitBefore != bestFitAfter) { if (bestFitBefore != bestFitAfter) {
@ -780,7 +776,7 @@ int EntityTreeElement::readElementDataFromBuffer(const unsigned char* data, int
entityItemID = entityItem->getEntityItemID(); entityItemID = entityItem->getEntityItemID();
_myTree->setContainingElement(entityItemID, this); _myTree->setContainingElement(entityItemID, this);
_myTree->emitAddingEntity(entityItemID); // we just added an entity _myTree->emitAddingEntity(entityItemID); // we just added an entity
EntityItem::SimulationState newState = entityItem->getSimulationState(); EntityItem::SimulationState newState = entityItem->computeSimulationState();
_myTree->changeEntityState(entityItem, EntityItem::Static, newState); _myTree->changeEntityState(entityItem, EntityItem::Static, newState);
} }
} }