Enhance native wheel handling with topology management

This commit is contained in:
iChris4 committed 2026-09-25 02:21:10 +02:00
1 parent 1d7f2549bd
commit 3d48514182
5 files changed
+484 -44

No files matched your search

+28 -3
View File
@@ -740,6 +740,24 @@ bool PublishNativeWheelMesh(uint32_t part, const Mtx34& model_view, const Mtx34&
if (version < 8 || version > 11) {
return false;
}
Mtx34 body_from_vertices = kIdentityMtx34;
Mtx34 wheel_model_view = model_view;
if (!whole_part) {
// Body::mtx is the model placement, while the root bone may have
// its own authored rotation (notably the Baby Booster). GX draws
// its positions through placement * root, so both wheel selection
// and Aurora's local-player matrix match must include that root.
const uint32_t bone_dic_offset = Memory::Read32(mdl + 0x14);
if (!bone_dic_offset || bone_dic_offset > 0x100000) return false;
const uint32_t bone_dic = mdl + bone_dic_offset;
if (!Memory::Contains(bone_dic, 40) || !Memory::Read32(bone_dic + 4)) return false;
const uint32_t bone_offset = Memory::Read32(bone_dic + 36);
if (bone_offset > 0x100000) return false;
const uint32_t root_bone = bone_dic + bone_offset;
if (!Memory::Contains(root_bone, 0xa0) || Memory::Read32(root_bone + 0x10) != 0 ||
!ReadGuestMtx34(root_bone + 0x70, body_from_vertices)) return false;
wheel_model_view = ComposeMtx(model_view, body_from_vertices);
}
const uint32_t dic_offset = Memory::Read32(mdl + 0x18);
if (dic_offset == 0 || dic_offset > 0x100000) {
return false;
@@ -795,8 +813,15 @@ bool PublishNativeWheelMesh(uint32_t part, const Mtx34& model_view, const Mtx34&
for (auto& point : points) {
point = detail::TransformPoint(correction, point.x, point.y, point.z);
}
} else if (RotateNativeWheelVertices(points, center, radius, angle, &correction) < 8) {
continue;
} else {
const uint32_t mdl_size = Memory::Read32(mdl + 4);
const uint8_t* mdl_bytes = mdl_size <= 0x1000000 ? Memory::GetPointer(mdl, mdl_size) : nullptr;
NativeWheelTopology topology(num);
if (!ReadNativeWheelTopology(mdl_bytes, mdl_size, Memory::Read32(header + 0x10), topology) ||
RotateNativeWheelVertices(points, topology, center, radius, angle, &correction,
body_from_vertices) < 8) {
continue;
}
}
const uint8_t* source = Memory::GetPointer(data, size);
if (source == nullptr) {
@@ -825,7 +850,7 @@ bool PublishNativeWheelMesh(uint32_t part, const Mtx34& model_view, const Mtx34&
}
}
}
if (valid && GxNativeWheel::PostVertices(data, bytes.data(), size, model_view.data())) {
if (valid && GxNativeWheel::PostVertices(data, bytes.data(), size, wheel_model_view.data())) {
published = true;
g_state.wheel_arrays_posted = true;
}