mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:24:00 +02:00
Merge pull request #9358 from AndrewMeadows/model-cleanup
minor cleanup for Model rendering code
This commit is contained in:
commit
ca53235d54
6 changed files with 49 additions and 56 deletions
|
@ -37,7 +37,7 @@ int SoftAttachmentModel::getJointIndexOverride(int i) const {
|
|||
|
||||
// virtual
|
||||
// use the _rigOverride matrices instead of the Model::_rig
|
||||
void SoftAttachmentModel::updateClusterMatrices(glm::vec3 modelPosition, glm::quat modelOrientation) {
|
||||
void SoftAttachmentModel::updateClusterMatrices() {
|
||||
if (!_needsUpdateClusterMatrices) {
|
||||
return;
|
||||
}
|
||||
|
@ -45,7 +45,6 @@ void SoftAttachmentModel::updateClusterMatrices(glm::vec3 modelPosition, glm::qu
|
|||
|
||||
const FBXGeometry& geometry = getFBXGeometry();
|
||||
|
||||
glm::mat4 modelToWorld = glm::mat4_cast(modelOrientation);
|
||||
for (int i = 0; i < _meshStates.size(); i++) {
|
||||
MeshState& state = _meshStates[i];
|
||||
const FBXMesh& mesh = geometry.meshes.at(i);
|
||||
|
@ -53,7 +52,7 @@ void SoftAttachmentModel::updateClusterMatrices(glm::vec3 modelPosition, glm::qu
|
|||
for (int j = 0; j < mesh.clusters.size(); j++) {
|
||||
const FBXCluster& cluster = mesh.clusters.at(j);
|
||||
|
||||
// TODO: cache these look ups as an optimization
|
||||
// TODO: cache these look-ups as an optimization
|
||||
int jointIndexOverride = getJointIndexOverride(cluster.jointIndex);
|
||||
glm::mat4 jointMatrix;
|
||||
if (jointIndexOverride >= 0 && jointIndexOverride < _rigOverride->getJointStateCount()) {
|
||||
|
@ -61,7 +60,13 @@ void SoftAttachmentModel::updateClusterMatrices(glm::vec3 modelPosition, glm::qu
|
|||
} else {
|
||||
jointMatrix = _rig->getJointTransform(cluster.jointIndex);
|
||||
}
|
||||
state.clusterMatrices[j] = modelToWorld * jointMatrix * cluster.inverseBindMatrix;
|
||||
#if GLM_ARCH & GLM_ARCH_SSE2
|
||||
glm::mat4 out, inverseBindMatrix = cluster.inverseBindMatrix;
|
||||
glm_mat4_mul((glm_vec4*)&jointMatrix, (glm_vec4*)&inverseBindMatrix, (glm_vec4*)&out);
|
||||
state.clusterMatrices[j] = out;
|
||||
#else
|
||||
state.clusterMatrices[j] = jointMatrix * cluster.inverseBindMatrix;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Once computed the cluster matrices, update the buffer(s)
|
||||
|
|
|
@ -31,7 +31,7 @@ public:
|
|||
~SoftAttachmentModel();
|
||||
|
||||
virtual void updateRig(float deltaTime, glm::mat4 parentTransform) override;
|
||||
virtual void updateClusterMatrices(glm::vec3 modelPosition, glm::quat modelOrientation) override;
|
||||
virtual void updateClusterMatrices() override;
|
||||
|
||||
protected:
|
||||
int getJointIndexOverride(int i) const;
|
||||
|
|
|
@ -63,8 +63,7 @@ void MeshPartPayload::updateMeshPart(const std::shared_ptr<const model::Mesh>& d
|
|||
|
||||
void MeshPartPayload::updateTransform(const Transform& transform, const Transform& offsetTransform) {
|
||||
_transform = transform;
|
||||
_offsetTransform = offsetTransform;
|
||||
Transform::mult(_drawTransform, _transform, _offsetTransform);
|
||||
Transform::mult(_drawTransform, _transform, offsetTransform);
|
||||
_worldBound = _localBound;
|
||||
_worldBound.transform(_drawTransform);
|
||||
}
|
||||
|
@ -360,8 +359,8 @@ void ModelMeshPartPayload::notifyLocationChanged() {
|
|||
|
||||
}
|
||||
|
||||
void ModelMeshPartPayload::updateTransformForSkinnedMesh(const Transform& transform, const Transform& offsetTransform, const QVector<glm::mat4>& clusterMatrices) {
|
||||
ModelMeshPartPayload::updateTransform(transform, offsetTransform);
|
||||
void ModelMeshPartPayload::updateTransformForSkinnedMesh(const Transform& transform, const QVector<glm::mat4>& clusterMatrices) {
|
||||
_transform = transform;
|
||||
|
||||
if (clusterMatrices.size() > 0) {
|
||||
_worldBound = AABox();
|
||||
|
@ -371,8 +370,10 @@ void ModelMeshPartPayload::updateTransformForSkinnedMesh(const Transform& transf
|
|||
_worldBound += clusterBound;
|
||||
}
|
||||
|
||||
// clusterMatrix has world rotation but not world translation.
|
||||
_worldBound.translate(transform.getTranslation());
|
||||
_worldBound.transform(transform);
|
||||
if (clusterMatrices.size() == 1) {
|
||||
_transform = _transform.worldTransform(Transform(clusterMatrices[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -520,23 +521,15 @@ void ModelMeshPartPayload::bindTransform(gpu::Batch& batch, const ShapePipeline:
|
|||
// Still relying on the raw data from the model
|
||||
const Model::MeshState& state = _model->_meshStates.at(_meshIndex);
|
||||
|
||||
Transform transform;
|
||||
if (state.clusterBuffer) {
|
||||
if (canCauterize && _model->getCauterizeBones()) {
|
||||
batch.setUniformBuffer(ShapePipeline::Slot::BUFFER::SKINNING, state.cauterizedClusterBuffer);
|
||||
} else {
|
||||
batch.setUniformBuffer(ShapePipeline::Slot::BUFFER::SKINNING, state.clusterBuffer);
|
||||
}
|
||||
} else {
|
||||
if (canCauterize && _model->getCauterizeBones()) {
|
||||
transform = Transform(state.cauterizedClusterMatrices[0]);
|
||||
} else {
|
||||
transform = Transform(state.clusterMatrices[0]);
|
||||
}
|
||||
}
|
||||
|
||||
transform.preTranslate(_transform.getTranslation());
|
||||
batch.setModelTransform(transform);
|
||||
batch.setModelTransform(_transform);
|
||||
}
|
||||
|
||||
void ModelMeshPartPayload::startFade() {
|
||||
|
@ -569,8 +562,7 @@ void ModelMeshPartPayload::render(RenderArgs* args) const {
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
// When an individual mesh parts like this finishes its fade, we will mark the Model as
|
||||
// When an individual mesh parts like this finishes its fade, we will mark the Model as
|
||||
// having render items that need updating
|
||||
bool nextIsFading = _isFading ? isStillFading() : false;
|
||||
bool startFading = !_isFading && !_hasFinishedFade && _hasStartedFade;
|
||||
|
@ -592,7 +584,7 @@ void ModelMeshPartPayload::render(RenderArgs* args) const {
|
|||
|
||||
// Bind the model transform and the skinCLusterMatrices if needed
|
||||
bool canCauterize = args->_renderMode != RenderArgs::SHADOW_RENDER_MODE;
|
||||
_model->updateClusterMatrices(_transform.getTranslation(), _transform.getRotation());
|
||||
_model->updateClusterMatrices();
|
||||
bindTransform(batch, locations, canCauterize);
|
||||
|
||||
//Bind the index buffer and vertex buffer and Blend shapes if needed
|
||||
|
|
|
@ -34,7 +34,7 @@ public:
|
|||
virtual void updateMeshPart(const std::shared_ptr<const model::Mesh>& drawMesh, int partIndex);
|
||||
|
||||
virtual void notifyLocationChanged() {}
|
||||
virtual void updateTransform(const Transform& transform, const Transform& offsetTransform);
|
||||
void updateTransform(const Transform& transform, const Transform& offsetTransform);
|
||||
|
||||
virtual void updateMaterial(model::MaterialPointer drawMaterial);
|
||||
|
||||
|
@ -56,13 +56,12 @@ public:
|
|||
model::Mesh::Part _drawPart;
|
||||
|
||||
std::shared_ptr<const model::Material> _drawMaterial;
|
||||
|
||||
|
||||
model::Box _localBound;
|
||||
Transform _drawTransform;
|
||||
Transform _transform;
|
||||
Transform _offsetTransform;
|
||||
mutable model::Box _worldBound;
|
||||
|
||||
|
||||
bool _hasColorAttrib = false;
|
||||
|
||||
size_t getVerticesCount() const { return _drawMesh ? _drawMesh->getNumVertices() : 0; }
|
||||
|
@ -86,7 +85,7 @@ public:
|
|||
typedef Payload::DataPointer Pointer;
|
||||
|
||||
void notifyLocationChanged() override;
|
||||
void updateTransformForSkinnedMesh(const Transform& transform, const Transform& offsetTransform, const QVector<glm::mat4>& clusterMatrices);
|
||||
void updateTransformForSkinnedMesh(const Transform& transform, const QVector<glm::mat4>& clusterMatrices);
|
||||
|
||||
// Entity fade in
|
||||
void startFade();
|
||||
|
@ -101,7 +100,7 @@ public:
|
|||
|
||||
// ModelMeshPartPayload functions to perform render
|
||||
void bindMesh(gpu::Batch& batch) const override;
|
||||
void bindTransform(gpu::Batch& batch, const render::ShapePipeline::LocationsPointer locations, bool canCauterize) const override;
|
||||
void bindTransform(gpu::Batch& batch, const render::ShapePipeline::LocationsPointer locations, bool canCauterize = true) const override;
|
||||
|
||||
void initCache();
|
||||
|
||||
|
|
|
@ -92,7 +92,6 @@ Model::Model(RigPointer rig, QObject* parent) :
|
|||
_snapModelToRegistrationPoint(false),
|
||||
_snappedToRegistrationPoint(false),
|
||||
_cauterizeBones(false),
|
||||
_pupilDilation(0.0f),
|
||||
_url(HTTP_INVALID_COM),
|
||||
_isVisible(true),
|
||||
_blendNumber(0),
|
||||
|
@ -217,23 +216,17 @@ void Model::updateRenderItems() {
|
|||
render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene();
|
||||
|
||||
Transform modelTransform;
|
||||
modelTransform.setScale(scale);
|
||||
modelTransform.setTranslation(self->_translation);
|
||||
modelTransform.setRotation(self->_rotation);
|
||||
|
||||
Transform modelMeshOffset;
|
||||
if (self->isLoaded()) {
|
||||
// includes model offset and unitScale.
|
||||
modelMeshOffset = Transform(self->_rig->getGeometryToRigTransform());
|
||||
} else {
|
||||
modelMeshOffset.postTranslate(self->_offset);
|
||||
}
|
||||
Transform scaledModelTransform(modelTransform);
|
||||
scaledModelTransform.setScale(scale);
|
||||
|
||||
uint32_t deleteGeometryCounter = self->_deleteGeometryCounter;
|
||||
|
||||
render::PendingChanges pendingChanges;
|
||||
foreach (auto itemID, self->_modelMeshRenderItems.keys()) {
|
||||
pendingChanges.updateItem<ModelMeshPartPayload>(itemID, [modelTransform, modelMeshOffset, deleteGeometryCounter](ModelMeshPartPayload& data) {
|
||||
pendingChanges.updateItem<ModelMeshPartPayload>(itemID, [modelTransform, deleteGeometryCounter](ModelMeshPartPayload& data) {
|
||||
if (data._model && data._model->isLoaded()) {
|
||||
if (!data.hasStartedFade() && data._model->getGeometry()->areTexturesLoaded()) {
|
||||
data.startFade();
|
||||
|
@ -241,11 +234,11 @@ void Model::updateRenderItems() {
|
|||
// Ensure the model geometry was not reset between frames
|
||||
if (deleteGeometryCounter == data._model->_deleteGeometryCounter) {
|
||||
// lazy update of cluster matrices used for rendering. We need to update them here, so we can correctly update the bounding box.
|
||||
data._model->updateClusterMatrices(modelTransform.getTranslation(), modelTransform.getRotation());
|
||||
data._model->updateClusterMatrices();
|
||||
|
||||
// update the model transform and bounding box for this render item.
|
||||
const Model::MeshState& state = data._model->_meshStates.at(data._meshIndex);
|
||||
data.updateTransformForSkinnedMesh(modelTransform, modelMeshOffset, state.clusterMatrices);
|
||||
data.updateTransformForSkinnedMesh(modelTransform, state.clusterMatrices);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -255,9 +248,9 @@ void Model::updateRenderItems() {
|
|||
Transform collisionMeshOffset;
|
||||
collisionMeshOffset.setIdentity();
|
||||
foreach (auto itemID, self->_collisionRenderItems.keys()) {
|
||||
pendingChanges.updateItem<MeshPartPayload>(itemID, [modelTransform, collisionMeshOffset](MeshPartPayload& data) {
|
||||
pendingChanges.updateItem<MeshPartPayload>(itemID, [scaledModelTransform, collisionMeshOffset](MeshPartPayload& data) {
|
||||
// update the model transform for this render item.
|
||||
data.updateTransform(modelTransform, collisionMeshOffset);
|
||||
data.updateTransform(scaledModelTransform, collisionMeshOffset);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -295,6 +288,7 @@ bool Model::updateGeometry() {
|
|||
|
||||
if (_rig->jointStatesEmpty() && getFBXGeometry().joints.size() > 0) {
|
||||
initJointStates();
|
||||
assert(_meshStates.empty());
|
||||
|
||||
const FBXGeometry& fbxGeometry = getFBXGeometry();
|
||||
foreach (const FBXMesh& mesh, fbxGeometry.meshes) {
|
||||
|
@ -304,6 +298,9 @@ bool Model::updateGeometry() {
|
|||
|
||||
_meshStates.append(state);
|
||||
|
||||
// Note: we add empty buffers for meshes that lack blendshapes so we can access the buffers by index
|
||||
// later in ModelMeshPayload, however the vast majority of meshes will not have them.
|
||||
// TODO? make _blendedVertexBuffers a map instead of vector and only add for meshes with blendshapes?
|
||||
auto buffer = std::make_shared<gpu::Buffer>();
|
||||
if (!mesh.blendshapes.isEmpty()) {
|
||||
buffer->resize((mesh.vertices.size() + mesh.normals.size()) * sizeof(glm::vec3));
|
||||
|
@ -1152,7 +1149,7 @@ void Model::simulateInternal(float deltaTime) {
|
|||
}
|
||||
|
||||
// virtual
|
||||
void Model::updateClusterMatrices(glm::vec3 modelPosition, glm::quat modelOrientation) {
|
||||
void Model::updateClusterMatrices() {
|
||||
PerformanceTimer perfTimer("Model::updateClusterMatrices");
|
||||
|
||||
if (!_needsUpdateClusterMatrices || !isLoaded()) {
|
||||
|
@ -1167,7 +1164,6 @@ void Model::updateClusterMatrices(glm::vec3 modelPosition, glm::quat modelOrient
|
|||
glm::vec4(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
auto cauterizeMatrix = _rig->getJointTransform(geometry.neckJointIndex) * zeroScale;
|
||||
|
||||
glm::mat4 modelToWorld = glm::mat4_cast(modelOrientation);
|
||||
for (int i = 0; i < _meshStates.size(); i++) {
|
||||
MeshState& state = _meshStates[i];
|
||||
const FBXMesh& mesh = geometry.meshes.at(i);
|
||||
|
@ -1175,12 +1171,11 @@ void Model::updateClusterMatrices(glm::vec3 modelPosition, glm::quat modelOrient
|
|||
const FBXCluster& cluster = mesh.clusters.at(j);
|
||||
auto jointMatrix = _rig->getJointTransform(cluster.jointIndex);
|
||||
#if GLM_ARCH & GLM_ARCH_SSE2
|
||||
glm::mat4 temp, out, inverseBindMatrix = cluster.inverseBindMatrix;
|
||||
glm_mat4_mul((glm_vec4*)&modelToWorld, (glm_vec4*)&jointMatrix, (glm_vec4*)&temp);
|
||||
glm_mat4_mul((glm_vec4*)&temp, (glm_vec4*)&inverseBindMatrix, (glm_vec4*)&out);
|
||||
glm::mat4 out, inverseBindMatrix = cluster.inverseBindMatrix;
|
||||
glm_mat4_mul((glm_vec4*)&jointMatrix, (glm_vec4*)&inverseBindMatrix, (glm_vec4*)&out);
|
||||
state.clusterMatrices[j] = out;
|
||||
#else
|
||||
state.clusterMatrices[j] = modelToWorld * jointMatrix * cluster.inverseBindMatrix;
|
||||
#else
|
||||
state.clusterMatrices[j] = jointMatrix * cluster.inverseBindMatrix;
|
||||
#endif
|
||||
|
||||
// as an optimization, don't build cautrizedClusterMatrices if the boneSet is empty.
|
||||
|
@ -1188,7 +1183,13 @@ void Model::updateClusterMatrices(glm::vec3 modelPosition, glm::quat modelOrient
|
|||
if (_cauterizeBoneSet.find(cluster.jointIndex) != _cauterizeBoneSet.end()) {
|
||||
jointMatrix = cauterizeMatrix;
|
||||
}
|
||||
state.cauterizedClusterMatrices[j] = modelToWorld * jointMatrix * cluster.inverseBindMatrix;
|
||||
#if GLM_ARCH & GLM_ARCH_SSE2
|
||||
glm::mat4 out, inverseBindMatrix = cluster.inverseBindMatrix;
|
||||
glm_mat4_mul((glm_vec4*)&jointMatrix, (glm_vec4*)&inverseBindMatrix, (glm_vec4*)&out);
|
||||
state.cauterizedClusterMatrices[j] = out;
|
||||
#else
|
||||
state.cauterizedClusterMatrices[j] = jointMatrix * cluster.inverseBindMatrix;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -126,7 +126,7 @@ public:
|
|||
bool getSnapModelToRegistrationPoint() { return _snapModelToRegistrationPoint; }
|
||||
|
||||
virtual void simulate(float deltaTime, bool fullUpdate = true);
|
||||
virtual void updateClusterMatrices(glm::vec3 modelPosition, glm::quat modelOrientation);
|
||||
virtual void updateClusterMatrices();
|
||||
|
||||
/// Returns a reference to the shared geometry.
|
||||
const Geometry::Pointer& getGeometry() const { return _renderGeometry; }
|
||||
|
@ -251,9 +251,6 @@ signals:
|
|||
protected:
|
||||
bool addedToScene() const { return _addedToScene; }
|
||||
|
||||
void setPupilDilation(float dilation) { _pupilDilation = dilation; }
|
||||
float getPupilDilation() const { return _pupilDilation; }
|
||||
|
||||
void setBlendshapeCoefficients(const QVector<float>& coefficients) { _blendshapeCoefficients = coefficients; }
|
||||
const QVector<float>& getBlendshapeCoefficients() const { return _blendshapeCoefficients; }
|
||||
|
||||
|
@ -347,7 +344,6 @@ protected:
|
|||
void deleteGeometry();
|
||||
void initJointTransforms();
|
||||
|
||||
float _pupilDilation;
|
||||
QVector<float> _blendshapeCoefficients;
|
||||
|
||||
QUrl _url;
|
||||
|
|
Loading…
Reference in a new issue