New approach to physics readiness - now (mostly) working

This commit is contained in:
Simon Walton 2018-08-09 16:24:04 -07:00
parent 4395e1fa26
commit 875407b3fe
5 changed files with 34 additions and 76 deletions

View file

@ -6322,10 +6322,11 @@ void Application::clearDomainOctreeDetails() {
_octreeServerSceneStats.clear(); _octreeServerSceneStats.clear();
}); });
_octreeProcessor.resetCompletionSequenceNumber();
// reset the model renderer // reset the model renderer
getEntities()->clear(); getEntities()->clear();
_octreeProcessor.startEntitySequence();
auto skyStage = DependencyManager::get<SceneScriptingInterface>()->getSkyStage(); auto skyStage = DependencyManager::get<SceneScriptingInterface>()->getSkyStage();
skyStage->setBackgroundMode(graphics::SunSkyStage::SKY_DEFAULT); skyStage->setBackgroundMode(graphics::SunSkyStage::SKY_DEFAULT);

View file

@ -122,7 +122,7 @@ void OctreePacketProcessor::processPacket(QSharedPointer<ReceivedMessage> messag
OCTREE_PACKET_SEQUENCE completionNumber; OCTREE_PACKET_SEQUENCE completionNumber;
message->readPrimitive(&completionNumber); message->readPrimitive(&completionNumber);
_completionSequenceNumber = completionNumber; completionNumber;
_safeLanding->setCompletionSequenceNumbers(0, completionNumber); _safeLanding->setCompletionSequenceNumbers(0, completionNumber);
} break; } break;
@ -132,26 +132,6 @@ void OctreePacketProcessor::processPacket(QSharedPointer<ReceivedMessage> messag
} }
} }
void OctreePacketProcessor::resetCompletionSequenceNumber() {
_completionSequenceNumber = INVALID_SEQUENCE;
}
namespace {
template<typename T> bool lessThanWraparound(int a, int b) {
constexpr int MAX_T_VALUE = std::numeric_limits<T>::max();
if (b <= a) {
b += MAX_T_VALUE;
}
return (b - a) < (MAX_T_VALUE / 2);
}
}
//bool OctreePacketProcessor::octreeSequenceIsComplete(int sequenceNumber) const {
// // If we've received the flagged seq # and the current one is >= it.
// return _completionSequenceNumber != INVALID_SEQUENCE &&
// !lessThanWraparound<OCTREE_PACKET_SEQUENCE>(sequenceNumber, _completionSequenceNumber);
//}
void OctreePacketProcessor::startEntitySequence() { void OctreePacketProcessor::startEntitySequence() {
_safeLanding->startEntitySequence(qApp->getEntities()); _safeLanding->startEntitySequence(qApp->getEntities());
} }

View file

@ -31,9 +31,6 @@ public:
signals: signals:
void packetVersionMismatch(); void packetVersionMismatch();
public slots:
void resetCompletionSequenceNumber();
protected: protected:
virtual void processPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode) override; virtual void processPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode) override;
@ -41,8 +38,6 @@ private slots:
void handleOctreePacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode); void handleOctreePacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
private: private:
static constexpr int INVALID_SEQUENCE = -1;
std::atomic<int> _completionSequenceNumber { INVALID_SEQUENCE };
std::unique_ptr<SafeLanding> _safeLanding; std::unique_ptr<SafeLanding> _safeLanding;
}; };
#endif // hifi_OctreePacketProcessor_h #endif // hifi_OctreePacketProcessor_h

View file

@ -12,7 +12,6 @@
#include "SafeLanding.h" #include "SafeLanding.h"
#include "EntityTreeRenderer.h" #include "EntityTreeRenderer.h"
#include "ModelEntityItem.h" #include "ModelEntityItem.h"
#include "model-networking/ModelCache.h"
#include "InterfaceLogging.h" #include "InterfaceLogging.h"
const int SafeLanding::SEQUENCE_MODULO = std::numeric_limits<OCTREE_PACKET_SEQUENCE>::max() + 1; const int SafeLanding::SEQUENCE_MODULO = std::numeric_limits<OCTREE_PACKET_SEQUENCE>::max() + 1;
@ -31,9 +30,6 @@ bool SafeLanding::SequenceLessThan::operator()(const int& a, const int& b) const
return lessThanWraparound<OCTREE_PACKET_SEQUENCE>(a, b); return lessThanWraparound<OCTREE_PACKET_SEQUENCE>(a, b);
} }
SafeLanding::SafeLanding() {
}
void SafeLanding::startEntitySequence(QSharedPointer<EntityTreeRenderer> entityTreeRenderer) { void SafeLanding::startEntitySequence(QSharedPointer<EntityTreeRenderer> entityTreeRenderer) {
if (!_trackingEntities) { if (!_trackingEntities) {
auto entityTree = entityTreeRenderer->getTree(); auto entityTree = entityTreeRenderer->getTree();
@ -59,19 +55,20 @@ void SafeLanding::stopEntitySequence() {
} }
void SafeLanding::addTrackedEntity(const EntityItemID& entityID) { void SafeLanding::addTrackedEntity(const EntityItemID& entityID) {
volatile EntityItemID id = entityID;
if (_trackingEntities) { if (_trackingEntities) {
EntityItemPointer entity = _entityTree->findEntityByID(entityID); EntityItemPointer entity = _entityTree->findEntityByID(entityID);
if (entity) {
const auto& entityType = entity->getType();
// Entity types of interest:
static const std::set<EntityTypes::EntityType> solidTypes
{ EntityTypes::Box, EntityTypes::Sphere, EntityTypes::Shape, EntityTypes::Model };
if (solidTypes.count(entity->getType()) && !entity->getCollisionless()) { if (entity && !entity->getCollisionless()) {
const auto& entityType = entity->getType();
if (entityType == EntityTypes::Model) {
ModelEntityItem * modelEntity = std::dynamic_pointer_cast<ModelEntityItem>(entity).get();
auto shapeType = modelEntity->getShapeType();
if (shapeType == SHAPE_TYPE_COMPOUND || shapeType == SHAPE_TYPE_STATIC_MESH ||
shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) {
// Only track entities with downloaded collision bodies.
_trackedEntities.emplace(entityID, entity); _trackedEntities.emplace(entityID, entity);
trackResources(entity); qCDebug(interfaceapp) << "Safe Landing: Tracking entity " << entity->getItemName();
qCDebug(interfaceapp) << "Tracking entity " << entity->getItemName(); }
} }
} }
} }
@ -112,58 +109,46 @@ bool SafeLanding::sequenceNumbersComplete() {
return false; return false;
} }
void SafeLanding::trackResources(EntityItemPointer entity) {
if (entity->getType() == EntityTypes::Model) {
ModelEntityItem * modelEntity = std::dynamic_pointer_cast<ModelEntityItem>(entity).get();
QString resourceURL;
QSharedPointer<Resource> resource;
auto shapeType = modelEntity->getShapeType();
if (shapeType == SHAPE_TYPE_COMPOUND) {
resourceURL = modelEntity->getCompoundShapeURL();
resource = DependencyManager::get<ModelCache>()->getCollisionGeometryResource(resourceURL);
} else if (shapeType == SHAPE_TYPE_STATIC_MESH || shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) {
resourceURL = modelEntity->getModelURL();
resource = DependencyManager::get<ModelCache>()->getGeometryResource(resourceURL);
}
if (resource) {
connect(resource.data(), &Resource::loaded, this, &SafeLanding::resourceLoaded);
// Remove it either way:
connect(resource.data(), &Resource::failed, this, &SafeLanding::resourceLoaded);
if (!resource->isLoaded()) {
_trackedURLs.insert(resourceURL);
}
}
}
}
void SafeLanding::resourceLoaded() { void SafeLanding::resourceLoaded() {
QObject * sender = QObject::sender(); QObject * sender = QObject::sender();
if (sender) { if (sender) {
Resource * resource = dynamic_cast<Resource*>(sender); Resource * resource = dynamic_cast<Resource*>(sender);
const QString resourceURL = resource->getURL().toString(); const QString resourceURL = resource->getURL().toString();
_trackedURLs.erase(resourceURL); _trackedURLs.erase(resourceURL);
qCDebug(interfaceapp) << "Removed tracked URL" << resourceURL; qCDebug(interfaceapp) << "Safe Landing: Removed tracked URL" << resourceURL;
} }
} }
bool SafeLanding::isLoadSequenceComplete() { bool SafeLanding::isLoadSequenceComplete() {
if (sequenceNumbersComplete() && _trackedURLs.empty()) { if (sequenceNumbersComplete() && entityPhysicsComplete()) {
_trackingEntities = false; _trackingEntities = false;
_trackedEntities.clear(); _trackedEntities.clear();
qCDebug(interfaceapp) << "Safe Landing: load sequence complete";
} }
return !_trackingEntities; return !_trackingEntities;
} }
void SafeLanding::DebugDumpSequenceIDs() const { bool SafeLanding::entityPhysicsComplete() {
for (auto entityMapIter = _trackedEntities.begin(); entityMapIter != _trackedEntities.end(); ++entityMapIter) {
auto entity = entityMapIter->second;
if (!entity->shouldBePhysical() || entity->isReadyToComputeShape()) {
entityMapIter = _trackedEntities.erase(entityMapIter);
if (entityMapIter == _trackedEntities.end()) {
break;
}
}
}
return _trackedEntities.empty();
}
void SafeLanding::debugDumpSequenceIDs() const {
int p = -1; int p = -1;
qCDebug(interfaceapp) << "Sequence set size:" << _sequenceNumbers.size(); qCDebug(interfaceapp) << "Sequence set size:" << _sequenceNumbers.size();
for (auto s: _sequenceNumbers) { for (auto s: _sequenceNumbers) {
if (p == -1) { if (p == -1) {
p = s; p = s;
qCDebug(interfaceapp) << "First: " << s; qCDebug(interfaceapp) << "First:" << s;
} else { } else {
if (s != p + 1) { if (s != p + 1) {
qCDebug(interfaceapp) << "Gap from" << p << "to" << s << "(exclusive)"; qCDebug(interfaceapp) << "Gap from" << p << "to" << s << "(exclusive)";

View file

@ -24,9 +24,6 @@ class EntityItemID;
class SafeLanding : public QObject { class SafeLanding : public QObject {
public: public:
SafeLanding();
~SafeLanding() = default;
void startEntitySequence(QSharedPointer<EntityTreeRenderer> entityTreeRenderer); void startEntitySequence(QSharedPointer<EntityTreeRenderer> entityTreeRenderer);
void stopEntitySequence(); void stopEntitySequence();
void setCompletionSequenceNumbers(int first, int last); void setCompletionSequenceNumbers(int first, int last);
@ -40,8 +37,8 @@ private slots:
private: private:
bool sequenceNumbersComplete(); bool sequenceNumbersComplete();
void trackResources(EntityItemPointer entity); void debugDumpSequenceIDs() const;
void DebugDumpSequenceIDs() const; bool entityPhysicsComplete();
bool _trackingEntities { false }; bool _trackingEntities { false };
EntityTreePointer _entityTree; EntityTreePointer _entityTree;