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;
}
bool EntityTypes::registerEntityTypeName(EntityType_t entityType, const QString& name) {
bool EntityTypes::registerEntityType(EntityType_t entityType, const QString& name) {
_typeNameHash.insert(entityType, name);
return true;
}
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")
&& EntityTypes::registerEntityTypeName(EntityTypes::Model, "Model"); // TODO: move this to model subclass
bool registered = EntityTypes::registerEntityType(EntityTypes::Base, "Base")
&& EntityTypes::registerEntityType(EntityTypes::Model, "Model"); // TODO: move this to model subclass
uint32_t EntityItem::_nextID = 0;
@ -663,7 +666,8 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
encodedType = typeCoder; // determine true length
dataAt += encodedType.size();
bytesRead += encodedType.size();
_type = typeCoder;
quint32 type = typeCoder;
_type = (EntityTypes::EntityType_t)type;
// _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* result = NULL;
#if 0
bool wantDebug = false;
if (wantDebug) {
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;
newEntityItem.debugDump();
}
#endif
// TODO: need to make this actually return something...
return result;

View file

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

View file

@ -249,8 +249,9 @@ public:
virtual OctreeElement* PossiblyCreateChildAt(OctreeElement* element, int childIndex);
private:
EntityTree* _tree;
const EntityItem* _existingEntity;
EntityItem* _existingEntity;
EntityTreeElement* _containingElement;
const EntityItemProperties& _properties;
EntityItemID _entityItemID;
bool _foundOld;
bool _foundNew;
@ -271,11 +272,14 @@ UpdateEntityOperator::UpdateEntityOperator(EntityTree* tree,
_tree(tree),
_existingEntity(existingEntity),
_containingElement(containingElement),
_properties(properties),
_entityItemID(existingEntity->getEntityItemID()),
_foundOld(false),
_foundNew(false),
_removeOld(false),
_changeTime(usecTimestampNow())
_changeTime(usecTimestampNow()),
_oldEntityCube(),
_newEntityCube()
{
// caller must have verified existence of containingElement and oldEntity
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 (entityTreeElement->bestFitBounds(_newEntityCube)) {
if (entityTreeElement->addOrUpdateEntity(_existingEntity, properties)) {
if (entityTreeElement->addOrUpdateEntity(_existingEntity, _properties)) {
//qDebug() << "UpdateEntityOperator::PreRecursion()... model was updated!";
_foundNew = true;
@ -363,8 +366,6 @@ bool UpdateEntityOperator::PreRecursion(OctreeElement* element) {
// means we're still searching for our old model and this branch
// contains our old model. In which case we want to keep searching.
}
}
} else {
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.
// Check to see if
if (!_foundNew) {
int indexOfChildContainingNewEntity = element->getMyChildContaining(_newEntity.getAACube());
int indexOfChildContainingNewEntity = element->getMyChildContaining(_newEntityCube);
if (childIndex == indexOfChildContainingNewEntity) {
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
// can be determined to just be the path to the entity
void EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProperties& properties) {
#if 0
EntityItem* updateItem = NULL;
bool entityMightMove = properties.containsBoundsProperties();
@ -455,11 +458,14 @@ void EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProp
}
storeEntity(updateItem);
#endif
}
void EntityTree::addEntity(const EntityItemID& entityID, const EntityItemProperties& properties) {
#if 0
EntityItem updateItem(entityID, properties);
storeEntity(updateItem);
#endif
}
class EntityToDeleteDetails {
@ -825,7 +831,7 @@ void EntityTree::findEntities(const AACube& cube, QVector<EntityItem*> foundEnti
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);
bool wantDebug = false;
@ -839,8 +845,8 @@ const EntityItem* EntityTree::findEntityByID(uint32_t id, bool alreadyLocked) co
return findEntityByEntityItemID(entityID);
}
const EntityItem* EntityTree::findEntityByEntityItemID(const EntityItemID& entityID) const {
const EntityItem* foundEntity = NULL;
EntityItem* EntityTree::findEntityByEntityItemID(const EntityItemID& entityID) const {
EntityItem* foundEntity = NULL;
EntityTreeElement* containingElement = getContainingElement(entityID);
if (containingElement) {
foundEntity = containingElement->getEntityWithEntityItemID(entityID);
@ -856,14 +862,19 @@ int EntityTree::processEditPacketData(PacketType packetType, const unsigned char
// we handle these types of "edit" packets
switch (packetType) {
case PacketTypeEntityAddOrEdit: {
bool isValid;
EntityItem newEntity = EntityItem::fromEditPacket(editData, maxLength, processedBytes, this, isValid);
// TODO: need to do this
#if 0
bool isValid = false;
EntityItem* newEntity = NULL; // EntityItem::fromEditPacket(editData, maxLength, processedBytes, this, isValid);
if (isValid) {
storeEntity(newEntity, senderNode);
if (newEntity.isNewlyCreated()) {
notifyNewlyCreatedEntity(newEntity, senderNode);
}
}
#endif
} break;
default:
@ -1146,3 +1157,12 @@ void EntityTree::debugDumpMap() {
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 deleteEntitys(QSet<EntityItemID> modelIDs);
const EntityItem* findClosestEntity(glm::vec3 position, float targetRadius);
const EntityItem* findEntityByID(uint32_t id, bool alreadyLocked = false) const;
const EntityItem* findEntityByEntityItemID(const EntityItemID& modelID) const;
EntityItem* findEntityByID(uint32_t id, bool alreadyLocked = false) const;
EntityItem* findEntityByEntityItemID(const EntityItemID& modelID) const;
/// finds all models that touch a sphere
/// \param center the center of the sphere
@ -95,6 +95,11 @@ public:
void setContainingElement(const EntityItemID& entityItemID, EntityTreeElement* element);
void debugDumpMap();
void rememberDirtyCube(const AACube& cube);
void rememberEntityToMove(const EntityItem* entity);
private:
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,
ReadBitstreamToTreeParams& args) {
@ -667,17 +676,45 @@ int EntityTreeElement::readElementDataFromBuffer(const unsigned char* data, int
if (bytesLeftToRead >= (int)(numberOfEntities * expectedBytesPerEntity)) {
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);
const EntityItem* existingEntityItem = _myTree->findEntityByEntityItemID(entityItemID);
if (existingEntityItem) {
// copy original properties...
tempEntity.copyChangedProperties(*existingEntityItem);
}
// read only the changed properties
int bytesForThisEntity = tempEntity.readEntityDataFromBuffer(dataAt, bytesLeftToRead, args);
EntityItem* entityItem = _myTree->findEntityByEntityItemID(entityItemID);
bool newEntity = false;
_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;
bytesLeftToRead -= bytesForThisEntity;
bytesRead += bytesForThisEntity;
@ -688,6 +725,10 @@ int EntityTreeElement::readElementDataFromBuffer(const unsigned char* data, int
return bytesRead;
}
void EntityTreeElement::addEntityItem(EntityItem* entity) {
_entityItems->push_back(entity);
}
// will average a "common reduced LOD view" from the the child elements...
void EntityTreeElement::calculateAverageFromChildren() {
// nothing to do here yet...

View file

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

View file

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

View file

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