mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 18:50:00 +02:00
Created Model::TransformComponents class
This commit is contained in:
parent
515d13a4c1
commit
18113d824c
9 changed files with 237 additions and 304 deletions
|
@ -20,19 +20,35 @@ using namespace render;
|
||||||
CauterizedMeshPartPayload::CauterizedMeshPartPayload(ModelPointer model, int meshIndex, int partIndex, int shapeIndex, const Transform& transform, const Transform& offsetTransform)
|
CauterizedMeshPartPayload::CauterizedMeshPartPayload(ModelPointer model, int meshIndex, int partIndex, int shapeIndex, const Transform& transform, const Transform& offsetTransform)
|
||||||
: ModelMeshPartPayload(model, meshIndex, partIndex, shapeIndex, transform, offsetTransform) {}
|
: ModelMeshPartPayload(model, meshIndex, partIndex, shapeIndex, transform, offsetTransform) {}
|
||||||
|
|
||||||
void CauterizedMeshPartPayload::updateClusterBuffer(const std::vector<glm::mat4>& clusterMatrices, const std::vector<glm::mat4>& cauterizedClusterMatrices) {
|
#ifdef SKIN_COMP
|
||||||
ModelMeshPartPayload::updateClusterBuffer(clusterMatrices);
|
void CauterizedMeshPartPayload::updateClusterBuffer(const std::vector<Model::TransformComponents>& clusterTransforms, const std::vector<Model::TransformComponents>& cauterizedClusterTransforms) {
|
||||||
|
ModelMeshPartPayload::updateClusterBuffer(clusterTransforms);
|
||||||
|
|
||||||
if (cauterizedClusterMatrices.size() > 1) {
|
if (cauterizedClusterTransforms.size() > 1) {
|
||||||
if (!_cauterizedClusterBuffer) {
|
if (!_cauterizedClusterBuffer) {
|
||||||
_cauterizedClusterBuffer = std::make_shared<gpu::Buffer>(cauterizedClusterMatrices.size() * sizeof(glm::mat4),
|
_cauterizedClusterBuffer = std::make_shared<gpu::Buffer>(cauterizedClusterTransforms.size() * sizeof(Model::TransformComponents),
|
||||||
(const gpu::Byte*) cauterizedClusterMatrices.data());
|
(const gpu::Byte*) cauterizedClusterTransforms.data());
|
||||||
} else {
|
} else {
|
||||||
_cauterizedClusterBuffer->setSubData(0, cauterizedClusterMatrices.size() * sizeof(glm::mat4),
|
_cauterizedClusterBuffer->setSubData(0, cauterizedClusterTransforms.size() * sizeof(Model::TransformComponents),
|
||||||
(const gpu::Byte*) cauterizedClusterMatrices.data());
|
(const gpu::Byte*) cauterizedClusterTransforms.data());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
void CauterizedMeshPartPayload::updateClusterBuffer(const std::vector<glm::mat4>& clusterTransforms, const std::vector<glm::mat4>& cauterizedClusterTransforms) {
|
||||||
|
ModelMeshPartPayload::updateClusterBuffer(clusterTransforms);
|
||||||
|
|
||||||
|
if (cauterizedClusterTransforms.size() > 1) {
|
||||||
|
if (!_cauterizedClusterBuffer) {
|
||||||
|
_cauterizedClusterBuffer = std::make_shared<gpu::Buffer>(cauterizedClusterTransforms.size() * sizeof(glm::mat4),
|
||||||
|
(const gpu::Byte*) cauterizedClusterTransforms.data());
|
||||||
|
} else {
|
||||||
|
_cauterizedClusterBuffer->setSubData(0, cauterizedClusterTransforms.size() * sizeof(glm::mat4),
|
||||||
|
(const gpu::Byte*) cauterizedClusterTransforms.data());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void CauterizedMeshPartPayload::updateTransformForCauterizedMesh(const Transform& renderTransform) {
|
void CauterizedMeshPartPayload::updateTransformForCauterizedMesh(const Transform& renderTransform) {
|
||||||
_cauterizedTransform = renderTransform;
|
_cauterizedTransform = renderTransform;
|
||||||
|
|
|
@ -14,8 +14,11 @@
|
||||||
class CauterizedMeshPartPayload : public ModelMeshPartPayload {
|
class CauterizedMeshPartPayload : public ModelMeshPartPayload {
|
||||||
public:
|
public:
|
||||||
CauterizedMeshPartPayload(ModelPointer model, int meshIndex, int partIndex, int shapeIndex, const Transform& transform, const Transform& offsetTransform);
|
CauterizedMeshPartPayload(ModelPointer model, int meshIndex, int partIndex, int shapeIndex, const Transform& transform, const Transform& offsetTransform);
|
||||||
|
#ifdef SKIN_COMP
|
||||||
void updateClusterBuffer(const std::vector<glm::mat4>& clusterMatrices, const std::vector<glm::mat4>& cauterizedClusterMatrices);
|
void updateClusterBuffer(const std::vector<Model::TransformComponents>& clusterTransforms, const std::vector<Model::TransformComponents>& cauterizedClusterTransforms);
|
||||||
|
#else
|
||||||
|
void updateClusterBuffer(const std::vector<glm::mat4>& clusterTransforms, const std::vector<glm::mat4>& cauterizedClusterTransforms);
|
||||||
|
#endif
|
||||||
|
|
||||||
void updateTransformForCauterizedMesh(const Transform& renderTransform);
|
void updateTransformForCauterizedMesh(const Transform& renderTransform);
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ bool CauterizedModel::updateGeometry() {
|
||||||
const FBXGeometry& fbxGeometry = getFBXGeometry();
|
const FBXGeometry& fbxGeometry = getFBXGeometry();
|
||||||
foreach (const FBXMesh& mesh, fbxGeometry.meshes) {
|
foreach (const FBXMesh& mesh, fbxGeometry.meshes) {
|
||||||
Model::MeshState state;
|
Model::MeshState state;
|
||||||
state.clusterMatrices.resize(mesh.clusters.size());
|
state.clusterTransforms.resize(mesh.clusters.size());
|
||||||
_cauterizeMeshStates.append(state);
|
_cauterizeMeshStates.append(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,47 +116,14 @@ void CauterizedModel::updateClusterMatrices() {
|
||||||
for (int j = 0; j < mesh.clusters.size(); j++) {
|
for (int j = 0; j < mesh.clusters.size(); j++) {
|
||||||
const FBXCluster& cluster = mesh.clusters.at(j);
|
const FBXCluster& cluster = mesh.clusters.at(j);
|
||||||
|
|
||||||
/* AJT: TODO REMOVE */
|
|
||||||
#ifdef SKIN_MATRIX
|
|
||||||
SKIN_ASSERT(false);
|
|
||||||
auto jointMatrix = _rig.getJointTransform(cluster.jointIndex);
|
auto jointMatrix = _rig.getJointTransform(cluster.jointIndex);
|
||||||
glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, state.clusterMatrices[j]);
|
|
||||||
#endif
|
|
||||||
#ifdef SKIN_COMP
|
#ifdef SKIN_COMP
|
||||||
|
// AJT: TODO: optimize
|
||||||
if (debug) {
|
glm::mat4 m;
|
||||||
qDebug() << "AJT: _meshState[" << i << "], cluster[" << j << "]";
|
glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, m);
|
||||||
}
|
state.clusterTransforms[j] = Model::TransformComponents(m);
|
||||||
|
#else
|
||||||
AnimPose jointPose = _rig.getJointPose(cluster.jointIndex);
|
glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, state.clusterTransforms[j]);
|
||||||
AnimPose result = jointPose * AnimPose(cluster.inverseBindMatrix);
|
|
||||||
result.rot() = glm::normalize(result.rot());
|
|
||||||
|
|
||||||
// pack scale rotation and translation into a mat4.
|
|
||||||
state.clusterMatrices[j][0].x = result.scale().x;
|
|
||||||
state.clusterMatrices[j][0].y = result.scale().y;
|
|
||||||
state.clusterMatrices[j][0].z = result.scale().z;
|
|
||||||
|
|
||||||
state.clusterMatrices[j][1].x = result.rot().x;
|
|
||||||
state.clusterMatrices[j][1].y = result.rot().y;
|
|
||||||
state.clusterMatrices[j][1].z = result.rot().z;
|
|
||||||
state.clusterMatrices[j][1].w = result.rot().w;
|
|
||||||
|
|
||||||
state.clusterMatrices[j][2].x = result.trans().x;
|
|
||||||
state.clusterMatrices[j][2].y = result.trans().y;
|
|
||||||
state.clusterMatrices[j][2].z = result.trans().z;
|
|
||||||
|
|
||||||
// AJT REMOVE
|
|
||||||
if (debug) {
|
|
||||||
glm::mat4 jointMatrix = _rig.getJointTransform(cluster.jointIndex);
|
|
||||||
glm::mat4 m;
|
|
||||||
glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, m);
|
|
||||||
qDebug() << "AJT: m =" << m;
|
|
||||||
qDebug() << "AJT: (AnimPose)m =" << AnimPose(m);
|
|
||||||
qDebug() << "AJT: result =" << result;
|
|
||||||
qDebug() << "AJT: (mat4)result =" << (glm::mat4)result;
|
|
||||||
SKIN_ASSERT(result.fuzzyEqual(AnimPose(m)));
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,60 +144,18 @@ void CauterizedModel::updateClusterMatrices() {
|
||||||
for (int j = 0; j < mesh.clusters.size(); j++) {
|
for (int j = 0; j < mesh.clusters.size(); j++) {
|
||||||
const FBXCluster& cluster = mesh.clusters.at(j);
|
const FBXCluster& cluster = mesh.clusters.at(j);
|
||||||
|
|
||||||
#ifdef SKIN_MATRIX
|
|
||||||
SKIN_ASSERT(false);
|
|
||||||
// AJT: TODO REMOVE:
|
|
||||||
auto jointMatrix = _rig.getJointTransform(cluster.jointIndex);
|
auto jointMatrix = _rig.getJointTransform(cluster.jointIndex);
|
||||||
if (_cauterizeBoneSet.find(cluster.jointIndex) != _cauterizeBoneSet.end()) {
|
if (_cauterizeBoneSet.find(cluster.jointIndex) != _cauterizeBoneSet.end()) {
|
||||||
jointMatrix = cauterizeMatrix;
|
jointMatrix = cauterizeMatrix;
|
||||||
}
|
}
|
||||||
glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, state.clusterMatrices[j]);
|
|
||||||
#endif
|
|
||||||
#ifdef SKIN_COMP
|
#ifdef SKIN_COMP
|
||||||
|
// AJT: TODO: optimize
|
||||||
if (debug) {
|
glm::mat4 m;
|
||||||
qDebug() << "AJT: CAUTERIZED _meshState[" << i << "], cluster[" << j << "]";
|
glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, m);
|
||||||
}
|
state.clusterTransforms[j] = Model::TransformComponents(m);
|
||||||
|
#else
|
||||||
auto jointPose = _rig.getJointPose(cluster.jointIndex);
|
glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, state.clusterTransforms[j]);
|
||||||
/*
|
|
||||||
if (_cauterizeBoneSet.find(cluster.jointIndex) != _cauterizeBoneSet.end()) {
|
|
||||||
jointPose = cauterizePose;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
AnimPose result = jointPose * AnimPose(cluster.inverseBindMatrix);
|
|
||||||
result.rot() = glm::normalize(result.rot());
|
|
||||||
|
|
||||||
// pack scale rotation and translation into a mat4.
|
|
||||||
state.clusterMatrices[j][0].x = result.scale().x;
|
|
||||||
state.clusterMatrices[j][0].y = result.scale().y;
|
|
||||||
state.clusterMatrices[j][0].z = result.scale().z;
|
|
||||||
|
|
||||||
state.clusterMatrices[j][1].x = result.rot().x;
|
|
||||||
state.clusterMatrices[j][1].y = result.rot().y;
|
|
||||||
state.clusterMatrices[j][1].z = result.rot().z;
|
|
||||||
state.clusterMatrices[j][1].w = result.rot().w;
|
|
||||||
|
|
||||||
state.clusterMatrices[j][2].x = result.trans().x;
|
|
||||||
state.clusterMatrices[j][2].y = result.trans().y;
|
|
||||||
state.clusterMatrices[j][2].z = result.trans().z;
|
|
||||||
|
|
||||||
// AJT REMOVE
|
|
||||||
auto jointMatrix = _rig.getJointTransform(cluster.jointIndex);
|
|
||||||
/*
|
|
||||||
if (_cauterizeBoneSet.find(cluster.jointIndex) != _cauterizeBoneSet.end()) {
|
|
||||||
jointMatrix = cauterizeMatrix;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
if (debug) {
|
|
||||||
glm::mat4 m;
|
|
||||||
glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, m);
|
|
||||||
qDebug() << "AJT: m =" << m;
|
|
||||||
qDebug() << "AJT: (AnimPose)m =" << AnimPose(m);
|
|
||||||
qDebug() << "AJT: result =" << result;
|
|
||||||
qDebug() << "AJT: (mat4)result =" << (glm::mat4)result;
|
|
||||||
SKIN_ASSERT(result.fuzzyEqual(AnimPose(m)));
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -288,43 +213,31 @@ void CauterizedModel::updateRenderItems() {
|
||||||
|
|
||||||
auto itemID = self->_modelMeshRenderItemIDs[i];
|
auto itemID = self->_modelMeshRenderItemIDs[i];
|
||||||
auto meshIndex = self->_modelMeshRenderItemShapes[i].meshIndex;
|
auto meshIndex = self->_modelMeshRenderItemShapes[i].meshIndex;
|
||||||
auto clusterMatrices(self->getMeshState(meshIndex).clusterMatrices);
|
auto clusterTransforms(self->getMeshState(meshIndex).clusterTransforms);
|
||||||
auto clusterMatricesCauterized(self->getCauterizeMeshState(meshIndex).clusterMatrices);
|
auto clusterTransformsCauterized(self->getCauterizeMeshState(meshIndex).clusterTransforms);
|
||||||
|
|
||||||
bool invalidatePayloadShapeKey = self->shouldInvalidatePayloadShapeKey(meshIndex);
|
bool invalidatePayloadShapeKey = self->shouldInvalidatePayloadShapeKey(meshIndex);
|
||||||
|
|
||||||
transaction.updateItem<CauterizedMeshPartPayload>(itemID, [modelTransform, clusterMatrices, clusterMatricesCauterized, invalidatePayloadShapeKey,
|
transaction.updateItem<CauterizedMeshPartPayload>(itemID, [modelTransform, clusterTransforms, clusterTransformsCauterized, invalidatePayloadShapeKey,
|
||||||
isWireframe, isVisible, isLayeredInFront, isLayeredInHUD, enableCauterization](CauterizedMeshPartPayload& data) {
|
isWireframe, isVisible, isLayeredInFront, isLayeredInHUD, enableCauterization](CauterizedMeshPartPayload& data) {
|
||||||
data.updateClusterBuffer(clusterMatrices, clusterMatricesCauterized);
|
data.updateClusterBuffer(clusterTransforms, clusterTransformsCauterized);
|
||||||
|
|
||||||
Transform renderTransform = modelTransform;
|
Transform renderTransform = modelTransform;
|
||||||
if (clusterMatrices.size() == 1) {
|
if (clusterTransforms.size() == 1) {
|
||||||
#ifdef SKIN_MATRIX
|
|
||||||
SKIN_ASSERT(false);
|
|
||||||
renderTransform = modelTransform.worldTransform(Transform(clusterMatrices[0]));
|
|
||||||
#endif
|
|
||||||
#ifdef SKIN_COMP
|
#ifdef SKIN_COMP
|
||||||
glm::vec3 scale(clusterMatrices[0][0]);
|
renderTransform = modelTransform.worldTransform(Transform(clusterTransforms[0].getMatrix()));
|
||||||
glm::quat rot(clusterMatrices[0][1].w, clusterMatrices[0][1].x, clusterMatrices[0][1].y, clusterMatrices[0][1].z);
|
#else
|
||||||
glm::vec3 trans(clusterMatrices[0][2]);
|
renderTransform = modelTransform.worldTransform(Transform(clusterTransforms[0]));
|
||||||
glm::mat4 m = createMatFromScaleQuatAndPos(scale, rot, trans);
|
|
||||||
renderTransform = modelTransform.worldTransform(Transform(m));
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
data.updateTransformForSkinnedMesh(renderTransform, modelTransform);
|
data.updateTransformForSkinnedMesh(renderTransform, modelTransform);
|
||||||
|
|
||||||
renderTransform = modelTransform;
|
renderTransform = modelTransform;
|
||||||
if (clusterMatricesCauterized.size() == 1) {
|
if (clusterTransformsCauterized.size() == 1) {
|
||||||
#ifdef SKIN_MATRIX
|
|
||||||
SKIN_ASSERT(false);
|
|
||||||
renderTransform = modelTransform.worldTransform(Transform(clusterMatricesCauterized[0]));
|
|
||||||
#endif
|
|
||||||
#ifdef SKIN_COMP
|
#ifdef SKIN_COMP
|
||||||
glm::vec3 scale(clusterMatricesCauterized[0][0]);
|
renderTransform = modelTransform.worldTransform(Transform(clusterTransformsCauterized[0].getMatrix()));
|
||||||
glm::quat rot(clusterMatricesCauterized[0][1].w, clusterMatricesCauterized[0][1].x, clusterMatricesCauterized[0][1].y, clusterMatricesCauterized[0][1].z);
|
#else
|
||||||
glm::vec3 trans(clusterMatricesCauterized[0][2]);
|
renderTransform = modelTransform.worldTransform(Transform(clusterTransformsCauterized[0]));
|
||||||
glm::mat4 m = createMatFromScaleQuatAndPos(scale, rot, trans);
|
|
||||||
renderTransform = modelTransform.worldTransform(Transform(m));
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
data.updateTransformForCauterizedMesh(renderTransform);
|
data.updateTransformForCauterizedMesh(renderTransform);
|
||||||
|
|
|
@ -326,22 +326,17 @@ ModelMeshPartPayload::ModelMeshPartPayload(ModelPointer model, int meshIndex, in
|
||||||
const Model::MeshState& state = model->getMeshState(_meshIndex);
|
const Model::MeshState& state = model->getMeshState(_meshIndex);
|
||||||
|
|
||||||
updateMeshPart(modelMesh, partIndex);
|
updateMeshPart(modelMesh, partIndex);
|
||||||
computeAdjustedLocalBound(state.clusterMatrices);
|
computeAdjustedLocalBound(state.clusterTransforms);
|
||||||
|
|
||||||
updateTransform(transform, offsetTransform);
|
updateTransform(transform, offsetTransform);
|
||||||
Transform renderTransform = transform;
|
Transform renderTransform = transform;
|
||||||
if (state.clusterMatrices.size() == 1) {
|
if (state.clusterTransforms.size() == 1) {
|
||||||
#ifdef SKIN_MATRIX
|
|
||||||
SKIN_ASSERT(false);
|
|
||||||
renderTransform = transform.worldTransform(Transform(state.clusterMatrices[0]));
|
|
||||||
#endif
|
|
||||||
#ifdef SKIN_COMP
|
#ifdef SKIN_COMP
|
||||||
glm::vec3 scale(state.clusterMatrices[0][0]);
|
renderTransform = transform.worldTransform(Transform(state.clusterTransforms[0].getMatrix()));
|
||||||
glm::quat rot(state.clusterMatrices[0][1].w, state.clusterMatrices[0][1].x, state.clusterMatrices[0][1].y, state.clusterMatrices[0][1].z);
|
#else
|
||||||
glm::vec3 trans(state.clusterMatrices[0][2]);
|
renderTransform = transform.worldTransform(Transform(state.clusterTransforms[0]));
|
||||||
glm::mat4 m = createMatFromScaleQuatAndPos(scale, rot, trans);
|
|
||||||
renderTransform = transform.worldTransform(Transform(m));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
updateTransformForSkinnedMesh(renderTransform, transform);
|
updateTransformForSkinnedMesh(renderTransform, transform);
|
||||||
|
|
||||||
|
@ -371,20 +366,36 @@ void ModelMeshPartPayload::notifyLocationChanged() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SKIN_COMP
|
||||||
void ModelMeshPartPayload::updateClusterBuffer(const std::vector<glm::mat4>& clusterMatrices) {
|
void ModelMeshPartPayload::updateClusterBuffer(const std::vector<Model::TransformComponents>& clusterTransforms) {
|
||||||
// Once computed the cluster matrices, update the buffer(s)
|
// Once computed the cluster matrices, update the buffer(s)
|
||||||
if (clusterMatrices.size() > 1) {
|
if (clusterTransforms.size() > 1) {
|
||||||
if (!_clusterBuffer) {
|
if (!_clusterBuffer) {
|
||||||
_clusterBuffer = std::make_shared<gpu::Buffer>(clusterMatrices.size() * sizeof(glm::mat4),
|
_clusterBuffer = std::make_shared<gpu::Buffer>(clusterTransforms.size() * sizeof(Model::TransformComponents),
|
||||||
(const gpu::Byte*) clusterMatrices.data());
|
(const gpu::Byte*) clusterTransforms.data());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_clusterBuffer->setSubData(0, clusterMatrices.size() * sizeof(glm::mat4),
|
_clusterBuffer->setSubData(0, clusterTransforms.size() * sizeof(Model::TransformComponents),
|
||||||
(const gpu::Byte*) clusterMatrices.data());
|
(const gpu::Byte*) clusterTransforms.data());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
void ModelMeshPartPayload::updateClusterBuffer(const std::vector<glm::mat4>& clusterTransforms) {
|
||||||
|
// Once computed the cluster matrices, update the buffer(s)
|
||||||
|
if (clusterTransforms.size() > 1) {
|
||||||
|
if (!_clusterBuffer) {
|
||||||
|
_clusterBuffer = std::make_shared<gpu::Buffer>(clusterTransforms.size() * sizeof(glm::mat4),
|
||||||
|
(const gpu::Byte*) clusterTransforms.data());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_clusterBuffer->setSubData(0, clusterTransforms.size() * sizeof(glm::mat4),
|
||||||
|
(const gpu::Byte*) clusterTransforms.data());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void ModelMeshPartPayload::updateTransformForSkinnedMesh(const Transform& renderTransform, const Transform& boundTransform) {
|
void ModelMeshPartPayload::updateTransformForSkinnedMesh(const Transform& renderTransform, const Transform& boundTransform) {
|
||||||
_transform = renderTransform;
|
_transform = renderTransform;
|
||||||
|
@ -550,23 +561,27 @@ void ModelMeshPartPayload::render(RenderArgs* args) {
|
||||||
args->_details._trianglesRendered += _drawPart._numIndices / INDICES_PER_TRIANGLE;
|
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[0]);
|
|
||||||
for (int i = 1; i < (int)clusterMatrices.size(); ++i) {
|
|
||||||
AABox clusterBound = _localBound;
|
|
||||||
#ifdef SKIN_MATRIX
|
|
||||||
SKIN_ASSERT(false);
|
|
||||||
clusterBound.transform(clusterMatrices[i]);
|
|
||||||
#endif
|
|
||||||
#ifdef SKIN_COMP
|
#ifdef SKIN_COMP
|
||||||
// AJT: FIXME: TODO: SLOW AS SHIT
|
void ModelMeshPartPayload::computeAdjustedLocalBound(const std::vector<Model::TransformComponents>& clusterTransforms) {
|
||||||
glm::vec3 scale(clusterMatrices[i][0]);
|
#else
|
||||||
glm::quat rot(clusterMatrices[i][1].w, clusterMatrices[i][1].x, clusterMatrices[i][1].y, clusterMatrices[i][1].z);
|
void ModelMeshPartPayload::computeAdjustedLocalBound(const std::vector<glm::mat4>& clusterTransforms) {
|
||||||
glm::vec3 trans(clusterMatrices[i][2]);
|
#endif
|
||||||
glm::mat4 m = createMatFromScaleQuatAndPos(scale, rot, trans);
|
_adjustedLocalBound = _localBound;
|
||||||
clusterBound.transform(m);
|
if (clusterTransforms.size() > 0) {
|
||||||
|
#ifdef SKIN_COMP
|
||||||
|
// AJT: TODO: optimize
|
||||||
|
_adjustedLocalBound.transform(clusterTransforms[0].getMatrix());
|
||||||
|
#else
|
||||||
|
_adjustedLocalBound.transform(clusterTransforms[0]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (int i = 1; i < (int)clusterTransforms.size(); ++i) {
|
||||||
|
AABox clusterBound = _localBound;
|
||||||
|
#ifdef SKIN_COMP
|
||||||
|
// AJT: TODO: optimize
|
||||||
|
clusterBound.transform(clusterTransforms[i].getMatrix());
|
||||||
|
#else
|
||||||
|
clusterBound.transform(clusterTransforms[i]);
|
||||||
#endif
|
#endif
|
||||||
_adjustedLocalBound += clusterBound;
|
_adjustedLocalBound += clusterBound;
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,11 @@ public:
|
||||||
typedef Payload::DataPointer Pointer;
|
typedef Payload::DataPointer Pointer;
|
||||||
|
|
||||||
void notifyLocationChanged() override;
|
void notifyLocationChanged() override;
|
||||||
void updateClusterBuffer(const std::vector<glm::mat4>& clusterMatrices);
|
#ifdef SKIN_COMP
|
||||||
|
void updateClusterBuffer(const std::vector<Model::TransformComponents>& clusterTransforms);
|
||||||
|
#else
|
||||||
|
void updateClusterBuffer(const std::vector<glm::mat4>& clusterTransforms);
|
||||||
|
#endif
|
||||||
void updateTransformForSkinnedMesh(const Transform& renderTransform, const Transform& boundTransform);
|
void updateTransformForSkinnedMesh(const Transform& renderTransform, const Transform& boundTransform);
|
||||||
|
|
||||||
// Render Item interface
|
// Render Item interface
|
||||||
|
@ -104,7 +108,11 @@ public:
|
||||||
void bindMesh(gpu::Batch& batch) override;
|
void bindMesh(gpu::Batch& batch) override;
|
||||||
void bindTransform(gpu::Batch& batch, const render::ShapePipeline::LocationsPointer locations, RenderArgs::RenderMode renderMode) const override;
|
void bindTransform(gpu::Batch& batch, const render::ShapePipeline::LocationsPointer locations, RenderArgs::RenderMode renderMode) const override;
|
||||||
|
|
||||||
|
#ifdef SKIN_COMP
|
||||||
|
void computeAdjustedLocalBound(const std::vector<Model::TransformComponents>& clusterTransforms);
|
||||||
|
#else
|
||||||
void computeAdjustedLocalBound(const std::vector<glm::mat4>& clusterMatrices);
|
void computeAdjustedLocalBound(const std::vector<glm::mat4>& clusterMatrices);
|
||||||
|
#endif
|
||||||
|
|
||||||
gpu::BufferPointer _clusterBuffer;
|
gpu::BufferPointer _clusterBuffer;
|
||||||
|
|
||||||
|
|
|
@ -266,25 +266,20 @@ void Model::updateRenderItems() {
|
||||||
|
|
||||||
auto itemID = self->_modelMeshRenderItemIDs[i];
|
auto itemID = self->_modelMeshRenderItemIDs[i];
|
||||||
auto meshIndex = self->_modelMeshRenderItemShapes[i].meshIndex;
|
auto meshIndex = self->_modelMeshRenderItemShapes[i].meshIndex;
|
||||||
auto clusterMatrices(self->getMeshState(meshIndex).clusterMatrices);
|
auto clusterTransforms(self->getMeshState(meshIndex).clusterTransforms);
|
||||||
|
|
||||||
bool invalidatePayloadShapeKey = self->shouldInvalidatePayloadShapeKey(meshIndex);
|
bool invalidatePayloadShapeKey = self->shouldInvalidatePayloadShapeKey(meshIndex);
|
||||||
|
|
||||||
transaction.updateItem<ModelMeshPartPayload>(itemID, [modelTransform, clusterMatrices, invalidatePayloadShapeKey,
|
transaction.updateItem<ModelMeshPartPayload>(itemID, [modelTransform, clusterTransforms, invalidatePayloadShapeKey,
|
||||||
isWireframe, isVisible, isLayeredInFront, isLayeredInHUD](ModelMeshPartPayload& data) {
|
isWireframe, isVisible, isLayeredInFront, isLayeredInHUD](ModelMeshPartPayload& data) {
|
||||||
data.updateClusterBuffer(clusterMatrices);
|
data.updateClusterBuffer(clusterTransforms);
|
||||||
|
|
||||||
Transform renderTransform = modelTransform;
|
Transform renderTransform = modelTransform;
|
||||||
if (clusterMatrices.size() == 1) {
|
if (clusterTransforms.size() == 1) {
|
||||||
#ifdef SKIN_MATRIX
|
|
||||||
SKIN_ASSERT(false);
|
|
||||||
renderTransform = modelTransform.worldTransform(Transform(clusterMatrices[0]));
|
|
||||||
#endif
|
|
||||||
#ifdef SKIN_COMP
|
#ifdef SKIN_COMP
|
||||||
glm::vec3 scale(clusterMatrices[0][0]);
|
renderTransform = modelTransform.worldTransform(Transform(clusterTransforms[0].getMatrix()));
|
||||||
glm::quat rot(clusterMatrices[0][1].w, clusterMatrices[0][1].x, clusterMatrices[0][1].y, clusterMatrices[0][1].z);
|
#else
|
||||||
glm::vec3 trans(clusterMatrices[0][2]);
|
renderTransform = modelTransform.worldTransform(Transform(clusterTransforms[0]));
|
||||||
glm::mat4 m = createMatFromScaleQuatAndPos(scale, rot, trans);
|
|
||||||
renderTransform = modelTransform.worldTransform(Transform(m));
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
data.updateTransformForSkinnedMesh(renderTransform, modelTransform);
|
data.updateTransformForSkinnedMesh(renderTransform, modelTransform);
|
||||||
|
@ -338,7 +333,7 @@ bool Model::updateGeometry() {
|
||||||
const FBXGeometry& fbxGeometry = getFBXGeometry();
|
const FBXGeometry& fbxGeometry = getFBXGeometry();
|
||||||
foreach (const FBXMesh& mesh, fbxGeometry.meshes) {
|
foreach (const FBXMesh& mesh, fbxGeometry.meshes) {
|
||||||
MeshState state;
|
MeshState state;
|
||||||
state.clusterMatrices.resize(mesh.clusters.size());
|
state.clusterTransforms.resize(mesh.clusters.size());
|
||||||
_meshStates.push_back(state);
|
_meshStates.push_back(state);
|
||||||
|
|
||||||
// Note: we add empty buffers for meshes that lack blendshapes so we can access the buffers by index
|
// Note: we add empty buffers for meshes that lack blendshapes so we can access the buffers by index
|
||||||
|
@ -1169,7 +1164,7 @@ void Model::updateRig(float deltaTime, glm::mat4 parentTransform) {
|
||||||
void Model::computeMeshPartLocalBounds() {
|
void Model::computeMeshPartLocalBounds() {
|
||||||
for (auto& part : _modelMeshRenderItems) {
|
for (auto& part : _modelMeshRenderItems) {
|
||||||
const Model::MeshState& state = _meshStates.at(part->_meshIndex);
|
const Model::MeshState& state = _meshStates.at(part->_meshIndex);
|
||||||
part->computeAdjustedLocalBound(state.clusterMatrices);
|
part->computeAdjustedLocalBound(state.clusterTransforms);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1187,30 +1182,14 @@ void Model::updateClusterMatrices() {
|
||||||
const FBXMesh& mesh = geometry.meshes.at(i);
|
const FBXMesh& mesh = geometry.meshes.at(i);
|
||||||
for (int j = 0; j < mesh.clusters.size(); j++) {
|
for (int j = 0; j < mesh.clusters.size(); j++) {
|
||||||
const FBXCluster& cluster = mesh.clusters.at(j);
|
const FBXCluster& cluster = mesh.clusters.at(j);
|
||||||
|
|
||||||
// AJT: TODO FIXME
|
|
||||||
#ifdef SKIN_MATRIX
|
|
||||||
SKIN_ASSERT(false);
|
|
||||||
auto jointMatrix = _rig.getJointTransform(cluster.jointIndex);
|
auto jointMatrix = _rig.getJointTransform(cluster.jointIndex);
|
||||||
glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, state.clusterMatrices[j]);
|
|
||||||
#endif
|
|
||||||
#ifdef SKIN_COMP
|
#ifdef SKIN_COMP
|
||||||
AnimPose jointPose = _rig.getJointPose(cluster.jointIndex);
|
// AJT: TODO: optimize
|
||||||
AnimPose result = jointPose * AnimPose(cluster.inverseBindMatrix);
|
glm::mat4 mat;
|
||||||
|
glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, mat);
|
||||||
// pack scale rotation and translation into a mat4.
|
state.clusterTransforms[j] = TransformComponents(mat);
|
||||||
state.clusterMatrices[j][0].x = result.scale().x;
|
#else
|
||||||
state.clusterMatrices[j][0].y = result.scale().y;
|
glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, state.clusterTransforms[j]);
|
||||||
state.clusterMatrices[j][0].z = result.scale().z;
|
|
||||||
|
|
||||||
state.clusterMatrices[j][1].x = result.rot().x;
|
|
||||||
state.clusterMatrices[j][1].y = result.rot().y;
|
|
||||||
state.clusterMatrices[j][1].z = result.rot().z;
|
|
||||||
state.clusterMatrices[j][1].w = result.rot().w;
|
|
||||||
|
|
||||||
state.clusterMatrices[j][2].x = result.trans().x;
|
|
||||||
state.clusterMatrices[j][2].y = result.trans().y;
|
|
||||||
state.clusterMatrices[j][2].z = result.trans().z;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,8 +43,6 @@
|
||||||
} \
|
} \
|
||||||
} while(false)
|
} while(false)
|
||||||
|
|
||||||
//#define SKIN_MATRIX
|
|
||||||
//#define SKIN_DUAL_QUAT
|
|
||||||
#define SKIN_COMP
|
#define SKIN_COMP
|
||||||
|
|
||||||
class AbstractViewStateInterface;
|
class AbstractViewStateInterface;
|
||||||
|
@ -257,9 +255,50 @@ public:
|
||||||
int getRenderInfoDrawCalls() const { return _renderInfoDrawCalls; }
|
int getRenderInfoDrawCalls() const { return _renderInfoDrawCalls; }
|
||||||
bool getRenderInfoHasTransparent() const { return _renderInfoHasTransparent; }
|
bool getRenderInfoHasTransparent() const { return _renderInfoHasTransparent; }
|
||||||
|
|
||||||
|
class TransformComponents {
|
||||||
|
public:
|
||||||
|
TransformComponents() {}
|
||||||
|
TransformComponents(const glm::mat4& m) {
|
||||||
|
AnimPose p(m);
|
||||||
|
_scale.x = p.scale().x;
|
||||||
|
_scale.y = p.scale().y;
|
||||||
|
_scale.z = p.scale().z;
|
||||||
|
_rot = p.rot();
|
||||||
|
_trans.x = p.trans().x;
|
||||||
|
_trans.y = p.trans().y;
|
||||||
|
_trans.z = p.trans().z;
|
||||||
|
}
|
||||||
|
|
||||||
|
TransformComponents(const glm::vec3& scale, const glm::quat& rot, const glm::vec3& trans) {
|
||||||
|
_scale.x = scale.x;
|
||||||
|
_scale.y = scale.y;
|
||||||
|
_scale.z = scale.z;
|
||||||
|
_rot = rot;
|
||||||
|
_trans.x = trans.x;
|
||||||
|
_trans.y = trans.y;
|
||||||
|
_trans.z = trans.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 getScale() const { return glm::vec3(_scale); }
|
||||||
|
glm::quat getRot() const { return _rot; }
|
||||||
|
glm::vec3 getTrans() const { return glm::vec3(_trans); }
|
||||||
|
glm::mat4 getMatrix() const { return createMatFromScaleQuatAndPos(getScale(), getRot(), getTrans()); };
|
||||||
|
|
||||||
|
protected:
|
||||||
|
glm::vec4 _scale { 1.0f, 1.0f, 1.0f, 0.0f };
|
||||||
|
glm::quat _rot { 1.0f, 0.0f, 0.0f, 0.0f };
|
||||||
|
glm::vec4 _trans { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||||
|
glm::vec4 _padding { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||||
|
};
|
||||||
|
|
||||||
class MeshState {
|
class MeshState {
|
||||||
public:
|
public:
|
||||||
std::vector<glm::mat4> clusterMatrices;
|
#ifdef SKIN_COMP
|
||||||
|
std::vector<TransformComponents> clusterTransforms;
|
||||||
|
#else
|
||||||
|
std::vector<glm::mat4> clusterTransforms;
|
||||||
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const MeshState& getMeshState(int index) { return _meshStates.at(index); }
|
const MeshState& getMeshState(int index) { return _meshStates.at(index); }
|
||||||
|
|
|
@ -38,60 +38,11 @@ void dqMul(vec4 lhsReal, vec4 lhsImag, vec4 rhsReal, vec4 rhsImag, out vec4 real
|
||||||
imagOut = quatMul(lhsReal, rhsImag) + quatMul(lhsImag, rhsReal);
|
imagOut = quatMul(lhsReal, rhsImag) + quatMul(lhsImag, rhsReal);
|
||||||
}
|
}
|
||||||
|
|
||||||
// dual quat blend
|
void skinPosition(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPosition, out vec4 skinnedPosition) {
|
||||||
void blendClusters_dual_quat(ivec4 skinClusterIndex, vec4 skinClusterWeight, out vec3 scaleOut, out vec4 rotOut, out vec3 posOut) {
|
vec3 sAccum = vec3(0.0, 0.0, 0.0);
|
||||||
vec3 scale = vec3(0.0, 0.0, 0.0);
|
vec4 rAccum = vec4(0.0, 0.0, 0.0, 0.0);
|
||||||
vec4 dqReal = vec4(0.0, 0.0, 0.0, 0.0);
|
vec3 tAccum = vec3(0.0, 0.0, 0.0);
|
||||||
vec4 dqImag = vec4(0.0, 0.0, 0.0, 0.0);
|
|
||||||
for (int i = 0; i < INDICES_PER_VERTEX; i++) {
|
|
||||||
mat4 clusterMatrix = clusterMatrices[(skinClusterIndex[i])];
|
|
||||||
float clusterWeight = skinClusterWeight[i];
|
|
||||||
|
|
||||||
vec3 s = vec3(clusterMatrix[0][0], clusterMatrix[0][1], clusterMatrix[0][2]);
|
|
||||||
vec4 dqr = vec4(clusterMatrix[1][0], clusterMatrix[1][1], clusterMatrix[1][2], clusterMatrix[1][3]);
|
|
||||||
vec4 dqi = vec4(clusterMatrix[2][0], clusterMatrix[2][1], clusterMatrix[2][2], clusterMatrix[2][3]);
|
|
||||||
|
|
||||||
scale += s * clusterWeight;
|
|
||||||
dqReal += dqr * clusterWeight;
|
|
||||||
dqImag += dqi * clusterWeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
scaleOut = scale;
|
|
||||||
|
|
||||||
float dqLen = length(dqReal);
|
|
||||||
dqReal *= 1.0 / dqLen;
|
|
||||||
dqImag *= 1.0 / dqLen;
|
|
||||||
|
|
||||||
rotOut = dqReal;
|
|
||||||
|
|
||||||
vec4 invReal = quatConj(dqReal);
|
|
||||||
posOut.xyz = 2.0 * quatMul(dqImag, invReal).xyz;
|
|
||||||
}
|
|
||||||
|
|
||||||
// rigid dual quat blend
|
|
||||||
void blendClusters_rigid_dual_quat(ivec4 skinClusterIndex, vec4 skinClusterWeight, out vec3 scaleOut, out vec4 rotOut, out vec3 posOut) {
|
|
||||||
float maxWeight = 0.0;
|
|
||||||
for (int i = 0; i < INDICES_PER_VERTEX; i++) {
|
|
||||||
mat4 clusterMatrix = clusterMatrices[(skinClusterIndex[i])];
|
|
||||||
float clusterWeight = skinClusterWeight[i];
|
|
||||||
|
|
||||||
vec3 s = vec3(clusterMatrix[0][0], clusterMatrix[0][1], clusterMatrix[0][2]);
|
|
||||||
vec4 dqr = vec4(clusterMatrix[1][0], clusterMatrix[1][1], clusterMatrix[1][2], clusterMatrix[1][3]);
|
|
||||||
vec4 dqi = vec4(clusterMatrix[2][0], clusterMatrix[2][1], clusterMatrix[2][2], clusterMatrix[2][3]);
|
|
||||||
|
|
||||||
if (clusterWeight > maxWeight) {
|
|
||||||
maxWeight = clusterWeight;
|
|
||||||
scaleOut = s;
|
|
||||||
rotOut = dqr;
|
|
||||||
vec4 invReal = quatConj(dqr);
|
|
||||||
posOut = 2.0 * quatMul(dqi, invReal).xyz;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// rigid componentwise blend
|
|
||||||
void blendClusters(ivec4 skinClusterIndex, vec4 skinClusterWeight, out vec3 scaleOut, out vec4 rotOut, out vec3 posOut) {
|
|
||||||
float maxWeight = 0.0;
|
|
||||||
for (int i = 0; i < INDICES_PER_VERTEX; i++) {
|
for (int i = 0; i < INDICES_PER_VERTEX; i++) {
|
||||||
mat4 clusterMatrix = clusterMatrices[(skinClusterIndex[i])];
|
mat4 clusterMatrix = clusterMatrices[(skinClusterIndex[i])];
|
||||||
float clusterWeight = skinClusterWeight[i];
|
float clusterWeight = skinClusterWeight[i];
|
||||||
|
@ -100,51 +51,83 @@ void blendClusters(ivec4 skinClusterIndex, vec4 skinClusterWeight, out vec3 scal
|
||||||
vec4 r = vec4(clusterMatrix[1][0], clusterMatrix[1][1], clusterMatrix[1][2], clusterMatrix[1][3]);
|
vec4 r = vec4(clusterMatrix[1][0], clusterMatrix[1][1], clusterMatrix[1][2], clusterMatrix[1][3]);
|
||||||
vec3 t = vec3(clusterMatrix[2][0], clusterMatrix[2][1], clusterMatrix[2][2]);
|
vec3 t = vec3(clusterMatrix[2][0], clusterMatrix[2][1], clusterMatrix[2][2]);
|
||||||
|
|
||||||
if (clusterWeight > maxWeight) {
|
if (dot(r, rAccum) < 0) {
|
||||||
maxWeight = clusterWeight;
|
r = -r;
|
||||||
scaleOut = s;
|
|
||||||
rotOut = r;
|
|
||||||
posOut = t;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sAccum += s * clusterWeight;
|
||||||
|
rAccum += r * clusterWeight;
|
||||||
|
tAccum += t * clusterWeight;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void skinPosition(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPosition, out vec4 skinnedPosition) {
|
rAccum = normalize(rAccum);
|
||||||
|
|
||||||
vec3 scale, pos;
|
skinnedPosition = vec4(rotateByQuat(rAccum, (vec3(inPosition) * sAccum)) + tAccum, 1);
|
||||||
vec4 rot;
|
|
||||||
blendClusters(skinClusterIndex, skinClusterWeight, scale, rot, pos);
|
|
||||||
|
|
||||||
skinnedPosition.xyz = rotateByQuat(rot, (vec3(inPosition) * scale)) + pos;
|
|
||||||
skinnedPosition.w = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void skinPositionNormal(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPosition, vec3 inNormal,
|
void skinPositionNormal(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPosition, vec3 inNormal,
|
||||||
out vec4 skinnedPosition, out vec3 skinnedNormal) {
|
out vec4 skinnedPosition, out vec3 skinnedNormal) {
|
||||||
|
|
||||||
vec3 scale, pos;
|
vec3 sAccum = vec3(0.0, 0.0, 0.0);
|
||||||
vec4 rot;
|
vec4 rAccum = vec4(0.0, 0.0, 0.0, 0.0);
|
||||||
blendClusters(skinClusterIndex, skinClusterWeight, scale, rot, pos);
|
vec3 tAccum = vec3(0.0, 0.0, 0.0);
|
||||||
|
|
||||||
skinnedNormal.xyz = rotateByQuat(rot, inNormal * scale);
|
for (int i = 0; i < INDICES_PER_VERTEX; i++) {
|
||||||
|
mat4 clusterMatrix = clusterMatrices[(skinClusterIndex[i])];
|
||||||
|
float clusterWeight = skinClusterWeight[i];
|
||||||
|
|
||||||
|
vec3 s = vec3(clusterMatrix[0][0], clusterMatrix[0][1], clusterMatrix[0][2]);
|
||||||
|
vec4 r = vec4(clusterMatrix[1][0], clusterMatrix[1][1], clusterMatrix[1][2], clusterMatrix[1][3]);
|
||||||
|
vec3 t = vec3(clusterMatrix[2][0], clusterMatrix[2][1], clusterMatrix[2][2]);
|
||||||
|
|
||||||
|
if (dot(r, rAccum) < 0) {
|
||||||
|
r = -r;
|
||||||
|
}
|
||||||
|
|
||||||
|
sAccum += s * clusterWeight;
|
||||||
|
rAccum += r * clusterWeight;
|
||||||
|
tAccum += t * clusterWeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
rAccum = normalize(rAccum);
|
||||||
|
|
||||||
|
skinnedPosition = vec4(rotateByQuat(rAccum, (vec3(inPosition) * sAccum)) + tAccum, 1);
|
||||||
|
skinnedNormal = rotateByQuat(rAccum, inNormal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void skinPositionNormalTangent(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPosition, vec3 inNormal, vec3 inTangent,
|
void skinPositionNormalTangent(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPosition, vec3 inNormal, vec3 inTangent,
|
||||||
out vec4 skinnedPosition, out vec3 skinnedNormal, out vec3 skinnedTangent) {
|
out vec4 skinnedPosition, out vec3 skinnedNormal, out vec3 skinnedTangent) {
|
||||||
|
|
||||||
vec3 scale, pos;
|
vec3 sAccum = vec3(0.0, 0.0, 0.0);
|
||||||
vec4 rot;
|
vec4 rAccum = vec4(0.0, 0.0, 0.0, 0.0);
|
||||||
blendClusters(skinClusterIndex, skinClusterWeight, scale, rot, pos);
|
vec3 tAccum = vec3(0.0, 0.0, 0.0);
|
||||||
|
|
||||||
skinnedPosition.xyz = rotateByQuat(rot, (vec3(inPosition) * scale)) + pos;
|
for (int i = 0; i < INDICES_PER_VERTEX; i++) {
|
||||||
skinnedPosition.w = 1;
|
mat4 clusterMatrix = clusterMatrices[(skinClusterIndex[i])];
|
||||||
|
float clusterWeight = skinClusterWeight[i];
|
||||||
|
|
||||||
skinnedNormal = rotateByQuat(rot, inNormal * scale);
|
vec3 s = vec3(clusterMatrix[0][0], clusterMatrix[0][1], clusterMatrix[0][2]);
|
||||||
skinnedTangent = rotateByQuat(rot, inTangent * scale);
|
vec4 r = vec4(clusterMatrix[1][0], clusterMatrix[1][1], clusterMatrix[1][2], clusterMatrix[1][3]);
|
||||||
|
vec3 t = vec3(clusterMatrix[2][0], clusterMatrix[2][1], clusterMatrix[2][2]);
|
||||||
|
|
||||||
|
if (dot(r, rAccum) < 0) {
|
||||||
|
r = -r;
|
||||||
|
}
|
||||||
|
|
||||||
|
sAccum += s * clusterWeight;
|
||||||
|
rAccum += r * clusterWeight;
|
||||||
|
tAccum += t * clusterWeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
rAccum = normalize(rAccum);
|
||||||
|
|
||||||
|
skinnedPosition = vec4(rotateByQuat(rAccum, (vec3(inPosition) * sAccum)) + tAccum, 1);
|
||||||
|
skinnedNormal = rotateByQuat(rAccum, inNormal);
|
||||||
|
skinnedTangent = rotateByQuat(rAccum, inTangent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ORIGINAL
|
|
||||||
/*
|
/*
|
||||||
|
// ORIGINAL
|
||||||
void skinPosition(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPosition, out vec4 skinnedPosition) {
|
void skinPosition(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPosition, out vec4 skinnedPosition) {
|
||||||
vec4 newPosition = vec4(0.0, 0.0, 0.0, 0.0);
|
vec4 newPosition = vec4(0.0, 0.0, 0.0, 0.0);
|
||||||
|
|
||||||
|
@ -193,5 +176,4 @@ void skinPositionNormalTangent(ivec4 skinClusterIndex, vec4 skinClusterWeight, v
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
<@endif@>
|
<@endif@>
|
||||||
|
|
|
@ -50,7 +50,6 @@ void SoftAttachmentModel::updateClusterMatrices() {
|
||||||
for (int j = 0; j < mesh.clusters.size(); j++) {
|
for (int j = 0; j < mesh.clusters.size(); j++) {
|
||||||
const FBXCluster& cluster = mesh.clusters.at(j);
|
const FBXCluster& cluster = mesh.clusters.at(j);
|
||||||
|
|
||||||
#ifdef SKIN_MATRIX
|
|
||||||
// TODO: cache these look-ups as an optimization
|
// TODO: cache these look-ups as an optimization
|
||||||
int jointIndexOverride = getJointIndexOverride(cluster.jointIndex);
|
int jointIndexOverride = getJointIndexOverride(cluster.jointIndex);
|
||||||
glm::mat4 jointMatrix;
|
glm::mat4 jointMatrix;
|
||||||
|
@ -59,35 +58,14 @@ void SoftAttachmentModel::updateClusterMatrices() {
|
||||||
} else {
|
} else {
|
||||||
jointMatrix = _rig.getJointTransform(cluster.jointIndex);
|
jointMatrix = _rig.getJointTransform(cluster.jointIndex);
|
||||||
}
|
}
|
||||||
SKIN_ASSERT(false);
|
|
||||||
glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, state.clusterMatrices[j]);
|
|
||||||
#endif
|
|
||||||
#ifdef SKIN_COMP
|
#ifdef SKIN_COMP
|
||||||
// TODO: cache these look-ups as an optimization
|
// AJT: TODO: Optimize
|
||||||
int jointIndexOverride = getJointIndexOverride(cluster.jointIndex);
|
glm::mat4 m;
|
||||||
AnimPose jointPose;
|
glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, m);
|
||||||
if (jointIndexOverride >= 0 && jointIndexOverride < _rigOverride.getJointStateCount()) {
|
state.clusterTransforms[j] = Model::TransformComponents(m);
|
||||||
jointPose = _rigOverride.getJointPose(jointIndexOverride);
|
#else
|
||||||
} else {
|
glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, state.clusterTransforms[j]);
|
||||||
jointPose = _rig.getJointPose(cluster.jointIndex);
|
|
||||||
}
|
|
||||||
AnimPose result = jointPose * AnimPose(cluster.inverseBindMatrix);
|
|
||||||
|
|
||||||
// pack scale rotation and translation into a mat4.
|
|
||||||
state.clusterMatrices[j][0].x = result.scale().x;
|
|
||||||
state.clusterMatrices[j][0].y = result.scale().y;
|
|
||||||
state.clusterMatrices[j][0].z = result.scale().z;
|
|
||||||
|
|
||||||
state.clusterMatrices[j][1].x = result.rot().x;
|
|
||||||
state.clusterMatrices[j][1].y = result.rot().y;
|
|
||||||
state.clusterMatrices[j][1].z = result.rot().z;
|
|
||||||
state.clusterMatrices[j][1].w = result.rot().w;
|
|
||||||
|
|
||||||
state.clusterMatrices[j][2].x = result.trans().x;
|
|
||||||
state.clusterMatrices[j][2].y = result.trans().y;
|
|
||||||
state.clusterMatrices[j][2].z = result.trans().z;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue