From 635f58629a4310214ab0d1f70273f93dea7c5aa7 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Thu, 31 Mar 2016 14:58:25 -0700 Subject: [PATCH 1/3] MeshPartPayload: remove dead code --- .../render-utils/src/MeshPartPayload.cpp | 20 ------------------- 1 file changed, 20 deletions(-) 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); From bc967f0ab0d12fc69b44575d0461ec1eb3661231 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Thu, 31 Mar 2016 14:59:27 -0700 Subject: [PATCH 2/3] Model: update renderItems when items are added to the scene. * Renamed enqueueLocationChange to updateRenderItems * Call updateRenderItems when models are added to the scene. This will fix entity render bounds being incorrect when they are first added to the scene, then later being correct after a position update. * Renamed getMeshPartBound to getRenderableMeshBound. * Avatar now uses getRenderableMeshBound() to do boundingRadius vs frustum check. * Model::getRenderableMeshBound now returns a more accurate bound, because it is the same one used for rendering. This will fix avatar freezing, when they are in the corner of your frustum. This was due to matrices not being updated because the avatar had to a small bounding sphere. --- interface/src/avatar/Avatar.cpp | 2 +- libraries/render-utils/src/Model.cpp | 63 +++++++--------------------- libraries/render-utils/src/Model.h | 4 +- 3 files changed, 16 insertions(+), 53 deletions(-) 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 From d670853941c8ec0d2b39a9fdfdb1923658729ef6 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Thu, 31 Mar 2016 16:10:04 -0700 Subject: [PATCH 3/3] AnimDebugDraw: enable bound now that culling works. :) --- libraries/render-utils/src/AnimDebugDraw.cpp | 6 ------ 1 file changed, 6 deletions(-) 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++) {