diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index c4ac9b09e5..a537ecd0f3 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -162,6 +162,19 @@ void RenderableModelEntityItem::remapTextures() { } } +void RenderableModelEntityItem::doInitialModelSimulation() { + _model->setScaleToFit(true, getDimensions()); + _model->setSnapModelToRegistrationPoint(true, getRegistrationPoint()); + _model->setRotation(getRotation()); + _model->setTranslation(getPosition()); + { + PerformanceTimer perfTimer("_model->simulate"); + _model->simulate(0.0f); + } + _needsInitialSimulation = false; +} + + // TODO: we need a solution for changes to the postion/rotation/etc of a model... // this current code path only addresses that in this setup case... not the changing/moving case bool RenderableModelEntityItem::readyToAddToScene(RenderArgs* renderArgs) { @@ -172,22 +185,12 @@ bool RenderableModelEntityItem::readyToAddToScene(RenderArgs* renderArgs) { getModel(renderer); } if (renderArgs && _model && _needsInitialSimulation && _model->isActive() && _model->isLoaded()) { - _model->setScaleToFit(true, getDimensions()); - _model->setSnapModelToRegistrationPoint(true, getRegistrationPoint()); - _model->setRotation(getRotation()); - _model->setTranslation(getPosition()); - // make sure to simulate so everything gets set up correctly for rendering - { - PerformanceTimer perfTimer("_model->simulate"); - _model->simulate(0.0f); - } - _needsInitialSimulation = false; - + doInitialModelSimulation(); _model->renderSetup(renderArgs); } bool ready = !_needsInitialSimulation && _model && _model->readyToAddToScene(renderArgs); - return ready; + return ready; } class RenderableModelEntityItemMeta { @@ -348,18 +351,7 @@ void RenderableModelEntityItem::updateModelBounds() { _model->getRotation() != getRotation() || _model->getRegistrationPoint() != getRegistrationPoint()) && _model->isActive() && _dimensionsInitialized) { - _model->setScaleToFit(true, dimensions); - _model->setSnapModelToRegistrationPoint(true, getRegistrationPoint()); - _model->setRotation(getRotation()); - _model->setTranslation(getPosition()); - - // make sure to simulate so everything gets set up correctly for rendering - { - PerformanceTimer perfTimer("_model->simulate"); - _model->simulate(0.0f); - } - - _needsInitialSimulation = false; + doInitialModelSimulation(); _needsJointSimulation = false; } } @@ -592,8 +584,7 @@ bool RenderableModelEntityItem::isReadyToComputeShape() { if (_needsInitialSimulation) { // the _model's offset will be wrong until _needsInitialSimulation is false PerformanceTimer perfTimer("_model->simulate"); - _model->simulate(0.0f); - _needsInitialSimulation = false; + doInitialModelSimulation(); } return true; @@ -807,6 +798,29 @@ void RenderableModelEntityItem::locationChanged(bool tellPhysics) { if (_model && _model->isActive()) { _model->setRotation(getRotation()); _model->setTranslation(getPosition()); + + void* key = (void*)this; + std::weak_ptr weakSelf = + std::static_pointer_cast(getThisPointer()); + + AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [weakSelf]() { + auto self = weakSelf.lock(); + if (!self) { + return; + } + + render::ItemID myMetaItem = self->getMetaRenderItem(); + + if (myMetaItem == render::Item::INVALID_ITEM_ID) { + return; + } + + render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene(); + render::PendingChanges pendingChanges; + + pendingChanges.updateItem(myMetaItem); + scene->enqueuePendingChanges(pendingChanges); + }); } } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 59208d209d..d2de45f538 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -38,6 +38,8 @@ public: EntityPropertyFlags& propertyFlags, bool overwriteLocalData, bool& somethingChanged) override; + void doInitialModelSimulation(); + virtual bool readyToAddToScene(RenderArgs* renderArgs = nullptr); virtual bool addToScene(EntityItemPointer self, std::shared_ptr scene, render::PendingChanges& pendingChanges) override; virtual void removeFromScene(EntityItemPointer self, std::shared_ptr scene, render::PendingChanges& pendingChanges) override; @@ -87,6 +89,8 @@ public: bool hasRenderAnimation() const { return !_renderAnimationProperties.getURL().isEmpty(); } const QString& getRenderAnimationURL() const { return _renderAnimationProperties.getURL(); } + render::ItemID getMetaRenderItem() { return _myMetaItem; } + private: QVariantMap parseTexturesToMap(QString textures); void remapTextures(); diff --git a/libraries/entities/src/UpdateEntityOperator.cpp b/libraries/entities/src/UpdateEntityOperator.cpp index 94599496b0..84f801b059 100644 --- a/libraries/entities/src/UpdateEntityOperator.cpp +++ b/libraries/entities/src/UpdateEntityOperator.cpp @@ -23,7 +23,6 @@ UpdateEntityOperator::UpdateEntityOperator(EntityTreePointer tree, _foundOld(false), _foundNew(false), _removeOld(false), - _dontMove(false), // assume we'll be moving _changeTime(usecTimestampNow()), _oldEntityCube(), _newEntityCube(), @@ -43,32 +42,23 @@ UpdateEntityOperator::UpdateEntityOperator(EntityTreePointer tree, _oldEntityCube = _existingEntity->getQueryAACube(); _oldEntityBox = _oldEntityCube.clamp((float)-HALF_TREE_SCALE, (float)HALF_TREE_SCALE); // clamp to domain bounds - // If our new properties don't have bounds details (no change to position, etc) or if this containing element would - // be the best fit for our new properties, then just do the new portion of the store pass, since the change path will - // be the same for both parts of the update - bool oldElementBestFit = _containingElement->bestFitBounds(newQueryAACube); + _newEntityCube = newQueryAACube; + _newEntityBox = _newEntityCube.clamp((float)-HALF_TREE_SCALE, (float)HALF_TREE_SCALE); // clamp to domain bounds + + // set oldElementBestFit true if the entity was in the correct element before this operator was run. + bool oldElementBestFit = _containingElement->bestFitBounds(_oldEntityBox); // For some reason we've seen a case where the original containing element isn't a best fit for the old properties // in this case we want to move it, even if the properties haven't changed. if (!oldElementBestFit) { - _newEntityCube = _oldEntityCube; + _oldEntityBox = _existingEntity->getElement()->getAACube(); _removeOld = true; // our properties are going to move us, so remember this for later processing if (_wantDebug) { - qCDebug(entities) << " **** UNUSUAL CASE **** no changes, but not best fit... consider it a move.... **"; - } - } else { - _foundOld = true; - _newEntityCube = _oldEntityCube; - _dontMove = true; - - if (_wantDebug) { - qCDebug(entities) << " **** TYPICAL NO MOVE CASE **** oldElementBestFit:" << oldElementBestFit; + qCDebug(entities) << " **** UNUSUAL CASE **** not best fit.... **"; } } - _newEntityBox = _newEntityCube.clamp((float)-HALF_TREE_SCALE, (float)HALF_TREE_SCALE); // clamp to domain bounds - if (_wantDebug) { qCDebug(entities) << " _entityItemID:" << _entityItemID; qCDebug(entities) << " _containingElementCube:" << _containingElementCube; diff --git a/libraries/entities/src/UpdateEntityOperator.h b/libraries/entities/src/UpdateEntityOperator.h index ea6faabe3e..8b5bbdf135 100644 --- a/libraries/entities/src/UpdateEntityOperator.h +++ b/libraries/entities/src/UpdateEntityOperator.h @@ -37,7 +37,6 @@ private: bool _foundOld; bool _foundNew; bool _removeOld; - bool _dontMove; quint64 _changeTime; AACube _oldEntityCube; diff --git a/libraries/render/src/render/Scene.cpp b/libraries/render/src/render/Scene.cpp index e091b4842c..0b1d8fb55f 100644 --- a/libraries/render/src/render/Scene.cpp +++ b/libraries/render/src/render/Scene.cpp @@ -157,6 +157,11 @@ void Scene::updateItems(const ItemIDs& ids, UpdateFunctors& functors) { auto updateFunctor = functors.begin(); for (auto updateID : ids) { + if (updateID == Item::INVALID_ITEM_ID) { + updateFunctor++; + continue; + } + // Access the true item auto& item = _items[updateID]; auto oldCell = item.getCell();