Trying to set the ClusterBuffer in the render loop instead of the game loop

This commit is contained in:
Sam Gateau 2017-11-02 03:45:27 -07:00
parent 4dba5b8b36
commit 56510abd1e
8 changed files with 112 additions and 26 deletions

View file

@ -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)) {

View file

@ -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<glm::mat4>& clusterMatrices, const QVector<glm::mat4>& cauterizedClusterMatrices) {
// Once computed the cluster matrices, update the buffer(s)
if (clusterMatrices.size() > 1) {
if (!_clusterBuffer) {
_clusterBuffer = std::make_shared<gpu::Buffer>(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<gpu::Buffer>(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 {

View file

@ -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<glm::mat4>& clusterMatrices, const QVector<glm::mat4>& 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;

View file

@ -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<Model> weakSelf = shared_from_this();
std::weak_ptr<CauterizedModel> weakSelf = std::dynamic_pointer_cast<CauterizedModel>(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<render::ItemID> keys = self->getRenderItems().keys();
int meshIndex{ 0 };
foreach (auto itemID, keys) {
transaction.updateItem<CauterizedMeshPartPayload>(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<CauterizedMeshPartPayload>(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<CauterizedModel*>(model.get());
/*CauterizedModel* cModel = static_cast<CauterizedModel*>(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);

View file

@ -367,12 +367,27 @@ void ModelMeshPartPayload::notifyLocationChanged() {
}
void ModelMeshPartPayload::updateClusterBuffer(const QVector<glm::mat4>& clusterMatrices) {
// Once computed the cluster matrices, update the buffer(s)
if (clusterMatrices.size() > 1) {
if (!_clusterBuffer) {
_clusterBuffer = std::make_shared<gpu::Buffer>(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 {

View file

@ -87,6 +87,7 @@ public:
typedef Payload::DataPointer Pointer;
void notifyLocationChanged() override;
void updateClusterBuffer(const QVector<glm::mat4>& clusterMatrices);
void updateTransformForSkinnedMesh(const Transform& renderTransform,
const Transform& boundTransform,
const gpu::BufferPointer& buffer);

View file

@ -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<ModelMeshPartPayload>(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<ModelMeshPartPayload>(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<gpu::Buffer>(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

View file

@ -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<gpu::Buffer>(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