diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 3417011051..64a2388a42 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -141,7 +141,7 @@ AABox Avatar::getBounds() const { if (!_skeletonModel->isRenderable()) { return AABox(getPosition(), getUniformScale()); // approximately 2m tall, scaled to user request. } - return _skeletonModel->getPartBounds(0, 0, getPosition(), getOrientation()); + return _skeletonModel->getRenderableMeshBound(); } void Avatar::animateScaleChanges(float deltaTime) { diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 0bd2687169..e11ab2b9d5 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -94,12 +94,12 @@ bool Model::needsFixupInScene() const { void Model::setTranslation(const glm::vec3& translation) { _translation = translation; - enqueueLocationChange(); + updateRenderItems(); } void Model::setRotation(const glm::quat& rotation) { _rotation = rotation; - enqueueLocationChange(); + updateRenderItems(); } void Model::setScale(const glm::vec3& scale) { @@ -129,7 +129,7 @@ void Model::setOffset(const glm::vec3& offset) { _snappedToRegistrationPoint = false; } -void Model::enqueueLocationChange() { +void Model::updateRenderItems() { _needsUpdateClusterMatrices = true; @@ -560,9 +560,6 @@ bool Model::addToScene(std::shared_ptr scene, render::PendingChan auto item = scene->allocateID(); auto renderPayload = std::make_shared(renderItem); pendingChanges.resetItem(item, renderPayload); - pendingChanges.updateItem(item, [](ModelMeshPartPayload& data) { - data.notifyLocationChanged(); - }); _modelMeshRenderItems.insert(item, renderPayload); somethingAdded = true; } @@ -571,13 +568,11 @@ bool Model::addToScene(std::shared_ptr scene, render::PendingChan auto item = scene->allocateID(); auto renderPayload = std::make_shared(renderItem); pendingChanges.resetItem(item, renderPayload); - pendingChanges.updateItem(item, [](MeshPartPayload& data) { - data.notifyLocationChanged(); - }); _collisionRenderItems.insert(item, renderPayload); somethingAdded = true; } + updateRenderItems(); _readyWhenAdded = readyToAddToScene(); return somethingAdded; @@ -599,9 +594,6 @@ bool Model::addToScene(std::shared_ptr scene, auto renderPayload = std::make_shared(renderItem); renderPayload->addStatusGetters(statusGetters); pendingChanges.resetItem(item, renderPayload); - pendingChanges.updateItem(item, [](ModelMeshPartPayload& data) { - data.notifyLocationChanged(); - }); _modelMeshRenderItems.insert(item, renderPayload); somethingAdded = true; } @@ -611,13 +603,12 @@ bool Model::addToScene(std::shared_ptr scene, auto renderPayload = std::make_shared(renderItem); renderPayload->addStatusGetters(statusGetters); pendingChanges.resetItem(item, renderPayload); - pendingChanges.updateItem(item, [](MeshPartPayload& data) { - data.notifyLocationChanged(); - }); _collisionRenderItems.insert(item, renderPayload); somethingAdded = true; } + updateRenderItems(); + _readyWhenAdded = readyToAddToScene(); return somethingAdded; @@ -1185,38 +1176,17 @@ void Model::deleteGeometry() { _blendedBlendshapeCoefficients.clear(); } -AABox Model::getPartBounds(int meshIndex, int partIndex, glm::vec3 modelPosition, glm::quat modelOrientation) const { - +AABox Model::getRenderableMeshBound() const { if (!isLoaded()) { return AABox(); - } - - if (meshIndex < _meshStates.size()) { - const MeshState& state = _meshStates.at(meshIndex); - bool isSkinned = state.clusterMatrices.size() > 1; - if (isSkinned) { - // if we're skinned return the entire mesh extents because we can't know for sure our clusters don't move us - return calculateScaledOffsetAABox(getFBXGeometry().meshExtents, modelPosition, modelOrientation); + } else { + // Build a bound using the last known bound from all the renderItems. + AABox totalBound; + for (auto& renderItem : _modelMeshRenderItemsSet) { + totalBound += renderItem->getBound(); } + return totalBound; } - if (getFBXGeometry().meshes.size() > meshIndex) { - - // FIX ME! - This is currently a hack because for some mesh parts our efforts to calculate the bounding - // box of the mesh part fails. It seems to create boxes that are not consistent with where the - // geometry actually renders. If instead we make all the parts share the bounds of the entire subMesh - // things will render properly. - // - // return calculateScaledOffsetAABox(_calculatedMeshPartBoxes[QPair(meshIndex, partIndex)]); - // - // NOTE: we also don't want to use the _calculatedMeshBoxes[] because they don't handle avatar moving correctly - // without recalculating them... - // return _calculatedMeshBoxes[meshIndex]; - // - // If we not skinned use the bounds of the subMesh for all it's parts - const FBXMesh& mesh = getFBXGeometry().meshes.at(meshIndex); - return calculateScaledOffsetExtents(mesh.meshExtents, modelPosition, modelOrientation); - } - return AABox(); } void Model::segregateMeshGroups() { @@ -1308,20 +1278,15 @@ bool Model::initWhenReady(render::ScenePointer scene) { auto renderPayload = std::make_shared(renderItem); _modelMeshRenderItems.insert(item, renderPayload); pendingChanges.resetItem(item, renderPayload); - pendingChanges.updateItem(item, [transform, offset](MeshPartPayload& data) { - data.notifyLocationChanged(); - }); } foreach (auto renderItem, _collisionRenderItemsSet) { auto item = scene->allocateID(); auto renderPayload = std::make_shared(renderItem); _collisionRenderItems.insert(item, renderPayload); pendingChanges.resetItem(item, renderPayload); - pendingChanges.updateItem(item, [transform, offset](MeshPartPayload& data) { - data.notifyLocationChanged(); - }); } scene->enqueuePendingChanges(pendingChanges); + updateRenderItems(); _readyWhenAdded = true; return true; diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index e4a8fa3b36..20b5bbf9e6 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -99,7 +99,7 @@ public: bool isVisible() const { return _isVisible; } void updateRenderItems(); - AABox getPartBounds(int meshIndex, int partIndex, glm::vec3 modelPosition, glm::quat modelOrientation) const; + AABox getRenderableMeshBound() const; bool maybeStartBlender(); @@ -207,8 +207,6 @@ public: void setScale(const glm::vec3& scale); const glm::vec3& getScale() const { return _scale; } - void enqueueLocationChange(); - /// enables/disables scale to fit behavior, the model will be automatically scaled to the specified largest dimension bool getIsScaledToFit() const { return _scaledToFit; } /// is model scaled to fit glm::vec3 getScaleToFitDimensions() const; /// the dimensions model is scaled to, including inferred y/z