From 06fb7ccc236ad130310b1db6e489ba596db42a1b Mon Sep 17 00:00:00 2001 From: Max <34987259+mparisi20@users.noreply.github.com> Date: Sat, 30 May 2026 16:38:48 -0400 Subject: [PATCH] Match so_model_virtual_node.cpp --- config/RSBE01_02/rels/sora_melee/splits.txt | 3 + config/RSBE01_02/rels/sora_melee/symbols.txt | 28 +++---- config/RSBE01_02/symbols.txt | 2 +- configure.py | 1 + include/lib/BrawlHeaders | 2 +- .../model/so_model_module_impl_variable.cpp | 4 +- .../so/model/so_model_module_simple.cpp | 2 +- .../so/model/so_model_virtual_node.cpp | 73 +++++++++++++++++++ 8 files changed, 96 insertions(+), 19 deletions(-) create mode 100644 src/mo_melee/sora_melee/so/model/so_model_virtual_node.cpp diff --git a/config/RSBE01_02/rels/sora_melee/splits.txt b/config/RSBE01_02/rels/sora_melee/splits.txt index da58770..847d569 100644 --- a/config/RSBE01_02/rels/sora_melee/splits.txt +++ b/config/RSBE01_02/rels/sora_melee/splits.txt @@ -16,6 +16,9 @@ mo_melee/sora_melee/so/model/so_model_module_simple.cpp: .rodata start:0x00000318 end:0x00000320 .data start:0x000007D0 end:0x00000A88 +mo_melee/sora_melee/so/model/so_model_virtual_node.cpp: + .text start:0x0000EEAC end:0x0000F288 + mo_melee/sora_melee/so/model/so_model_module_impl_variable.cpp: .text start:0x0000F288 end:0x0000FED0 .data start:0x00000A98 end:0x00000C78 diff --git a/config/RSBE01_02/rels/sora_melee/symbols.txt b/config/RSBE01_02/rels/sora_melee/symbols.txt index 4676904..48363a8 100644 --- a/config/RSBE01_02/rels/sora_melee/symbols.txt +++ b/config/RSBE01_02/rels/sora_melee/symbols.txt @@ -140,7 +140,7 @@ setScnMdl__17soModelModuleImplFPQ34nw4r3g3d6ScnMdlPvQ211gfSceneRoot9LayerType = setScnMdlExtern__17soModelModuleImplFPQ34nw4r3g3d6ScnMdl = .text:0x00008E0C; // type:function size:0x10 detachScnMdl__17soModelModuleImplFPv = .text:0x00008E1C; // type:function size:0x2B8 fn_27_90D4 = .text:0x000090D4; // type:function size:0x160 -getRealNodeId__19soModelModuleSimpleFUl = .text:0x00009234; // type:function size:0x8 +getRealNodeId__19soModelModuleSimpleCFUl = .text:0x00009234; // type:function size:0x8 fn_27_923C = .text:0x0000923C; // type:function size:0x294 fn_27_94D0 = .text:0x000094D0; // type:function size:0x208 fn_27_96D8 = .text:0x000096D8; // type:function size:0x64 @@ -165,7 +165,7 @@ setNodeRotate__17soModelModuleImplFUlP5Vec3f = .text:0x0000A734; // type:functio getNodeTranslate__17soModelModuleImplFUl = .text:0x0000A824; // type:function size:0xC4 setNodeTranslate__17soModelModuleImplFUlP5Vec3f = .text:0x0000A8E8; // type:function size:0xF0 getCorrectNodeId__17soModelModuleImplFUl = .text:0x0000A9D8; // type:function size:0x24 -getNodeGlobalMtx__17soModelModuleImplFUlP6Matrixb = .text:0x0000A9FC; // type:function size:0x150 +getNodeGlobalMtx__17soModelModuleImplCFUlP6Matrixb = .text:0x0000A9FC; // type:function size:0x150 setNodeGlobalMtx__17soModelModuleImplFUlP6Matrixb = .text:0x0000AB4C; // type:function size:0xA8 getNodeGlobalPosition__17soModelModuleImplFUlb = .text:0x0000ABF4; // type:function size:0x120 getNodeGlobalPosition__17soModelModuleImplFUlPC5Vec3fbb = .text:0x0000AD14; // type:function size:0x134 @@ -217,7 +217,7 @@ detachScnMdl__19soModelModuleSimpleFPv = .text:0x0000E368; // type:function size resetLayerType__19soModelModuleSimpleFQ211gfSceneRoot9LayerType = .text:0x0000E3C8; // type:function size:0xC0 getNodeId__19soModelModuleSimpleFPCc = .text:0x0000E488; // type:function size:0x94 getNodeName__19soModelModuleSimpleFUl = .text:0x0000E51C; // type:function size:0xB4 -getNodeGlobalMtx__19soModelModuleSimpleFUlP6Matrixb = .text:0x0000E5D0; // type:function size:0x54 +getNodeGlobalMtx__19soModelModuleSimpleCFUlP6Matrixb = .text:0x0000E5D0; // type:function size:0x54 getNodeGlobalPosition__19soModelModuleSimpleFUlb = .text:0x0000E624; // type:function size:0x58 getNodeGlobalPosition__19soModelModuleSimpleFUlPC5Vec3fbb = .text:0x0000E67C; // type:function size:0x68 getNodeLocalPosition__19soModelModuleSimpleFUlb = .text:0x0000E6E4; // type:function size:0x58 @@ -288,18 +288,18 @@ setUpSkinningMtx__19soModelModuleSimpleFv = .text:0x0000EE9C; // type:function s setUpMtx__19soModelModuleSimpleFUl = .text:0x0000EEA0; // type:function size:0x4 setUpMtx__19soModelModuleSimpleFPUll = .text:0x0000EEA4; // type:function size:0x4 setUpMtxFinal__19soModelModuleSimpleFv = .text:0x0000EEA8; // type:function size:0x4 -fn_27_EEAC = .text:0x0000EEAC; // type:function size:0x20 -fn_27_EECC = .text:0x0000EECC; // type:function size:0x40 -fn_27_EF0C = .text:0x0000EF0C; // type:function size:0x14 -fn_27_EF20 = .text:0x0000EF20; // type:function size:0x118 -fn_27_F038 = .text:0x0000F038; // type:function size:0xB0 -fn_27_F0E8 = .text:0x0000F0E8; // type:function size:0xAC -fn_27_F194 = .text:0x0000F194; // type:function size:0x40 -fn_27_F1D4 = .text:0x0000F1D4; // type:function size:0x64 -fn_27_F238 = .text:0x0000F238; // type:function size:0x50 +__ct__18soModelVirtualNodeFv = .text:0x0000EEAC; // type:function size:0x20 +__dt__18soModelVirtualNodeFv = .text:0x0000EECC; // type:function size:0x40 +init__18soModelVirtualNodeFUlUlP18UnkVirtualNodeInfoP6Matrix = .text:0x0000EF0C; // type:function size:0x14 +updateMatrix__18soModelVirtualNodeFRC13soModelModuleUlRC5Vec3f = .text:0x0000EF20; // type:function size:0x118 +getMatrix__18soModelVirtualNodeCFUlR6Matrix = .text:0x0000F038; // type:function size:0xB0 +setMatrix__18soModelVirtualNodeFUlR6Matrix = .text:0x0000F0E8; // type:function size:0xAC +isNode__18soModelVirtualNodeCFUl = .text:0x0000F194; // type:function size:0x40 +getOffset__18soModelVirtualNodeCFUlR5Vec3f = .text:0x0000F1D4; // type:function size:0x64 +getNodeParent__18soModelVirtualNodeCFUlRUl = .text:0x0000F238; // type:function size:0x50 __ct__25soModelModuleImplVariableFP16soModuleAccesserPvUlUlPvf = .text:0x0000F288; // type:function size:0x5C __dt__25soModelModuleImplVariableFv = .text:0x0000F2E4; // type:function size:0x58 -getRealNodeId__25soModelModuleImplVariableFUl = .text:0x0000F33C; // type:function size:0x44 +getRealNodeId__25soModelModuleImplVariableCFUl = .text:0x0000F33C; // type:function size:0x44 setUpMtx__25soModelModuleImplVariableFPUll = .text:0x0000F380; // type:function size:0x84 clearNodeSRT__25soModelModuleImplVariableFUl = .text:0x0000F404; // type:function size:0x44 setNodeSRT__25soModelModuleImplVariableFUlP5Vec3fP5Vec3fP5Vec3f = .text:0x0000F448; // type:function size:0x74 @@ -319,7 +319,7 @@ getNodeGlobalPosition__25soModelModuleImplVariableFUlb = .text:0x0000F888; // ty getNodeGlobalPosition__25soModelModuleImplVariableFUlPC5Vec3fbb = .text:0x0000F8F4; // type:function size:0x74 getNodeLocalPosition__25soModelModuleImplVariableFUlb = .text:0x0000F968; // type:function size:0x6C getNodeLocalMtxFromNode__25soModelModuleImplVariableFUlUlP6Matrixb = .text:0x0000F9D4; // type:function size:0x84 -getNodeGlobalMtx__25soModelModuleImplVariableFUlP6Matrixb = .text:0x0000FA58; // type:function size:0x64 +getNodeGlobalMtx__25soModelModuleImplVariableCFUlP6Matrixb = .text:0x0000FA58; // type:function size:0x64 setNodeGlobalMtx__25soModelModuleImplVariableFUlP6Matrixb = .text:0x0000FABC; // type:function size:0x64 getNodeGlobalRotation__25soModelModuleImplVariableFUlb = .text:0x0000FB20; // type:function size:0x6C isNode__25soModelModuleImplVariableFUl = .text:0x0000FB8C; // type:function size:0x44 diff --git a/config/RSBE01_02/symbols.txt b/config/RSBE01_02/symbols.txt index dffa610..292a885 100644 --- a/config/RSBE01_02/symbols.txt +++ b/config/RSBE01_02/symbols.txt @@ -2902,7 +2902,7 @@ fn_8003ECA0 = .text:0x8003ECA0; // type:function size:0x178 getRotate__6MatrixFP5Vec3f = .text:0x8003EE18; // type:function size:0x224 fn_8003F03C = .text:0x8003F03C; // type:function size:0x38 fn_8003F074 = .text:0x8003F074; // type:function size:0x88 -fn_8003F0FC = .text:0x8003F0FC; // type:function size:0x1B0 +setSRT__6MatrixFRC5Vec3fRC5Vec3fRC5Vec3f = .text:0x8003F0FC; // type:function size:0x1B0 fn_8003F2AC = .text:0x8003F2AC; // type:function size:0x24C mul__6MatrixCFPC6MatrixP6Matrix = .text:0x8003F4F8; // type:function size:0xA8 inverse__6MatrixCFP6Matrix = .text:0x8003F5A0; // type:function size:0x2F8 diff --git a/configure.py b/configure.py index 5c9d283..d398217 100755 --- a/configure.py +++ b/configure.py @@ -805,6 +805,7 @@ def MatchingFor(*versions): "host": False, "objects": [ Object(Matching, "mo_melee/sora_melee/so/model/so_model_module_simple.cpp"), + Object(Matching, "mo_melee/sora_melee/so/model/so_model_virtual_node.cpp"), Object(Matching, "mo_melee/sora_melee/so/model/so_model_module_impl_variable.cpp"), Object(Matching, "mo_melee/sora_melee/so/anim/so_anim_chr.cpp"), Object(Matching, "mo_melee/sora_melee/so/so_controller_module_link_ref.cpp"), diff --git a/include/lib/BrawlHeaders b/include/lib/BrawlHeaders index ad36b88..6b0a9cc 160000 --- a/include/lib/BrawlHeaders +++ b/include/lib/BrawlHeaders @@ -1 +1 @@ -Subproject commit ad36b88d1744182df276b82f97e00b97ecc5ba53 +Subproject commit 6b0a9cc487c230183d3672a577ca715377d57bd7 diff --git a/src/mo_melee/sora_melee/so/model/so_model_module_impl_variable.cpp b/src/mo_melee/sora_melee/so/model/so_model_module_impl_variable.cpp index 96ba104..4885eb4 100644 --- a/src/mo_melee/sora_melee/so/model/so_model_module_impl_variable.cpp +++ b/src/mo_melee/sora_melee/so/model/so_model_module_impl_variable.cpp @@ -11,7 +11,7 @@ soModelModuleImplVariable::~soModelModuleImplVariable() { } static inline u32 minus400(u32 p1) { return p1 - 400; } -int soModelModuleImplVariable::getRealNodeId(u32 p1) { +int soModelModuleImplVariable::getRealNodeId(u32 p1) const { if (p1 < 400 || p1 == 0xFFFFFFFF) { return p1; } @@ -100,7 +100,7 @@ void soModelModuleImplVariable::getNodeLocalMtxFromNode(u32 p1, u32 p2, Matrix* return soModelModuleImpl::getNodeLocalMtxFromNode(getRealNodeId(p1), getRealNodeId(p2), p3, p4); } -void soModelModuleImplVariable::getNodeGlobalMtx(u32 p1, Matrix* p2, bool p3) { +void soModelModuleImplVariable::getNodeGlobalMtx(u32 p1, Matrix* p2, bool p3) const { return soModelModuleImpl::getNodeGlobalMtx(getRealNodeId(p1), p2, p3); } diff --git a/src/mo_melee/sora_melee/so/model/so_model_module_simple.cpp b/src/mo_melee/sora_melee/so/model/so_model_module_simple.cpp index 4a319a5..73cbe92 100644 --- a/src/mo_melee/sora_melee/so/model/so_model_module_simple.cpp +++ b/src/mo_melee/sora_melee/so/model/so_model_module_simple.cpp @@ -69,7 +69,7 @@ const char* soModelModuleSimple::getNodeName(u32 p1) { return nullptr; } -void soModelModuleSimple::getNodeGlobalMtx(u32 idx, Matrix* outMtx, bool) { +void soModelModuleSimple::getNodeGlobalMtx(u32 idx, Matrix* outMtx, bool) const { getScnMdl()->GetScnMtxPos(outMtx, nw4r::g3d::ScnMdl::MTX_WORLD, idx); } diff --git a/src/mo_melee/sora_melee/so/model/so_model_virtual_node.cpp b/src/mo_melee/sora_melee/so/model/so_model_virtual_node.cpp new file mode 100644 index 0000000..c8eb72a --- /dev/null +++ b/src/mo_melee/sora_melee/so/model/so_model_virtual_node.cpp @@ -0,0 +1,73 @@ +#include +#include +#include +#include +#include + +// Same logic as isNode, but inlining the function call doesn't match +#define IF_VALID_NODE_ID(ID, CODE) \ + if (!m_nodeInfo) \ + return false; \ + if ((ID) >= m_start && (ID) < (m_start + m_end)) { \ + CODE \ + return true; \ + } \ + return false; + +soModelVirtualNode::soModelVirtualNode() : + m_start(0), + m_end(0), + m_nodeInfo(nullptr), + m_matrices(nullptr), + m_unused(true) { } + +soModelVirtualNode::~soModelVirtualNode() { } + +void soModelVirtualNode::init(u32 start, u32 end, UnkVirtualNodeInfo* info, Matrix* mtxs) { + m_start = start; + m_end = end; + m_nodeInfo = info; + m_matrices = mtxs; +} + +bool soModelVirtualNode::updateMatrix(const soModelModule& mod, u32 id, const Vec3f& scale) { + IF_VALID_NODE_ID(id, + u32 idx = id - m_start; + mod.getNodeGlobalMtx(m_nodeInfo[idx].m_parentNodeId, &m_matrices[idx], true); + Vec3f rot; + Vec3f xlate; + Matrix srt(true); + xlate = m_nodeInfo[idx].m_translate; + rot = m_nodeInfo[idx].m_rotate; + srt.setSRT(scale, rot, xlate); + m_matrices[idx].mul(&srt, &m_matrices[idx]); + ) +} + +bool soModelVirtualNode::getMatrix(u32 id, Matrix& mtx) const { + IF_VALID_NODE_ID(id, + mtx = m_matrices[id - m_start]; + ) +} + +bool soModelVirtualNode::setMatrix(u32 id, Matrix& mtx) { + IF_VALID_NODE_ID(id, + m_matrices[id - m_start] = mtx; + ) +} + +bool soModelVirtualNode::isNode(u32 id) const { + IF_VALID_NODE_ID(id, /* nothing */) +} + +bool soModelVirtualNode::getOffset(u32 id, Vec3f& offset) const { + IF_VALID_NODE_ID(id, + offset = m_nodeInfo[id - m_start].m_translate; + ) +} + +bool soModelVirtualNode::getNodeParent(u32 id, u32& parent) const { + IF_VALID_NODE_ID(id, + parent = m_nodeInfo[id - m_start].m_parentNodeId; + ) +}