mirror of
https://github.com/overte-org/overte.git
synced 2025-07-23 06:44:07 +02:00
trying to fix entity editing bugs, needs testing
This commit is contained in:
parent
6c066605cd
commit
0ad5f47bfd
8 changed files with 45 additions and 18 deletions
|
@ -12,6 +12,7 @@
|
||||||
#include "EntityPriorityQueue.h"
|
#include "EntityPriorityQueue.h"
|
||||||
|
|
||||||
const float PrioritizedEntity::DO_NOT_SEND = -1.0e-6f;
|
const float PrioritizedEntity::DO_NOT_SEND = -1.0e-6f;
|
||||||
|
const float PrioritizedEntity::WHEN_IN_DOUBT_PRIORITY = 1.0f;
|
||||||
|
|
||||||
void ConicalView::set(const ViewFrustum& viewFrustum) {
|
void ConicalView::set(const ViewFrustum& viewFrustum) {
|
||||||
// The ConicalView has two parts: a central sphere (same as ViewFrustum) and a circular cone that bounds the frustum part.
|
// The ConicalView has two parts: a central sphere (same as ViewFrustum) and a circular cone that bounds the frustum part.
|
||||||
|
|
|
@ -40,12 +40,14 @@ private:
|
||||||
class PrioritizedEntity {
|
class PrioritizedEntity {
|
||||||
public:
|
public:
|
||||||
static const float DO_NOT_SEND;
|
static const float DO_NOT_SEND;
|
||||||
|
static const float WHEN_IN_DOUBT_PRIORITY;
|
||||||
|
|
||||||
PrioritizedEntity(EntityItemPointer entity, float priority) : _weakEntity(entity), _rawEntityPointer(entity.get()), _priority(priority) {}
|
PrioritizedEntity(EntityItemPointer entity, float priority, bool forceSend = false) : _weakEntity(entity), _rawEntityPointer(entity.get()), _priority(priority), _forceSend(forceSend) {}
|
||||||
float updatePriority(const ConicalView& view);
|
float updatePriority(const ConicalView& view);
|
||||||
EntityItemPointer getEntity() const { return _weakEntity.lock(); }
|
EntityItemPointer getEntity() const { return _weakEntity.lock(); }
|
||||||
EntityItem* getRawEntityPointer() const { return _rawEntityPointer; }
|
EntityItem* getRawEntityPointer() const { return _rawEntityPointer; }
|
||||||
float getPriority() const { return _priority; }
|
float getPriority() const { return _priority; }
|
||||||
|
bool shouldForceSend() const { return _forceSend; }
|
||||||
|
|
||||||
class Compare {
|
class Compare {
|
||||||
public:
|
public:
|
||||||
|
@ -57,6 +59,7 @@ private:
|
||||||
EntityItemWeakPointer _weakEntity;
|
EntityItemWeakPointer _weakEntity;
|
||||||
EntityItem* _rawEntityPointer;
|
EntityItem* _rawEntityPointer;
|
||||||
float _priority;
|
float _priority;
|
||||||
|
bool _forceSend;
|
||||||
};
|
};
|
||||||
|
|
||||||
using EntityPriorityQueue = std::priority_queue< PrioritizedEntity, std::vector<PrioritizedEntity>, PrioritizedEntity::Compare >;
|
using EntityPriorityQueue = std::priority_queue< PrioritizedEntity, std::vector<PrioritizedEntity>, PrioritizedEntity::Compare >;
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
EntityTreeSendThread::EntityTreeSendThread(OctreeServer* myServer, const SharedNodePointer& node) :
|
EntityTreeSendThread::EntityTreeSendThread(OctreeServer* myServer, const SharedNodePointer& node) :
|
||||||
OctreeSendThread(myServer, node)
|
OctreeSendThread(myServer, node)
|
||||||
{
|
{
|
||||||
|
connect(std::static_pointer_cast<EntityTree>(myServer->getOctree()).get(), &EntityTree::editingEntityPointer, this, &EntityTreeSendThread::editingEntityPointer, Qt::QueuedConnection);
|
||||||
connect(std::static_pointer_cast<EntityTree>(myServer->getOctree()).get(), &EntityTree::deletingEntityPointer, this, &EntityTreeSendThread::deletingEntityPointer, Qt::QueuedConnection);
|
connect(std::static_pointer_cast<EntityTree>(myServer->getOctree()).get(), &EntityTree::deletingEntityPointer, this, &EntityTreeSendThread::deletingEntityPointer, Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,29 +109,29 @@ void EntityTreeSendThread::traverseTreeAndSendContents(SharedNodePointer node, O
|
||||||
// Re-add elements from previous traversal if they still need to be sent
|
// Re-add elements from previous traversal if they still need to be sent
|
||||||
while (!prevSendQueue.empty()) {
|
while (!prevSendQueue.empty()) {
|
||||||
EntityItemPointer entity = prevSendQueue.top().getEntity();
|
EntityItemPointer entity = prevSendQueue.top().getEntity();
|
||||||
|
bool forceSend = prevSendQueue.top().shouldForceSend();
|
||||||
prevSendQueue.pop();
|
prevSendQueue.pop();
|
||||||
if (entity) {
|
if (entity) {
|
||||||
bool success = false;
|
bool success = false;
|
||||||
AACube cube = entity->getQueryAACube(success);
|
AACube cube = entity->getQueryAACube(success);
|
||||||
if (success) {
|
if (success) {
|
||||||
if (_traversal.getCurrentView().cubeIntersectsKeyhole(cube)) {
|
if (forceSend || _traversal.getCurrentView().cubeIntersectsKeyhole(cube)) {
|
||||||
float priority = _conicalView.computePriority(cube);
|
float priority = _conicalView.computePriority(cube);
|
||||||
if (priority != PrioritizedEntity::DO_NOT_SEND) {
|
if (forceSend || priority != PrioritizedEntity::DO_NOT_SEND) {
|
||||||
float renderAccuracy = calculateRenderAccuracy(_traversal.getCurrentView().getPosition(),
|
float renderAccuracy = calculateRenderAccuracy(_traversal.getCurrentView().getPosition(),
|
||||||
cube,
|
cube,
|
||||||
_traversal.getCurrentRootSizeScale(),
|
_traversal.getCurrentRootSizeScale(),
|
||||||
lodLevelOffset);
|
lodLevelOffset);
|
||||||
|
|
||||||
// Only send entities if they are large enough to see
|
// Only send entities if they are large enough to see, or we need to update them to be out of view
|
||||||
if (renderAccuracy > 0.0f) {
|
if (forceSend || renderAccuracy > 0.0f) {
|
||||||
_sendQueue.push(PrioritizedEntity(entity, priority));
|
_sendQueue.push(PrioritizedEntity(entity, priority));
|
||||||
_entitiesInQueue.insert(entity.get());
|
_entitiesInQueue.insert(entity.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const float WHEN_IN_DOUBT_PRIORITY = 1.0f;
|
_sendQueue.push(PrioritizedEntity(entity, PrioritizedEntity::WHEN_IN_DOUBT_PRIORITY));
|
||||||
_sendQueue.push(PrioritizedEntity(entity, WHEN_IN_DOUBT_PRIORITY));
|
|
||||||
_entitiesInQueue.insert(entity.get());
|
_entitiesInQueue.insert(entity.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -274,8 +275,7 @@ void EntityTreeSendThread::startNewTraversal(const ViewFrustum& view, EntityTree
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const float WHEN_IN_DOUBT_PRIORITY = 1.0f;
|
_sendQueue.push(PrioritizedEntity(entity, PrioritizedEntity::WHEN_IN_DOUBT_PRIORITY));
|
||||||
_sendQueue.push(PrioritizedEntity(entity, WHEN_IN_DOUBT_PRIORITY));
|
|
||||||
_entitiesInQueue.insert(entity.get());
|
_entitiesInQueue.insert(entity.get());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -310,8 +310,7 @@ void EntityTreeSendThread::startNewTraversal(const ViewFrustum& view, EntityTree
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const float WHEN_IN_DOUBT_PRIORITY = 1.0f;
|
_sendQueue.push(PrioritizedEntity(entity, PrioritizedEntity::WHEN_IN_DOUBT_PRIORITY));
|
||||||
_sendQueue.push(PrioritizedEntity(entity, WHEN_IN_DOUBT_PRIORITY));
|
|
||||||
_entitiesInQueue.insert(entity.get());
|
_entitiesInQueue.insert(entity.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -364,8 +363,7 @@ void EntityTreeSendThread::startNewTraversal(const ViewFrustum& view, EntityTree
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const float WHEN_IN_DOUBT_PRIORITY = 1.0f;
|
_sendQueue.push(PrioritizedEntity(entity, PrioritizedEntity::WHEN_IN_DOUBT_PRIORITY));
|
||||||
_sendQueue.push(PrioritizedEntity(entity, WHEN_IN_DOUBT_PRIORITY));
|
|
||||||
_entitiesInQueue.insert(entity.get());
|
_entitiesInQueue.insert(entity.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -454,6 +452,23 @@ bool EntityTreeSendThread::traverseTreeAndBuildNextPacketPayload(EncodeBitstream
|
||||||
#endif // SEND_SORTED_ENTITIES
|
#endif // SEND_SORTED_ENTITIES
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EntityTreeSendThread::editingEntityPointer(const EntityItemPointer entity) {
|
||||||
|
if (entity) {
|
||||||
|
if (_entitiesInQueue.find(entity.get()) == _entitiesInQueue.end() && _knownState.find(entity.get()) != _knownState.end()) {
|
||||||
|
bool success = false;
|
||||||
|
AACube cube = entity->getQueryAACube(success);
|
||||||
|
if (success) {
|
||||||
|
float priority = _conicalView.computePriority(cube);
|
||||||
|
_sendQueue.push(PrioritizedEntity(entity, priority, true));
|
||||||
|
_entitiesInQueue.insert(entity.get());
|
||||||
|
} else {
|
||||||
|
_sendQueue.push(PrioritizedEntity(entity, PrioritizedEntity::WHEN_IN_DOUBT_PRIORITY, true));
|
||||||
|
_entitiesInQueue.insert(entity.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void EntityTreeSendThread::deletingEntityPointer(EntityItem* entity) {
|
void EntityTreeSendThread::deletingEntityPointer(EntityItem* entity) {
|
||||||
_knownState.erase(entity);
|
_knownState.erase(entity);
|
||||||
}
|
}
|
|
@ -54,6 +54,7 @@ private:
|
||||||
uint16_t _numEntities { 0 };
|
uint16_t _numEntities { 0 };
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
void editingEntityPointer(const EntityItemPointer entity);
|
||||||
void deletingEntityPointer(EntityItem* entity);
|
void deletingEntityPointer(EntityItem* entity);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,8 @@
|
||||||
#include "EntitySimulation.h"
|
#include "EntitySimulation.h"
|
||||||
#include "EntityDynamicFactoryInterface.h"
|
#include "EntityDynamicFactoryInterface.h"
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(EntityItemPointer);
|
||||||
|
int entityItemPointernMetaTypeId = qRegisterMetaType<EntityItemPointer>();
|
||||||
int EntityItem::_maxActionsDataSize = 800;
|
int EntityItem::_maxActionsDataSize = 800;
|
||||||
quint64 EntityItem::_rememberDeletedActionTime = 20 * USECS_PER_SECOND;
|
quint64 EntityItem::_rememberDeletedActionTime = 20 * USECS_PER_SECOND;
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,8 @@ class MeshProxyList;
|
||||||
/// EntityItem class this is the base class for all entity types. It handles the basic properties and functionality available
|
/// EntityItem class this is the base class for all entity types. It handles the basic properties and functionality available
|
||||||
/// to all other entity types. In particular: postion, size, rotation, age, lifetime, velocity, gravity. You can not instantiate
|
/// to all other entity types. In particular: postion, size, rotation, age, lifetime, velocity, gravity. You can not instantiate
|
||||||
/// one directly, instead you must only construct one of it's derived classes with additional features.
|
/// one directly, instead you must only construct one of it's derived classes with additional features.
|
||||||
class EntityItem : public SpatiallyNestable, public ReadWriteLockable {
|
class EntityItem : public QObject, public SpatiallyNestable, public ReadWriteLockable {
|
||||||
|
Q_OBJECT
|
||||||
// These two classes manage lists of EntityItem pointers and must be able to cleanup pointers when an EntityItem is deleted.
|
// These two classes manage lists of EntityItem pointers and must be able to cleanup pointers when an EntityItem is deleted.
|
||||||
// To make the cleanup robust each EntityItem has backpointers to its manager classes (which are only ever set/cleared by
|
// To make the cleanup robust each EntityItem has backpointers to its manager classes (which are only ever set/cleared by
|
||||||
// the managers themselves, hence they are fiends) whose NULL status can be used to determine which managers still need to
|
// the managers themselves, hence they are fiends) whose NULL status can be used to determine which managers still need to
|
||||||
|
|
|
@ -307,7 +307,9 @@ bool EntityTree::updateEntity(EntityItemPointer entity, const EntityItemProperti
|
||||||
}
|
}
|
||||||
UpdateEntityOperator theOperator(getThisPointer(), containingElement, entity, queryCube);
|
UpdateEntityOperator theOperator(getThisPointer(), containingElement, entity, queryCube);
|
||||||
recurseTreeWithOperator(&theOperator);
|
recurseTreeWithOperator(&theOperator);
|
||||||
entity->setProperties(tempProperties);
|
if (entity->setProperties(tempProperties)) {
|
||||||
|
emit editingEntityPointer(entity);
|
||||||
|
}
|
||||||
_isDirty = true;
|
_isDirty = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -382,7 +384,9 @@ bool EntityTree::updateEntity(EntityItemPointer entity, const EntityItemProperti
|
||||||
}
|
}
|
||||||
UpdateEntityOperator theOperator(getThisPointer(), containingElement, entity, newQueryAACube);
|
UpdateEntityOperator theOperator(getThisPointer(), containingElement, entity, newQueryAACube);
|
||||||
recurseTreeWithOperator(&theOperator);
|
recurseTreeWithOperator(&theOperator);
|
||||||
entity->setProperties(properties);
|
if (entity->setProperties(properties)) {
|
||||||
|
emit editingEntityPointer(entity);
|
||||||
|
}
|
||||||
|
|
||||||
// if the entity has children, run UpdateEntityOperator on them. If the children have children, recurse
|
// if the entity has children, run UpdateEntityOperator on them. If the children have children, recurse
|
||||||
QQueue<SpatiallyNestablePointer> toProcess;
|
QQueue<SpatiallyNestablePointer> toProcess;
|
||||||
|
@ -1257,7 +1261,7 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c
|
||||||
if (!isPhysics) {
|
if (!isPhysics) {
|
||||||
properties.setLastEditedBy(senderNode->getUUID());
|
properties.setLastEditedBy(senderNode->getUUID());
|
||||||
}
|
}
|
||||||
updateEntity(entityItemID, properties, senderNode);
|
updateEntity(existingEntity, properties, senderNode);
|
||||||
existingEntity->markAsChangedOnServer();
|
existingEntity->markAsChangedOnServer();
|
||||||
endUpdate = usecTimestampNow();
|
endUpdate = usecTimestampNow();
|
||||||
_totalUpdates++;
|
_totalUpdates++;
|
||||||
|
|
|
@ -271,6 +271,7 @@ signals:
|
||||||
void deletingEntity(const EntityItemID& entityID);
|
void deletingEntity(const EntityItemID& entityID);
|
||||||
void deletingEntityPointer(EntityItem* entityID);
|
void deletingEntityPointer(EntityItem* entityID);
|
||||||
void addingEntity(const EntityItemID& entityID);
|
void addingEntity(const EntityItemID& entityID);
|
||||||
|
void editingEntityPointer(const EntityItemPointer& entityID);
|
||||||
void entityScriptChanging(const EntityItemID& entityItemID, const bool reload);
|
void entityScriptChanging(const EntityItemID& entityItemID, const bool reload);
|
||||||
void entityServerScriptChanging(const EntityItemID& entityItemID, const bool reload);
|
void entityServerScriptChanging(const EntityItemID& entityItemID, const bool reload);
|
||||||
void newCollisionSoundURL(const QUrl& url, const EntityItemID& entityID);
|
void newCollisionSoundURL(const QUrl& url, const EntityItemID& entityID);
|
||||||
|
|
Loading…
Reference in a new issue