mirror of
https://github.com/overte-org/overte.git
synced 2025-04-17 00:33:12 +02:00
more hacking on virtualizing entities
This commit is contained in:
parent
c449ba27a9
commit
29e02f2681
8 changed files with 112 additions and 31 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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...
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue