mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-07-23 14:54:29 +02:00
name changes and improved flow for SafeLanding logic
This commit is contained in:
parent
00185ee82e
commit
dfb7ac7044
5 changed files with 81 additions and 88 deletions
|
@ -6198,13 +6198,13 @@ void Application::update(float deltaTime) {
|
||||||
|
|
||||||
// we haven't yet enabled physics. we wait until we think we have all the collision information
|
// we haven't yet enabled physics. we wait until we think we have all the collision information
|
||||||
// for nearby entities before starting bullet up.
|
// for nearby entities before starting bullet up.
|
||||||
quint64 now = usecTimestampNow();
|
|
||||||
if (isServerlessMode()) {
|
if (isServerlessMode()) {
|
||||||
tryToEnablePhysics();
|
tryToEnablePhysics();
|
||||||
} else if (_failedToConnectToEntityServer) {
|
} else if (_failedToConnectToEntityServer) {
|
||||||
_octreeProcessor.stopSafeLanding();
|
_octreeProcessor.stopSafeLanding();
|
||||||
} else {
|
} else {
|
||||||
if (_octreeProcessor.isLoadSequenceComplete()) {
|
_octreeProcessor.updateSafeLanding();
|
||||||
|
if (_octreeProcessor.safeLandingIsComplete()) {
|
||||||
tryToEnablePhysics();
|
tryToEnablePhysics();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,7 +115,7 @@ void OctreePacketProcessor::processPacket(QSharedPointer<ReceivedMessage> messag
|
||||||
auto renderer = qApp->getEntities();
|
auto renderer = qApp->getEntities();
|
||||||
if (renderer) {
|
if (renderer) {
|
||||||
renderer->processDatagram(*message, sendingNode);
|
renderer->processDatagram(*message, sendingNode);
|
||||||
_safeLanding->updateSequence(renderer->getLastOctreeMessageSequence());
|
_safeLanding->addToSequence(renderer->getLastOctreeMessageSequence());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
@ -137,6 +137,14 @@ void OctreePacketProcessor::startSafeLanding() {
|
||||||
_safeLanding->startTracking(qApp->getEntities());
|
_safeLanding->startTracking(qApp->getEntities());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OctreePacketProcessor::updateSafeLanding() {
|
||||||
|
_safeLanding->updateTracking();
|
||||||
|
}
|
||||||
|
|
||||||
void OctreePacketProcessor::stopSafeLanding() {
|
void OctreePacketProcessor::stopSafeLanding() {
|
||||||
_safeLanding->stopTracking();
|
_safeLanding->stopTracking();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OctreePacketProcessor::safeLandingIsComplete() const {
|
||||||
|
return _safeLanding->trackingIsComplete();
|
||||||
|
}
|
||||||
|
|
|
@ -26,8 +26,10 @@ public:
|
||||||
~OctreePacketProcessor();
|
~OctreePacketProcessor();
|
||||||
|
|
||||||
void startSafeLanding();
|
void startSafeLanding();
|
||||||
|
void updateSafeLanding();
|
||||||
void stopSafeLanding();
|
void stopSafeLanding();
|
||||||
bool isLoadSequenceComplete() const { return _safeLanding->isLoadSequenceComplete(); }
|
bool safeLandingIsComplete() const;
|
||||||
|
|
||||||
float domainLoadingProgress() const { return _safeLanding->loadingProgressPercentage(); }
|
float domainLoadingProgress() const { return _safeLanding->loadingProgressPercentage(); }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
|
@ -40,18 +40,18 @@ void SafeLanding::startTracking(QSharedPointer<EntityTreeRenderer> entityTreeRen
|
||||||
Locker lock(_lock);
|
Locker lock(_lock);
|
||||||
_entityTreeRenderer = entityTreeRenderer;
|
_entityTreeRenderer = entityTreeRenderer;
|
||||||
_trackedEntities.clear();
|
_trackedEntities.clear();
|
||||||
_trackingEntities = true;
|
|
||||||
_maxTrackedEntityCount = 0;
|
_maxTrackedEntityCount = 0;
|
||||||
|
_initialStart = INVALID_SEQUENCE;
|
||||||
|
_initialEnd = INVALID_SEQUENCE;
|
||||||
|
_sequenceNumbers.clear();
|
||||||
|
_trackingEntities = true;
|
||||||
|
_startTime = usecTimestampNow();
|
||||||
|
|
||||||
connect(std::const_pointer_cast<EntityTree>(entityTree).get(),
|
connect(std::const_pointer_cast<EntityTree>(entityTree).get(),
|
||||||
&EntityTree::addingEntity, this, &SafeLanding::addTrackedEntity, Qt::DirectConnection);
|
&EntityTree::addingEntity, this, &SafeLanding::addTrackedEntity, Qt::DirectConnection);
|
||||||
connect(std::const_pointer_cast<EntityTree>(entityTree).get(),
|
connect(std::const_pointer_cast<EntityTree>(entityTree).get(),
|
||||||
&EntityTree::deletingEntity, this, &SafeLanding::deleteTrackedEntity);
|
&EntityTree::deletingEntity, this, &SafeLanding::deleteTrackedEntity);
|
||||||
|
|
||||||
_sequenceNumbers.clear();
|
|
||||||
_initialStart = INVALID_SEQUENCE;
|
|
||||||
_initialEnd = INVALID_SEQUENCE;
|
|
||||||
_startTime = usecTimestampNow();
|
|
||||||
EntityTreeRenderer::setEntityLoadingPriorityFunction(&ElevatedPriority);
|
EntityTreeRenderer::setEntityLoadingPriorityFunction(&ElevatedPriority);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,24 +83,71 @@ void SafeLanding::deleteTrackedEntity(const EntityItemID& entityID) {
|
||||||
|
|
||||||
void SafeLanding::finishSequence(int first, int last) {
|
void SafeLanding::finishSequence(int first, int last) {
|
||||||
Locker lock(_lock);
|
Locker lock(_lock);
|
||||||
if (_initialStart == INVALID_SEQUENCE) {
|
if (_trackingEntities) {
|
||||||
_initialStart = first;
|
_initialStart = first;
|
||||||
_initialEnd = last;
|
_initialEnd = last;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SafeLanding::updateSequence(int sequenceNumber) {
|
void SafeLanding::addToSequence(int sequenceNumber) {
|
||||||
if (_trackingEntities) {
|
|
||||||
Locker lock(_lock);
|
Locker lock(_lock);
|
||||||
|
if (_trackingEntities) {
|
||||||
_sequenceNumbers.insert(sequenceNumber);
|
_sequenceNumbers.insert(sequenceNumber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SafeLanding::isLoadSequenceComplete() {
|
void SafeLanding::updateTracking() {
|
||||||
if (isEntityLoadingComplete() && isSequenceNumbersComplete()) {
|
if (!_trackingEntities || !_entityTreeRenderer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Locker lock(_lock);
|
||||||
|
|
||||||
|
bool enableInterstitial = DependencyManager::get<NodeList>()->getDomainHandler().getInterstitialModeEnabled();
|
||||||
|
|
||||||
|
auto entityMapIter = _trackedEntities.begin();
|
||||||
|
while (entityMapIter != _trackedEntities.end()) {
|
||||||
|
auto entity = entityMapIter->second;
|
||||||
|
bool isVisuallyReady = true;
|
||||||
|
if (enableInterstitial) {
|
||||||
|
auto entityRenderable = _entityTreeRenderer->renderableForEntityId(entityMapIter->first);
|
||||||
|
if (!entityRenderable) {
|
||||||
|
_entityTreeRenderer->addingEntity(entityMapIter->first);
|
||||||
|
}
|
||||||
|
|
||||||
|
isVisuallyReady = entity->isVisuallyReady() || (!entityRenderable && !entity->isParentPathComplete());
|
||||||
|
}
|
||||||
|
if (isEntityPhysicsReady(entity) && isVisuallyReady) {
|
||||||
|
entityMapIter = _trackedEntities.erase(entityMapIter);
|
||||||
|
} else {
|
||||||
|
if (!isVisuallyReady) {
|
||||||
|
entity->requestRenderUpdate();
|
||||||
|
}
|
||||||
|
entityMapIter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enableInterstitial) {
|
||||||
|
_trackedEntityStabilityCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_trackedEntities.empty()) {
|
||||||
|
// no more tracked entities --> check sequenceNumbers
|
||||||
|
if (_initialStart != INVALID_SEQUENCE) {
|
||||||
|
Locker lock(_lock);
|
||||||
|
int sequenceSize = _initialStart <= _initialEnd ? _initialEnd - _initialStart:
|
||||||
|
_initialEnd + SEQUENCE_MODULO - _initialStart;
|
||||||
|
auto startIter = _sequenceNumbers.find(_initialStart);
|
||||||
|
auto endIter = _sequenceNumbers.find(_initialEnd - 1);
|
||||||
|
|
||||||
|
bool missingSequenceNumbers = qApp->isMissingSequenceNumbers();
|
||||||
|
if (sequenceSize == 0 ||
|
||||||
|
(startIter != _sequenceNumbers.end() &&
|
||||||
|
endIter != _sequenceNumbers.end() &&
|
||||||
|
((distance(startIter, endIter) == sequenceSize - 1) || !missingSequenceNumbers))) {
|
||||||
stopTracking();
|
stopTracking();
|
||||||
}
|
}
|
||||||
return !_trackingEntities;
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SafeLanding::stopTracking() {
|
void SafeLanding::stopTracking() {
|
||||||
|
@ -114,12 +161,13 @@ void SafeLanding::stopTracking() {
|
||||||
&EntityTree::deletingEntity, this, &SafeLanding::deleteTrackedEntity);
|
&EntityTree::deletingEntity, this, &SafeLanding::deleteTrackedEntity);
|
||||||
_entityTreeRenderer.reset();
|
_entityTreeRenderer.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
_initialStart = INVALID_SEQUENCE;
|
|
||||||
_initialEnd = INVALID_SEQUENCE;
|
|
||||||
EntityTreeRenderer::setEntityLoadingPriorityFunction(StandardPriority);
|
EntityTreeRenderer::setEntityLoadingPriorityFunction(StandardPriority);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SafeLanding::trackingIsComplete() const {
|
||||||
|
return !_trackingEntities && (_initialStart != INVALID_SEQUENCE);
|
||||||
|
}
|
||||||
|
|
||||||
float SafeLanding::loadingProgressPercentage() {
|
float SafeLanding::loadingProgressPercentage() {
|
||||||
Locker lock(_lock);
|
Locker lock(_lock);
|
||||||
static const int MINIMUM_TRACKED_ENTITY_STABILITY_COUNT = 15;
|
static const int MINIMUM_TRACKED_ENTITY_STABILITY_COUNT = 15;
|
||||||
|
@ -136,29 +184,6 @@ float SafeLanding::loadingProgressPercentage() {
|
||||||
return entityReadyPercentage;
|
return entityReadyPercentage;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SafeLanding::isSequenceNumbersComplete() {
|
|
||||||
if (_initialStart != INVALID_SEQUENCE) {
|
|
||||||
Locker lock(_lock);
|
|
||||||
int sequenceSize = _initialStart <= _initialEnd ? _initialEnd - _initialStart:
|
|
||||||
_initialEnd + SEQUENCE_MODULO - _initialStart;
|
|
||||||
auto startIter = _sequenceNumbers.find(_initialStart);
|
|
||||||
auto endIter = _sequenceNumbers.find(_initialEnd - 1);
|
|
||||||
|
|
||||||
bool missingSequenceNumbers = qApp->isMissingSequenceNumbers();
|
|
||||||
if (sequenceSize == 0 ||
|
|
||||||
(startIter != _sequenceNumbers.end()
|
|
||||||
&& endIter != _sequenceNumbers.end()
|
|
||||||
&& ((distance(startIter, endIter) == sequenceSize - 1) || !missingSequenceNumbers))) {
|
|
||||||
bool enableInterstitial = DependencyManager::get<NodeList>()->getDomainHandler().getInterstitialModeEnabled();
|
|
||||||
if (!enableInterstitial) {
|
|
||||||
_trackingEntities = false; // Don't track anything else that comes in.
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SafeLanding::isEntityPhysicsReady(const EntityItemPointer& entity) {
|
bool SafeLanding::isEntityPhysicsReady(const EntityItemPointer& entity) {
|
||||||
if (entity && !entity->getCollisionless()) {
|
if (entity && !entity->getCollisionless()) {
|
||||||
const auto& entityType = entity->getType();
|
const auto& entityType = entity->getType();
|
||||||
|
@ -176,51 +201,9 @@ bool SafeLanding::isEntityPhysicsReady(const EntityItemPointer& entity) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SafeLanding::isEntityLoadingComplete() {
|
|
||||||
Locker lock(_lock);
|
|
||||||
if (!_entityTreeRenderer) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
auto entityMapIter = _trackedEntities.begin();
|
|
||||||
|
|
||||||
bool enableInterstitial = DependencyManager::get<NodeList>()->getDomainHandler().getInterstitialModeEnabled();
|
|
||||||
|
|
||||||
while (entityMapIter != _trackedEntities.end()) {
|
|
||||||
auto entity = entityMapIter->second;
|
|
||||||
|
|
||||||
bool isVisuallyReady = true;
|
|
||||||
|
|
||||||
if (enableInterstitial) {
|
|
||||||
auto entityRenderable = _entityTreeRenderer->renderableForEntityId(entityMapIter->first);
|
|
||||||
if (!entityRenderable) {
|
|
||||||
_entityTreeRenderer->addingEntity(entityMapIter->first);
|
|
||||||
}
|
|
||||||
|
|
||||||
isVisuallyReady = entity->isVisuallyReady() || (!entityRenderable && !entity->isParentPathComplete());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isEntityPhysicsReady(entity) && isVisuallyReady) {
|
|
||||||
entityMapIter = _trackedEntities.erase(entityMapIter);
|
|
||||||
} else {
|
|
||||||
if (!isVisuallyReady) {
|
|
||||||
entity->requestRenderUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
entityMapIter++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enableInterstitial) {
|
|
||||||
_trackedEntityStabilityCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _trackedEntities.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
float SafeLanding::ElevatedPriority(const EntityItem& entityItem) {
|
float SafeLanding::ElevatedPriority(const EntityItem& entityItem) {
|
||||||
return entityItem.getCollisionless() ? 0.0f : 10.0f;
|
return entityItem.getCollisionless() ? 0.0f : 10.0f;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,10 +26,12 @@ class EntityItemID;
|
||||||
class SafeLanding : public QObject {
|
class SafeLanding : public QObject {
|
||||||
public:
|
public:
|
||||||
void startTracking(QSharedPointer<EntityTreeRenderer> entityTreeRenderer);
|
void startTracking(QSharedPointer<EntityTreeRenderer> entityTreeRenderer);
|
||||||
|
void updateTracking();
|
||||||
void stopTracking();
|
void stopTracking();
|
||||||
|
bool trackingIsComplete() const;
|
||||||
|
|
||||||
void finishSequence(int first, int last); // 'last' exclusive.
|
void finishSequence(int first, int last); // 'last' exclusive.
|
||||||
void updateSequence(int sequenceNumber);
|
void addToSequence(int sequenceNumber);
|
||||||
bool isLoadSequenceComplete();
|
|
||||||
float loadingProgressPercentage();
|
float loadingProgressPercentage();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
@ -37,10 +39,8 @@ private slots:
|
||||||
void deleteTrackedEntity(const EntityItemID& entityID);
|
void deleteTrackedEntity(const EntityItemID& entityID);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool isSequenceNumbersComplete();
|
|
||||||
bool isEntityPhysicsReady(const EntityItemPointer& entity);
|
bool isEntityPhysicsReady(const EntityItemPointer& entity);
|
||||||
void debugDumpSequenceIDs() const;
|
void debugDumpSequenceIDs() const;
|
||||||
bool isEntityLoadingComplete();
|
|
||||||
|
|
||||||
std::mutex _lock;
|
std::mutex _lock;
|
||||||
using Locker = std::lock_guard<std::mutex>;
|
using Locker = std::lock_guard<std::mutex>;
|
||||||
|
|
Loading…
Reference in a new issue