Merge pull request #14608 from SamGondelman/zone

Case 19080: Fix zone with invalid script not loading
This commit is contained in:
Jeff Clinton 2018-12-19 08:49:33 -08:00 committed by GitHub
commit 16c7619aa7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 22 additions and 48 deletions

View file

@ -61,8 +61,7 @@ EntityTreeRenderer::EntityTreeRenderer(bool wantScripts, AbstractViewStateInterf
_lastPointerEventValid(false), _lastPointerEventValid(false),
_viewState(viewState), _viewState(viewState),
_scriptingServices(scriptingServices), _scriptingServices(scriptingServices),
_displayModelBounds(false), _displayModelBounds(false)
_layeredZones(this)
{ {
setMouseRayPickResultOperator([](unsigned int rayPickID) { setMouseRayPickResultOperator([](unsigned int rayPickID) {
RayToEntityIntersectionResult entityResult; RayToEntityIntersectionResult entityResult;
@ -516,41 +515,36 @@ bool EntityTreeRenderer::findBestZoneAndMaybeContainingEntities(QVector<EntityIt
auto hasScript = !entity->getScript().isEmpty(); auto hasScript = !entity->getScript().isEmpty();
// only consider entities that are zones or have scripts, all other entities can // only consider entities that are zones or have scripts, all other entities can
// be ignored because they can have events fired on them. // be ignored because they can't have events fired on them.
// FIXME - this could be optimized further by determining if the script is loaded // FIXME - this could be optimized further by determining if the script is loaded
// and if it has either an enterEntity or leaveEntity method // and if it has either an enterEntity or leaveEntity method
// //
// also, don't flag a scripted entity as containing the avatar until the script is loaded, // also, don't flag a scripted entity as containing the avatar until the script is loaded,
// so that the script is awake in time to receive the "entityEntity" call (even if the entity is a zone). // so that the script is awake in time to receive the "entityEntity" call (even if the entity is a zone).
if ((!hasScript && isZone) || bool contains = false;
(hasScript && entity->isScriptPreloadFinished())) { bool scriptHasLoaded = hasScript && entity->isScriptPreloadFinished();
// now check to see if the point contains our entity, this can be expensive if if (isZone || scriptHasLoaded) {
// the entity has a collision hull contains = entity->contains(_avatarPosition);
if (entity->contains(_avatarPosition)) { }
if (contains) {
// if this entity is a zone and visible, add it to our layered zones
if (isZone && entity->getVisible() && renderableForEntity(entity)) {
_layeredZones.insert(std::dynamic_pointer_cast<ZoneEntityItem>(entity));
}
if ((!hasScript && isZone) || scriptHasLoaded) {
if (entitiesContainingAvatar) { if (entitiesContainingAvatar) {
*entitiesContainingAvatar << entity->getEntityItemID(); *entitiesContainingAvatar << entity->getEntityItemID();
} }
// if this entity is a zone and visible, determine if it is the bestZone
if (isZone && entity->getVisible() && renderableForEntity(entity)) {
auto zone = std::dynamic_pointer_cast<ZoneEntityItem>(entity);
_layeredZones.insert(zone);
}
}
} }
} }
}
// check if our layered zones have changed // check if our layered zones have changed
if (_layeredZones.empty()) { if ((_layeredZones.empty() && oldLayeredZones.empty()) || (!oldLayeredZones.empty() && _layeredZones.contains(oldLayeredZones))) {
if (oldLayeredZones.empty()) { return;
return;
}
} else if (!oldLayeredZones.empty()) {
if (_layeredZones.contains(oldLayeredZones)) {
return;
}
} }
_layeredZones.apply();
applyLayeredZones(); applyLayeredZones();
@ -653,8 +647,8 @@ bool EntityTreeRenderer::applyLayeredZones() {
} else { } else {
qCWarning(entitiesrenderer) << "EntityTreeRenderer::applyLayeredZones(), Unexpected null scene, possibly during application shutdown"; qCWarning(entitiesrenderer) << "EntityTreeRenderer::applyLayeredZones(), Unexpected null scene, possibly during application shutdown";
} }
return true; return true;
} }
void EntityTreeRenderer::processEraseMessage(ReceivedMessage& message, const SharedNodePointer& sourceNode) { void EntityTreeRenderer::processEraseMessage(ReceivedMessage& message, const SharedNodePointer& sourceNode) {
@ -1151,18 +1145,12 @@ std::pair<EntityTreeRenderer::LayeredZones::iterator, bool> EntityTreeRenderer::
return { it, success }; return { it, success };
} }
void EntityTreeRenderer::LayeredZones::apply() {
assert(_entityTreeRenderer);
}
void EntityTreeRenderer::LayeredZones::update(std::shared_ptr<ZoneEntityItem> zone) { void EntityTreeRenderer::LayeredZones::update(std::shared_ptr<ZoneEntityItem> zone) {
assert(_entityTreeRenderer);
bool isVisible = zone->isVisible(); bool isVisible = zone->isVisible();
if (empty() && isVisible) { if (empty() && isVisible) {
// there are no zones: set this one // there are no zones: set this one
insert(zone); insert(zone);
apply();
return; return;
} else { } else {
LayeredZone zoneLayer(zone); LayeredZone zoneLayer(zone);

View file

@ -205,42 +205,28 @@ private:
class LayeredZones : public std::set<LayeredZone> { class LayeredZones : public std::set<LayeredZone> {
public: public:
LayeredZones(EntityTreeRenderer* parent) : _entityTreeRenderer(parent) {} LayeredZones() {};
LayeredZones(LayeredZones&& other); LayeredZones(LayeredZones&& other);
// avoid accidental misconstruction // avoid accidental misconstruction
LayeredZones() = delete;
LayeredZones(const LayeredZones&) = delete; LayeredZones(const LayeredZones&) = delete;
LayeredZones& operator=(const LayeredZones&) = delete; LayeredZones& operator=(const LayeredZones&) = delete;
LayeredZones& operator=(LayeredZones&&) = delete; LayeredZones& operator=(LayeredZones&&) = delete;
void clear(); void clear();
std::pair<iterator, bool> insert(const LayeredZone& layer); std::pair<iterator, bool> insert(const LayeredZone& layer);
void apply();
void update(std::shared_ptr<ZoneEntityItem> zone); void update(std::shared_ptr<ZoneEntityItem> zone);
bool contains(const LayeredZones& other); bool contains(const LayeredZones& other);
std::shared_ptr<ZoneEntityItem> getZone() { return empty() ? nullptr : begin()->zone; } std::shared_ptr<ZoneEntityItem> getZone() { return empty() ? nullptr : begin()->zone; }
private: private:
void applyPartial(iterator layer);
std::map<QUuid, iterator> _map; std::map<QUuid, iterator> _map;
iterator _skyboxLayer{ end() }; iterator _skyboxLayer { end() };
EntityTreeRenderer* _entityTreeRenderer;
}; };
LayeredZones _layeredZones; LayeredZones _layeredZones;
QString _zoneUserData;
NetworkTexturePointer _ambientTexture;
NetworkTexturePointer _skyboxTexture;
QString _ambientTextureURL;
QString _skyboxTextureURL;
float _avgRenderableUpdateCost { 0.0f }; float _avgRenderableUpdateCost { 0.0f };
bool _pendingAmbientTexture { false };
bool _pendingSkyboxTexture { false };
uint64_t _lastZoneCheck { 0 }; uint64_t _lastZoneCheck { 0 };
const uint64_t ZONE_CHECK_INTERVAL = USECS_PER_MSEC * 100; // ~10hz const uint64_t ZONE_CHECK_INTERVAL = USECS_PER_MSEC * 100; // ~10hz