mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 16:38:27 +02:00
be picky when finding nearby entities at login
This commit is contained in:
parent
0f4e7fb532
commit
0bcecdbe66
5 changed files with 58 additions and 16 deletions
|
@ -5639,14 +5639,38 @@ bool Application::nearbyEntitiesAreReadyForPhysics() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AABox avatarBox(getMyAvatar()->getPosition() - glm::vec3(0.5f * PHYSICS_READY_RANGE), glm::vec3(PHYSICS_READY_RANGE));
|
// We don't want to use EntityTree::findEntities(AABox, ...) method because that scan will snarf parented entities
|
||||||
|
// whose bounding boxes cannot be computed (it is too loose for our purposes here). Instead we manufacture
|
||||||
|
// custom filters and use the general-purpose EntityTree::findEntities(filter, ...)
|
||||||
QVector<EntityItemPointer> entities;
|
QVector<EntityItemPointer> entities;
|
||||||
entityTree->withReadLock([&] {
|
entityTree->withReadLock([&] {
|
||||||
entityTree->findEntities(avatarBox, entities);
|
AABox avatarBox(getMyAvatar()->getPosition() - glm::vec3(PHYSICS_READY_RANGE), glm::vec3(2 * PHYSICS_READY_RANGE));
|
||||||
|
|
||||||
|
// create two functions that use avatarBox (entityScan and elementScan), the second calls the first
|
||||||
|
std::function<bool (EntityItemPointer&)> entityScan = [=](EntityItemPointer& entity) {
|
||||||
|
if (entity->shouldBePhysical()) {
|
||||||
|
bool success = false;
|
||||||
|
AABox entityBox = entity->getAABox(success);
|
||||||
|
// important: bail for entities that cannot supply a valid AABox
|
||||||
|
return success && avatarBox.touches(entityBox);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
std::function<bool(const OctreeElementPointer&, void*)> elementScan = [&](const OctreeElementPointer& element, void* unused) {
|
||||||
|
if (element->getAACube().touches(avatarBox)) {
|
||||||
|
EntityTreeElementPointer entityTreeElement = std::static_pointer_cast<EntityTreeElement>(element);
|
||||||
|
entityTreeElement->getEntities(entityScan, entities);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Pass the second function to the general-purpose EntityTree::findEntities()
|
||||||
|
// which will traverse the tree, apply the two filter functions (to element, then to entities)
|
||||||
|
// as it traverses. The end result will be a list of entities that match.
|
||||||
|
entityTree->findEntities(elementScan, entities);
|
||||||
});
|
});
|
||||||
|
|
||||||
// For reasons I haven't found, we don't necessarily have the full scene when we receive a stats packet. Apply
|
|
||||||
// a heuristic to try to decide when we actually know about all of the nearby entities.
|
|
||||||
uint32_t nearbyCount = entities.size();
|
uint32_t nearbyCount = entities.size();
|
||||||
if (nearbyCount == _nearbyEntitiesCountAtLastPhysicsCheck) {
|
if (nearbyCount == _nearbyEntitiesCountAtLastPhysicsCheck) {
|
||||||
_nearbyEntitiesStabilityCount++;
|
_nearbyEntitiesStabilityCount++;
|
||||||
|
@ -5662,18 +5686,11 @@ bool Application::nearbyEntitiesAreReadyForPhysics() {
|
||||||
bool result = true;
|
bool result = true;
|
||||||
foreach (EntityItemPointer entity, entities) {
|
foreach (EntityItemPointer entity, entities) {
|
||||||
if (entity->shouldBePhysical() && !entity->isReadyToComputeShape()) {
|
if (entity->shouldBePhysical() && !entity->isReadyToComputeShape()) {
|
||||||
// BUG: the findEntities() query above is sometimes returning objects that don't actually overlap
|
static QString repeatedMessage =
|
||||||
// TODO: investigate and fix findQueries() but in the meantime...
|
LogHandler::getInstance().addRepeatedMessageRegex("Physics disabled until entity loads: .*");
|
||||||
// WORKAROUND: test the overlap of each entity to verify it matters
|
qCDebug(interfaceapp) << "Physics disabled until entity loads: " << entity->getID() << entity->getName();
|
||||||
bool success = false;
|
// don't break here because we want all the relevant entities to start their downloads
|
||||||
AACube entityCube = entity->getQueryAACube(success);
|
result = false;
|
||||||
if (success && avatarBox.touches(entityCube)) {
|
|
||||||
static QString repeatedMessage =
|
|
||||||
LogHandler::getInstance().addRepeatedMessageRegex("Physics disabled until entity loads: .*");
|
|
||||||
qCDebug(interfaceapp) << "Physics disabled until entity loads: " << entity->getID() << entity->getName();
|
|
||||||
// don't break here because we want all the relevant entities to start their downloads
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -864,6 +864,12 @@ void EntityTree::findEntities(const ViewFrustum& frustum, QVector<EntityItemPoin
|
||||||
foundEntities.swap(args.entities);
|
foundEntities.swap(args.entities);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: assumes caller has handled locking
|
||||||
|
void EntityTree::findEntities(RecurseOctreeOperation& elementFilter,
|
||||||
|
QVector<EntityItemPointer>& foundEntities) {
|
||||||
|
recurseTreeWithOperation(elementFilter, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
EntityItemPointer EntityTree::findEntityByID(const QUuid& id) {
|
EntityItemPointer EntityTree::findEntityByID(const QUuid& id) {
|
||||||
EntityItemID entityID(id);
|
EntityItemID entityID(id);
|
||||||
return findEntityByEntityItemID(entityID);
|
return findEntityByEntityItemID(entityID);
|
||||||
|
|
|
@ -165,6 +165,11 @@ public:
|
||||||
/// \param foundEntities[out] vector of EntityItemPointer
|
/// \param foundEntities[out] vector of EntityItemPointer
|
||||||
void findEntities(const ViewFrustum& frustum, QVector<EntityItemPointer>& foundEntities);
|
void findEntities(const ViewFrustum& frustum, QVector<EntityItemPointer>& foundEntities);
|
||||||
|
|
||||||
|
/// finds all entities that match scanOperator
|
||||||
|
/// \parameter scanOperator function that scans entities that match criteria
|
||||||
|
/// \parameter foundEntities[out] vector of EntityItemPointer
|
||||||
|
void findEntities(RecurseOctreeOperation& scanOperator, QVector<EntityItemPointer>& foundEntities);
|
||||||
|
|
||||||
void addNewlyCreatedHook(NewlyCreatedEntityHook* hook);
|
void addNewlyCreatedHook(NewlyCreatedEntityHook* hook);
|
||||||
void removeNewlyCreatedHook(NewlyCreatedEntityHook* hook);
|
void removeNewlyCreatedHook(NewlyCreatedEntityHook* hook);
|
||||||
|
|
||||||
|
|
|
@ -869,6 +869,14 @@ void EntityTreeElement::getEntities(const ViewFrustum& frustum, QVector<EntityIt
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EntityTreeElement::getEntities(EntityItemFilter& filter, QVector<EntityItemPointer>& foundEntities) {
|
||||||
|
forEachEntity([&](EntityItemPointer entity) {
|
||||||
|
if (filter(entity)) {
|
||||||
|
foundEntities.push_back(entity);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
EntityItemPointer EntityTreeElement::getEntityWithEntityItemID(const EntityItemID& id) const {
|
EntityItemPointer EntityTreeElement::getEntityWithEntityItemID(const EntityItemID& id) const {
|
||||||
EntityItemPointer foundEntity = NULL;
|
EntityItemPointer foundEntity = NULL;
|
||||||
withReadLock([&] {
|
withReadLock([&] {
|
||||||
|
|
|
@ -27,6 +27,7 @@ class EntityTreeElement;
|
||||||
using EntityItems = QVector<EntityItemPointer>;
|
using EntityItems = QVector<EntityItemPointer>;
|
||||||
using EntityTreeElementWeakPointer = std::weak_ptr<EntityTreeElement>;
|
using EntityTreeElementWeakPointer = std::weak_ptr<EntityTreeElement>;
|
||||||
using EntityTreeElementPointer = std::shared_ptr<EntityTreeElement>;
|
using EntityTreeElementPointer = std::shared_ptr<EntityTreeElement>;
|
||||||
|
using EntityItemFilter = std::function<bool(EntityItemPointer&)>;
|
||||||
|
|
||||||
class EntityTreeUpdateArgs {
|
class EntityTreeUpdateArgs {
|
||||||
public:
|
public:
|
||||||
|
@ -199,6 +200,11 @@ public:
|
||||||
/// \param entities[out] vector of non-const EntityItemPointer
|
/// \param entities[out] vector of non-const EntityItemPointer
|
||||||
void getEntities(const ViewFrustum& frustum, QVector<EntityItemPointer>& foundEntities);
|
void getEntities(const ViewFrustum& frustum, QVector<EntityItemPointer>& foundEntities);
|
||||||
|
|
||||||
|
/// finds all entities that match filter
|
||||||
|
/// \param filter function that adds matching entities to foundEntities
|
||||||
|
/// \param entities[out] vector of non-const EntityItemPointer
|
||||||
|
void getEntities(EntityItemFilter& filter, QVector<EntityItemPointer>& foundEntities);
|
||||||
|
|
||||||
EntityItemPointer getEntityWithID(uint32_t id) const;
|
EntityItemPointer getEntityWithID(uint32_t id) const;
|
||||||
EntityItemPointer getEntityWithEntityItemID(const EntityItemID& id) const;
|
EntityItemPointer getEntityWithEntityItemID(const EntityItemID& id) const;
|
||||||
void getEntitiesInside(const AACube& box, QVector<EntityItemPointer>& foundEntities);
|
void getEntitiesInside(const AACube& box, QVector<EntityItemPointer>& foundEntities);
|
||||||
|
|
Loading…
Reference in a new issue