mirror of
https://github.com/overte-org/overte.git
synced 2025-04-11 17:14:58 +02:00
the clusterMatrices should be working, but n skin index and weights are assigned yet
This commit is contained in:
parent
8af507571c
commit
05ac9aefa8
7 changed files with 242 additions and 117 deletions
|
@ -30,6 +30,34 @@ AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel) {
|
|||
|
||||
// we make a copy of the inverseBindMatrices in order to prevent mutating the model bind pose
|
||||
// when we are dealing with a joint offset in the model
|
||||
for (int i = 0; i < (int)hfmModel.dynamicTransforms.size(); i++) {
|
||||
const auto& defor = hfmModel.dynamicTransforms[i];
|
||||
std::vector<HFMCluster> dummyClustersList;
|
||||
|
||||
for (int j = 0; j < defor.clusters.size(); j++) {
|
||||
std::vector<glm::mat4> bindMatrices;
|
||||
// cast into a non-const reference, so we can mutate the FBXCluster
|
||||
HFMCluster& cluster = const_cast<HFMCluster&>(defor.clusters.at(j));
|
||||
|
||||
HFMCluster localCluster;
|
||||
localCluster.jointIndex = cluster.jointIndex;
|
||||
localCluster.inverseBindMatrix = cluster.inverseBindMatrix;
|
||||
localCluster.inverseBindTransform.evalFromRawMatrix(localCluster.inverseBindMatrix);
|
||||
|
||||
// if we have a joint offset in the fst file then multiply its inverse by the
|
||||
// model cluster inverse bind matrix
|
||||
if (hfmModel.jointRotationOffsets.contains(cluster.jointIndex)) {
|
||||
AnimPose localOffset(hfmModel.jointRotationOffsets[cluster.jointIndex], glm::vec3());
|
||||
localCluster.inverseBindMatrix = (glm::mat4)localOffset.inverse() * cluster.inverseBindMatrix;
|
||||
localCluster.inverseBindTransform.evalFromRawMatrix(localCluster.inverseBindMatrix);
|
||||
}
|
||||
dummyClustersList.push_back(localCluster);
|
||||
}
|
||||
_clusterBindMatrixOriginalValues.push_back(dummyClustersList);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
for (int i = 0; i < (int)hfmModel.meshes.size(); i++) {
|
||||
const HFMMesh& mesh = hfmModel.meshes.at(i);
|
||||
std::vector<HFMCluster> dummyClustersList;
|
||||
|
@ -55,6 +83,7 @@ AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel) {
|
|||
}
|
||||
_clusterBindMatrixOriginalValues.push_back(dummyClustersList);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
AnimSkeleton::AnimSkeleton(const std::vector<HFMJoint>& joints, const QMap<int, glm::quat> jointOffsets) {
|
||||
|
|
|
@ -70,6 +70,8 @@ public:
|
|||
std::vector<int> lookUpJointIndices(const std::vector<QString>& jointNames) const;
|
||||
const HFMCluster getClusterBindMatricesOriginalValues(const int meshIndex, const int clusterIndex) const { return _clusterBindMatrixOriginalValues[meshIndex][clusterIndex]; }
|
||||
|
||||
// const HFMCluster getClusterBindMatricesOriginalValues(const int meshIndex, const int clusterIndex) const { return _clusterBindMatrixOriginalValues[meshIndex][clusterIndex]; }
|
||||
|
||||
protected:
|
||||
void buildSkeletonFromJoints(const std::vector<HFMJoint>& joints, const QMap<int, glm::quat> jointOffsets);
|
||||
|
||||
|
|
|
@ -32,8 +32,8 @@ bool CauterizedModel::updateGeometry() {
|
|||
bool needsFullUpdate = Model::updateGeometry();
|
||||
if (_isCauterized && needsFullUpdate) {
|
||||
assert(_cauterizeMeshStates.empty());
|
||||
const HFMModel& hfmModel = getHFMModel();
|
||||
/* const auto& hfmDynamicTransforms = hfmModel.dynamicTransforms;
|
||||
/* const HFMModel& hfmModel = getHFMModel();
|
||||
const auto& hfmDynamicTransforms = hfmModel.dynamicTransforms;
|
||||
for (int i = 0; i < hfmDynamicTransforms.size(); i++) {
|
||||
const auto& dynT = hfmDynamicTransforms[i];
|
||||
MeshState state;
|
||||
|
@ -45,7 +45,27 @@ bool CauterizedModel::updateGeometry() {
|
|||
_cauterizeMeshStates.append(state);
|
||||
_meshStates.push_back(state);
|
||||
}*/
|
||||
foreach (const HFMMesh& mesh, hfmModel.meshes) {
|
||||
|
||||
const HFMModel& hfmModel = getHFMModel();
|
||||
const auto& hfmDynamicTransforms = hfmModel.dynamicTransforms;
|
||||
int i = 0;
|
||||
/* for (const auto& mesh: hfmModel.meshes) {
|
||||
MeshState state;
|
||||
state.clusterDualQuaternions.resize(mesh.clusters.size());
|
||||
state.clusterMatrices.resize(mesh.clusters.size());
|
||||
_meshStates.push_back(state);
|
||||
i++;
|
||||
}
|
||||
*/
|
||||
for (int i = 0; i < hfmDynamicTransforms.size(); i++) {
|
||||
const auto& dynT = hfmDynamicTransforms[i];
|
||||
MeshState state;
|
||||
state.clusterDualQuaternions.resize(dynT.clusters.size());
|
||||
state.clusterMatrices.resize(dynT.clusters.size());
|
||||
_cauterizeMeshStates.push_back(state);
|
||||
}
|
||||
|
||||
/* foreach (const HFMMesh& mesh, hfmModel.meshes) {
|
||||
Model::MeshState state;
|
||||
if (_useDualQuaternionSkinning) {
|
||||
state.clusterDualQuaternions.resize(mesh.clusters.size());
|
||||
|
@ -54,7 +74,7 @@ bool CauterizedModel::updateGeometry() {
|
|||
state.clusterMatrices.resize(mesh.clusters.size());
|
||||
_cauterizeMeshStates.append(state);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
return needsFullUpdate;
|
||||
}
|
||||
|
@ -64,11 +84,6 @@ void CauterizedModel::createRenderItemSet() {
|
|||
assert(isLoaded());
|
||||
const auto& meshes = _renderGeometry->getMeshes();
|
||||
|
||||
// all of our mesh vectors must match in size
|
||||
if (meshes.size() != _meshStates.size()) {
|
||||
qCDebug(renderutils) << "WARNING!!!! Mesh Sizes don't match! We will not segregate mesh groups yet.";
|
||||
// return;
|
||||
}
|
||||
|
||||
// We should not have any existing renderItems if we enter this section of code
|
||||
Q_ASSERT(_modelMeshRenderItems.isEmpty());
|
||||
|
@ -88,7 +103,20 @@ void CauterizedModel::createRenderItemSet() {
|
|||
Transform::mult(transform, transform, offset);
|
||||
|
||||
// Run through all of the meshes, and place them into their segregated, but unsorted buckets
|
||||
// Run through all of the meshes, and place them into their segregated, but unsorted buckets
|
||||
int shapeID = 0;
|
||||
const auto& shapes = _renderGeometry->getHFMModel().shapes;
|
||||
for (shapeID; shapeID < shapes.size(); shapeID++) {
|
||||
const auto& shape = shapes[shapeID];
|
||||
|
||||
_modelMeshRenderItems << std::make_shared<CauterizedMeshPartPayload>(shared_from_this(), shape.mesh, shape.meshPart, shapeID, transform);
|
||||
|
||||
auto material = getNetworkModel()->getShapeMaterial(shapeID);
|
||||
_modelMeshMaterialNames.push_back(material ? material->getName() : "");
|
||||
_modelMeshRenderItemShapes.emplace_back(ShapeInfo{ (int)shape.mesh, shape.dynamicTransform });
|
||||
}
|
||||
|
||||
/* int shapeID = 0;
|
||||
uint32_t numMeshes = (uint32_t)meshes.size();
|
||||
for (uint32_t i = 0; i < numMeshes; i++) {
|
||||
const auto& mesh = meshes.at(i);
|
||||
|
@ -106,7 +134,7 @@ void CauterizedModel::createRenderItemSet() {
|
|||
_modelMeshRenderItemShapes.emplace_back(ShapeInfo{ (int)i });
|
||||
shapeID++;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
} else {
|
||||
Model::createRenderItemSet();
|
||||
}
|
||||
|
@ -122,6 +150,38 @@ void CauterizedModel::updateClusterMatrices() {
|
|||
updateShapeStatesFromRig();
|
||||
|
||||
_needsUpdateClusterMatrices = false;
|
||||
|
||||
|
||||
const HFMModel& hfmModel = getHFMModel();
|
||||
const auto& hfmDynamicTransforms = hfmModel.dynamicTransforms;
|
||||
for (int i = 0; i < (int)_meshStates.size(); i++) {
|
||||
MeshState& state = _meshStates[i];
|
||||
const auto& deformer = hfmDynamicTransforms[i];
|
||||
|
||||
int meshIndex = i;
|
||||
int clusterIndex = 0;
|
||||
|
||||
for (int d = 0; d < deformer.clusters.size(); d++) {
|
||||
const auto& cluster = deformer.clusters[d];
|
||||
clusterIndex = d;
|
||||
|
||||
const auto& cbmov = _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex);
|
||||
|
||||
if (_useDualQuaternionSkinning) {
|
||||
auto jointPose = _rig.getJointPose(cluster.jointIndex);
|
||||
Transform jointTransform(jointPose.rot(), jointPose.scale(), jointPose.trans());
|
||||
Transform clusterTransform;
|
||||
Transform::mult(clusterTransform, jointTransform, cbmov.inverseBindTransform);
|
||||
state.clusterDualQuaternions[d] = Model::TransformDualQuaternion(clusterTransform);
|
||||
}
|
||||
else {
|
||||
auto jointMatrix = _rig.getJointTransform(cluster.jointIndex);
|
||||
glm_mat4u_mul(jointMatrix, cbmov.inverseBindMatrix, state.clusterMatrices[d]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
/*
|
||||
const HFMModel& hfmModel = getHFMModel();
|
||||
for (int i = 0; i < (int)_meshStates.size(); i++) {
|
||||
Model::MeshState& state = _meshStates[i];
|
||||
|
@ -145,7 +205,7 @@ void CauterizedModel::updateClusterMatrices() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
// as an optimization, don't build cautrizedClusterMatrices if the boneSet is empty.
|
||||
if (!_cauterizeBoneSet.empty()) {
|
||||
|
||||
|
@ -236,42 +296,66 @@ void CauterizedModel::updateRenderItems() {
|
|||
|
||||
auto itemID = self->_modelMeshRenderItemIDs[i];
|
||||
auto meshIndex = self->_modelMeshRenderItemShapes[i].meshIndex;
|
||||
auto deformerIndex = self->_modelMeshRenderItemShapes[i].meshIndex;
|
||||
|
||||
const auto& shapeState = self->getShapeState(i);
|
||||
|
||||
// const auto& meshState = self->getMeshState(meshIndex);
|
||||
// const auto& cauterizedMeshState = self->getCauterizeMeshState(meshIndex);
|
||||
MeshState meshState;
|
||||
MeshState cauterizedMeshState;
|
||||
auto deformerIndex = self->_modelMeshRenderItemShapes[i].deformerIndex;
|
||||
bool isDeformed = (deformerIndex != hfm::UNDEFINED_KEY);
|
||||
|
||||
|
||||
// auto meshIndex = self->_modelMeshRenderItemShapes[i].meshIndex;
|
||||
// auto deformerIndex = self->_modelMeshRenderItemShapes[i].meshIndex;
|
||||
|
||||
// const auto& shapeState = self->getShapeState(i);
|
||||
|
||||
|
||||
bool invalidatePayloadShapeKey = self->shouldInvalidatePayloadShapeKey(meshIndex);
|
||||
bool useDualQuaternionSkinning = self->getUseDualQuaternionSkinning();
|
||||
|
||||
transaction.updateItem<ModelMeshPartPayload>(itemID, [modelTransform, shapeState, meshState, useDualQuaternionSkinning, cauterizedMeshState, invalidatePayloadShapeKey,
|
||||
primitiveMode, renderItemKeyGlobalFlags, enableCauterization](ModelMeshPartPayload& mmppData) {
|
||||
CauterizedMeshPartPayload& data = static_cast<CauterizedMeshPartPayload&>(mmppData);
|
||||
if (useDualQuaternionSkinning) {
|
||||
data.updateClusterBuffer(meshState.clusterDualQuaternions,
|
||||
cauterizedMeshState.clusterDualQuaternions);
|
||||
data.computeAdjustedLocalBound(meshState.clusterDualQuaternions);
|
||||
} else {
|
||||
data.updateClusterBuffer(meshState.clusterMatrices,
|
||||
cauterizedMeshState.clusterMatrices);
|
||||
data.computeAdjustedLocalBound(meshState.clusterMatrices);
|
||||
}
|
||||
|
||||
Transform renderTransform = modelTransform;
|
||||
if (meshState.clusterMatrices.size() <= 2) {
|
||||
|
||||
if (isDeformed) {
|
||||
|
||||
const auto& meshState = self->getMeshState(deformerIndex);
|
||||
const auto& cauterizedMeshState = self->getCauterizeMeshState(deformerIndex);
|
||||
|
||||
transaction.updateItem<ModelMeshPartPayload>(itemID, [modelTransform, shapeState, meshState, useDualQuaternionSkinning, cauterizedMeshState, invalidatePayloadShapeKey,
|
||||
primitiveMode, renderItemKeyGlobalFlags, enableCauterization](ModelMeshPartPayload& mmppData) {
|
||||
CauterizedMeshPartPayload& data = static_cast<CauterizedMeshPartPayload&>(mmppData);
|
||||
if (useDualQuaternionSkinning) {
|
||||
data.updateClusterBuffer(meshState.clusterDualQuaternions,
|
||||
cauterizedMeshState.clusterDualQuaternions);
|
||||
} else {
|
||||
data.updateClusterBuffer(meshState.clusterMatrices,
|
||||
cauterizedMeshState.clusterMatrices);
|
||||
}
|
||||
|
||||
Transform renderTransform = modelTransform;
|
||||
// if (meshState.clusterMatrices.size() <= 2) {
|
||||
renderTransform = modelTransform.worldTransform(shapeState._rootFromJointTransform);
|
||||
// }
|
||||
data.updateTransform(renderTransform);
|
||||
data.updateTransformForCauterizedMesh(renderTransform);
|
||||
|
||||
data.setEnableCauterization(enableCauterization);
|
||||
data.updateKey(renderItemKeyGlobalFlags);
|
||||
data.setShapeKey(invalidatePayloadShapeKey, primitiveMode, useDualQuaternionSkinning);
|
||||
});
|
||||
} else {
|
||||
transaction.updateItem<ModelMeshPartPayload>(itemID, [modelTransform, shapeState, invalidatePayloadShapeKey, primitiveMode, renderItemKeyGlobalFlags](ModelMeshPartPayload& data) {
|
||||
|
||||
Transform renderTransform = modelTransform;
|
||||
// if (meshState.clusterMatrices.size() <= 1) {
|
||||
renderTransform = modelTransform.worldTransform(shapeState._rootFromJointTransform);
|
||||
}
|
||||
data.updateTransform(renderTransform);
|
||||
data.updateTransformForCauterizedMesh(renderTransform);
|
||||
// }
|
||||
data.updateTransform(renderTransform);
|
||||
|
||||
data.setEnableCauterization(enableCauterization);
|
||||
data.updateKey(renderItemKeyGlobalFlags);
|
||||
data.setShapeKey(invalidatePayloadShapeKey, primitiveMode, useDualQuaternionSkinning);
|
||||
});
|
||||
// data.setEnableCauterization(enableCauterization);
|
||||
data.updateKey(renderItemKeyGlobalFlags);
|
||||
data.setShapeKey(invalidatePayloadShapeKey, primitiveMode, false);
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
scene->enqueueTransaction(transaction);
|
||||
|
|
|
@ -213,17 +213,13 @@ ModelMeshPartPayload::ModelMeshPartPayload(ModelPointer model, int meshIndex, in
|
|||
|
||||
updateMeshPart(modelMesh, partIndex);
|
||||
|
||||
if (useDualQuaternionSkinning) {
|
||||
// computeAdjustedLocalBound(state.clusterDualQuaternions);
|
||||
} else {
|
||||
// computeAdjustedLocalBound(state.clusterMatrices);
|
||||
}
|
||||
|
||||
Transform renderTransform = transform;
|
||||
const Model::ShapeState& shapeState = model->getShapeState(shapeIndex);
|
||||
renderTransform = transform.worldTransform(shapeState._rootFromJointTransform);
|
||||
updateTransform(renderTransform);
|
||||
|
||||
_deformerIndex = shape.dynamicTransform;
|
||||
|
||||
initCache(model);
|
||||
|
||||
#if defined(Q_OS_MAC) || defined(Q_OS_ANDROID)
|
||||
|
@ -245,7 +241,9 @@ void ModelMeshPartPayload::initCache(const ModelPointer& model) {
|
|||
if (_drawMesh) {
|
||||
auto vertexFormat = _drawMesh->getVertexFormat();
|
||||
_hasColorAttrib = vertexFormat->hasAttribute(gpu::Stream::COLOR);
|
||||
_isSkinned = vertexFormat->hasAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT) && vertexFormat->hasAttribute(gpu::Stream::SKIN_CLUSTER_INDEX);
|
||||
if (_deformerIndex != hfm::UNDEFINED_KEY) {
|
||||
_isSkinned = vertexFormat->hasAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT) && vertexFormat->hasAttribute(gpu::Stream::SKIN_CLUSTER_INDEX);
|
||||
}
|
||||
|
||||
const HFMModel& hfmModel = model->getHFMModel();
|
||||
const HFMMesh& mesh = hfmModel.meshes.at(_meshIndex);
|
||||
|
@ -432,38 +430,6 @@ void ModelMeshPartPayload::render(RenderArgs* args) {
|
|||
args->_details._trianglesRendered += _drawPart._numIndices / INDICES_PER_TRIANGLE;
|
||||
}
|
||||
|
||||
void ModelMeshPartPayload::computeAdjustedLocalBound(const std::vector<glm::mat4>& clusterMatrices) {
|
||||
_adjustedLocalBound = _localBound;
|
||||
if (clusterMatrices.size() > 0) {
|
||||
_adjustedLocalBound.transform(clusterMatrices.back());
|
||||
|
||||
for (int i = 0; i < (int)clusterMatrices.size() - 1; ++i) {
|
||||
AABox clusterBound = _localBound;
|
||||
clusterBound.transform(clusterMatrices[i]);
|
||||
_adjustedLocalBound += clusterBound;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ModelMeshPartPayload::computeAdjustedLocalBound(const std::vector<Model::TransformDualQuaternion>& clusterDualQuaternions) {
|
||||
_adjustedLocalBound = _localBound;
|
||||
if (clusterDualQuaternions.size() > 0) {
|
||||
Transform rootTransform(clusterDualQuaternions.back().getRotation(),
|
||||
clusterDualQuaternions.back().getScale(),
|
||||
clusterDualQuaternions.back().getTranslation());
|
||||
_adjustedLocalBound.transform(rootTransform);
|
||||
|
||||
for (int i = 0; i < (int)clusterDualQuaternions.size() - 1; ++i) {
|
||||
AABox clusterBound = _localBound;
|
||||
Transform transform(clusterDualQuaternions[i].getRotation(),
|
||||
clusterDualQuaternions[i].getScale(),
|
||||
clusterDualQuaternions[i].getTranslation());
|
||||
clusterBound.transform(transform);
|
||||
_adjustedLocalBound += clusterBound;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ModelMeshPartPayload::setBlendshapeBuffer(const std::unordered_map<int, gpu::BufferPointer>& blendshapeBuffers, const QVector<int>& blendedMeshSizes) {
|
||||
if (_meshIndex < blendedMeshSizes.length() && blendedMeshSizes.at(_meshIndex) == _meshNumVertices) {
|
||||
auto blendshapeBuffer = blendshapeBuffers.find(_meshIndex);
|
||||
|
|
|
@ -57,7 +57,6 @@ public:
|
|||
bool _hasColorAttrib { false };
|
||||
|
||||
graphics::Box _localBound;
|
||||
graphics::Box _adjustedLocalBound;
|
||||
mutable graphics::Box _worldBound;
|
||||
std::shared_ptr<const graphics::Mesh> _drawMesh;
|
||||
|
||||
|
@ -111,12 +110,6 @@ public:
|
|||
void bindMesh(gpu::Batch& batch) override;
|
||||
void bindTransform(gpu::Batch& batch, RenderArgs::RenderMode renderMode) const override;
|
||||
|
||||
// matrix palette skinning
|
||||
void computeAdjustedLocalBound(const std::vector<glm::mat4>& clusterMatrices);
|
||||
|
||||
// dual quaternion skinning
|
||||
void computeAdjustedLocalBound(const std::vector<Model::TransformDualQuaternion>& clusterDualQuaternions);
|
||||
|
||||
gpu::BufferPointer _clusterBuffer;
|
||||
|
||||
enum class ClusterBufferType { Matrices, DualQuaternions };
|
||||
|
@ -124,6 +117,7 @@ public:
|
|||
|
||||
int _meshIndex;
|
||||
int _shapeID;
|
||||
int _deformerIndex;
|
||||
|
||||
bool _isSkinned{ false };
|
||||
bool _isBlendShaped { false };
|
||||
|
|
|
@ -186,7 +186,7 @@ bool Model::shouldInvalidatePayloadShapeKey(int meshIndex) {
|
|||
const auto& networkMeshes = getNetworkModel()->getMeshes();
|
||||
// if our index is ever out of range for either meshes or networkMeshes, then skip it, and set our _meshGroupsKnown
|
||||
// to false to rebuild out mesh groups.
|
||||
if (meshIndex < 0 || meshIndex >= (int)networkMeshes.size() || meshIndex >= (int)hfmModel.meshes.size() || meshIndex >= (int)_meshStates.size()) {
|
||||
if (meshIndex < 0 || meshIndex >= (int)networkMeshes.size() || meshIndex >= (int)hfmModel.meshes.size() /* || meshIndex >= (int)_meshStates.size()*/) {
|
||||
_needsFixupInScene = true; // trigger remove/add cycle
|
||||
invalidCalculatedMeshBoxes(); // if we have to reload, we need to assume our mesh boxes are all invalid
|
||||
return true;
|
||||
|
@ -233,32 +233,51 @@ void Model::updateRenderItems() {
|
|||
auto meshIndex = self->_modelMeshRenderItemShapes[i].meshIndex;
|
||||
|
||||
const auto& shapeState = self->getShapeState(i);
|
||||
// const auto& meshState = self->getMeshState(meshIndex);
|
||||
MeshState meshState;
|
||||
|
||||
auto deformerIndex = self->_modelMeshRenderItemShapes[i].deformerIndex;
|
||||
bool isDeformed = (deformerIndex != hfm::UNDEFINED_KEY);
|
||||
|
||||
bool invalidatePayloadShapeKey = self->shouldInvalidatePayloadShapeKey(meshIndex);
|
||||
bool useDualQuaternionSkinning = self->getUseDualQuaternionSkinning();
|
||||
|
||||
transaction.updateItem<ModelMeshPartPayload>(itemID, [modelTransform, shapeState, meshState, useDualQuaternionSkinning,
|
||||
invalidatePayloadShapeKey, primitiveMode, renderItemKeyGlobalFlags, cauterized](ModelMeshPartPayload& data) {
|
||||
if (useDualQuaternionSkinning) {
|
||||
data.updateClusterBuffer(meshState.clusterDualQuaternions);
|
||||
data.computeAdjustedLocalBound(meshState.clusterDualQuaternions);
|
||||
} else {
|
||||
data.updateClusterBuffer(meshState.clusterMatrices);
|
||||
data.computeAdjustedLocalBound(meshState.clusterMatrices);
|
||||
}
|
||||
|
||||
if (isDeformed) {
|
||||
|
||||
Transform renderTransform = modelTransform;
|
||||
if (meshState.clusterMatrices.size() <= 1) {
|
||||
const auto& meshState = self->getMeshState(deformerIndex);
|
||||
// MeshState meshState;
|
||||
bool useDualQuaternionSkinning = self->getUseDualQuaternionSkinning();
|
||||
|
||||
|
||||
transaction.updateItem<ModelMeshPartPayload>(itemID, [modelTransform, shapeState, meshState, useDualQuaternionSkinning,
|
||||
invalidatePayloadShapeKey, primitiveMode, renderItemKeyGlobalFlags, cauterized](ModelMeshPartPayload& data) {
|
||||
if (useDualQuaternionSkinning) {
|
||||
data.updateClusterBuffer(meshState.clusterDualQuaternions);
|
||||
} else {
|
||||
data.updateClusterBuffer(meshState.clusterMatrices);
|
||||
}
|
||||
|
||||
Transform renderTransform = modelTransform;
|
||||
// if (meshState.clusterMatrices.size() <= 1) {
|
||||
renderTransform = modelTransform.worldTransform(shapeState._rootFromJointTransform);
|
||||
// }
|
||||
data.updateTransform(renderTransform);
|
||||
|
||||
data.setCauterized(cauterized);
|
||||
data.updateKey(renderItemKeyGlobalFlags);
|
||||
data.setShapeKey(invalidatePayloadShapeKey, primitiveMode, useDualQuaternionSkinning);
|
||||
});
|
||||
} else {
|
||||
transaction.updateItem<ModelMeshPartPayload>(itemID, [modelTransform, shapeState, invalidatePayloadShapeKey, primitiveMode, renderItemKeyGlobalFlags](ModelMeshPartPayload& data) {
|
||||
|
||||
Transform renderTransform = modelTransform;
|
||||
// if (meshState.clusterMatrices.size() <= 1) {
|
||||
renderTransform = modelTransform.worldTransform(shapeState._rootFromJointTransform);
|
||||
}
|
||||
data.updateTransform(renderTransform);
|
||||
// }
|
||||
data.updateTransform(renderTransform);
|
||||
|
||||
data.setCauterized(cauterized);
|
||||
data.updateKey(renderItemKeyGlobalFlags);
|
||||
data.setShapeKey(invalidatePayloadShapeKey, primitiveMode, useDualQuaternionSkinning);
|
||||
});
|
||||
data.updateKey(renderItemKeyGlobalFlags);
|
||||
data.setShapeKey(invalidatePayloadShapeKey, primitiveMode, false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
AbstractViewStateInterface::instance()->getMain3DScene()->enqueueTransaction(transaction);
|
||||
|
@ -317,8 +336,8 @@ bool Model::updateGeometry() {
|
|||
|
||||
const HFMModel& hfmModel = getHFMModel();
|
||||
const auto& hfmDynamicTransforms = hfmModel.dynamicTransforms;
|
||||
/* int i = 0;
|
||||
for (const auto& mesh: hfmModel.meshes) {
|
||||
int i = 0;
|
||||
/* for (const auto& mesh: hfmModel.meshes) {
|
||||
MeshState state;
|
||||
state.clusterDualQuaternions.resize(mesh.clusters.size());
|
||||
state.clusterMatrices.resize(mesh.clusters.size());
|
||||
|
@ -326,13 +345,13 @@ bool Model::updateGeometry() {
|
|||
i++;
|
||||
}
|
||||
*/
|
||||
/*for (int i = 0; i < hfmDynamicTransforms.size(); i++) {
|
||||
for (int i = 0; i < hfmDynamicTransforms.size(); i++) {
|
||||
const auto& dynT = hfmDynamicTransforms[i];
|
||||
MeshState state;
|
||||
state.clusterDualQuaternions.resize(dynT.clusters.size());
|
||||
state.clusterMatrices.resize(dynT.clusters.size());
|
||||
_meshStates.push_back(state);
|
||||
}*/
|
||||
}
|
||||
|
||||
needFullUpdate = true;
|
||||
emit rigReady();
|
||||
|
@ -1407,8 +1426,34 @@ void Model::updateClusterMatrices() {
|
|||
|
||||
_needsUpdateClusterMatrices = false;
|
||||
const HFMModel& hfmModel = getHFMModel();
|
||||
const auto& hfmDynamicTransforms = hfmModel.dynamicTransforms;
|
||||
for (int i = 0; i < (int) _meshStates.size(); i++) {
|
||||
MeshState& state = _meshStates[i];
|
||||
const auto& deformer = hfmDynamicTransforms[i];
|
||||
|
||||
int meshIndex = i;
|
||||
int clusterIndex = 0;
|
||||
|
||||
for (int d = 0; d < deformer.clusters.size(); d++) {
|
||||
const auto& cluster = deformer.clusters[d];
|
||||
clusterIndex = d;
|
||||
|
||||
const auto& cbmov = _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex);
|
||||
|
||||
if (_useDualQuaternionSkinning) {
|
||||
auto jointPose = _rig.getJointPose(cluster.jointIndex);
|
||||
Transform jointTransform(jointPose.rot(), jointPose.scale(), jointPose.trans());
|
||||
Transform clusterTransform;
|
||||
Transform::mult(clusterTransform, jointTransform, cbmov.inverseBindTransform);
|
||||
state.clusterDualQuaternions[d] = Model::TransformDualQuaternion(clusterTransform);
|
||||
}
|
||||
else {
|
||||
auto jointMatrix = _rig.getJointTransform(cluster.jointIndex);
|
||||
glm_mat4u_mul(jointMatrix, cbmov.inverseBindMatrix, state.clusterMatrices[d]);
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
int meshIndex = i;
|
||||
const HFMMesh& mesh = hfmModel.meshes.at(i);
|
||||
for (int j = 0; j < mesh.clusters.size(); j++) {
|
||||
|
@ -1425,7 +1470,7 @@ void Model::updateClusterMatrices() {
|
|||
auto jointMatrix = _rig.getJointTransform(cluster.jointIndex);
|
||||
glm_mat4u_mul(jointMatrix, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindMatrix, state.clusterMatrices[j]);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
// post the blender if we're not currently waiting for one to finish
|
||||
|
@ -1474,12 +1519,6 @@ void Model::createRenderItemSet() {
|
|||
assert(isLoaded());
|
||||
const auto& meshes = _renderGeometry->getMeshes();
|
||||
|
||||
// all of our mesh vectors must match in size
|
||||
if (meshes.size() != _meshStates.size()) {
|
||||
qCDebug(renderutils) << "WARNING!!!! Mesh Sizes don't match! " << meshes.size() << _meshStates.size() << " We will not segregate mesh groups yet.";
|
||||
// return;
|
||||
}
|
||||
|
||||
// We should not have any existing renderItems if we enter this section of code
|
||||
Q_ASSERT(_modelMeshRenderItems.isEmpty());
|
||||
|
||||
|
@ -1497,6 +1536,17 @@ void Model::createRenderItemSet() {
|
|||
|
||||
// Run through all of the meshes, and place them into their segregated, but unsorted buckets
|
||||
int shapeID = 0;
|
||||
const auto& shapes = _renderGeometry->getHFMModel().shapes;
|
||||
for (shapeID; shapeID < shapes.size(); shapeID++) {
|
||||
const auto& shape = shapes[shapeID];
|
||||
|
||||
_modelMeshRenderItems << std::make_shared<ModelMeshPartPayload>(shared_from_this(), shape.mesh, shape.meshPart, shapeID, transform);
|
||||
|
||||
auto material = getNetworkModel()->getShapeMaterial(shapeID);
|
||||
_modelMeshMaterialNames.push_back(material ? material->getName() : "");
|
||||
_modelMeshRenderItemShapes.emplace_back(ShapeInfo{ (int)shape.mesh, shape.dynamicTransform });
|
||||
}
|
||||
/*
|
||||
uint32_t numMeshes = (uint32_t)meshes.size();
|
||||
for (uint32_t i = 0; i < numMeshes; i++) {
|
||||
const auto& mesh = meshes.at(i);
|
||||
|
@ -1513,7 +1563,7 @@ void Model::createRenderItemSet() {
|
|||
_modelMeshRenderItemShapes.emplace_back(ShapeInfo{ (int)i });
|
||||
shapeID++;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
bool Model::isRenderable() const {
|
||||
|
|
|
@ -473,7 +473,7 @@ protected:
|
|||
QVector<std::shared_ptr<ModelMeshPartPayload>> _modelMeshRenderItems;
|
||||
QMap<render::ItemID, render::PayloadPointer> _modelMeshRenderItemsMap;
|
||||
render::ItemIDs _modelMeshRenderItemIDs;
|
||||
using ShapeInfo = struct { int meshIndex; int deformerIndex; };
|
||||
using ShapeInfo = struct { int meshIndex; uint32_t deformerIndex{ hfm::UNDEFINED_KEY }; };
|
||||
std::vector<ShapeInfo> _modelMeshRenderItemShapes;
|
||||
std::vector<std::string> _modelMeshMaterialNames;
|
||||
|
||||
|
|
Loading…
Reference in a new issue