mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-21 00:25:44 +00:00
fix: gltf mesh wrong bone and invertBindMatrix transformations
This commit is contained in:
parent
17dee65337
commit
9979275f8c
@ -5,6 +5,7 @@
|
|||||||
#include "XModel/Gltf/GltfConstants.h"
|
#include "XModel/Gltf/GltfConstants.h"
|
||||||
#include "XModel/Gltf/JsonGltf.h"
|
#include "XModel/Gltf/JsonGltf.h"
|
||||||
|
|
||||||
|
#include <Eigen>
|
||||||
#include <format>
|
#include <format>
|
||||||
|
|
||||||
using namespace gltf;
|
using namespace gltf;
|
||||||
@ -222,20 +223,27 @@ namespace
|
|||||||
JsonNode boneNode;
|
JsonNode boneNode;
|
||||||
const auto& bone = xmodel.m_bones[boneIndex];
|
const auto& bone = xmodel.m_bones[boneIndex];
|
||||||
|
|
||||||
Vector3f translation(bone.globalOffset[0], bone.globalOffset[2], -bone.globalOffset[1]);
|
Eigen::Vector3f translation(bone.globalOffset[0], bone.globalOffset[2], -bone.globalOffset[1]);
|
||||||
Quaternion32 rotation(bone.globalRotation.m_x, bone.globalRotation.m_z, -bone.globalRotation.m_y, bone.globalRotation.m_w);
|
Eigen::Quaternionf rotation(bone.globalRotation.m_w, bone.globalRotation.m_x, bone.globalRotation.m_z, -bone.globalRotation.m_y);
|
||||||
if (bone.parentIndex >= 0)
|
if (bone.parentIndex >= 0)
|
||||||
{
|
{
|
||||||
const auto& parentBone = xmodel.m_bones[bone.parentIndex];
|
const auto& parentBone = xmodel.m_bones[bone.parentIndex];
|
||||||
translation -= Vector3f(parentBone.globalOffset[0], parentBone.globalOffset[2], -parentBone.globalOffset[1]);
|
const auto inverseParentRotation =
|
||||||
rotation /= Quaternion32(
|
Eigen::Quaternionf(
|
||||||
parentBone.globalRotation.m_x, parentBone.globalRotation.m_z, -parentBone.globalRotation.m_y, parentBone.globalRotation.m_w);
|
parentBone.globalRotation.m_w, parentBone.globalRotation.m_x, parentBone.globalRotation.m_z, -parentBone.globalRotation.m_y)
|
||||||
|
.normalized()
|
||||||
|
.inverse()
|
||||||
|
.normalized();
|
||||||
|
|
||||||
|
translation -= Eigen::Vector3f(parentBone.globalOffset[0], parentBone.globalOffset[2], -parentBone.globalOffset[1]);
|
||||||
|
translation = inverseParentRotation * translation;
|
||||||
|
rotation = inverseParentRotation * rotation;
|
||||||
}
|
}
|
||||||
rotation.Normalize();
|
rotation.normalize();
|
||||||
|
|
||||||
boneNode.name = bone.name;
|
boneNode.name = bone.name;
|
||||||
boneNode.translation = std::to_array({translation.x(), translation.y(), translation.z()});
|
boneNode.translation = std::to_array({translation.x(), translation.y(), translation.z()});
|
||||||
boneNode.rotation = std::to_array({rotation.m_x, rotation.m_y, rotation.m_z, rotation.m_w});
|
boneNode.rotation = std::to_array({rotation.x(), rotation.y(), rotation.z(), rotation.w()});
|
||||||
|
|
||||||
std::vector<unsigned> children;
|
std::vector<unsigned> children;
|
||||||
for (auto maybeChildIndex = 0u; maybeChildIndex < boneCount; maybeChildIndex++)
|
for (auto maybeChildIndex = 0u; maybeChildIndex < boneCount; maybeChildIndex++)
|
||||||
@ -267,6 +275,7 @@ namespace
|
|||||||
skin.joints.emplace_back(boneIndex + m_first_bone_node);
|
skin.joints.emplace_back(boneIndex + m_first_bone_node);
|
||||||
|
|
||||||
skin.inverseBindMatrices = m_inverse_bind_matrices_accessor;
|
skin.inverseBindMatrices = m_inverse_bind_matrices_accessor;
|
||||||
|
skin.skeleton = m_first_bone_node;
|
||||||
|
|
||||||
gltf.skins->emplace_back(std::move(skin));
|
gltf.skins->emplace_back(std::move(skin));
|
||||||
}
|
}
|
||||||
@ -511,29 +520,29 @@ namespace
|
|||||||
auto* inverseBindMatrixData = reinterpret_cast<float*>(&bufferData[currentBufferOffset]);
|
auto* inverseBindMatrixData = reinterpret_cast<float*>(&bufferData[currentBufferOffset]);
|
||||||
for (const auto& bone : xmodel.m_bones)
|
for (const auto& bone : xmodel.m_bones)
|
||||||
{
|
{
|
||||||
Matrix32 inverseBindMatrix;
|
const auto translation = Eigen::Translation3f(bone.globalOffset[0], bone.globalOffset[2], -bone.globalOffset[1]);
|
||||||
inverseBindMatrix.m_data[0][3] = -bone.globalOffset[0];
|
const auto rotation =
|
||||||
inverseBindMatrix.m_data[1][3] = -bone.globalOffset[2];
|
Eigen::Quaternionf(bone.globalRotation.m_w, bone.globalRotation.m_x, bone.globalRotation.m_z, -bone.globalRotation.m_y);
|
||||||
inverseBindMatrix.m_data[2][3] = bone.globalOffset[1];
|
|
||||||
|
|
||||||
// In-memory = row major
|
const auto inverseBindMatrix = (translation * rotation).matrix().inverse();
|
||||||
// gltf = column major
|
|
||||||
inverseBindMatrixData[0] = inverseBindMatrix.m_data[0][0];
|
// GLTF matrix is column major
|
||||||
inverseBindMatrixData[1] = inverseBindMatrix.m_data[1][0];
|
inverseBindMatrixData[0] = inverseBindMatrix(0, 0);
|
||||||
inverseBindMatrixData[2] = inverseBindMatrix.m_data[2][0];
|
inverseBindMatrixData[1] = inverseBindMatrix(1, 0);
|
||||||
inverseBindMatrixData[3] = inverseBindMatrix.m_data[3][0];
|
inverseBindMatrixData[2] = inverseBindMatrix(2, 0);
|
||||||
inverseBindMatrixData[4] = inverseBindMatrix.m_data[0][1];
|
inverseBindMatrixData[3] = inverseBindMatrix(3, 0);
|
||||||
inverseBindMatrixData[5] = inverseBindMatrix.m_data[1][1];
|
inverseBindMatrixData[4] = inverseBindMatrix(0, 1);
|
||||||
inverseBindMatrixData[6] = inverseBindMatrix.m_data[2][1];
|
inverseBindMatrixData[5] = inverseBindMatrix(1, 1);
|
||||||
inverseBindMatrixData[7] = inverseBindMatrix.m_data[3][1];
|
inverseBindMatrixData[6] = inverseBindMatrix(2, 1);
|
||||||
inverseBindMatrixData[8] = inverseBindMatrix.m_data[0][2];
|
inverseBindMatrixData[7] = inverseBindMatrix(3, 1);
|
||||||
inverseBindMatrixData[9] = inverseBindMatrix.m_data[1][2];
|
inverseBindMatrixData[8] = inverseBindMatrix(0, 2);
|
||||||
inverseBindMatrixData[10] = inverseBindMatrix.m_data[2][2];
|
inverseBindMatrixData[9] = inverseBindMatrix(1, 2);
|
||||||
inverseBindMatrixData[11] = inverseBindMatrix.m_data[3][2];
|
inverseBindMatrixData[10] = inverseBindMatrix(2, 2);
|
||||||
inverseBindMatrixData[12] = inverseBindMatrix.m_data[0][3];
|
inverseBindMatrixData[11] = inverseBindMatrix(3, 2);
|
||||||
inverseBindMatrixData[13] = inverseBindMatrix.m_data[1][3];
|
inverseBindMatrixData[12] = inverseBindMatrix(0, 3);
|
||||||
inverseBindMatrixData[14] = inverseBindMatrix.m_data[2][3];
|
inverseBindMatrixData[13] = inverseBindMatrix(1, 3);
|
||||||
inverseBindMatrixData[15] = inverseBindMatrix.m_data[3][3];
|
inverseBindMatrixData[14] = inverseBindMatrix(2, 3);
|
||||||
|
inverseBindMatrixData[15] = inverseBindMatrix(3, 3);
|
||||||
|
|
||||||
inverseBindMatrixData += 16u;
|
inverseBindMatrixData += 16u;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user