more hacking on virtualizing entities

This commit is contained in:
ZappoMan 2014-07-07 09:36:31 -07:00
parent c449ba27a9
commit 29e02f2681
8 changed files with 112 additions and 31 deletions

View file

@ -37,18 +37,21 @@ const QString& EntityTypes::getEntityTypeName(EntityType_t entityType) {
return matchedTypeName != _typeNameHash.end() ? matchedTypeName.value() : UNKNOWN_EntityType_t_NAME; return matchedTypeName != _typeNameHash.end() ? matchedTypeName.value() : UNKNOWN_EntityType_t_NAME;
} }
bool EntityTypes::registerEntityTypeName(EntityType_t entityType, const QString& name) { bool EntityTypes::registerEntityType(EntityType_t entityType, const QString& name) {
_typeNameHash.insert(entityType, name); _typeNameHash.insert(entityType, name);
return true; return true;
} }
EntityItem* EntityTypes::constructEntityItem(EntityType_t entityType, const EntityItemID& entityID, const EntityItemProperties& properties) { EntityItem* EntityTypes::constructEntityItem(EntityType_t entityType, const EntityItemID& entityID, const EntityItemProperties& properties) {
return new EntityItem(entityID, properties); // for now, needs to support registration of constructor return NULL; // new EntityItem(entityID, properties); // for now, needs to support registration of constructor
} }
EntityItem* EntityTypes::constructEntityItem(const unsigned char* data, int bytesToRead) {
return NULL; // TODO Implement this for real!
}
bool registered = EntityTypes::registerEntityTypeName(EntityTypes::Base, "Base") bool registered = EntityTypes::registerEntityType(EntityTypes::Base, "Base")
&& EntityTypes::registerEntityTypeName(EntityTypes::Model, "Model"); // TODO: move this to model subclass && EntityTypes::registerEntityType(EntityTypes::Model, "Model"); // TODO: move this to model subclass
uint32_t EntityItem::_nextID = 0; uint32_t EntityItem::_nextID = 0;
@ -663,7 +666,8 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
encodedType = typeCoder; // determine true length encodedType = typeCoder; // determine true length
dataAt += encodedType.size(); dataAt += encodedType.size();
bytesRead += encodedType.size(); bytesRead += encodedType.size();
_type = typeCoder; quint32 type = typeCoder;
_type = (EntityTypes::EntityType_t)type;
// _lastEdited // _lastEdited
memcpy(&_lastEdited, dataAt, sizeof(_lastEdited)); memcpy(&_lastEdited, dataAt, sizeof(_lastEdited));
@ -783,6 +787,8 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
EntityItem* EntityItem::fromEditPacket(const unsigned char* data, int length, int& processedBytes, EntityTree* tree, bool& valid) { EntityItem* EntityItem::fromEditPacket(const unsigned char* data, int length, int& processedBytes, EntityTree* tree, bool& valid) {
EntityItem* result = NULL; EntityItem* result = NULL;
#if 0
bool wantDebug = false; bool wantDebug = false;
if (wantDebug) { if (wantDebug) {
qDebug() << "EntityItem EntityItem::fromEditPacket() length=" << length; qDebug() << "EntityItem EntityItem::fromEditPacket() length=" << length;
@ -967,6 +973,8 @@ EntityItem* EntityItem::fromEditPacket(const unsigned char* data, int length, in
qDebug() << " EntityItem id in packet:" << editID; qDebug() << " EntityItem id in packet:" << editID;
newEntityItem.debugDump(); newEntityItem.debugDump();
} }
#endif
// TODO: need to make this actually return something... // TODO: need to make this actually return something...
return result; return result;

View file

@ -70,12 +70,18 @@ public:
typedef enum EntityType { typedef enum EntityType {
Base, Base,
Model, Model,
Particle Particle,
Box,
Sphere,
Plane,
Cylinder
} EntityType_t; } EntityType_t;
static const QString& getEntityTypeName(EntityType_t entityType); static const QString& getEntityTypeName(EntityType_t entityType);
static bool registerEntityType(EntityType_t entityType, const QString& name); static bool registerEntityType(EntityType_t entityType, const QString& name);
static EntityItem* constructEntityItem(EntityType_t entityType, const EntityItemID& entityID, const EntityItemProperties& properties); static EntityItem* constructEntityItem(EntityType_t entityType, const EntityItemID& entityID, const EntityItemProperties& properties);
static EntityItem* constructEntityItem(const unsigned char* data, int bytesToRead);
private: private:
static QHash<EntityType_t, QString> _typeNameHash; static QHash<EntityType_t, QString> _typeNameHash;
}; };

View file

@ -249,8 +249,9 @@ public:
virtual OctreeElement* PossiblyCreateChildAt(OctreeElement* element, int childIndex); virtual OctreeElement* PossiblyCreateChildAt(OctreeElement* element, int childIndex);
private: private:
EntityTree* _tree; EntityTree* _tree;
const EntityItem* _existingEntity; EntityItem* _existingEntity;
EntityTreeElement* _containingElement; EntityTreeElement* _containingElement;
const EntityItemProperties& _properties;
EntityItemID _entityItemID; EntityItemID _entityItemID;
bool _foundOld; bool _foundOld;
bool _foundNew; bool _foundNew;
@ -271,11 +272,14 @@ UpdateEntityOperator::UpdateEntityOperator(EntityTree* tree,
_tree(tree), _tree(tree),
_existingEntity(existingEntity), _existingEntity(existingEntity),
_containingElement(containingElement), _containingElement(containingElement),
_properties(properties),
_entityItemID(existingEntity->getEntityItemID()), _entityItemID(existingEntity->getEntityItemID()),
_foundOld(false), _foundOld(false),
_foundNew(false), _foundNew(false),
_removeOld(false), _removeOld(false),
_changeTime(usecTimestampNow()) _changeTime(usecTimestampNow()),
_oldEntityCube(),
_newEntityCube()
{ {
// caller must have verified existence of containingElement and oldEntity // caller must have verified existence of containingElement and oldEntity
assert(_containingElement && _existingEntity); assert(_containingElement && _existingEntity);
@ -353,8 +357,7 @@ bool UpdateEntityOperator::PreRecursion(OctreeElement* element) {
// If this element is the best fit for the new entity properties, then add/or update it // If this element is the best fit for the new entity properties, then add/or update it
if (entityTreeElement->bestFitBounds(_newEntityCube)) { if (entityTreeElement->bestFitBounds(_newEntityCube)) {
if (entityTreeElement->addOrUpdateEntity(_existingEntity, _properties)) {
if (entityTreeElement->addOrUpdateEntity(_existingEntity, properties)) {
//qDebug() << "UpdateEntityOperator::PreRecursion()... model was updated!"; //qDebug() << "UpdateEntityOperator::PreRecursion()... model was updated!";
_foundNew = true; _foundNew = true;
@ -363,8 +366,6 @@ bool UpdateEntityOperator::PreRecursion(OctreeElement* element) {
// means we're still searching for our old model and this branch // means we're still searching for our old model and this branch
// contains our old model. In which case we want to keep searching. // contains our old model. In which case we want to keep searching.
} }
}
} else { } else {
keepSearching = true; keepSearching = true;
} }
@ -393,7 +394,7 @@ OctreeElement* UpdateEntityOperator::PossiblyCreateChildAt(OctreeElement* elemen
// We only care if this happens while still searching for the new model location. // We only care if this happens while still searching for the new model location.
// Check to see if // Check to see if
if (!_foundNew) { if (!_foundNew) {
int indexOfChildContainingNewEntity = element->getMyChildContaining(_newEntity.getAACube()); int indexOfChildContainingNewEntity = element->getMyChildContaining(_newEntityCube);
if (childIndex == indexOfChildContainingNewEntity) { if (childIndex == indexOfChildContainingNewEntity) {
return element->addChildAtIndex(childIndex); return element->addChildAtIndex(childIndex);
@ -409,6 +410,8 @@ OctreeElement* UpdateEntityOperator::PossiblyCreateChildAt(OctreeElement* elemen
// move to a different EntityTreeElement, otherwise it will not move. If the entity can not move, then the dirty path // move to a different EntityTreeElement, otherwise it will not move. If the entity can not move, then the dirty path
// can be determined to just be the path to the entity // can be determined to just be the path to the entity
void EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProperties& properties) { void EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProperties& properties) {
#if 0
EntityItem* updateItem = NULL; EntityItem* updateItem = NULL;
bool entityMightMove = properties.containsBoundsProperties(); bool entityMightMove = properties.containsBoundsProperties();
@ -455,11 +458,14 @@ void EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProp
} }
storeEntity(updateItem); storeEntity(updateItem);
#endif
} }
void EntityTree::addEntity(const EntityItemID& entityID, const EntityItemProperties& properties) { void EntityTree::addEntity(const EntityItemID& entityID, const EntityItemProperties& properties) {
#if 0
EntityItem updateItem(entityID, properties); EntityItem updateItem(entityID, properties);
storeEntity(updateItem); storeEntity(updateItem);
#endif
} }
class EntityToDeleteDetails { class EntityToDeleteDetails {
@ -825,7 +831,7 @@ void EntityTree::findEntities(const AACube& cube, QVector<EntityItem*> foundEnti
foundEntitys.swap(args._foundEntitys); foundEntitys.swap(args._foundEntitys);
} }
const EntityItem* EntityTree::findEntityByID(uint32_t id, bool alreadyLocked) const { EntityItem* EntityTree::findEntityByID(uint32_t id, bool alreadyLocked) const {
EntityItemID entityID(id); EntityItemID entityID(id);
bool wantDebug = false; bool wantDebug = false;
@ -839,8 +845,8 @@ const EntityItem* EntityTree::findEntityByID(uint32_t id, bool alreadyLocked) co
return findEntityByEntityItemID(entityID); return findEntityByEntityItemID(entityID);
} }
const EntityItem* EntityTree::findEntityByEntityItemID(const EntityItemID& entityID) const { EntityItem* EntityTree::findEntityByEntityItemID(const EntityItemID& entityID) const {
const EntityItem* foundEntity = NULL; EntityItem* foundEntity = NULL;
EntityTreeElement* containingElement = getContainingElement(entityID); EntityTreeElement* containingElement = getContainingElement(entityID);
if (containingElement) { if (containingElement) {
foundEntity = containingElement->getEntityWithEntityItemID(entityID); foundEntity = containingElement->getEntityWithEntityItemID(entityID);
@ -856,14 +862,19 @@ int EntityTree::processEditPacketData(PacketType packetType, const unsigned char
// we handle these types of "edit" packets // we handle these types of "edit" packets
switch (packetType) { switch (packetType) {
case PacketTypeEntityAddOrEdit: { case PacketTypeEntityAddOrEdit: {
bool isValid; // TODO: need to do this
EntityItem newEntity = EntityItem::fromEditPacket(editData, maxLength, processedBytes, this, isValid);
#if 0
bool isValid = false;
EntityItem* newEntity = NULL; // EntityItem::fromEditPacket(editData, maxLength, processedBytes, this, isValid);
if (isValid) { if (isValid) {
storeEntity(newEntity, senderNode); storeEntity(newEntity, senderNode);
if (newEntity.isNewlyCreated()) { if (newEntity.isNewlyCreated()) {
notifyNewlyCreatedEntity(newEntity, senderNode); notifyNewlyCreatedEntity(newEntity, senderNode);
} }
} }
#endif
} break; } break;
default: default:
@ -1146,3 +1157,12 @@ void EntityTree::debugDumpMap() {
qDebug() << i.key() << ": " << i.value(); qDebug() << i.key() << ": " << i.value();
} }
} }
void EntityTree::rememberDirtyCube(const AACube& cube) {
// TODO: do something here
}
void EntityTree::rememberEntityToMove(const EntityItem* entity) {
// TODO: do something here
}

View file

@ -58,8 +58,8 @@ public:
void deleteEntity(const EntityItemID& modelID); void deleteEntity(const EntityItemID& modelID);
void deleteEntitys(QSet<EntityItemID> modelIDs); void deleteEntitys(QSet<EntityItemID> modelIDs);
const EntityItem* findClosestEntity(glm::vec3 position, float targetRadius); const EntityItem* findClosestEntity(glm::vec3 position, float targetRadius);
const EntityItem* findEntityByID(uint32_t id, bool alreadyLocked = false) const; EntityItem* findEntityByID(uint32_t id, bool alreadyLocked = false) const;
const EntityItem* findEntityByEntityItemID(const EntityItemID& modelID) const; EntityItem* findEntityByEntityItemID(const EntityItemID& modelID) const;
/// finds all models that touch a sphere /// finds all models that touch a sphere
/// \param center the center of the sphere /// \param center the center of the sphere
@ -95,6 +95,11 @@ public:
void setContainingElement(const EntityItemID& entityItemID, EntityTreeElement* element); void setContainingElement(const EntityItemID& entityItemID, EntityTreeElement* element);
void debugDumpMap(); void debugDumpMap();
void rememberDirtyCube(const AACube& cube);
void rememberEntityToMove(const EntityItem* entity);
private: private:
static bool updateOperation(OctreeElement* element, void* extraData); static bool updateOperation(OctreeElement* element, void* extraData);

View file

@ -641,6 +641,15 @@ bool EntityTreeElement::removeEntityItem(const EntityItem* entity) {
} }
// Things we want to accomplish as we read these entities from the data buffer.
//
// 1) correctly update the properties of the entity
// 2) add any new entities that didn't previously exist
// 3) mark our tree as dirty down to the path of the previous location of the entity
// 4) mark our tree as dirty down to the path of the new location of the entity
//
// Since we're potentially reading several entities, we'd prefer to do all the moving around
// and dirty path marking in one pass.
int EntityTreeElement::readElementDataFromBuffer(const unsigned char* data, int bytesLeftToRead, int EntityTreeElement::readElementDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
ReadBitstreamToTreeParams& args) { ReadBitstreamToTreeParams& args) {
@ -667,17 +676,45 @@ int EntityTreeElement::readElementDataFromBuffer(const unsigned char* data, int
if (bytesLeftToRead >= (int)(numberOfEntities * expectedBytesPerEntity)) { if (bytesLeftToRead >= (int)(numberOfEntities * expectedBytesPerEntity)) {
for (uint16_t i = 0; i < numberOfEntities; i++) { for (uint16_t i = 0; i < numberOfEntities; i++) {
EntityItem tempEntity; // we will read into this int bytesForThisEntity = 0;
EntityItemID entityItemID = EntityItem::readEntityItemIDFromBuffer(dataAt, bytesLeftToRead, args); EntityItemID entityItemID = EntityItem::readEntityItemIDFromBuffer(dataAt, bytesLeftToRead, args);
const EntityItem* existingEntityItem = _myTree->findEntityByEntityItemID(entityItemID); EntityItem* entityItem = _myTree->findEntityByEntityItemID(entityItemID);
if (existingEntityItem) { bool newEntity = false;
// copy original properties...
tempEntity.copyChangedProperties(*existingEntityItem);
}
// read only the changed properties
int bytesForThisEntity = tempEntity.readEntityDataFromBuffer(dataAt, bytesLeftToRead, args);
_myTree->storeEntity(tempEntity); // If the item already exists in our tree, we want do the following...
// 1) remember the old cube for the entity so we can mark it as dirty
// 2) allow the existing item to read from the databuffer
// 3) check to see if after reading the item, the
if (entityItem) {
AACube existingEntityCube = entityItem->getAACube();
_myTree->rememberDirtyCube(existingEntityCube);
bytesForThisEntity = entityItem->readEntityDataFromBuffer(dataAt, bytesLeftToRead, args);
} else {
entityItem = EntityTypes::constructEntityItem(dataAt, bytesLeftToRead);
if (entityItem) {
bytesForThisEntity = entityItem->readEntityDataFromBuffer(dataAt, bytesLeftToRead, args);
addEntityItem(entityItem); // add this new entity to this elements entities
newEntity = true;
}
}
if (entityItem) {
if (newEntity) {
AACube newEntityCube = entityItem->getAACube();
_myTree->rememberDirtyCube(newEntityCube);
}
if (!bestFitEntityBounds(entityItem)) {
_myTree->rememberEntityToMove(entityItem);
if (!newEntity) {
AACube newEntityCube = entityItem->getAACube();
_myTree->rememberDirtyCube(newEntityCube);
}
}
}
// Move the buffer forward to read more entities
dataAt += bytesForThisEntity; dataAt += bytesForThisEntity;
bytesLeftToRead -= bytesForThisEntity; bytesLeftToRead -= bytesForThisEntity;
bytesRead += bytesForThisEntity; bytesRead += bytesForThisEntity;
@ -688,6 +725,10 @@ int EntityTreeElement::readElementDataFromBuffer(const unsigned char* data, int
return bytesRead; return bytesRead;
} }
void EntityTreeElement::addEntityItem(EntityItem* entity) {
_entityItems->push_back(entity);
}
// will average a "common reduced LOD view" from the the child elements... // will average a "common reduced LOD view" from the the child elements...
void EntityTreeElement::calculateAverageFromChildren() { void EntityTreeElement::calculateAverageFromChildren() {
// nothing to do here yet... // nothing to do here yet...

View file

@ -122,6 +122,7 @@ public:
bool updateEntity(const EntityItem& entity); bool updateEntity(const EntityItem& entity);
bool addOrUpdateEntity(EntityItem* entity, const EntityItemProperties& properties); bool addOrUpdateEntity(EntityItem* entity, const EntityItemProperties& properties);
void addEntityItem(EntityItem* entity);
void updateEntityItemID(FindAndUpdateEntityItemIDArgs* args); void updateEntityItemID(FindAndUpdateEntityItemIDArgs* args);

View file

@ -292,7 +292,7 @@ void EntityTests::modelTreeTests(bool verbose) {
EntityTreeElement* containingElement = tree.getContainingElement(modelID); EntityTreeElement* containingElement = tree.getContainingElement(modelID);
AACube elementCube = containingElement ? containingElement->getAACube() : AACube(); AACube elementCube = containingElement ? containingElement->getAACube() : AACube();
bool elementIsBestFit = containingElement->bestFitEntityBounds(*foundEntityByID); bool elementIsBestFit = containingElement->bestFitEntityBounds(foundEntityByID);
if (extraVerbose) { if (extraVerbose) {
qDebug() << "foundEntityByRadius=" << foundEntityByRadius; qDebug() << "foundEntityByRadius=" << foundEntityByRadius;

View file

@ -1271,7 +1271,7 @@ void OctreeTests::byteCountCodingTests(bool verbose) {
void OctreeTests::modelItemTests(bool verbose) { void OctreeTests::modelItemTests(bool verbose) {
#ifdef HIDE_SUBCLASS_METHODS #if 0 // def HIDE_SUBCLASS_METHODS
//verbose = true; //verbose = true;
EntityTreeElementExtraEncodeData modelTreeElementExtraEncodeData; EntityTreeElementExtraEncodeData modelTreeElementExtraEncodeData;