From 56510abd1ebadf399ffb58a5aec1dba6622b1fcd Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 2 Nov 2017 03:45:27 -0700 Subject: [PATCH] Trying to set the ClusterBuffer in the render loop instead of the game loop --- .../src/avatars-renderer/Avatar.cpp | 3 +- .../src/CauterizedMeshPartPayload.cpp | 27 +++++++++- .../src/CauterizedMeshPartPayload.h | 2 + .../render-utils/src/CauterizedModel.cpp | 49 ++++++++++++++----- .../render-utils/src/MeshPartPayload.cpp | 17 ++++++- libraries/render-utils/src/MeshPartPayload.h | 1 + libraries/render-utils/src/Model.cpp | 35 +++++++++---- .../render-utils/src/SoftAttachmentModel.cpp | 4 +- 8 files changed, 112 insertions(+), 26 deletions(-) diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index f9f2fd868a..bbd0110c11 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -730,8 +730,9 @@ void Avatar::simulateAttachments(float deltaTime) { // soft attachments do not have transform offsets // model->setTranslation(getPosition()); // model->setRotation(getOrientation() * Quaternions::Y_180); - model->setTransformNoUpdateRenderItems(Transform(getOrientation() * Quaternions::Y_180, glm::vec3(1.0), getPosition()); + model->setTransformNoUpdateRenderItems(Transform(getOrientation() * Quaternions::Y_180, glm::vec3(1.0), getPosition())); model->simulate(deltaTime); + model->updateRenderItems(); } else { if (_skeletonModel->getJointPositionInWorldFrame(jointIndex, jointPosition) && _skeletonModel->getJointRotationInWorldFrame(jointIndex, jointRotation)) { diff --git a/libraries/render-utils/src/CauterizedMeshPartPayload.cpp b/libraries/render-utils/src/CauterizedMeshPartPayload.cpp index 07628904f1..068eb03378 100644 --- a/libraries/render-utils/src/CauterizedMeshPartPayload.cpp +++ b/libraries/render-utils/src/CauterizedMeshPartPayload.cpp @@ -20,11 +20,36 @@ using namespace render; CauterizedMeshPartPayload::CauterizedMeshPartPayload(ModelPointer model, int meshIndex, int partIndex, int shapeIndex, const Transform& transform, const Transform& offsetTransform) : ModelMeshPartPayload(model, meshIndex, partIndex, shapeIndex, transform, offsetTransform) {} +void CauterizedMeshPartPayload::updateClusterBuffer(const QVector& clusterMatrices, const QVector& cauterizedClusterMatrices) { + + // Once computed the cluster matrices, update the buffer(s) + if (clusterMatrices.size() > 1) { + if (!_clusterBuffer) { + _clusterBuffer = std::make_shared(clusterMatrices.size() * sizeof(glm::mat4), + (const gpu::Byte*) clusterMatrices.constData()); + } else { + _clusterBuffer->setSubData(0, clusterMatrices.size() * sizeof(glm::mat4), + (const gpu::Byte*) clusterMatrices.constData()); + } + } + + if (cauterizedClusterMatrices.size() > 1) { + if (!_cauterizedClusterBuffer) { + _cauterizedClusterBuffer = std::make_shared(cauterizedClusterMatrices.size() * sizeof(glm::mat4), + (const gpu::Byte*) cauterizedClusterMatrices.constData()); + } + else { + _cauterizedClusterBuffer->setSubData(0, clusterMatrices.size() * sizeof(glm::mat4), + (const gpu::Byte*) clusterMatrices.constData()); + } + } +} + void CauterizedMeshPartPayload::updateTransformForCauterizedMesh( const Transform& renderTransform, const gpu::BufferPointer& buffer) { _cauterizedTransform = renderTransform; - _cauterizedClusterBuffer = buffer; + // _cauterizedClusterBuffer = buffer; } void CauterizedMeshPartPayload::bindTransform(gpu::Batch& batch, const render::ShapePipeline::LocationsPointer locations, RenderArgs::RenderMode renderMode) const { diff --git a/libraries/render-utils/src/CauterizedMeshPartPayload.h b/libraries/render-utils/src/CauterizedMeshPartPayload.h index 5e3135ea84..4bd20461eb 100644 --- a/libraries/render-utils/src/CauterizedMeshPartPayload.h +++ b/libraries/render-utils/src/CauterizedMeshPartPayload.h @@ -15,6 +15,8 @@ class CauterizedMeshPartPayload : public ModelMeshPartPayload { public: CauterizedMeshPartPayload(ModelPointer model, int meshIndex, int partIndex, int shapeIndex, const Transform& transform, const Transform& offsetTransform); + void updateClusterBuffer(const QVector& clusterMatrices, const QVector& cauterizedClusterMatrices); + void updateTransformForCauterizedMesh(const Transform& renderTransform, const gpu::BufferPointer& buffer); void bindTransform(gpu::Batch& batch, const render::ShapePipeline::LocationsPointer locations, RenderArgs::RenderMode renderMode) const override; diff --git a/libraries/render-utils/src/CauterizedModel.cpp b/libraries/render-utils/src/CauterizedModel.cpp index 47ada457a0..28993dd4f0 100644 --- a/libraries/render-utils/src/CauterizedModel.cpp +++ b/libraries/render-utils/src/CauterizedModel.cpp @@ -111,6 +111,7 @@ void CauterizedModel::updateClusterMatrices() { glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, state.clusterMatrices[j]); } + /* // Once computed the cluster matrices, update the buffer(s) if (mesh.clusters.size() > 1) { if (!state.clusterBuffer) { @@ -121,6 +122,7 @@ void CauterizedModel::updateClusterMatrices() { (const gpu::Byte*) state.clusterMatrices.constData()); } } + */ } // as an optimization, don't build cautrizedClusterMatrices if the boneSet is empty. @@ -143,7 +145,7 @@ void CauterizedModel::updateClusterMatrices() { } glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, state.clusterMatrices[j]); } - +/* if (!_cauterizeBoneSet.empty() && (state.clusterMatrices.size() > 1)) { if (!state.clusterBuffer) { state.clusterBuffer = @@ -153,7 +155,7 @@ void CauterizedModel::updateClusterMatrices() { state.clusterBuffer->setSubData(0, state.clusterMatrices.size() * sizeof(glm::mat4), (const gpu::Byte*) state.clusterMatrices.constData()); } - } + }*/ } } @@ -181,7 +183,7 @@ void CauterizedModel::updateRenderItems() { // queue up this work for later processing, at the end of update and just before rendering. // the application will ensure only the last lambda is actually invoked. void* key = (void*)this; - std::weak_ptr weakSelf = shared_from_this(); + std::weak_ptr weakSelf = std::dynamic_pointer_cast(shared_from_this()); AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [weakSelf, scale]() { // do nothing, if the model has already been destroyed. auto self = weakSelf.lock(); @@ -203,33 +205,58 @@ void CauterizedModel::updateRenderItems() { uint32_t deleteGeometryCounter = self->getGeometryCounter(); + if (!self->isLoaded()) { + return; + } render::Transaction transaction; QList keys = self->getRenderItems().keys(); + int meshIndex{ 0 }; foreach (auto itemID, keys) { - transaction.updateItem(itemID, [modelTransform, deleteGeometryCounter](CauterizedMeshPartPayload& data) { - ModelPointer model = data._model.lock(); - if (model && model->isLoaded()) { + const Model::MeshState& state = self->getMeshState(meshIndex); + auto clusterMatrices(state.clusterMatrices); + const Model::MeshState& cState = self->getCauterizeMeshState(meshIndex); + auto clusterMatricesCauterized(cState.clusterMatrices); + + transaction.updateItem(itemID, [modelTransform, deleteGeometryCounter, clusterMatrices, clusterMatricesCauterized](CauterizedMeshPartPayload& data) { + // ModelPointer model = data._model.lock(); + // if (model && model->isLoaded()) { // Ensure the model geometry was not reset between frames - if (deleteGeometryCounter == model->getGeometryCounter()) { + // if (deleteGeometryCounter == model->getGeometryCounter()) { + data.updateClusterBuffer(clusterMatrices, clusterMatricesCauterized); + // this stuff identical to what happens in regular Model - const Model::MeshState& state = model->getMeshState(data._meshIndex); + /*const Model::MeshState& state = model->getMeshState(data._meshIndex); Transform renderTransform = modelTransform; if (state.clusterMatrices.size() == 1) { renderTransform = modelTransform.worldTransform(Transform(state.clusterMatrices[0])); } data.updateTransformForSkinnedMesh(renderTransform, modelTransform, state.clusterBuffer); + */ + Transform renderTransform = modelTransform; + if (clusterMatrices.size() == 1) { + renderTransform = modelTransform.worldTransform(Transform(clusterMatrices[0])); + } + data.updateTransformForSkinnedMesh(renderTransform, modelTransform, nullptr); + // this stuff for cauterized mesh - CauterizedModel* cModel = static_cast(model.get()); + /*CauterizedModel* cModel = static_cast(model.get()); const Model::MeshState& cState = cModel->getCauterizeMeshState(data._meshIndex); renderTransform = modelTransform; if (cState.clusterMatrices.size() == 1) { renderTransform = modelTransform.worldTransform(Transform(cState.clusterMatrices[0])); } data.updateTransformForCauterizedMesh(renderTransform, cState.clusterBuffer); - } - } + */ + renderTransform = modelTransform; + if (clusterMatricesCauterized.size() == 1) { + renderTransform = modelTransform.worldTransform(Transform(clusterMatricesCauterized[0])); + } + data.updateTransformForCauterizedMesh(renderTransform, nullptr); + // } + // } }); + meshIndex++; } scene->enqueueTransaction(transaction); diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index 8b65c9f7ce..abb0d299e1 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -367,12 +367,27 @@ void ModelMeshPartPayload::notifyLocationChanged() { } + +void ModelMeshPartPayload::updateClusterBuffer(const QVector& clusterMatrices) { + // Once computed the cluster matrices, update the buffer(s) + if (clusterMatrices.size() > 1) { + if (!_clusterBuffer) { + _clusterBuffer = std::make_shared(clusterMatrices.size() * sizeof(glm::mat4), + (const gpu::Byte*) clusterMatrices.constData()); + } + else { + _clusterBuffer->setSubData(0, clusterMatrices.size() * sizeof(glm::mat4), + (const gpu::Byte*) clusterMatrices.constData()); + } + } +} + void ModelMeshPartPayload::updateTransformForSkinnedMesh(const Transform& renderTransform, const Transform& boundTransform, const gpu::BufferPointer& buffer) { _transform = renderTransform; _worldBound = _adjustedLocalBound; _worldBound.transform(boundTransform); - _clusterBuffer = buffer; + // _clusterBuffer = buffer; } ItemKey ModelMeshPartPayload::getKey() const { diff --git a/libraries/render-utils/src/MeshPartPayload.h b/libraries/render-utils/src/MeshPartPayload.h index 99c14510b5..0e8464f873 100644 --- a/libraries/render-utils/src/MeshPartPayload.h +++ b/libraries/render-utils/src/MeshPartPayload.h @@ -87,6 +87,7 @@ public: typedef Payload::DataPointer Pointer; void notifyLocationChanged() override; + void updateClusterBuffer(const QVector& clusterMatrices); void updateTransformForSkinnedMesh(const Transform& renderTransform, const Transform& boundTransform, const gpu::BufferPointer& buffer); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 97f62a3ce0..cbb27f0498 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -240,22 +240,37 @@ void Model::updateRenderItems() { uint32_t deleteGeometryCounter = self->_deleteGeometryCounter; render::Transaction transaction; + int meshIndex{ 0 }; foreach (auto itemID, self->_modelMeshRenderItemsMap.keys()) { - transaction.updateItem(itemID, [deleteGeometryCounter, modelTransform](ModelMeshPartPayload& data) { - ModelPointer model = data._model.lock(); - if (model && model->isLoaded()) { - // Ensure the model geometry was not reset between frames - if (deleteGeometryCounter == model->_deleteGeometryCounter) { + const Model::MeshState& state = self->getMeshState(meshIndex); + auto clusterMatrices(state.clusterMatrices); - const Model::MeshState& state = model->getMeshState(data._meshIndex); + transaction.updateItem(itemID, [deleteGeometryCounter, modelTransform, clusterMatrices](ModelMeshPartPayload& data) { + // ModelPointer model = data._model.lock(); + // if (model && model->isLoaded()) { + // Ensure the model geometry was not reset between frames + // if (deleteGeometryCounter == model->_deleteGeometryCounter) { + + /*const Model::MeshState& state = model->getMeshState(data._meshIndex); Transform renderTransform = modelTransform; if (state.clusterMatrices.size() == 1) { renderTransform = modelTransform.worldTransform(Transform(state.clusterMatrices[0])); } data.updateTransformForSkinnedMesh(renderTransform, modelTransform, state.clusterBuffer); - } - } + */ + + data.updateClusterBuffer(clusterMatrices); + + Transform renderTransform = modelTransform; + if (clusterMatrices.size() == 1) { + renderTransform = modelTransform.worldTransform(Transform(clusterMatrices[0])); + } + data.updateTransformForSkinnedMesh(renderTransform, modelTransform, nullptr); + + // } + // } }); + meshIndex++; } Transform collisionMeshOffset; @@ -1136,7 +1151,7 @@ void Model::updateClusterMatrices() { glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, state.clusterMatrices[j]); } - // Once computed the cluster matrices, update the buffer(s) + /* // Once computed the cluster matrices, update the buffer(s) if (mesh.clusters.size() > 1) { if (!state.clusterBuffer) { state.clusterBuffer = std::make_shared(state.clusterMatrices.size() * sizeof(glm::mat4), @@ -1145,7 +1160,7 @@ void Model::updateClusterMatrices() { state.clusterBuffer->setSubData(0, state.clusterMatrices.size() * sizeof(glm::mat4), (const gpu::Byte*) state.clusterMatrices.constData()); } - } + }*/ } // post the blender if we're not currently waiting for one to finish diff --git a/libraries/render-utils/src/SoftAttachmentModel.cpp b/libraries/render-utils/src/SoftAttachmentModel.cpp index 63b18d49b8..975d099ac3 100644 --- a/libraries/render-utils/src/SoftAttachmentModel.cpp +++ b/libraries/render-utils/src/SoftAttachmentModel.cpp @@ -62,7 +62,7 @@ void SoftAttachmentModel::updateClusterMatrices() { } // Once computed the cluster matrices, update the buffer(s) - if (mesh.clusters.size() > 1) { + /* if (mesh.clusters.size() > 1) { if (!state.clusterBuffer) { state.clusterBuffer = std::make_shared(state.clusterMatrices.size() * sizeof(glm::mat4), (const gpu::Byte*) state.clusterMatrices.constData()); @@ -70,7 +70,7 @@ void SoftAttachmentModel::updateClusterMatrices() { state.clusterBuffer->setSubData(0, state.clusterMatrices.size() * sizeof(glm::mat4), (const gpu::Byte*) state.clusterMatrices.constData()); } - } + }*/ } // post the blender if we're not currently waiting for one to finish