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/AnimDebugDraw.cpp b/libraries/render-utils/src/AnimDebugDraw.cpp index a0f7d7eca1..e2abc226e5 100644 --- a/libraries/render-utils/src/AnimDebugDraw.cpp +++ b/libraries/render-utils/src/AnimDebugDraw.cpp @@ -392,20 +392,14 @@ void AnimDebugDraw::update() { assert(numVerts == (v - verts)); - // The RenderItem culling is not working correctly - // Workaround this issue by using the default constructed - // item._bound which is a 16 km cube. - /* render::Item::Bound theBound; for (int i = 0; i < numVerts; i++) { theBound += verts[i].pos; } data._bound = theBound; - */ data._isVisible = (numVerts > 0); - data._indexBuffer->resize(sizeof(uint16_t) * numVerts); uint16_t* indices = (uint16_t*)data._indexBuffer->editData(); for (int i = 0; i < numVerts; i++) { diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index d295b07caf..102aada9cb 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -520,26 +520,6 @@ void ModelMeshPartPayload::render(RenderArgs* args) const { return; } - // render the part bounding box -#ifdef DEBUG_BOUNDING_PARTS - { - AABox partBounds = getPartBounds(_meshIndex, partIndex); - - glm::vec4 cubeColor(1.0f, 1.0f, 0.0f, 1.0f); - if (isSkinned) { - cubeColor = glm::vec4(0.0f, 1.0f, 1.0f, 1.0f); - } else if (args->_viewFrustum->boxIntersectsFrustum(partBounds)) { - cubeColor = glm::vec4(1.0f, 0.0f, 1.0f, 1.0f); - } - - Transform transform; - transform.setTranslation(partBounds.calcCenter()); - transform.setScale(partBounds.getDimensions()); - batch.setModelTransform(transform); - DependencyManager::get()->renderWireCube(batch, 1.0f, cubeColor); - } -#endif //def DEBUG_BOUNDING_PARTS - auto locations = args->_pipeline->locations; assert(locations); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 3a5928f3d1..858f7d3ee7 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -89,12 +89,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) { @@ -124,7 +124,7 @@ void Model::setOffset(const glm::vec3& offset) { _snappedToRegistrationPoint = false; } -void Model::enqueueLocationChange() { +void Model::updateRenderItems() { _needsUpdateClusterMatrices = true; @@ -552,50 +552,33 @@ bool Model::addToScene(std::shared_ptr scene, bool somethingAdded = false; - if (_modelMeshRenderItems.size()) { - for (auto item : _modelMeshRenderItems.keys()) { - pendingChanges.updateItem(item, [](ModelMeshPartPayload& data) { - data.notifyLocationChanged(); - }); - } - } else { - for (auto renderItem : _modelMeshRenderItemsSet) { + if (_modelMeshRenderItems.empty()) { + foreach (auto renderItem, _modelMeshRenderItemsSet) { auto item = scene->allocateID(); auto renderPayload = std::make_shared(renderItem); if (statusGetters.size()) { renderPayload->addStatusGetters(statusGetters); } pendingChanges.resetItem(item, renderPayload); - pendingChanges.updateItem(item, [](ModelMeshPartPayload& data) { - data.notifyLocationChanged(); - }); _modelMeshRenderItems.insert(item, renderPayload); somethingAdded = true; } } - - if (_collisionRenderItems.size()) { - for (auto item : _collisionRenderItems.keys()) { - pendingChanges.updateItem(item, [](MeshPartPayload& data) { - data.notifyLocationChanged(); - }); - } - } else { - for (auto renderItem : _collisionRenderItemsSet) { + if (_collisionRenderItems.empty()) { + foreach (auto renderItem, _collisionRenderItemsSet) { auto item = scene->allocateID(); auto renderPayload = std::make_shared(renderItem); if (statusGetters.size()) { 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; @@ -1169,38 +1152,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() { @@ -1292,20 +1254,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 239d0e7c28..4e6e727b44 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -102,7 +102,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(); @@ -213,8 +213,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