Merge pull request #15523 from SamGondelman/zone

Case 22466, BUGZ-102: Fix zone rendering issues
This commit is contained in:
Shannon Romano 2019-05-08 14:52:33 -07:00 committed by GitHub
commit 4bd41a1aa3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 141 additions and 263 deletions

View file

@ -220,6 +220,7 @@ void EntityTreeRenderer::stopDomainAndNonOwnedEntities() {
void EntityTreeRenderer::clearDomainAndNonOwnedEntities() { void EntityTreeRenderer::clearDomainAndNonOwnedEntities() {
stopDomainAndNonOwnedEntities(); stopDomainAndNonOwnedEntities();
auto sessionUUID = getTree()->getMyAvatarSessionUUID();
std::unordered_map<EntityItemID, EntityRendererPointer> savedEntities; std::unordered_map<EntityItemID, EntityRendererPointer> savedEntities;
// remove all entities from the scene // remove all entities from the scene
auto scene = _viewState->getMain3DScene(); auto scene = _viewState->getMain3DScene();
@ -227,7 +228,7 @@ void EntityTreeRenderer::clearDomainAndNonOwnedEntities() {
for (const auto& entry : _entitiesInScene) { for (const auto& entry : _entitiesInScene) {
const auto& renderer = entry.second; const auto& renderer = entry.second;
const EntityItemPointer& entityItem = renderer->getEntity(); const EntityItemPointer& entityItem = renderer->getEntity();
if (!(entityItem->isLocalEntity() || (entityItem->isAvatarEntity() && entityItem->getOwningAvatarID() == getTree()->getMyAvatarSessionUUID()))) { if (!(entityItem->isLocalEntity() || (entityItem->isAvatarEntity() && entityItem->getOwningAvatarID() == sessionUUID))) {
fadeOutRenderable(renderer); fadeOutRenderable(renderer);
} else { } else {
savedEntities[entry.first] = entry.second; savedEntities[entry.first] = entry.second;
@ -238,7 +239,9 @@ void EntityTreeRenderer::clearDomainAndNonOwnedEntities() {
_renderablesToUpdate = savedEntities; _renderablesToUpdate = savedEntities;
_entitiesInScene = savedEntities; _entitiesInScene = savedEntities;
_layeredZones.clearNonLocalLayeredZones(); if (_layeredZones.clearDomainAndNonOwnedZones(sessionUUID)) {
applyLayeredZones();
}
OctreeProcessor::clearDomainAndNonOwnedEntities(); OctreeProcessor::clearDomainAndNonOwnedEntities();
} }
@ -271,6 +274,9 @@ void EntityTreeRenderer::clear() {
// reset the zone to the default (while we load the next scene) // reset the zone to the default (while we load the next scene)
_layeredZones.clear(); _layeredZones.clear();
if (!_shuttingDown) {
applyLayeredZones();
}
OctreeProcessor::clear(); OctreeProcessor::clear();
} }
@ -363,6 +369,7 @@ void EntityTreeRenderer::addPendingEntities(const render::ScenePointer& scene, r
for (const auto& processedId : processedIds) { for (const auto& processedId : processedIds) {
_entitiesToAdd.erase(processedId); _entitiesToAdd.erase(processedId);
} }
forceRecheckEntities();
} }
} }
} }
@ -537,8 +544,7 @@ void EntityTreeRenderer::handleSpaceUpdate(std::pair<int32_t, glm::vec4> proxyUp
_spaceUpdates.emplace_back(proxyUpdate.first, proxyUpdate.second); _spaceUpdates.emplace_back(proxyUpdate.first, proxyUpdate.second);
} }
bool EntityTreeRenderer::findBestZoneAndMaybeContainingEntities(QSet<EntityItemID>& entitiesContainingAvatar) { void EntityTreeRenderer::findBestZoneAndMaybeContainingEntities(QSet<EntityItemID>& entitiesContainingAvatar) {
bool didUpdate = false;
float radius = 0.01f; // for now, assume 0.01 meter radius, because we actually check the point inside later float radius = 0.01f; // for now, assume 0.01 meter radius, because we actually check the point inside later
QVector<QUuid> entityIDs; QVector<QUuid> entityIDs;
@ -550,7 +556,7 @@ bool EntityTreeRenderer::findBestZoneAndMaybeContainingEntities(QSet<EntityItemI
// FIXME - if EntityTree had a findEntitiesContainingPoint() this could theoretically be a little faster // FIXME - if EntityTree had a findEntitiesContainingPoint() this could theoretically be a little faster
entityTree->evalEntitiesInSphere(_avatarPosition, radius, PickFilter(), entityIDs); entityTree->evalEntitiesInSphere(_avatarPosition, radius, PickFilter(), entityIDs);
LayeredZones oldLayeredZones(std::move(_layeredZones)); LayeredZones oldLayeredZones(_layeredZones);
_layeredZones.clear(); _layeredZones.clear();
// create a list of entities that actually contain the avatar's position // create a list of entities that actually contain the avatar's position
@ -578,8 +584,8 @@ bool EntityTreeRenderer::findBestZoneAndMaybeContainingEntities(QSet<EntityItemI
if (contains) { if (contains) {
// if this entity is a zone and visible, add it to our layered zones // if this entity is a zone and visible, add it to our layered zones
if (isZone && entity->getVisible() && renderableForEntity(entity)) { if (isZone && entity->getVisible() && renderableIdForEntity(entity) != render::Item::INVALID_ITEM_ID) {
_layeredZones.insert(std::dynamic_pointer_cast<ZoneEntityItem>(entity)); _layeredZones.emplace(std::dynamic_pointer_cast<ZoneEntityItem>(entity));
} }
if ((!hasScript && isZone) || scriptHasLoaded) { if ((!hasScript && isZone) || scriptHasLoaded) {
@ -588,24 +594,16 @@ bool EntityTreeRenderer::findBestZoneAndMaybeContainingEntities(QSet<EntityItemI
} }
} }
// check if our layered zones have changed if (!_layeredZones.equals(oldLayeredZones)) {
if ((_layeredZones.empty() && oldLayeredZones.empty()) || (!oldLayeredZones.empty() && _layeredZones.contains(oldLayeredZones))) {
return;
}
applyLayeredZones(); applyLayeredZones();
}
didUpdate = true;
}); });
return didUpdate;
} }
bool EntityTreeRenderer::checkEnterLeaveEntities() { void EntityTreeRenderer::checkEnterLeaveEntities() {
PROFILE_RANGE(simulation_physics, "EnterLeave"); PROFILE_RANGE(simulation_physics, "EnterLeave");
PerformanceTimer perfTimer("enterLeave"); PerformanceTimer perfTimer("enterLeave");
auto now = usecTimestampNow(); auto now = usecTimestampNow();
bool didUpdate = false;
if (_tree && !_shuttingDown) { if (_tree && !_shuttingDown) {
glm::vec3 avatarPosition = _viewState->getAvatarPosition(); glm::vec3 avatarPosition = _viewState->getAvatarPosition();
@ -623,7 +621,7 @@ bool EntityTreeRenderer::checkEnterLeaveEntities() {
_forceRecheckEntities = false; _forceRecheckEntities = false;
QSet<EntityItemID> entitiesContainingAvatar; QSet<EntityItemID> entitiesContainingAvatar;
didUpdate = findBestZoneAndMaybeContainingEntities(entitiesContainingAvatar); findBestZoneAndMaybeContainingEntities(entitiesContainingAvatar);
// Note: at this point we don't need to worry about the tree being locked, because we only deal with // Note: at this point we don't need to worry about the tree being locked, because we only deal with
// EntityItemIDs from here. The callEntityScriptMethod() method is robust against attempting to call scripts // EntityItemIDs from here. The callEntityScriptMethod() method is robust against attempting to call scripts
@ -649,7 +647,6 @@ bool EntityTreeRenderer::checkEnterLeaveEntities() {
} }
} }
} }
return didUpdate;
} }
void EntityTreeRenderer::leaveDomainAndNonOwnedEntities() { void EntityTreeRenderer::leaveDomainAndNonOwnedEntities() {
@ -696,18 +693,12 @@ bool EntityTreeRenderer::applyLayeredZones() {
// in the expected layered order and update the scene with it // in the expected layered order and update the scene with it
auto scene = _viewState->getMain3DScene(); auto scene = _viewState->getMain3DScene();
if (scene) { if (scene) {
render::Transaction transaction;
render::ItemIDs list; render::ItemIDs list;
for (auto& zone : _layeredZones) { _layeredZones.appendRenderIDs(list, this);
auto id = renderableIdForEntity(zone.zone);
// The zone may not have been rendered yet.
if (id != render::Item::INVALID_ITEM_ID) {
list.push_back(id);
}
}
render::Selection selection("RankedZones", list);
transaction.resetSelection(selection);
render::Selection selection("RankedZones", list);
render::Transaction transaction;
transaction.resetSelection(selection);
scene->enqueueTransaction(transaction); scene->enqueueTransaction(transaction);
} else { } else {
qCWarning(entitiesrenderer) << "EntityTreeRenderer::applyLayeredZones(), Unexpected null scene, possibly during application shutdown"; qCWarning(entitiesrenderer) << "EntityTreeRenderer::applyLayeredZones(), Unexpected null scene, possibly during application shutdown";
@ -1018,7 +1009,6 @@ void EntityTreeRenderer::deletingEntity(const EntityItemID& entityID) {
} }
void EntityTreeRenderer::addingEntity(const EntityItemID& entityID) { void EntityTreeRenderer::addingEntity(const EntityItemID& entityID) {
forceRecheckEntities(); // reset our state to force checking our inside/outsideness of entities
checkAndCallPreload(entityID); checkAndCallPreload(entityID);
auto entity = std::static_pointer_cast<EntityTree>(_tree)->findEntityByID(entityID); auto entity = std::static_pointer_cast<EntityTree>(_tree)->findEntityByID(entityID);
if (entity) { if (entity) {
@ -1190,107 +1180,98 @@ void EntityTreeRenderer::updateEntityRenderStatus(bool shouldRenderEntities) {
} }
void EntityTreeRenderer::updateZone(const EntityItemID& id) { void EntityTreeRenderer::updateZone(const EntityItemID& id) {
// Get in the zone! if (auto zone = std::dynamic_pointer_cast<ZoneEntityItem>(getTree()->findEntityByEntityItemID(id))) {
auto zone = std::dynamic_pointer_cast<ZoneEntityItem>(getTree()->findEntityByEntityItemID(id)); _layeredZones.update(zone, _avatarPosition, this);
if (zone && zone->contains(_avatarPosition)) { applyLayeredZones();
_layeredZones.update(zone);
} }
} }
EntityTreeRenderer::LayeredZones::LayeredZones(LayeredZones&& other) { bool EntityTreeRenderer::LayeredZones::clearDomainAndNonOwnedZones(const QUuid& sessionUUID) {
// In a swap: bool zonesChanged = false;
// > All iterators and references remain valid. The past-the-end iterator is invalidated.
bool isSkyboxLayerValid = (other._skyboxLayer != other.end());
swap(other); auto it = c.begin();
_map.swap(other._map); while (it != c.end()) {
_skyboxLayer = other._skyboxLayer; auto zone = it->zone.lock();
if (!zone || !(zone->isLocalEntity() || (zone->isAvatarEntity() && zone->getOwningAvatarID() == sessionUUID))) {
if (!isSkyboxLayerValid) { zonesChanged = true;
_skyboxLayer = end(); it = c.erase(it);
}
}
void EntityTreeRenderer::LayeredZones::clearNonLocalLayeredZones() {
std::set<LayeredZone> localLayeredZones;
std::map<QUuid, iterator> newMap;
for (auto iter = begin(); iter != end(); iter++) {
LayeredZone layeredZone = *iter;
if (layeredZone.zone->isLocalEntity()) {
bool success;
iterator it;
std::tie(it, success) = localLayeredZones.insert(layeredZone);
if (success) {
newMap.emplace(layeredZone.id, it);
}
}
}
std::set<LayeredZone>::operator=(localLayeredZones);
_map = newMap;
_skyboxLayer = empty() ? end() : begin();
}
void EntityTreeRenderer::LayeredZones::clear() {
std::set<LayeredZone>::clear();
_map.clear();
_skyboxLayer = end();
}
std::pair<EntityTreeRenderer::LayeredZones::iterator, bool> EntityTreeRenderer::LayeredZones::insert(const LayeredZone& layer) {
iterator it;
bool success;
std::tie(it, success) = std::set<LayeredZone>::insert(layer);
if (success) {
_map.emplace(it->id, it);
}
return { it, success };
}
void EntityTreeRenderer::LayeredZones::update(std::shared_ptr<ZoneEntityItem> zone) {
bool isVisible = zone->isVisible();
if (empty() && isVisible) {
// there are no zones: set this one
insert(zone);
return;
} else { } else {
LayeredZone zoneLayer(zone); it++;
// find this zone's layer, if it exists
iterator layer = end();
auto it = _map.find(zoneLayer.id);
if (it != _map.end()) {
layer = it->second;
// if the volume changed, we need to resort the layer (reinsertion)
// if the visibility changed, we need to erase the layer
if (zoneLayer.volume != layer->volume || !isVisible) {
erase(layer);
_map.erase(it);
layer = end();
} }
} }
// (re)insert this zone's layer if necessary if (zonesChanged) {
if (layer == end() && isVisible) { std::make_heap(c.begin(), c.end(), comp);
std::tie(layer, std::ignore) = insert(zoneLayer);
_map.emplace(layer->id, layer);
} }
return zonesChanged;
}
std::pair<bool, bool> EntityTreeRenderer::LayeredZones::getZoneInteractionProperties() const {
auto it = c.cbegin();
while (it != c.cend()) {
auto zone = it->zone.lock();
if (zone && zone->isDomainEntity()) {
return { zone->getFlyingAllowed(), zone->getGhostingAllowed() };
}
it++;
}
return { true, true };
}
void EntityTreeRenderer::LayeredZones::remove(const std::shared_ptr<ZoneEntityItem>& zone) {
auto it = c.begin();
while (it != c.end()) {
if (it->zone.lock() == zone) {
break;
}
it++;
}
if (it != c.end()) {
c.erase(it);
std::make_heap(c.begin(), c.end(), comp);
} }
} }
bool EntityTreeRenderer::LayeredZones::contains(const LayeredZones& other) { void EntityTreeRenderer::LayeredZones::update(std::shared_ptr<ZoneEntityItem> zone, const glm::vec3& position, EntityTreeRenderer* entityTreeRenderer) {
bool result = std::equal(other.begin(), other._skyboxLayer, begin()); // When a zone's position or visibility changes, we call this method
if (result) { // In order to resort our zones, we first remove the changed zone, and then re-insert it if necessary
// if valid, set the _skyboxLayer from the other LayeredZones remove(zone);
_skyboxLayer = std::next(begin(), std::distance(other.begin(), other._skyboxLayer));
// Only call contains if the zone is rendering
if (zone->isVisible() && entityTreeRenderer->renderableIdForEntity(zone) != render::Item::INVALID_ITEM_ID && zone->contains(position)) {
emplace(zone);
}
}
bool EntityTreeRenderer::LayeredZones::equals(const LayeredZones& other) const {
if (size() != other.size()) {
return false;
}
auto it = c.cbegin();
auto otherIt = other.c.cbegin();
while (it != c.cend()) {
if (*it != *otherIt) {
return false;
}
it++;
otherIt++;
}
return true;
}
void EntityTreeRenderer::LayeredZones::appendRenderIDs(render::ItemIDs& list, EntityTreeRenderer* entityTreeRenderer) const {
auto it = c.cbegin();
while (it != c.cend()) {
if (it->zone.lock()) {
auto id = entityTreeRenderer->renderableIdForEntityId(it->id);
if (id != render::Item::INVALID_ITEM_ID) {
list.push_back(id);
}
}
it++;
} }
return result;
} }
CalculateEntityLoadingPriority EntityTreeRenderer::_calculateEntityLoadingPriorityFunc = [](const EntityItem& item) -> float { CalculateEntityLoadingPriority EntityTreeRenderer::_calculateEntityLoadingPriorityFunc = [](const EntityItem& item) -> float {
@ -1298,14 +1279,7 @@ CalculateEntityLoadingPriority EntityTreeRenderer::_calculateEntityLoadingPriori
}; };
std::pair<bool, bool> EntityTreeRenderer::getZoneInteractionProperties() { std::pair<bool, bool> EntityTreeRenderer::getZoneInteractionProperties() {
for (auto& zone : _layeredZones) { return _layeredZones.getZoneInteractionProperties();
// Only domain entities control flying allowed and ghosting allowed
if (zone.zone && zone.zone->isDomainEntity()) {
return { zone.zone->getFlyingAllowed(), zone.zone->getGhostingAllowed() };
}
}
return { true, true };
} }
bool EntityTreeRenderer::wantsKeyboardFocus(const EntityItemID& id) const { bool EntityTreeRenderer::wantsKeyboardFocus(const EntityItemID& id) const {

View file

@ -169,7 +169,7 @@ private:
void resetEntitiesScriptEngine(); void resetEntitiesScriptEngine();
bool findBestZoneAndMaybeContainingEntities(QSet<EntityItemID>& entitiesContainingAvatar); void findBestZoneAndMaybeContainingEntities(QSet<EntityItemID>& entitiesContainingAvatar);
bool applyLayeredZones(); bool applyLayeredZones();
void stopDomainAndNonOwnedEntities(); void stopDomainAndNonOwnedEntities();
@ -180,7 +180,7 @@ private:
EntityItemID _currentClickingOnEntityID; EntityItemID _currentClickingOnEntityID;
QScriptValueList createEntityArgs(const EntityItemID& entityID); QScriptValueList createEntityArgs(const EntityItemID& entityID);
bool checkEnterLeaveEntities(); void checkEnterLeaveEntities();
void leaveDomainAndNonOwnedEntities(); void leaveDomainAndNonOwnedEntities();
void leaveAllEntities(); void leaveAllEntities();
void forceRecheckEntities(); void forceRecheckEntities();
@ -210,48 +210,38 @@ private:
class LayeredZone { class LayeredZone {
public: public:
LayeredZone(std::shared_ptr<ZoneEntityItem> zone, QUuid id, float volume) : zone(zone), id(id), volume(volume) {} LayeredZone(std::shared_ptr<ZoneEntityItem> zone) : zone(zone), id(zone->getID()), volume(zone->getVolumeEstimate()) {}
LayeredZone(std::shared_ptr<ZoneEntityItem> zone) : LayeredZone(zone, zone->getID(), zone->getVolumeEstimate()) {}
bool operator<(const LayeredZone& r) const { return std::tie(volume, id) < std::tie(r.volume, r.id); } bool operator>(const LayeredZone& r) const { return volume > r.volume; }
bool operator==(const LayeredZone& r) const { return id == r.id; } bool operator==(const LayeredZone& r) const { return zone.lock() == r.zone.lock(); }
bool operator<=(const LayeredZone& r) const { return (*this < r) || (*this == r); } bool operator!=(const LayeredZone& r) const { return !(*this == r); }
bool operator>=(const LayeredZone& r) const { return (*this > r) || (*this == r); }
std::shared_ptr<ZoneEntityItem> zone; std::weak_ptr<ZoneEntityItem> zone;
QUuid id; QUuid id;
float volume; float volume;
}; };
class LayeredZones : public std::set<LayeredZone> { class LayeredZones : public std::priority_queue<LayeredZone, std::vector<LayeredZone>, std::greater<LayeredZone>> {
public: public:
LayeredZones() {}; void clear() { *this = LayeredZones(); }
LayeredZones(LayeredZones&& other); bool clearDomainAndNonOwnedZones(const QUuid& sessionUUID);
// avoid accidental misconstruction bool equals(const LayeredZones& other) const;
LayeredZones(const LayeredZones&) = delete; void remove(const std::shared_ptr<ZoneEntityItem>& zone);
LayeredZones& operator=(const LayeredZones&) = delete; void update(std::shared_ptr<ZoneEntityItem> zone, const glm::vec3& position, EntityTreeRenderer* entityTreeRenderer);
LayeredZones& operator=(LayeredZones&&) = delete;
void clear(); void appendRenderIDs(render::ItemIDs& list, EntityTreeRenderer* entityTreeRenderer) const;
void clearNonLocalLayeredZones(); std::pair<bool, bool> getZoneInteractionProperties() const;
std::pair<iterator, bool> insert(const LayeredZone& layer);
void update(std::shared_ptr<ZoneEntityItem> zone);
bool contains(const LayeredZones& other);
std::shared_ptr<ZoneEntityItem> getZone() { return empty() ? nullptr : begin()->zone; }
private:
std::map<QUuid, iterator> _map;
iterator _skyboxLayer { end() };
}; };
LayeredZones _layeredZones; LayeredZones _layeredZones;
float _avgRenderableUpdateCost { 0.0f };
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
const float ZONE_CHECK_DISTANCE = 0.001f; const float ZONE_CHECK_DISTANCE = 0.001f;
float _avgRenderableUpdateCost { 0.0f };
ReadWriteLockable _changedEntitiesGuard; ReadWriteLockable _changedEntitiesGuard;
std::unordered_set<EntityItemID> _changedEntities; std::unordered_set<EntityItemID> _changedEntities;

View file

@ -92,9 +92,7 @@ void ZoneEntityRenderer::doRender(RenderArgs* args) {
} }
{ // Sun { // Sun
// Need an update ?
if (_needSunUpdate) { if (_needSunUpdate) {
// Do we need to allocate the light in the stage ?
if (LightStage::isIndexInvalid(_sunIndex)) { if (LightStage::isIndexInvalid(_sunIndex)) {
_sunIndex = _stage->addLight(_sunLight); _sunIndex = _stage->addLight(_sunLight);
} else { } else {
@ -107,9 +105,7 @@ void ZoneEntityRenderer::doRender(RenderArgs* args) {
{ // Ambient { // Ambient
updateAmbientMap(); updateAmbientMap();
// Need an update ?
if (_needAmbientUpdate) { if (_needAmbientUpdate) {
// Do we need to allocate the light in the stage ?
if (LightStage::isIndexInvalid(_ambientIndex)) { if (LightStage::isIndexInvalid(_ambientIndex)) {
_ambientIndex = _stage->addLight(_ambientLight); _ambientIndex = _stage->addLight(_ambientLight);
} else { } else {
@ -123,7 +119,7 @@ void ZoneEntityRenderer::doRender(RenderArgs* args) {
updateSkyboxMap(); updateSkyboxMap();
if (_needBackgroundUpdate) { if (_needBackgroundUpdate) {
if (_skyboxMode == COMPONENT_MODE_ENABLED && BackgroundStage::isIndexInvalid(_backgroundIndex)) { if (BackgroundStage::isIndexInvalid(_backgroundIndex)) {
_backgroundIndex = _backgroundStage->addBackground(_background); _backgroundIndex = _backgroundStage->addBackground(_background);
} }
_needBackgroundUpdate = false; _needBackgroundUpdate = false;
@ -186,24 +182,19 @@ void ZoneEntityRenderer::doRender(RenderArgs* args) {
} }
} }
void ZoneEntityRenderer::removeFromScene(const ScenePointer& scene, Transaction& transaction) {
#if 0
if (_model) {
_model->removeFromScene(scene, transaction);
}
#endif
Parent::removeFromScene(scene, transaction);
}
void ZoneEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { void ZoneEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) {
DependencyManager::get<EntityTreeRenderer>()->updateZone(entity->getID());
auto position = entity->getWorldPosition(); auto position = entity->getWorldPosition();
auto rotation = entity->getWorldOrientation(); auto rotation = entity->getWorldOrientation();
auto dimensions = entity->getScaledDimensions(); auto dimensions = entity->getScaledDimensions();
bool rotationChanged = rotation != _lastRotation; bool rotationChanged = rotation != _lastRotation;
bool transformChanged = rotationChanged || position != _lastPosition || dimensions != _lastDimensions; bool transformChanged = rotationChanged || position != _lastPosition || dimensions != _lastDimensions;
auto visible = entity->getVisible();
if (transformChanged || visible != _lastVisible) {
_lastVisible = visible;
DependencyManager::get<EntityTreeRenderer>()->updateZone(entity->getID());
}
auto proceduralUserData = entity->getUserData(); auto proceduralUserData = entity->getUserData();
bool proceduralUserDataChanged = _proceduralUserData != proceduralUserData; bool proceduralUserDataChanged = _proceduralUserData != proceduralUserData;
@ -226,25 +217,6 @@ void ZoneEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scen
_proceduralUserData = entity->getUserData(); _proceduralUserData = entity->getUserData();
} }
#if 0
if (_lastShapeURL != _typedEntity->getCompoundShapeURL()) {
_lastShapeURL = _typedEntity->getCompoundShapeURL();
_model.reset();
_model = std::make_shared<Model>();
_model->setIsWireframe(true);
_model->init();
_model->setURL(_lastShapeURL);
}
if (_model && _model->isActive()) {
_model->setScaleToFit(true, _lastDimensions);
_model->setSnapModelToRegistrationPoint(true, _entity->getRegistrationPoint());
_model->setRotation(_lastRotation);
_model->setTranslation(_lastPosition);
_model->simulate(0.0f);
}
#endif
updateKeyZoneItemFromEntity(entity); updateKeyZoneItemFromEntity(entity);
if (keyLightChanged) { if (keyLightChanged) {
@ -296,6 +268,10 @@ ItemKey ZoneEntityRenderer::getKey() {
} }
bool ZoneEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { bool ZoneEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const {
if (entity->getVisible() != _lastVisible) {
return true;
}
if (entity->keyLightPropertiesChanged() || if (entity->keyLightPropertiesChanged() ||
entity->ambientLightPropertiesChanged() || entity->ambientLightPropertiesChanged() ||
entity->hazePropertiesChanged() || entity->hazePropertiesChanged() ||
@ -323,25 +299,7 @@ bool ZoneEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoint
return true; return true;
} }
#if 0 // FIXME: do we need to trigger an update when shapeType changes? see doRenderUpdateAsynchronousTyped
if (_typedEntity->getCompoundShapeURL() != _lastShapeURL) {
return true;
}
if (_model) {
if (!_model->needsFixupInScene() && (!ZoneEntityItem::getDrawZoneBoundaries() || _entity->getShapeType() != SHAPE_TYPE_COMPOUND)) {
return true;
}
if (_model->needsFixupInScene() && (ZoneEntityItem::getDrawZoneBoundaries() || _entity->getShapeType() == SHAPE_TYPE_COMPOUND)) {
return true;
}
if (_lastModelActive != _model->isActive()) {
return true;
}
}
#endif
return false; return false;
} }
@ -450,7 +408,6 @@ void ZoneEntityRenderer::updateKeyZoneItemFromEntity(const TypedEntityPointer& e
} }
void ZoneEntityRenderer::setAmbientURL(const QString& ambientUrl) { void ZoneEntityRenderer::setAmbientURL(const QString& ambientUrl) {
// nothing change if nothing change
if (_ambientTextureURL == ambientUrl) { if (_ambientTextureURL == ambientUrl) {
return; return;
} }
@ -466,8 +423,6 @@ void ZoneEntityRenderer::setAmbientURL(const QString& ambientUrl) {
_pendingAmbientTexture = true; _pendingAmbientTexture = true;
auto textureCache = DependencyManager::get<TextureCache>(); auto textureCache = DependencyManager::get<TextureCache>();
_ambientTexture = textureCache->getTexture(_ambientTextureURL, image::TextureUsage::AMBIENT_TEXTURE); _ambientTexture = textureCache->getTexture(_ambientTextureURL, image::TextureUsage::AMBIENT_TEXTURE);
// keep whatever is assigned on the ambient map/sphere until texture is loaded
} }
} }
@ -492,7 +447,6 @@ void ZoneEntityRenderer::updateAmbientMap() {
} }
void ZoneEntityRenderer::setSkyboxURL(const QString& skyboxUrl) { void ZoneEntityRenderer::setSkyboxURL(const QString& skyboxUrl) {
// nothing change if nothing change
if (_skyboxTextureURL == skyboxUrl) { if (_skyboxTextureURL == skyboxUrl) {
return; return;
} }

View file

@ -24,9 +24,6 @@
#include "RenderableEntityItem.h" #include "RenderableEntityItem.h"
#include <ComponentMode.h> #include <ComponentMode.h>
#if 0
#include <Model.h>
#endif
namespace render { namespace entities { namespace render { namespace entities {
class ZoneEntityRenderer : public TypedEntityRenderer<ZoneEntityItem> { class ZoneEntityRenderer : public TypedEntityRenderer<ZoneEntityItem> {
@ -40,7 +37,6 @@ protected:
virtual void onRemoveFromSceneTyped(const TypedEntityPointer& entity) override; virtual void onRemoveFromSceneTyped(const TypedEntityPointer& entity) override;
virtual ItemKey getKey() override; virtual ItemKey getKey() override;
virtual void doRender(RenderArgs* args) override; virtual void doRender(RenderArgs* args) override;
virtual void removeFromScene(const ScenePointer& scene, Transaction& transaction) override;
virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override; virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override;
virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override; virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override;
virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override; virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override;
@ -76,14 +72,7 @@ private:
glm::vec3 _lastPosition; glm::vec3 _lastPosition;
glm::vec3 _lastDimensions; glm::vec3 _lastDimensions;
glm::quat _lastRotation; glm::quat _lastRotation;
bool _lastVisible;
// FIXME compount shapes are currently broken
// FIXME draw zone boundaries are currently broken (also broken in master)
#if 0
ModelPointer _model;
bool _lastModelActive { false };
QString _lastShapeURL;
#endif
LightStagePointer _stage; LightStagePointer _stage;
const graphics::LightPointer _sunLight { std::make_shared<graphics::Light>() }; const graphics::LightPointer _sunLight { std::make_shared<graphics::Light>() };
@ -137,25 +126,4 @@ private:
} } // namespace } } // namespace
#if 0
class NetworkGeometry;
class KeyLightPayload;
class RenderableZoneEntityItemMeta;
class RenderableZoneEntityItem : public ZoneEntityItem, public RenderableEntityInterface {
public:
virtual bool contains(const glm::vec3& point) const override;
virtual bool addToScene(const EntityItemPointer& self, const render::ScenePointer& scene, render::Transaction& transaction) override;
virtual void removeFromScene(const EntityItemPointer& self, const render::ScenePointer& scene, render::Transaction& transaction) override;
private:
virtual void locationChanged(bool tellPhysics = true, bool tellChildren = true) override { EntityItem::locationChanged(tellPhysics, tellChildren); notifyBoundChanged(); }
virtual void dimensionsChanged() override { EntityItem::dimensionsChanged(); notifyBoundChanged(); }
void notifyBoundChanged();
void notifyChangedRenderItem();
void sceneUpdateRenderItemFromEntity(render::Transaction& transaction);
};
#endif
#endif // hifi_RenderableZoneEntityItem_h #endif // hifi_RenderableZoneEntityItem_h

View file

@ -43,7 +43,9 @@ const Selection::Name ZoneRendererTask::ZONES_SELECTION { "RankedZones" };
void ZoneRendererTask::build(JobModel& task, const Varying& input, Varying& output) { void ZoneRendererTask::build(JobModel& task, const Varying& input, Varying& output) {
// Filter out the sorted list of zones // Filter out the sorted list of zones
const auto zoneItems = task.addJob<render::SelectSortItems>("FilterZones", input, ZONES_SELECTION.c_str()); // FIXME: the zones in the selection are already sorted, but we're doing another sort here to pick the selected items
// out of `input`, which means we're also looping over the inItems an extra time.
const auto zoneItems = task.addJob<render::SelectSortItems>("FilterZones", input, ZONES_SELECTION);
// just setup the current zone env // just setup the current zone env
task.addJob<SetupZones>("SetupZones", zoneItems); task.addJob<SetupZones>("SetupZones", zoneItems);

View file

@ -287,12 +287,7 @@ void Scene::processTransactionFrame(const Transaction& transaction) {
_numAllocatedItems.exchange(maxID); _numAllocatedItems.exchange(maxID);
} }
if (transaction.touchTransactions()) {
std::unique_lock<std::mutex> lock(_selectionsMutex);
// resets and potential NEW items
resetSelections(transaction._resetSelections); resetSelections(transaction._resetSelections);
}
resetHighlights(transaction._highlightResets); resetHighlights(transaction._highlightResets);
removeHighlights(transaction._highlightRemoves); removeHighlights(transaction._highlightRemoves);
@ -581,35 +576,34 @@ void Scene::resetItemTransition(ItemID itemId) {
} }
} }
// This function is thread safe
Selection Scene::getSelection(const Selection::Name& name) const { Selection Scene::getSelection(const Selection::Name& name) const {
std::unique_lock<std::mutex> lock(_selectionsMutex); std::unique_lock<std::mutex> lock(_selectionsMutex);
auto found = _selections.find(name); auto found = _selections.find(name);
if (found == _selections.end()) { if (found == _selections.end()) {
return Selection(); return Selection();
} else { } else {
return (*found).second; return found->second;
} }
} }
// This function is thread safe
bool Scene::isSelectionEmpty(const Selection::Name& name) const { bool Scene::isSelectionEmpty(const Selection::Name& name) const {
std::unique_lock<std::mutex> lock(_selectionsMutex); std::unique_lock<std::mutex> lock(_selectionsMutex);
auto found = _selections.find(name); auto found = _selections.find(name);
if (found == _selections.end()) { if (found == _selections.end()) {
return true; return true;
} else { } else {
return (*found).second.isEmpty(); return found->second.isEmpty();
} }
} }
void Scene::resetSelections(const Transaction::SelectionResets& transactions) { void Scene::resetSelections(const Transaction::SelectionResets& transactions) {
std::unique_lock<std::mutex> lock(_selectionsMutex);
for (auto selection : transactions) { for (auto selection : transactions) {
auto found = _selections.find(selection.getName()); auto found = _selections.find(selection.getName());
if (found == _selections.end()) { if (found == _selections.end()) {
_selections.insert(SelectionMap::value_type(selection.getName(), selection)); _selections[selection.getName()] = selection;
} else { } else {
(*found).second = selection; found->second = selection;
} }
} }
} }

View file

@ -78,9 +78,6 @@ public:
void merge(Transaction&& transaction); void merge(Transaction&& transaction);
void clear(); void clear();
// Checkers if there is work to do when processing the transaction
bool touchTransactions() const { return !_resetSelections.empty(); }
protected: protected:
using Reset = std::tuple<ItemID, PayloadPointer>; using Reset = std::tuple<ItemID, PayloadPointer>;

View file

@ -45,9 +45,8 @@ namespace render {
Name _name; Name _name;
ItemIDs _items; ItemIDs _items;
}; };
using Selections = std::vector<Selection>;
using SelectionMap = std::map<const Selection::Name, Selection>; using SelectionMap = std::unordered_map<Selection::Name, Selection>;
} }