mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-19 07:42:54 +00:00
Merge pull request #395 from Laupetin/fix/bad-xmodel-loading
fix: bad xmodel loading
This commit is contained in:
commit
d3bb99e92c
@ -286,7 +286,7 @@ namespace
|
||||
|
||||
common.m_vertices.emplace_back(vertex);
|
||||
|
||||
XModelVertexBoneWeights vertexWeights{common.m_bone_weight_data.weights.size(), 0u};
|
||||
XModelVertexBoneWeights vertexWeights{.weightOffset = common.m_bone_weight_data.weights.size(), .weightCount = 0u};
|
||||
for (auto i = 0u; i < std::extent_v<decltype(joints)>; i++)
|
||||
{
|
||||
if (std::abs(weights[i]) < std::numeric_limits<float>::epsilon())
|
||||
@ -315,12 +315,12 @@ namespace
|
||||
throw GltfLoadException("Requires primitives attribute POSITION");
|
||||
|
||||
AccessorsForVertex accessorsForVertex{
|
||||
*primitives.attributes.POSITION,
|
||||
primitives.attributes.NORMAL,
|
||||
primitives.attributes.COLOR_0,
|
||||
primitives.attributes.TEXCOORD_0,
|
||||
primitives.attributes.JOINTS_0,
|
||||
primitives.attributes.WEIGHTS_0,
|
||||
.positionAccessor = *primitives.attributes.POSITION,
|
||||
.normalAccessor = primitives.attributes.NORMAL,
|
||||
.colorAccessor = primitives.attributes.COLOR_0,
|
||||
.uvAccessor = primitives.attributes.TEXCOORD_0,
|
||||
.jointsAccessor = primitives.attributes.JOINTS_0,
|
||||
.weightsAccessor = primitives.attributes.WEIGHTS_0,
|
||||
};
|
||||
|
||||
const auto existingVertices = m_vertex_offset_for_accessors.find(accessorsForVertex);
|
||||
@ -328,7 +328,7 @@ namespace
|
||||
existingVertices == m_vertex_offset_for_accessors.end() ? CreateVertices(common, accessorsForVertex) : existingVertices->second;
|
||||
|
||||
// clang-format off
|
||||
auto* indexAccessor = GetAccessorForIndex(
|
||||
const auto* indexAccessor = GetAccessorForIndex(
|
||||
"INDICES",
|
||||
primitives.indices,
|
||||
{JsonAccessorType::SCALAR},
|
||||
@ -552,7 +552,7 @@ namespace
|
||||
common.m_bones.resize(skinBoneOffset + skin.joints.size());
|
||||
|
||||
constexpr float defaultTranslation[3]{0.0f, 0.0f, 0.0f};
|
||||
constexpr XModelQuaternion defaultRotation{0.0f, 0.0f, 0.0f, 1.0f};
|
||||
constexpr XModelQuaternion defaultRotation{.x = 0.0f, .y = 0.0f, .z = 0.0f, .w = 1.0f};
|
||||
constexpr float defaultScale[3]{1.0f, 1.0f, 1.0f};
|
||||
|
||||
return ConvertJoint(jRoot, skin, common, skinBoneOffset, rootNode, std::nullopt, defaultTranslation, defaultRotation, defaultScale);
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include JSON_HEADER
|
||||
|
||||
#include "Asset/AssetRegistration.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Utils/QuatInt16.h"
|
||||
#include "Utils/StringUtils.h"
|
||||
#include "XModel/Gltf/GltfBinInput.h"
|
||||
@ -44,7 +43,6 @@
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
#include <numeric>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
using namespace GAME;
|
||||
@ -146,17 +144,17 @@ namespace
|
||||
assert(common.m_vertex_bone_weights.size() == common.m_vertices.size());
|
||||
|
||||
XModelBone rootBone{
|
||||
"root",
|
||||
std::nullopt,
|
||||
{1.0f, 1.0f, 1.0f},
|
||||
{0.0f, 0.0f, 0.0f},
|
||||
{0.0f, 0.0f, 0.0f},
|
||||
{0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{0.0f, 0.0f, 0.0f, 1.0f},
|
||||
.name = "root",
|
||||
.parentIndex = std::nullopt,
|
||||
.scale = {1.0f, 1.0f, 1.0f},
|
||||
.globalOffset = {0.0f, 0.0f, 0.0f},
|
||||
.localOffset = {0.0f, 0.0f, 0.0f},
|
||||
.globalRotation = {.x = 0.0f, .y = 0.0f, .z = 0.0f, .w = 1.0f},
|
||||
.localRotation = {.x = 0.0f, .y = 0.0f, .z = 0.0f, .w = 1.0f},
|
||||
};
|
||||
common.m_bones.emplace_back(rootBone);
|
||||
|
||||
XModelBoneWeight rootWeight{0, 1.0f};
|
||||
XModelBoneWeight rootWeight{.boneIndex = 0, .weight = 1.0f};
|
||||
common.m_bone_weight_data.weights.emplace_back(rootWeight);
|
||||
|
||||
for (auto& vertexBoneWeights : common.m_vertex_bone_weights)
|
||||
@ -401,7 +399,7 @@ namespace
|
||||
}
|
||||
|
||||
static std::vector<std::optional<size_t>>
|
||||
GetRigidBoneIndicesForTris(const std::vector<size_t>& vertexIndices, XSurface& surface, const XModelCommon& common)
|
||||
GetRigidBoneIndicesForTris(const std::vector<size_t>& vertexIndices, const XSurface& surface, const XModelCommon& common)
|
||||
{
|
||||
std::vector<std::optional<size_t>> rigidBoneIndexForTri;
|
||||
rigidBoneIndexForTri.reserve(surface.triCount);
|
||||
@ -422,7 +420,7 @@ namespace
|
||||
return rigidBoneIndexForTri;
|
||||
}
|
||||
|
||||
static void ReorderRigidTrisByBoneIndex(const std::vector<size_t>& vertexIndices, XSurface& surface, const XModelCommon& common)
|
||||
static void ReorderRigidTrisByBoneIndex(const std::vector<size_t>& vertexIndices, const XSurface& surface, const XModelCommon& common)
|
||||
{
|
||||
const auto rigidBoneIndexForTri = GetRigidBoneIndicesForTris(vertexIndices, surface, common);
|
||||
|
||||
@ -456,17 +454,17 @@ namespace
|
||||
surface.partBits[partBitsIndex] |= 1 << shiftValue;
|
||||
}
|
||||
|
||||
void CreateVertListData(XSurface& surface, const std::vector<size_t>& vertexIndices, const XModelCommon& common) const
|
||||
void CreateVertListData(XSurface& surface, const std::vector<size_t>& xmodelToCommonVertexIndexLookup, const XModelCommon& common) const
|
||||
{
|
||||
ReorderRigidTrisByBoneIndex(vertexIndices, surface, common);
|
||||
const auto rigidBoneIndexForTri = GetRigidBoneIndicesForTris(vertexIndices, surface, common);
|
||||
ReorderRigidTrisByBoneIndex(xmodelToCommonVertexIndexLookup, surface, common);
|
||||
const auto rigidBoneIndexForTri = GetRigidBoneIndicesForTris(xmodelToCommonVertexIndexLookup, surface, common);
|
||||
|
||||
std::vector<XRigidVertList> vertLists;
|
||||
|
||||
auto currentVertexTail = 0u;
|
||||
auto currentTriTail = 0u;
|
||||
|
||||
const auto vertexCount = vertexIndices.size();
|
||||
const auto vertexCount = xmodelToCommonVertexIndexLookup.size();
|
||||
const auto triCount = static_cast<size_t>(surface.triCount);
|
||||
const auto boneCount = common.m_bones.size();
|
||||
for (auto boneIndex = 0u; boneIndex < boneCount; boneIndex++)
|
||||
@ -475,7 +473,7 @@ namespace
|
||||
boneVertList.boneOffset = static_cast<uint16_t>(boneIndex * sizeof(DObjSkelMat));
|
||||
|
||||
auto currentVertexHead = currentVertexTail;
|
||||
while (currentVertexHead < vertexCount && GetRigidBoneForVertex(currentVertexHead, common) == boneIndex)
|
||||
while (currentVertexHead < vertexCount && GetRigidBoneForVertex(xmodelToCommonVertexIndexLookup[currentVertexHead], common) == boneIndex)
|
||||
currentVertexHead++;
|
||||
|
||||
auto currentTriHead = currentTriTail;
|
||||
@ -512,7 +510,7 @@ namespace
|
||||
// TODO
|
||||
}
|
||||
|
||||
static void ReorderVerticesByWeightCount(std::vector<size_t>& vertexIndices, XSurface& surface, const XModelCommon& common)
|
||||
static void ReorderVerticesByWeightCount(std::vector<size_t>& vertexIndices, const XSurface& surface, const XModelCommon& common)
|
||||
{
|
||||
if (common.m_bone_weight_data.weights.empty())
|
||||
return;
|
||||
@ -541,13 +539,21 @@ namespace
|
||||
return false;
|
||||
});
|
||||
|
||||
std::vector<XSurfaceTri> preSortTris(surface.triCount);
|
||||
std::memcpy(preSortTris.data(), surface.triIndices, sizeof(XSurfaceTri) * surface.triCount);
|
||||
|
||||
std::vector<size_t> reverseLookup(reorderLookup.size());
|
||||
for (auto i = 0u; i < reverseLookup.size(); i++)
|
||||
reverseLookup[reorderLookup[i]] = i;
|
||||
|
||||
for (auto triIndex = 0u; triIndex < surface.triCount; triIndex++)
|
||||
{
|
||||
const auto& preSortTriIndices = preSortTris[triIndex];
|
||||
auto& triIndices = surface.triIndices[triIndex];
|
||||
|
||||
triIndices.i[0] = static_cast<uint16_t>(reorderLookup[triIndices.i[0]]);
|
||||
triIndices.i[1] = static_cast<uint16_t>(reorderLookup[triIndices.i[1]]);
|
||||
triIndices.i[2] = static_cast<uint16_t>(reorderLookup[triIndices.i[2]]);
|
||||
triIndices.i[0] = static_cast<uint16_t>(reverseLookup[preSortTriIndices.i[0]]);
|
||||
triIndices.i[1] = static_cast<uint16_t>(reverseLookup[preSortTriIndices.i[1]]);
|
||||
triIndices.i[2] = static_cast<uint16_t>(reverseLookup[preSortTriIndices.i[2]]);
|
||||
}
|
||||
|
||||
for (auto& entry : reorderLookup)
|
||||
@ -572,6 +578,7 @@ namespace
|
||||
surface.triCount = static_cast<uint16_t>(commonObject.m_faces.size());
|
||||
surface.triIndices = m_memory.Alloc<XSurfaceTri>(surface.triCount);
|
||||
|
||||
xmodelToCommonVertexIndexLookup.reserve(static_cast<size_t>(surface.triCount) * std::extent_v<decltype(XModelFace::vertexIndex)>);
|
||||
for (auto faceIndex = 0u; faceIndex < surface.triCount; faceIndex++)
|
||||
{
|
||||
const auto& face = commonObject.m_faces[faceIndex];
|
||||
@ -594,8 +601,6 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
ReorderVerticesByWeightCount(xmodelToCommonVertexIndexLookup, surface, common);
|
||||
|
||||
constexpr auto maxVertices = std::numeric_limits<decltype(XSurface::vertCount)>::max();
|
||||
if (vertexOffset + xmodelToCommonVertexIndexLookup.size() > maxVertices)
|
||||
{
|
||||
@ -603,6 +608,8 @@ namespace
|
||||
return false;
|
||||
}
|
||||
|
||||
ReorderVerticesByWeightCount(xmodelToCommonVertexIndexLookup, surface, common);
|
||||
|
||||
surface.baseVertIndex = static_cast<uint16_t>(vertexOffset);
|
||||
surface.vertCount = static_cast<uint16_t>(xmodelToCommonVertexIndexLookup.size());
|
||||
surface.verts0 = m_memory.Alloc<GfxPackedVertex>(surface.vertCount);
|
||||
|
Loading…
x
Reference in New Issue
Block a user