From afeae54b31f60337577ba0c3c3284b2c32666764 Mon Sep 17 00:00:00 2001 From: rjkiv <76180273+rjkiv@users.noreply.github.com> Date: Sun, 25 Aug 2024 03:16:20 -0700 Subject: [PATCH] Try to cleanup the char folder, get more TUs Equivalent (#324) * charuppertwist equivalent * charsleeve work * charservobone work * charpollgroup sortpolls * match charpollgroup * charnecktwist poll * charbone is equivalent * charguitarstring is equivalent * charmirror attempt * charinterest work * charikfoot work * charforetwist poll tweak * chareyes work * more chareyes work * charhair work * charcollide work * charcollide tweaks * charcollide highlight work * charcollide tweaks * more charactertest work * charactertest symbols * charutl work * charutl is equivalent * correct angle func name * waypoint work * waypoint symbols in retail * waypoint work * clipcollide work * more clipcollide work * clipgraphgen work * no charforetwist enter --- config/SZBE69/objects.json | 1 + config/SZBE69/symbols.txt | 348 +++++++++++++-------------- config/SZBE69_B8/objects.json | 35 ++- src/system/char/CharBone.h | 6 + src/system/char/CharBones.h | 2 + src/system/char/CharClip.h | 2 + src/system/char/CharCollide.cpp | 207 ++++++++++------ src/system/char/CharCollide.h | 58 +++-- src/system/char/CharCuff.cpp | 11 +- src/system/char/CharDriver.h | 1 + src/system/char/CharEyes.cpp | 170 ++++++++++++- src/system/char/CharEyes.h | 11 +- src/system/char/CharForeTwist.cpp | 2 +- src/system/char/CharForeTwist.h | 1 - src/system/char/CharGuitarString.cpp | 19 +- src/system/char/CharHair.cpp | 130 ++++++++++ src/system/char/CharHair.h | 5 + src/system/char/CharIKFoot.cpp | 57 +++++ src/system/char/CharIKFoot.h | 2 +- src/system/char/CharIKHand.h | 2 +- src/system/char/CharInterest.cpp | 58 ++++- src/system/char/CharInterest.h | 2 + src/system/char/CharMirror.cpp | 7 + src/system/char/CharMirror.h | 8 +- src/system/char/CharNeckTwist.cpp | 19 +- src/system/char/CharNeckTwist.h | 4 +- src/system/char/CharPollGroup.cpp | 12 +- src/system/char/CharServoBone.cpp | 34 +++ src/system/char/CharServoBone.h | 4 +- src/system/char/CharSleeve.cpp | 81 +++++++ src/system/char/CharSleeve.h | 24 +- src/system/char/CharUpperTwist.cpp | 20 ++ src/system/char/CharUpperTwist.h | 6 +- src/system/char/CharUtl.cpp | 59 +++-- src/system/char/CharUtl.h | 1 + src/system/char/Character.cpp | 6 +- src/system/char/Character.h | 6 +- src/system/char/CharacterTest.cpp | 150 ++++++++++++ src/system/char/CharacterTest.h | 13 +- src/system/char/ClipCollide.cpp | 264 +++++++++++++++++++- src/system/char/ClipCollide.h | 45 +++- src/system/char/ClipDistMap.h | 37 +++ src/system/char/ClipGraphGen.cpp | 74 ++++++ src/system/char/ClipGraphGen.h | 21 ++ src/system/char/Waypoint.cpp | 89 ++++++- src/system/char/Waypoint.h | 28 ++- src/system/math/Color.h | 3 +- src/system/math/MathFuncs.h | 4 + src/system/math/Mtx.h | 12 + src/system/math/Rot.h | 3 + src/system/math/Trig.h | 12 +- src/system/math/Vec.h | 26 +- src/system/rndobj/Mesh.cpp | 48 ++-- src/system/rndobj/Mesh.h | 20 +- src/system/rndobj/PostProc.h | 3 +- src/system/rndobj/Utl.h | 2 + 56 files changed, 1853 insertions(+), 422 deletions(-) create mode 100644 src/system/char/ClipDistMap.h create mode 100644 src/system/char/ClipGraphGen.cpp create mode 100644 src/system/char/ClipGraphGen.h diff --git a/config/SZBE69/objects.json b/config/SZBE69/objects.json index 0a706b3b..0394f2b5 100644 --- a/config/SZBE69/objects.json +++ b/config/SZBE69/objects.json @@ -102,6 +102,7 @@ "system/char/CharUtl.cpp": "NonMatching", "system/char/CharWeightable.cpp": "NonMatching", "system/char/CharWeightSetter.cpp": "NonMatching", + "system/char/Waypoint.cpp": "NonMatching", "system/math/Key.cpp": "NonMatching", "system/math/Rand.cpp": "NonMatching", diff --git a/config/SZBE69/symbols.txt b/config/SZBE69/symbols.txt index 0a6e9b42..ed8a677a 100644 --- a/config/SZBE69/symbols.txt +++ b/config/SZBE69/symbols.txt @@ -819,7 +819,7 @@ fn_8000DAFC = .text:0x8000DAFC; // type:function size:0x34 fn_8000DB30 = .text:0x8000DB30; // type:function size:0x4 fn_8000DB34 = .text:0x8000DB34; // type:function size:0x30 fn_8000DB64 = .text:0x8000DB64; // type:function size:0x10 -fn_8000DB74 = .text:0x8000DB74; // type:function size:0x28 +streq__FPCcPCc = .text:0x8000DB74; // type:function size:0x28 MergedGet0x8__FPv = .text:0x8000DB9C; // type:function size:0x8 begin__Q211stlpmtx_std66list>Fv = .text:0x8000DBA4; // type:function size:0xC fn_8000DBB0 = .text:0x8000DBB0; // type:function size:0x4 @@ -5814,7 +5814,7 @@ fn_800A55BC = .text:0x800A55BC; // type:function size:0x54 fn_800A5610 = .text:0x800A5610; // type:function size:0x8C fn_800A569C = .text:0x800A569C; // type:function size:0x68 fn_800A5704 = .text:0x800A5704; // type:function size:0x14 -fn_800A5718 = .text:0x800A5718; // type:function size:0x8 +MergedGet0x28__FPv = .text:0x800A5718; // type:function size:0x8 fn_800A5720 = .text:0x800A5720; // type:function size:0x54 fn_800A5774 = .text:0x800A5774; // type:function size:0x74 fn_800A57E8 = .text:0x800A57E8; // type:function size:0x8C @@ -6189,7 +6189,7 @@ fn_800AC7B4 = .text:0x800AC7B4; // type:function size:0x8 fn_800AC7BC = .text:0x800AC7BC; // type:function size:0x48 New__15NetSearchResultFv = .text:0x800AC804; // type:function size:0x30 __ct__15NetSearchResultFv = .text:0x800AC834; // type:function size:0xC0 -fn_800AC8F4 = .text:0x800AC8F4; // type:function size:0x8 +MergedGet0x30__FPv = .text:0x800AC8F4; // type:function size:0x8 __dt__15NetSearchResultFv = .text:0x800AC8FC; // type:function size:0xB8 Save__15NetSearchResultCFR9BinStream = .text:0x800AC9B4; // type:function size:0x70 Load__15NetSearchResultFR9BinStream = .text:0x800ACA24; // type:function size:0x74 @@ -6359,7 +6359,7 @@ fn_800B188C = .text:0x800B188C; // type:function size:0x10 EndGame__10NetSessionFib = .text:0x800B189C; // type:function size:0xD8 OnMsg__10NetSessionFRC10EndGameMsg = .text:0x800B1974; // type:function size:0xC8 MergedGetF0xC__FPv = .text:0x800B1A3C; // type:function size:0x8 -fn_800B1A44 = .text:0x800B1A44; // type:function size:0x8 +MergedGetB0x8__FPv = .text:0x800B1A44; // type:function size:0x8 fn_800B1A4C = .text:0x800B1A4C; // type:function size:0x8 HasUser__10NetSessionCFPC4User = .text:0x800B1A54; // type:function size:0x6C fn_800B1AC0 = .text:0x800B1AC0; // type:function size:0x24 @@ -7969,7 +7969,7 @@ Interp__Ffff = .text:0x800DED98; // type:function size:0xC Set__8TriangleFRC7Vector3RC7Vector3RC7Vector3 = .text:0x800DEDA4; // type:function size:0x70 Cross__FRC7Vector3RC7Vector3R7Vector3 = .text:0x800DEE14; // type:function size:0x3C scope:weak Subtract__FRC7Vector3RC7Vector3R7Vector3 = .text:0x800DEE50; // type:function size:0x30 -fn_800DEE80 = .text:0x800DEE80; // type:function size:0x3C +VertPos__7RndMeshCFi = .text:0x800DEE80; // type:function size:0x3C fn_800DEEBC = .text:0x800DEEBC; // type:function size:0x34 FastInvert__FRC9TransformR9Transform = .text:0x800DEEF0; // type:function size:0x5C Multiply__FRC7Vector3RCQ23Hmx7Matrix3R7Vector3 = .text:0x800DEF4C; // type:function size:0x44 @@ -8894,7 +8894,7 @@ fn_800F9A74 = .text:0x800F9A74; // type:function size:0x38 fn_800F9AAC = .text:0x800F9AAC; // type:function size:0x3C fn_800F9AE8 = .text:0x800F9AE8; // type:function size:0x3C fn_800F9B24 = .text:0x800F9B24; // type:function size:0x50 -fn_800F9B74 = .text:0x800F9B74; // type:function size:0x8 +MergedGet0x34__FPv = .text:0x800F9B74; // type:function size:0x8 fn_800F9B7C = .text:0x800F9B7C; // type:function size:0x38 fn_800F9BB4 = .text:0x800F9BB4; // type:function size:0x38 fn_800F9BEC = .text:0x800F9BEC; // type:function size:0x58 @@ -9184,7 +9184,7 @@ fn_80100070 = .text:0x80100070; // type:function size:0x8 fn_80100078 = .text:0x80100078; // type:function size:0x54 fn_801000CC = .text:0x801000CC; // type:function size:0x78 GetSlot__11BandUserMgrFP8BandUseri = .text:0x80100144; // type:function size:0xB8 -fn_801001FC = .text:0x801001FC; // type:function size:0x8 +MergedGet0x4C__FPv = .text:0x801001FC; // type:function size:0x8 fn_80100204 = .text:0x80100204; // type:function size:0x8 fn_8010020C = .text:0x8010020C; // type:function size:0x10 fn_8010021C = .text:0x8010021C; // type:function size:0x5C @@ -9573,7 +9573,7 @@ fn_8010CAF8 = .text:0x8010CAF8; // type:function size:0x1C0 fn_8010CCB8 = .text:0x8010CCB8; // type:function size:0x188 SetBpm__14FreestylePanelFi = .text:0x8010CE40; // type:function size:0x3C CreateController__14FreestylePanelFv = .text:0x8010CE7C; // type:function size:0x184 -fn_8010D000 = .text:0x8010D000; // type:function size:0x8 +MergedSet0x28__FPvPv = .text:0x8010D000; // type:function size:0x8 fn_8010D008 = .text:0x8010D008; // type:function size:0x30 OnMsg__14FreestylePanelFRC19JoypadConnectionMsg = .text:0x8010D038; // type:function size:0xBC EnableMetronome__14FreestylePanelFb = .text:0x8010D0F4; // type:function size:0x8 @@ -12836,7 +12836,7 @@ fn_8016BDA4 = .text:0x8016BDA4; // type:function size:0x168 fn_8016BF0C = .text:0x8016BF0C; // type:function size:0x8 fn_8016BF14 = .text:0x8016BF14; // type:function size:0xB0 fn_8016BFC4 = .text:0x8016BFC4; // type:function size:0x130 -fn_8016C0F4 = .text:0x8016C0F4; // type:function size:0x8 +MergedSet0x24__FPvPv = .text:0x8016C0F4; // type:function size:0x8 fn_8016C0FC = .text:0x8016C0FC; // type:function size:0x8 fn_8016C104 = .text:0x8016C104; // type:function size:0x2C fn_8016C130 = .text:0x8016C130; // type:function size:0x8 @@ -13385,7 +13385,7 @@ fn_8017A2A4 = .text:0x8017A2A4; // type:function size:0x218 fn_8017A4BC = .text:0x8017A4BC; // type:function size:0x68 fn_8017A524 = .text:0x8017A524; // type:function size:0xDC fn_8017A600 = .text:0x8017A600; // type:function size:0x240 -fn_8017A840 = .text:0x8017A840; // type:function size:0x8 +MergedSet0x1C__FPvPv = .text:0x8017A840; // type:function size:0x8 fn_8017A848 = .text:0x8017A848; // type:function size:0x8 fn_8017A850 = .text:0x8017A850; // type:function size:0x38 fn_8017A888 = .text:0x8017A888; // type:function size:0x10 @@ -14746,7 +14746,7 @@ fn_801AA6F4 = .text:0x801AA6F4; // type:function size:0x8 fn_801AA6FC = .text:0x801AA6FC; // type:function size:0x8 fn_801AA704 = .text:0x801AA704; // type:function size:0x2AC fn_801AA9B0 = .text:0x801AA9B0; // type:function size:0x8 -fn_801AA9B8 = .text:0x801AA9B8; // type:function size:0x8 +MergedGet0x19C__FPv = .text:0x801AA9B8; // type:function size:0x8 fn_801AA9C0 = .text:0x801AA9C0; // type:function size:0x74 fn_801AAA34 = .text:0x801AAA34; // type:function size:0x8 fn_801AAA3C = .text:0x801AAA3C; // type:function size:0x8 @@ -20134,7 +20134,7 @@ fn_8025CD88 = .text:0x8025CD88; // type:function size:0x8 fn_8025CD90 = .text:0x8025CD90; // type:function size:0x8 fn_8025CD98 = .text:0x8025CD98; // type:function size:0x8 fn_8025CDA0 = .text:0x8025CDA0; // type:function size:0x8 -fn_8025CDA8 = .text:0x8025CDA8; // type:function size:0x8 +MergedGetF0x148__FPv = .text:0x8025CDA8; // type:function size:0x8 fn_8025CDB0 = .text:0x8025CDB0; // type:function size:0x50 fn_8025CE00 = .text:0x8025CE00; // type:function size:0x8 fn_8025CE08 = .text:0x8025CE08; // type:function size:0x50 @@ -23603,7 +23603,7 @@ Update__5CSHA1FPCUcUl = .text:0x802D6CE4; // type:function size:0xEC Final__5CSHA1Fv = .text:0x802D6DD0; // type:function size:0x150 fn_802D6F20 = .text:0x802D6F20; // type:function size:0x14 fn_802D6F34 = .text:0x802D6F34; // type:function size:0x120 -fn_802D7054 = .text:0x802D7054; // type:function size:0x34 +__rs__FR9BinStreamRQ25CSHA16Digest = .text:0x802D7054; // type:function size:0x34 HashString__FPCci = .text:0x802D7088; // type:function size:0x34 SetBSPParams__FP9DataArray = .text:0x802D70BC; // type:function size:0xB0 GeoInit__Fv = .text:0x802D716C; // type:function size:0x148 @@ -23659,7 +23659,7 @@ __ct__Q211stlpmtx_std56vector<7Vector2,Q211stlpmtx_std22StlNodeAlloc<7Vector2>>F fn_802D8884 = .text:0x802D8884; // type:function size:0x30 fn_802D88B4 = .text:0x802D88B4; // type:function size:0x40 Intersect__FRC7SegmentRC6Sphere = .text:0x802D88F4; // type:function size:0x104 -fn_802D89F8 = .text:0x802D89F8; // type:function size:0x30 +__ct__5PlaneFRC7Vector3RC7Vector3 = .text:0x802D89F8; // type:function size:0x30 Normalize__FRC7Vector3R7Vector3 = .text:0x802D8A28; // type:function size:0x8C SetBSPParams__Fffiif = .text:0x802D8AB4; // type:function size:0x20 CheckBSPTree__FPC7BSPNodeRC3Box = .text:0x802D8AD4; // type:function size:0x7D0 @@ -23795,9 +23795,9 @@ fn_802DC840 = .text:0x802DC840; // type:function size:0x190 fn_802DC9D0 = .text:0x802DC9D0; // type:function size:0x54 fn_802DCA24 = .text:0x802DCA24; // type:function size:0x28 fn_802DCA4C = .text:0x802DCA4C; // type:function size:0x68 -fn_802DCAB4 = .text:0x802DCAB4; // type:function size:0x16C +MakeHSL__FRCQ23Hmx5ColorRfRfRf = .text:0x802DCAB4; // type:function size:0x16C Max__Ffff_f = .text:0x802DCC20; // type:function size:0x40 -fn_802DCC60 = .text:0x802DCC60; // type:function size:0x170 +MakeColor__FfffRQ23Hmx5Color = .text:0x802DCC60; // type:function size:0x170 __ls__FR10TextStreamRCQ23Hmx5Color = .text:0x802DCDD0; // type:function size:0x88 __sinit_\Color_cpp = .text:0x802DCE58; // type:function size:0x84 __ct__18LinearInterpolatorFffff = .text:0x802DCEDC; // type:function size:0x74 @@ -23809,7 +23809,7 @@ __ct__15ExpInterpolatorFfffff = .text:0x802DD0F0; // type:function size:0x7C Reset__15ExpInterpolatorFfffff = .text:0x802DD16C; // type:function size:0xCC Reset__15ExpInterpolatorFPC9DataArray = .text:0x802DD238; // type:function size:0xF4 Eval__15ExpInterpolatorFf = .text:0x802DD32C; // type:function size:0x4C -PowThunk__Fdd = .text:0x802DD378; // type:function size:0x4 +pow__3stdFff = .text:0x802DD378; // type:function size:0x4 __ct__18InvExpInterpolatorFfffff = .text:0x802DD37C; // type:function size:0x7C Reset__18InvExpInterpolatorFfffff = .text:0x802DD3F8; // type:function size:0xCC Reset__18InvExpInterpolatorFPC9DataArray = .text:0x802DD4C4; // type:function size:0xF4 @@ -28999,7 +28999,7 @@ __ct__17BandConfigurationFv = .text:0x80392CF0; // type:function size:0xE8 fn_80392DD8 = .text:0x80392DD8; // type:function size:0x8 fn_80392DE0 = .text:0x80392DE0; // type:function size:0x8 fn_80392DE8 = .text:0x80392DE8; // type:function size:0x48 -fn_80392E30 = .text:0x80392E30; // type:function size:0x4C +StaticClassName__8WaypointFv = .text:0x80392E30; // type:function size:0x4C fn_80392E7C = .text:0x80392E7C; // type:function size:0x50 fn_80392ECC = .text:0x80392ECC; // type:function size:0x38 fn_80392F04 = .text:0x80392F04; // type:function size:0xA4 @@ -30349,7 +30349,7 @@ fn_803BA7E8 = .text:0x803BA7E8; // type:function size:0x14 fn_803BA7FC = .text:0x803BA7FC; // type:function size:0x180 fn_803BA97C = .text:0x803BA97C; // type:function size:0x30 fn_803BA9AC = .text:0x803BA9AC; // type:function size:0x24 -fn_803BA9D0 = .text:0x803BA9D0; // type:function size:0x54 +RecipSqrtAccurate__Ff = .text:0x803BA9D0; // type:function size:0x54 fn_803BAA24 = .text:0x803BAA24; // type:function size:0x2C fn_803BAA50 = .text:0x803BAA50; // type:function size:0x1B4 fn_803BAC04 = .text:0x803BAC04; // type:function size:0x1C @@ -31187,7 +31187,7 @@ fn_803CFBF4 = .text:0x803CFBF4; // type:function size:0x60 fn_803CFC54 = .text:0x803CFC54; // type:function size:0x80 fn_803CFCD4 = .text:0x803CFCD4; // type:function size:0x80 fn_803CFD54 = .text:0x803CFD54; // type:function size:0x4D0 -fn_803D0224 = .text:0x803D0224; // type:function size:0x2C +end__36ObjPtrList<11CharCollide,9ObjectDir>CFv = .text:0x803D0224; // type:function size:0x2C fn_803D0250 = .text:0x803D0250; // type:function size:0xC begin__36ObjPtrList<11CharCollide,9ObjectDir>CFv = .text:0x803D025C; // type:function size:0x30 fn_803D028C = .text:0x803D028C; // type:function size:0x2C @@ -31638,7 +31638,7 @@ __dt__Q211stlpmtx_std72list>Fv = .text:0x803E07B8; // type:function size:0x4 @@ -38198,7 +38198,7 @@ NewObject__13CharNeckTwistFv = .text:0x8049A614; // type:function size:0x44 StaticClassName__13CharNeckTwistFv = .text:0x8049A658; // type:function size:0x4C Init__10CharMirrorFv = .text:0x8049A6A4; // type:function size:0x34 NewObject__10CharMirrorFv = .text:0x8049A6D8; // type:function size:0x44 -fn_8049A71C = .text:0x8049A71C; // type:function size:0x4C +StaticClassName__10CharMirrorFv = .text:0x8049A71C; // type:function size:0x4C Init__10CharLookAtFv = .text:0x8049A768; // type:function size:0x34 NewObject__10CharLookAtFv = .text:0x8049A79C; // type:function size:0x44 fn_8049A7E0 = .text:0x8049A7E0; // type:function size:0x4C @@ -38260,7 +38260,7 @@ NewObject__8CharCuffFv = .text:0x8049B5C0; // type:function size:0x48 StaticClassName__8CharCuffFv = .text:0x8049B608; // type:function size:0x4C Init__11CharCollideFv = .text:0x8049B654; // type:function size:0x34 NewObject__11CharCollideFv = .text:0x8049B688; // type:function size:0x48 -fn_8049B6D0 = .text:0x8049B6D0; // type:function size:0x4C +StaticClassName__11CharCollideFv = .text:0x8049B6D0; // type:function size:0x4C Init__13CharClipGroupFv = .text:0x8049B71C; // type:function size:0x34 NewObject__13CharClipGroupFv = .text:0x8049B750; // type:function size:0x44 fn_8049B794 = .text:0x8049B794; // type:function size:0x4C @@ -38899,7 +38899,7 @@ MakeString__FPCcfi_PCc = .text:0x804AE5D8; // type:function size:0x60 Print__9CharBonesFv = .text:0x804AE638; // type:function size:0x94 MakeString<6Symbol,f,PCc>__FPCc6SymbolfPCc_PCc = .text:0x804AE6CC; // type:function size:0x78 Invert__FRC9TransformR9Transform = .text:0x804AE744; // type:function size:0x5C -fn_804AE7A0 = .text:0x804AE7A0; // type:function size:0x8 +Target__8CharBoneCFv = .text:0x804AE7A0; // type:function size:0x8 fn_804AE7A8 = .text:0x804AE7A8; // type:function size:0x10 fn_804AE7B8 = .text:0x804AE7B8; // type:function size:0x10 fn_804AE7C8 = .text:0x804AE7C8; // type:function size:0x10 @@ -39041,7 +39041,7 @@ fn_804B2170 = .text:0x804B2170; // type:function size:0x48 fn_804B21B8 = .text:0x804B21B8; // type:function size:0xB0 fn_804B2268 = .text:0x804B2268; // type:function size:0xB0 fn_804B2318 = .text:0x804B2318; // type:function size:0x58C -NormalizeAngle__Ff = .text:0x804B28A4; // type:function size:0x60 +LimitAng__Ff = .text:0x804B28A4; // type:function size:0x60 Print__16CharBonesSamplesFv = .text:0x804B2904; // type:function size:0x120 SetVer__16CharBonesSamplesFi = .text:0x804B2A24; // type:function size:0xC Load__16CharBonesSamplesFR9BinStream = .text:0x804B2A30; // type:function size:0x5C @@ -39199,9 +39199,9 @@ fn_804B6B70 = .text:0x804B6B70; // type:function size:0xA8 fn_804B6C18 = .text:0x804B6C18; // type:function size:0x24 fn_804B6C3C = .text:0x804B6C3C; // type:function size:0x30 fn_804B6C6C = .text:0x804B6C6C; // type:function size:0x4C -fn_804B6CB8 = .text:0x804B6CB8; // type:function size:0x90 -fn_804B6D48 = .text:0x804B6D48; // type:function size:0xC0 -fn_804B6E08 = .text:0x804B6E08; // type:function size:0x58 +GetChannel__8CharClipF6Symbol = .text:0x804B6CB8; // type:function size:0x90 +EvaluateChannel__8CharClipFPvPCvif = .text:0x804B6D48; // type:function size:0xC0 +EvaluateChannel__8CharClipFPvPCvf = .text:0x804B6E08; // type:function size:0x58 ScaleDown__8CharClipFR9CharBonesf = .text:0x804B6E60; // type:function size:0x68 RotateBy__8CharClipFR9CharBonesf = .text:0x804B6EC8; // type:function size:0x5C fn_804B6F24 = .text:0x804B6F24; // type:function size:0x88 @@ -39546,10 +39546,10 @@ Highlight__11CharCollideFv = .text:0x804C2C24; // type:function size:0x1C0 Save__11CharCollideFR9BinStream = .text:0x804C2DE4; // type:function size:0x4 Load__11CharCollideFR9BinStream = .text:0x804C2DE8; // type:function size:0x1D0 Copy__11CharCollideFPCQ23Hmx6ObjectQ33Hmx6Object8CopyType = .text:0x804C2FB8; // type:function size:0xF0 -fn_804C30A8 = .text:0x804C30A8; // type:function size:0x3AC -fn_804C3454 = .text:0x804C3454; // type:function size:0x30 -fn_804C3484 = .text:0x804C3484; // type:function size:0x48 -fn_804C34CC = .text:0x804C34CC; // type:function size:0x18 +Deform__11CharCollideFv = .text:0x804C30A8; // type:function size:0x3AC +NumSpheres__11CharCollideFv = .text:0x804C3454; // type:function size:0x30 +CopyOriginalToCur__11CharCollideFv = .text:0x804C3484; // type:function size:0x48 +SyncShape__11CharCollideFv = .text:0x804C34CC; // type:function size:0x18 Handle__11CharCollideFP9DataArrayb = .text:0x804C34E4; // type:function size:0x124 SyncProperty__11CharCollideFR8DataNodeP9DataArrayi6PropOp = .text:0x804C3608; // type:function size:0x328 SetType__11CharCollideF6Symbol = .text:0x804C3930; // type:function size:0x144 @@ -39803,12 +39803,12 @@ __destroy_range_ __destroy_range_aux__11stlpmtx_stdFPQ28CharEyes17CharInterestStatePQ28CharEyes17CharInterestStatePQ28CharEyes17CharInterestStateRCQ211stlpmtx_std12__false_type_v = .text:0x804CB408; // type:function size:0x58 __copy_ptrs__11stlpmtx_stdFPQ28CharEyes17CharInterestStatePQ28CharEyes17CharInterestStatePQ28CharEyes17CharInterestStateRCQ211stlpmtx_std12__false_type_PQ28CharEyes17CharInterestState = .text:0x804CB460; // type:function size:0x28 __copy__11stlpmtx_stdFPQ28CharEyes17CharInterestStatePQ28CharEyes17CharInterestStatePQ28CharEyes17CharInterestStateRCQ211stlpmtx_std26random_access_iterator_tagPl_PQ28CharEyes17CharInterestState = .text:0x804CB488; // type:function size:0x68 -fn_804CB4F0 = .text:0x804CB4F0; // type:function size:0x4 -fn_804CB4F4 = .text:0x804CB4F4; // type:function size:0x334 +Highlight__8CharEyesFv = .text:0x804CB4F0; // type:function size:0x4 +UpdateOverlay__8CharEyesFv = .text:0x804CB4F4; // type:function size:0x334 fn_804CB828 = .text:0x804CB828; // type:function size:0x7C fn_804CB8A4 = .text:0x804CB8A4; // type:function size:0x8 -fn_804CB8AC = .text:0x804CB8AC; // type:function size:0x8 -fn_804CB8B4 = .text:0x804CB8B4; // type:function size:0x78 +ClearAllInterestObjects__8CharEyesFv = .text:0x804CB8AC; // type:function size:0x8 +AddInterestObject__8CharEyesFP12CharInterest = .text:0x804CB8B4; // type:function size:0x78 fn_804CB92C = .text:0x804CB92C; // type:function size:0x48 fn_804CB974 = .text:0x804CB974; // type:function size:0x24 fn_804CB998 = .text:0x804CB998; // type:function size:0x3C @@ -39820,7 +39820,7 @@ SetFocusInterest__8CharEyesFP12CharInteresti = .text:0x804CBAC8; // type:functio fn_804CBB74 = .text:0x804CBB74; // type:function size:0x168 fn_804CBCDC = .text:0x804CBCDC; // type:function size:0x48 fn_804CBD24 = .text:0x804CBD24; // type:function size:0xD8 -fn_804CBDFC = .text:0x804CBDFC; // type:function size:0xAC +ScaleToMagnitude__FRC7Vector3fR7Vector3 = .text:0x804CBDFC; // type:function size:0xAC fn_804CBEA8 = .text:0x804CBEA8; // type:function size:0x8 fn_804CBEB0 = .text:0x804CBEB0; // type:function size:0x78 Poll__8CharEyesFv = .text:0x804CBF28; // type:function size:0x608 @@ -40132,20 +40132,20 @@ __ct__Q211stlpmtx_std85_Vector_base>RQ211stlpmtx_std66list> = .text:0x804D6FA0; // type:function size:0xAC Hookup__8CharHairFv = .text:0x804D704C; // type:function size:0xC4 __pp__24ObjDirItr<11CharCollide>Fv = .text:0x804D7110; // type:function size:0x50 @@ -41085,25 +41085,25 @@ fn_804F1D70 = .text:0x804F1D70; // type:function size:0x5C fn_804F1DCC = .text:0x804F1DCC; // type:function size:0x5C fn_804F1E28 = .text:0x804F1E28; // type:function size:0x54 __ct__10CharMirrorFv = .text:0x804F1E7C; // type:function size:0xEC -fn_804F1F68 = .text:0x804F1F68; // type:function size:0x58 -fn_804F1FC0 = .text:0x804F1FC0; // type:function size:0x80 -fn_804F2040 = .text:0x804F2040; // type:function size:0x80 +__dt__Q211stlpmtx_std89vector>Fv = .text:0x804F1F68; // type:function size:0x58 +__dt__Q211stlpmtx_std95_Vector_impl>Fv = .text:0x804F1FC0; // type:function size:0x80 +__dt__Q211stlpmtx_std95_Vector_base>Fv = .text:0x804F2040; // type:function size:0x80 fn_804F20C0 = .text:0x804F20C0; // type:function size:0x58 -fn_804F2118 = .text:0x804F2118; // type:function size:0x54 +_Destroy_Range>__11stlpmtx_stdFQ211stlpmtx_std42reverse_iteratorQ211stlpmtx_std42reverse_iterator_v = .text:0x804F2118; // type:function size:0x54 fn_804F216C = .text:0x804F216C; // type:function size:0x5C fn_804F21C8 = .text:0x804F21C8; // type:function size:0x6C fn_804F2234 = .text:0x804F2234; // type:function size:0x28 -fn_804F225C = .text:0x804F225C; // type:function size:0x8 -fn_804F2264 = .text:0x804F2264; // type:function size:0x3C -fn_804F22A0 = .text:0x804F22A0; // type:function size:0x80 -fn_804F2320 = .text:0x804F2320; // type:function size:0x30 -fn_804F2350 = .text:0x804F2350; // type:function size:0x30 -fn_804F2380 = .text:0x804F2380; // type:function size:0x40 -fn_804F23C0 = .text:0x804F23C0; // type:function size:0x68 -fn_804F2428 = .text:0x804F2428; // type:function size:0x234 -fn_804F265C = .text:0x804F265C; // type:function size:0x58 -fn_804F26B4 = .text:0x804F26B4; // type:function size:0x58 -fn_804F270C = .text:0x804F270C; // type:function size:0x210 +rend__Q211stlpmtx_std95_Vector_impl>Fv = .text:0x804F225C; // type:function size:0x8 +rbegin__Q211stlpmtx_std95_Vector_impl>Fv = .text:0x804F2264; // type:function size:0x3C +__dt__34ObjPtr<13CharServoBone,9ObjectDir>Fv = .text:0x804F22A0; // type:function size:0x80 +__ct__Q211stlpmtx_std89vector>FRCQ211stlpmtx_std37StlNodeAlloc = .text:0x804F2320; // type:function size:0x30 +__ct__Q211stlpmtx_std95_Vector_impl>FRCQ211stlpmtx_std37StlNodeAlloc = .text:0x804F2350; // type:function size:0x30 +__ct__Q211stlpmtx_std95_Vector_base>FRCQ211stlpmtx_std37StlNodeAlloc = .text:0x804F2380; // type:function size:0x40 +__ct__34ObjPtr<13CharServoBone,9ObjectDir>FPQ23Hmx6ObjectP13CharServoBone = .text:0x804F23C0; // type:function size:0x68 +Poll__10CharMirrorFv = .text:0x804F2428; // type:function size:0x234 +SetServo__10CharMirrorFP13CharServoBone = .text:0x804F265C; // type:function size:0x58 +SetMirrorServo__10CharMirrorFP13CharServoBone = .text:0x804F26B4; // type:function size:0x58 +SyncBones__10CharMirrorFv = .text:0x804F270C; // type:function size:0x210 fn_804F291C = .text:0x804F291C; // type:function size:0x4 fn_804F2920 = .text:0x804F2920; // type:function size:0x90 fn_804F29B0 = .text:0x804F29B0; // type:function size:0x4 @@ -41114,21 +41114,21 @@ fn_804F2A88 = .text:0x804F2A88; // type:function size:0x2C fn_804F2AB4 = .text:0x804F2AB4; // type:function size:0x58 fn_804F2B0C = .text:0x804F2B0C; // type:function size:0x28 fn_804F2B34 = .text:0x804F2B34; // type:function size:0x68 -fn_804F2B9C = .text:0x804F2B9C; // type:function size:0x48 -fn_804F2BE4 = .text:0x804F2BE4; // type:function size:0x4 -fn_804F2BE8 = .text:0x804F2BE8; // type:function size:0x90 -fn_804F2C78 = .text:0x804F2C78; // type:function size:0x40 -fn_804F2CB8 = .text:0x804F2CB8; // type:function size:0x104 -fn_804F2DBC = .text:0x804F2DBC; // type:function size:0xA4 -fn_804F2E60 = .text:0x804F2E60; // type:function size:0x11C -fn_804F2F7C = .text:0x804F2F7C; // type:function size:0x1A4 -fn_804F3120 = .text:0x804F3120; // type:function size:0x3C -fn_804F315C = .text:0x804F315C; // type:function size:0xBC +PollDeps__10CharMirrorFRQ211stlpmtx_std66list>RQ211stlpmtx_std66list> = .text:0x804F2B9C; // type:function size:0x48 +Save__10CharMirrorFR9BinStream = .text:0x804F2BE4; // type:function size:0x4 +Load__10CharMirrorFR9BinStream = .text:0x804F2BE8; // type:function size:0x90 +__rs<13CharServoBone>__FR9BinStreamR34ObjPtr<13CharServoBone,9ObjectDir>_R9BinStream = .text:0x804F2C78; // type:function size:0x40 +Load__34ObjPtr<13CharServoBone,9ObjectDir>FR9BinStreambP9ObjectDir = .text:0x804F2CB8; // type:function size:0x104 +Copy__10CharMirrorFPCQ23Hmx6ObjectQ33Hmx6Object8CopyType = .text:0x804F2DBC; // type:function size:0xA4 +Handle__10CharMirrorFP9DataArrayb = .text:0x804F2E60; // type:function size:0x11C +SyncProperty__10CharMirrorFR8DataNodeP9DataArrayi6PropOp = .text:0x804F2F7C; // type:function size:0x1A4 +Obj<13CharServoBone>__8DataNodeCFPC9DataArray_P13CharServoBone = .text:0x804F3120; // type:function size:0x3C +__dt__10CharMirrorFv = .text:0x804F315C; // type:function size:0xBC fn_804F3218 = .text:0x804F3218; // type:function size:0x68 fn_804F3280 = .text:0x804F3280; // type:function size:0x2C fn_804F32AC = .text:0x804F32AC; // type:function size:0x6C -fn_804F3318 = .text:0x804F3318; // type:function size:0x134 -fn_804F344C = .text:0x804F344C; // type:function size:0x4 +SetType__10CharMirrorF6Symbol = .text:0x804F3318; // type:function size:0x134 +ClassName__10CharMirrorCFv = .text:0x804F344C; // type:function size:0x4 fn_804F3450 = .text:0x804F3450; // type:function size:0x190 fn_804F35E0 = .text:0x804F35E0; // type:function size:0x5C fn_804F363C = .text:0x804F363C; // type:function size:0x10 @@ -41141,20 +41141,20 @@ fn_804F38A0 = .text:0x804F38A0; // type:function size:0x60 fn_804F3900 = .text:0x804F3900; // type:function size:0x5C fn_804F395C = .text:0x804F395C; // type:function size:0x54 fn_804F39B0 = .text:0x804F39B0; // type:function size:0x14 -fn_804F39C4 = .text:0x804F39C4; // type:function size:0x14 -fn_804F39D8 = .text:0x804F39D8; // type:function size:0x14 -fn_804F39EC = .text:0x804F39EC; // type:function size:0x14 -fn_804F3A00 = .text:0x804F3A00; // type:function size:0x14 -fn_804F3A14 = .text:0x804F3A14; // type:function size:0x14 -fn_804F3A28 = .text:0x804F3A28; // type:function size:0x14 -fn_804F3A3C = .text:0x804F3A3C; // type:function size:0x14 -fn_804F3A50 = .text:0x804F3A50; // type:function size:0x14 -fn_804F3A64 = .text:0x804F3A64; // type:function size:0x8 -fn_804F3A6C = .text:0x804F3A6C; // type:function size:0x8 -fn_804F3A74 = .text:0x804F3A74; // type:function size:0x8 -fn_804F3A7C = .text:0x804F3A7C; // type:function size:0x8 -fn_804F3A84 = .text:0x804F3A84; // type:function size:0x8 -fn_804F3A8C = .text:0x804F3A8C; // type:function size:0x8 +@180@28@Load__10CharMirrorFR9BinStream = .text:0x804F39C4; // type:function size:0x14 +@180@28@Copy__10CharMirrorFPCQ23Hmx6ObjectQ33Hmx6Object8CopyType = .text:0x804F39D8; // type:function size:0x14 +@180@28@Save__10CharMirrorFR9BinStream = .text:0x804F39EC; // type:function size:0x14 +@180@28@__dt__10CharMirrorFv = .text:0x804F3A00; // type:function size:0x14 +@180@28@SyncProperty__10CharMirrorFR8DataNodeP9DataArrayi6PropOp = .text:0x804F3A14; // type:function size:0x14 +@180@28@Handle__10CharMirrorFP9DataArrayb = .text:0x804F3A28; // type:function size:0x14 +@180@28@SetType__10CharMirrorF6Symbol = .text:0x804F3A3C; // type:function size:0x14 +@180@28@ClassName__10CharMirrorCFv = .text:0x804F3A50; // type:function size:0x14 +@24@Poll__10CharMirrorFv = .text:0x804F3A64; // type:function size:0x8 +@24@Handle__10CharMirrorFP9DataArrayb = .text:0x804F3A6C; // type:function size:0x8 +@24@SetType__10CharMirrorF6Symbol = .text:0x804F3A74; // type:function size:0x8 +@24@ClassName__10CharMirrorCFv = .text:0x804F3A7C; // type:function size:0x8 +@24@__dt__10CharMirrorFv = .text:0x804F3A84; // type:function size:0x8 +@24@PollDeps__10CharMirrorFRQ211stlpmtx_std66list>RQ211stlpmtx_std66list> = .text:0x804F3A8C; // type:function size:0x8 __ct__13CharNeckTwistFv = .text:0x804F3A94; // type:function size:0xB0 Poll__13CharNeckTwistFv = .text:0x804F3B44; // type:function size:0x134 PollDeps__13CharNeckTwistFRQ211stlpmtx_std66list>RQ211stlpmtx_std66list> = .text:0x804F3C78; // type:function size:0x80 @@ -41391,7 +41391,7 @@ fn_804F9ED4 = .text:0x804F9ED4; // type:function size:0x54 fn_804F9F28 = .text:0x804F9F28; // type:function size:0x80 fn_804F9FA8 = .text:0x804F9FA8; // type:function size:0x68 fn_804FA010 = .text:0x804FA010; // type:function size:0x68 -fn_804FA078 = .text:0x804FA078; // type:function size:0xF8 +__dt__13CharacterTestFv = .text:0x804FA078; // type:function size:0xF8 fn_804FA170 = .text:0x804FA170; // type:function size:0x10 Load__13CharacterTestFR9BinStream = .text:0x804FA180; // type:function size:0x220 fn_804FA3A0 = .text:0x804FA3A0; // type:function size:0x40 @@ -41401,13 +41401,13 @@ fn_804FA584 = .text:0x804FA584; // type:function size:0x11C fn_804FA6A0 = .text:0x804FA6A0; // type:function size:0x4C fn_804FA6EC = .text:0x804FA6EC; // type:function size:0x78 fn_804FA764 = .text:0x804FA764; // type:function size:0x2C -fn_804FA790 = .text:0x804FA790; // type:function size:0x90 +Handle__13CharacterTestFP9DataArrayb = .text:0x804FA790; // type:function size:0x90 fn_804FA820 = .text:0x804FA820; // type:function size:0x110 fn_804FA930 = .text:0x804FA930; // type:function size:0x6C __ct__14CharUpperTwistFv = .text:0x804FA99C; // type:function size:0xCC __dt__14CharUpperTwistFv = .text:0x804FAA68; // type:function size:0xA4 Poll__14CharUpperTwistFv = .text:0x804FAB0C; // type:function size:0x154 -fn_804FAC60 = .text:0x804FAC60; // type:function size:0x50 +LookAt__FRQ23Hmx7Matrix3 = .text:0x804FAC60; // type:function size:0x50 PollDeps__14CharUpperTwistFRQ211stlpmtx_std66list>RQ211stlpmtx_std66list> = .text:0x804FACB0; // type:function size:0xA4 Save__14CharUpperTwistFR9BinStream = .text:0x804FAD54; // type:function size:0x4 Load__14CharUpperTwistFR9BinStream = .text:0x804FAD58; // type:function size:0x88 @@ -41445,15 +41445,15 @@ fn_804FB8BC = .text:0x804FB8BC; // type:function size:0x10 fn_804FB8CC = .text:0x804FB8CC; // type:function size:0x30 fn_804FB8FC = .text:0x804FB8FC; // type:function size:0x30 fn_804FB92C = .text:0x804FB92C; // type:function size:0x40 -fn_804FB96C = .text:0x804FB96C; // type:function size:0x58 +GrabBone__FP8CharBoneP9ObjectDir = .text:0x804FB96C; // type:function size:0x58 CharUtlMergeBones__FP9ObjectDirP9ObjectDiri = .text:0x804FB9C4; // type:function size:0x24C -fn_804FBC10 = .text:0x804FBC10; // type:function size:0x8 -fn_804FBC18 = .text:0x804FBC18; // type:function size:0x60 -fn_804FBC78 = .text:0x804FBC78; // type:function size:0x84 -fn_804FBCFC = .text:0x804FBCFC; // type:function size:0xFC -fn_804FBDF8 = .text:0x804FBDF8; // type:function size:0x90 -fn_804FBE88 = .text:0x804FBE88; // type:function size:0xA0 -fn_804FBF28 = .text:0x804FBF28; // type:function size:0xEC +SetTarget__8CharBoneFP8CharBone = .text:0x804FBC10; // type:function size:0x8 +__ct__11ClipPredictFP8CharClipRC7Vector3f = .text:0x804FBC18; // type:function size:0x60 +SetClip__11ClipPredictFP8CharClip = .text:0x804FBC78; // type:function size:0x84 +Predict__11ClipPredictFff = .text:0x804FBCFC; // type:function size:0xFC +CharUtlFindBone__FPCcP9ObjectDir = .text:0x804FBDF8; // type:function size:0x90 +Find<8CharBone>__9ObjectDirFPCcb_P8CharBone = .text:0x804FBE88; // type:function size:0xA0 +CharUtlFindBoneTrans__FPCcP9ObjectDir = .text:0x804FBF28; // type:function size:0xEC CharUtlResetHair__FP9Character = .text:0x804FC014; // type:function size:0x60 __pp__20ObjDirItr<8CharHair>Fv = .text:0x804FC074; // type:function size:0x50 Advance__20ObjDirItr<8CharHair>Fv = .text:0x804FC0C4; // type:function size:0xD0 @@ -41727,15 +41727,15 @@ fn_80504A40 = .text:0x80504A40; // type:function size:0x2C fn_80504A6C = .text:0x80504A6C; // type:function size:0x8 fn_80504A74 = .text:0x80504A74; // type:function size:0x8 fn_80504A7C = .text:0x80504A7C; // type:function size:0x8 -WaypointInit__Fv = .text:0x80504A84; // type:function size:0xC8 -Init__8WaypointFv = .text:0x80504B4C; // type:function size:0x34 +Init__8WaypointFv = .text:0x80504A84; // type:function size:0xC8 +Register__8WaypointFv = .text:0x80504B4C; // type:function size:0x34 NewObject__8WaypointFv = .text:0x80504B80; // type:function size:0x48 -fn_80504BC8 = .text:0x80504BC8; // type:function size:0x3C -fn_80504C04 = .text:0x80504C04; // type:function size:0xA4 +Terminate__8WaypointFv = .text:0x80504BC8; // type:function size:0x3C +Find__8WaypointFi = .text:0x80504C04; // type:function size:0xA4 fn_80504CA8 = .text:0x80504CA8; // type:function size:0x3C fn_80504CE4 = .text:0x80504CE4; // type:function size:0x3C -fn_80504D20 = .text:0x80504D20; // type:function size:0xEC -fn_80504E0C = .text:0x80504E0C; // type:function size:0x84 +FindNearest__8WaypointFRC7Vector3i = .text:0x80504D20; // type:function size:0xEC +__dt__33ObjOwnerPtr<8Waypoint,9ObjectDir>Fv = .text:0x80504E0C; // type:function size:0x84 fn_80504E90 = .text:0x80504E90; // type:function size:0x8 fn_80504E98 = .text:0x80504E98; // type:function size:0x6C fn_80504F04 = .text:0x80504F04; // type:function size:0x68 @@ -41754,57 +41754,57 @@ fn_8050550C = .text:0x8050550C; // type:function size:0x6C fn_80505578 = .text:0x80505578; // type:function size:0x28 fn_805055A0 = .text:0x805055A0; // type:function size:0x8 fn_805055A8 = .text:0x805055A8; // type:function size:0x3C -fn_805055E4 = .text:0x805055E4; // type:function size:0x50 -fn_80505634 = .text:0x80505634; // type:function size:0x30 -fn_80505664 = .text:0x80505664; // type:function size:0x30 -fn_80505694 = .text:0x80505694; // type:function size:0x40 -fn_805056D4 = .text:0x805056D4; // type:function size:0x15C +__ct__49ObjVector<33ObjOwnerPtr<8Waypoint,9ObjectDir>,Us>FPQ23Hmx6Object = .text:0x805055E4; // type:function size:0x50 +__ct__Q211stlpmtx_std113vector<33ObjOwnerPtr<8Waypoint,9ObjectDir>,Us,Q211stlpmtx_std49StlNodeAlloc<33ObjOwnerPtr<8Waypoint,9ObjectDir>>>FRCQ211stlpmtx_std49StlNodeAlloc<33ObjOwnerPtr<8Waypoint,9ObjectDir>> = .text:0x80505634; // type:function size:0x30 +__ct__Q211stlpmtx_std119_Vector_impl<33ObjOwnerPtr<8Waypoint,9ObjectDir>,Us,Q211stlpmtx_std49StlNodeAlloc<33ObjOwnerPtr<8Waypoint,9ObjectDir>>>FRCQ211stlpmtx_std49StlNodeAlloc<33ObjOwnerPtr<8Waypoint,9ObjectDir>> = .text:0x80505664; // type:function size:0x30 +__ct__Q211stlpmtx_std119_Vector_base<33ObjOwnerPtr<8Waypoint,9ObjectDir>,Us,Q211stlpmtx_std49StlNodeAlloc<33ObjOwnerPtr<8Waypoint,9ObjectDir>>>FRCQ211stlpmtx_std49StlNodeAlloc<33ObjOwnerPtr<8Waypoint,9ObjectDir>> = .text:0x80505694; // type:function size:0x40 +__dt__8WaypointFv = .text:0x805056D4; // type:function size:0x15C fn_80505830 = .text:0x80505830; // type:function size:0x5C -fn_8050588C = .text:0x8050588C; // type:function size:0xEC -fn_80505978 = .text:0x80505978; // type:function size:0x2C +Replace__8WaypointFPQ23Hmx6ObjectPQ23Hmx6Object = .text:0x8050588C; // type:function size:0xEC +erase__Q211stlpmtx_std113vector<33ObjOwnerPtr<8Waypoint,9ObjectDir>,Us,Q211stlpmtx_std49StlNodeAlloc<33ObjOwnerPtr<8Waypoint,9ObjectDir>>>FP33ObjOwnerPtr<8Waypoint,9ObjectDir> = .text:0x80505978; // type:function size:0x2C fn_805059A4 = .text:0x805059A4; // type:function size:0x84 fn_80505A28 = .text:0x80505A28; // type:function size:0x2C fn_80505A54 = .text:0x80505A54; // type:function size:0x28 fn_80505A7C = .text:0x80505A7C; // type:function size:0x68 -fn_80505AE4 = .text:0x80505AE4; // type:function size:0x4 -fn_80505AE8 = .text:0x80505AE8; // type:function size:0xB8 -fn_80505BA0 = .text:0x80505BA0; // type:function size:0xC -fn_80505BAC = .text:0x80505BAC; // type:function size:0xC -fn_80505BB8 = .text:0x80505BB8; // type:function size:0x180 -fn_80505D38 = .text:0x80505D38; // type:function size:0x6C -fn_80505DA4 = .text:0x80505DA4; // type:function size:0xBC -fn_80505E60 = .text:0x80505E60; // type:function size:0x5C -fn_80505EBC = .text:0x80505EBC; // type:function size:0x30 -fn_80505EEC = .text:0x80505EEC; // type:function size:0x60 -fn_80505F4C = .text:0x80505F4C; // type:function size:0x4 -fn_80505F50 = .text:0x80505F50; // type:function size:0x90 +Highlight__8WaypointFv = .text:0x80505AE4; // type:function size:0x4 +Constrain__8WaypointFR9Transform = .text:0x80505AE8; // type:function size:0xB8 +ShapeDelta__8WaypointFRC7Vector3R7Vector3 = .text:0x80505BA0; // type:function size:0xC +ShapeDelta__8WaypointFf = .text:0x80505BAC; // type:function size:0xC +ShapeDeltaBox__8WaypointFRC7Vector3ffR7Vector3 = .text:0x80505BB8; // type:function size:0x180 +ShapeDeltaAng__8WaypointFff = .text:0x80505D38; // type:function size:0x6C +Copy__8WaypointFPCQ23Hmx6ObjectQ33Hmx6Object8CopyType = .text:0x80505DA4; // type:function size:0xBC +__as__49ObjVector<33ObjOwnerPtr<8Waypoint,9ObjectDir>,Us>FRC49ObjVector<33ObjOwnerPtr<8Waypoint,9ObjectDir>,Us> = .text:0x80505E60; // type:function size:0x5C +__as__Q211stlpmtx_std113vector<33ObjOwnerPtr<8Waypoint,9ObjectDir>,Us,Q211stlpmtx_std49StlNodeAlloc<33ObjOwnerPtr<8Waypoint,9ObjectDir>>>FRCQ211stlpmtx_std113vector<33ObjOwnerPtr<8Waypoint,9ObjectDir>,Us,Q211stlpmtx_std49StlNodeAlloc<33ObjOwnerPtr<8Waypoint,9ObjectDir>>> = .text:0x80505EBC; // type:function size:0x30 +resize__49ObjVector<33ObjOwnerPtr<8Waypoint,9ObjectDir>,Us>FUl = .text:0x80505EEC; // type:function size:0x60 +resize__Q211stlpmtx_std113vector<33ObjOwnerPtr<8Waypoint,9ObjectDir>,Us,Q211stlpmtx_std49StlNodeAlloc<33ObjOwnerPtr<8Waypoint,9ObjectDir>>>FUlRC33ObjOwnerPtr<8Waypoint,9ObjectDir> = .text:0x80505F4C; // type:function size:0x4 +resize__Q211stlpmtx_std119_Vector_impl<33ObjOwnerPtr<8Waypoint,9ObjectDir>,Us,Q211stlpmtx_std49StlNodeAlloc<33ObjOwnerPtr<8Waypoint,9ObjectDir>>>FUlRC33ObjOwnerPtr<8Waypoint,9ObjectDir> = .text:0x80505F50; // type:function size:0x90 fn_80505FE0 = .text:0x80505FE0; // type:function size:0x4 fn_80505FE4 = .text:0x80505FE4; // type:function size:0x40 fn_80506024 = .text:0x80506024; // type:function size:0x8C fn_805060B0 = .text:0x805060B0; // type:function size:0x8 fn_805060B8 = .text:0x805060B8; // type:function size:0x2C fn_805060E4 = .text:0x805060E4; // type:function size:0x58 -fn_8050613C = .text:0x8050613C; // type:function size:0x6C -fn_805061A8 = .text:0x805061A8; // type:function size:0x4 -fn_805061AC = .text:0x805061AC; // type:function size:0x138 -fn_805062E4 = .text:0x805062E4; // type:function size:0x74 -fn_80506358 = .text:0x80506358; // type:function size:0x40 -fn_80506398 = .text:0x80506398; // type:function size:0x104 -fn_8050649C = .text:0x8050649C; // type:function size:0x2A0 -fn_8050673C = .text:0x8050673C; // type:function size:0x174 -fn_805068B0 = .text:0x805068B0; // type:function size:0xC0 -fn_80506970 = .text:0x80506970; // type:function size:0x124 +__ct__33ObjOwnerPtr<8Waypoint,9ObjectDir>FPQ23Hmx6ObjectP8Waypoint = .text:0x8050613C; // type:function size:0x6C +Save__8WaypointFR9BinStream = .text:0x805061A8; // type:function size:0x4 +Load__8WaypointFR9BinStream = .text:0x805061AC; // type:function size:0x138 +__rs<33ObjOwnerPtr<8Waypoint,9ObjectDir>,Us>__FR9BinStreamR49ObjVector<33ObjOwnerPtr<8Waypoint,9ObjectDir>,Us>_R9BinStream = .text:0x805062E4; // type:function size:0x74 +__rs<8Waypoint>__FR9BinStreamR33ObjOwnerPtr<8Waypoint,9ObjectDir>_R9BinStream = .text:0x80506358; // type:function size:0x40 +Load__33ObjOwnerPtr<8Waypoint,9ObjectDir>FR9BinStreambP9ObjectDir = .text:0x80506398; // type:function size:0x104 +SyncProperty__8WaypointFR8DataNodeP9DataArrayi6PropOp = .text:0x8050649C; // type:function size:0x2A0 +PropSync<33ObjOwnerPtr<8Waypoint,9ObjectDir>,Us>__FR49ObjVector<33ObjOwnerPtr<8Waypoint,9ObjectDir>,Us>R8DataNodeP9DataArrayi6PropOp_b = .text:0x8050673C; // type:function size:0x174 +PropSync<8Waypoint>__FR33ObjOwnerPtr<8Waypoint,9ObjectDir>R8DataNodeP9DataArrayi6PropOp_b = .text:0x805068B0; // type:function size:0xC0 +Handle__8WaypointFP9DataArrayb = .text:0x80506970; // type:function size:0x124 fn_80506A94 = .text:0x80506A94; // type:function size:0x68 fn_80506AFC = .text:0x80506AFC; // type:function size:0x2C -fn_80506B28 = .text:0x80506B28; // type:function size:0x58 +insert__Q211stlpmtx_std113vector<33ObjOwnerPtr<8Waypoint,9ObjectDir>,Us,Q211stlpmtx_std49StlNodeAlloc<33ObjOwnerPtr<8Waypoint,9ObjectDir>>>FP33ObjOwnerPtr<8Waypoint,9ObjectDir>RC33ObjOwnerPtr<8Waypoint,9ObjectDir> = .text:0x80506B28; // type:function size:0x58 fn_80506B80 = .text:0x80506B80; // type:function size:0x160 fn_80506CE0 = .text:0x80506CE0; // type:function size:0x5C fn_80506D3C = .text:0x80506D3C; // type:function size:0x10 fn_80506D4C = .text:0x80506D4C; // type:function size:0x28 fn_80506D74 = .text:0x80506D74; // type:function size:0x5C fn_80506DD0 = .text:0x80506DD0; // type:function size:0x60 -fn_80506E30 = .text:0x80506E30; // type:function size:0x144 -fn_80506F74 = .text:0x80506F74; // type:function size:0x4 +SetType__8WaypointF6Symbol = .text:0x80506E30; // type:function size:0x144 +ClassName__8WaypointCFv = .text:0x80506F74; // type:function size:0x4 fn_80506F78 = .text:0x80506F78; // type:function size:0x198 fn_80507110 = .text:0x80507110; // type:function size:0x5C fn_8050716C = .text:0x8050716C; // type:function size:0x54 @@ -41814,18 +41814,18 @@ fn_80507250 = .text:0x80507250; // type:function size:0x114 fn_80507364 = .text:0x80507364; // type:function size:0x5C fn_805073C0 = .text:0x805073C0; // type:function size:0x5C fn_8050741C = .text:0x8050741C; // type:function size:0x54 -fn_80507470 = .text:0x80507470; // type:function size:0x14 -fn_80507484 = .text:0x80507484; // type:function size:0x14 -fn_80507498 = .text:0x80507498; // type:function size:0x14 -fn_805074AC = .text:0x805074AC; // type:function size:0x14 -fn_805074C0 = .text:0x805074C0; // type:function size:0x14 -fn_805074D4 = .text:0x805074D4; // type:function size:0x14 -fn_805074E8 = .text:0x805074E8; // type:function size:0x14 -fn_805074FC = .text:0x805074FC; // type:function size:0x14 -fn_80507510 = .text:0x80507510; // type:function size:0x14 -fn_80507524 = .text:0x80507524; // type:function size:0x14 -fn_80507538 = .text:0x80507538; // type:function size:0x14 -fn_8050754C = .text:0x8050754C; // type:function size:0x14 +@184@28@Replace__8WaypointFPQ23Hmx6ObjectPQ23Hmx6Object = .text:0x80507470; // type:function size:0x14 +@184@28@Print__16RndTransformableFv = .text:0x80507484; // type:function size:0x14 +@184@28@Load__8WaypointFR9BinStream = .text:0x80507498; // type:function size:0x14 +@184@28@Copy__8WaypointFPCQ23Hmx6ObjectQ33Hmx6Object8CopyType = .text:0x805074AC; // type:function size:0x14 +@184@28@Save__8WaypointFR9BinStream = .text:0x805074C0; // type:function size:0x14 +@184@28@__dt__8WaypointFv = .text:0x805074D4; // type:function size:0x14 +@184@28@SyncProperty__8WaypointFR8DataNodeP9DataArrayi6PropOp = .text:0x805074E8; // type:function size:0x14 +@184@28@Handle__8WaypointFP9DataArrayb = .text:0x805074FC; // type:function size:0x14 +@184@28@SetType__8WaypointF6Symbol = .text:0x80507510; // type:function size:0x14 +@184@28@ClassName__8WaypointCFv = .text:0x80507524; // type:function size:0x14 +@216@8@Highlight__8WaypointFv = .text:0x80507538; // type:function size:0x14 +@216@8@__dt__8WaypointFv = .text:0x8050754C; // type:function size:0x14 __ct__16CharGuitarStringFv = .text:0x80507560; // type:function size:0xF0 __dt__16CharGuitarStringFv = .text:0x80507650; // type:function size:0xB0 Poll__16CharGuitarStringFv = .text:0x80507700; // type:function size:0x14C @@ -48369,7 +48369,7 @@ fn_805CCB30 = .text:0x805CCB30; // type:function size:0xC fn_805CCB3C = .text:0x805CCB3C; // type:function size:0x15C fn_805CCC98 = .text:0x805CCC98; // type:function size:0x10 fn_805CCCA8 = .text:0x805CCCA8; // type:function size:0xB8 -fn_805CCD60 = .text:0x805CCD60; // type:function size:0xD4 +WorldToScreen__6RndCamCFRC7Vector3R7Vector2 = .text:0x805CCD60; // type:function size:0xD4 fn_805CCE34 = .text:0x805CCE34; // type:function size:0x2C fn_805CCE60 = .text:0x805CCE60; // type:function size:0xA0 fn_805CCF00 = .text:0x805CCF00; // type:function size:0x80 @@ -51095,7 +51095,7 @@ fn_8062495C = .text:0x8062495C; // type:function size:0x50 fn_806249AC = .text:0x806249AC; // type:function size:0x4C fn_806249F8 = .text:0x806249F8; // type:function size:0x7C fn_80624A74 = .text:0x80624A74; // type:function size:0x7C -fn_80624AF0 = .text:0x80624AF0; // type:function size:0xC +Current__11RndPostProcFv = .text:0x80624AF0; // type:function size:0xC fn_80624AFC = .text:0x80624AFC; // type:function size:0x4 fn_80624B00 = .text:0x80624B00; // type:function size:0x4 fn_80624B04 = .text:0x80624B04; // type:function size:0x74 @@ -52446,9 +52446,9 @@ GenerationCount__FP16RndTransformableP16RndTransformable = .text:0x80655038; // fn_806550B4 = .text:0x806550B4; // type:function size:0x198 fn_8065524C = .text:0x8065524C; // type:function size:0x324 UtilDrawSphere__FRC7Vector3fRCQ23Hmx5Color = .text:0x80655570; // type:function size:0x120 -fn_80655690 = .text:0x80655690; // type:function size:0x45C +UtilDrawCigar__FRC9TransformPCfPCfRCQ23Hmx5Colori = .text:0x80655690; // type:function size:0x45C fn_80655AEC = .text:0x80655AEC; // type:function size:0x2BC -fn_80655DA8 = .text:0x80655DA8; // type:function size:0x260 +UtilDrawPlane__FRC5PlaneRC7Vector3RCQ23Hmx5Colorif = .text:0x80655DA8; // type:function size:0x260 UtilDrawAxes__FRC9TransformfRCQ23Hmx5Color = .text:0x80656008; // type:function size:0x180 SetLocalScale__FP16RndTransformableRC7Vector3 = .text:0x80656188; // type:function size:0x64 SpliceKeys__FP12RndTransAnimP12RndTransAnimff = .text:0x806561EC; // type:function size:0x660 @@ -60000,7 +60000,7 @@ lbl_807F0258 = .rodata:0x807F0258; // type:object size:0x20 data:4byte @D_0000f0bf00000000 = .rodata:0x807F0288; // type:object size:0x8 data:double @F_0000c842 = .rodata:0x807F0290; // type:object size:0x8 data:float @F_00008047 = .rodata:0x807F0298; // type:object size:0x8 data:float -lbl_807F02A0 = .rodata:0x807F02A0; // type:object size:0x4 data:float +@F_00004041 = .rodata:0x807F02A0; // type:object size:0x4 data:float lbl_807F02A4 = .rodata:0x807F02A4; // type:object size:0x4 data:float @F_00007f43 = .rodata:0x807F02A8; // type:object size:0x8 data:float lbl_807F02B0 = .rodata:0x807F02B0; // type:object size:0x8 data:string @@ -60047,7 +60047,7 @@ lbl_807F03B0 = .rodata:0x807F03B0; // type:object size:0x8 data:float lbl_807F03B8 = .rodata:0x807F03B8; // type:object size:0x4 data:float lbl_807F03BC = .rodata:0x807F03BC; // type:object size:0x4 data:float @F_3333333f = .rodata:0x807F03C0; // type:object size:0x4 data:float -lbl_807F03C4 = .rodata:0x807F03C4; // type:object size:0x4 data:float +@F_00007042 = .rodata:0x807F03C4; // type:object size:0x4 data:float @D_3333eb3f33333333 = .rodata:0x807F03C8; // type:object size:0x8 data:double @D_6666ee3f66666666 = .rodata:0x807F03D0; // type:object size:0x8 data:double lbl_807F03D8 = .rodata:0x807F03D8; // type:object size:0x8 data:double @@ -60362,10 +60362,10 @@ lbl_807F3ADC = .rodata:0x807F3ADC; // type:object size:0x4 data:float lbl_807F3AE0 = .rodata:0x807F3AE0; // type:object size:0x4 data:float lbl_807F3AE4 = .rodata:0x807F3AE4; // type:object size:0x4 data:float @F_3333c340 = .rodata:0x807F3AE8; // type:object size:0x4 data:float -lbl_807F3AF0 = .rodata:0x807F3AF0; // type:object size:0x8 data:double -lbl_807F3AF8 = .rodata:0x807F3AF8; // type:object size:0x8 data:double -lbl_807F3B00 = .rodata:0x807F3B00; // type:object size:0x4 data:float -lbl_807F3B04 = .rodata:0x807F3B04; // type:object size:0x4 data:float +@D_00002e4000000000 = .rodata:0x807F3AF0; // type:object size:0x8 data:double +@D_00003e4000000000 = .rodata:0x807F3AF8; // type:object size:0x8 data:double +@F_a4707dbf = .rodata:0x807F3B00; // type:object size:0x4 data:float +@F_000080be = .rodata:0x807F3B04; // type:object size:0x4 data:float @F_3baaaa3e = .rodata:0x807F3B08; // type:object size:0x8 data:float @F_0ad7233d = .rodata:0x807F3B10; // type:object size:0x4 data:float lbl_807F3B14 = .rodata:0x807F3B14; // type:object size:0x4 data:float @@ -60394,8 +60394,8 @@ lbl_807F3B70 = .rodata:0x807F3B70; // type:object size:0x8 data:float lbl_807F3B78 = .rodata:0x807F3B78; // type:object size:0x4 data:float lbl_807F3B7C = .rodata:0x807F3B7C; // type:object size:0x4 data:float @F_0ad7a33c = .rodata:0x807F3B80; // type:object size:0x8 data:float -lbl_807F3B88 = .rodata:0x807F3B88; // type:object size:0x4 data:float -lbl_807F3B8C = .rodata:0x807F3B8C; // type:object size:0x4 data:float +@F_fa7eaa3e = .rodata:0x807F3B88; // type:object size:0x4 data:float +@F_fa7e2a3f = .rodata:0x807F3B8C; // type:object size:0x4 data:float lbl_807F3B90 = .rodata:0x807F3B90; // type:object size:0x14 data:4byte lbl_807F3BA4 = .rodata:0x807F3BA4; // type:object size:0x14 data:4byte lbl_807F3BB8 = .rodata:0x807F3BB8; // type:object size:0x4 data:float @@ -70001,7 +70001,7 @@ lbl_80888A7C = .data:0x80888A7C; // type:object size:0xC lbl_80888A88 = .data:0x80888A88; // type:object size:0x8 @STRING@SetType__8CharEyesF6Symbol@0 = .data:0x80888A90; // type:object size:0x8 @STRING@SetType__8CharEyesF6Symbol = .data:0x80888A98; // type:object size:0x8 data:string -@LOCAL@SyncProperty__8CharEyesFR8DataNodeP9DataArrayi6PropOp@_s = .data:0x80888AA0; // type:object size:0xA0 +lbl_80888AA0 = .data:0x80888AA0; // type:object size:0xA0 __vt__12CharInterest = .data:0x80888B40; // type:object size:0xA8 __vt__39ObjPtr<18CharEyeDartRuleset,9ObjectDir> = .data:0x80888BE8; // type:object size:0x18 lbl_80888C00 = .data:0x80888C00; // type:object size:0x28 @@ -70110,7 +70110,7 @@ __vt__10CharMirror = .data:0x8088A500; // type:object size:0xC0 lbl_8088A5C0 = .data:0x8088A5C0; // type:object size:0xC lbl_8088A5CC = .data:0x8088A5CC; // type:object size:0x2C __RTTI__10CharMirror = .data:0x8088A5F8; // type:object size:0x8 -lbl_8088A600 = .data:0x8088A600; // type:object size:0x18 +__vt__34ObjPtr<13CharServoBone,9ObjectDir> = .data:0x8088A600; // type:object size:0x18 lbl_8088A618 = .data:0x8088A618; // type:object size:0x24 lbl_8088A63C = .data:0x8088A63C; // type:object size:0xC lbl_8088A648 = .data:0x8088A648; // type:object size:0x8 @@ -75786,8 +75786,8 @@ lbl_808E48E8 = .sbss:0x808E48E8; // type:object size:0x2 data:2byte lbl_808E48EA = .sbss:0x808E48EA; // type:object size:0x6 data:2byte gRev__12CharMeshHide = .sbss:0x808E48F0; // type:object size:0x2 data:2byte gAltRev__12CharMeshHide = .sbss:0x808E48F2; // type:object size:0x6 data:2byte -lbl_808E48F8 = .sbss:0x808E48F8; // type:object size:0x2 data:2byte -lbl_808E48FA = .sbss:0x808E48FA; // type:object size:0x6 data:2byte +gRev__10CharMirror = .sbss:0x808E48F8; // type:object size:0x2 data:2byte +gAltRev__10CharMirror = .sbss:0x808E48FA; // type:object size:0x6 data:2byte gRev__13CharNeckTwist = .sbss:0x808E4900; // type:object size:0x2 data:2byte gAltRev__13CharNeckTwist = .sbss:0x808E4902; // type:object size:0x6 data:2byte gRev__17CharPosConstraint = .sbss:0x808E4908; // type:object size:0x2 data:2byte @@ -75822,8 +75822,8 @@ lbl_808E4962 = .sbss:0x808E4962; // type:object size:0x1 data:byte lbl_808E4963 = .sbss:0x808E4963; // type:object size:0x5 data:byte lbl_808E4968 = .sbss:0x808E4968; // type:object size:0x1 data:byte lbl_808E4969 = .sbss:0x808E4969; // type:object size:0x7 data:byte -lbl_808E4970 = .sbss:0x808E4970; // type:object size:0x2 data:2byte -lbl_808E4972 = .sbss:0x808E4972; // type:object size:0x6 data:2byte +gRev__8Waypoint = .sbss:0x808E4970; // type:object size:0x2 data:2byte +gAltRev__8Waypoint = .sbss:0x808E4972; // type:object size:0x6 data:2byte gRev__16CharGuitarString = .sbss:0x808E4978; // type:object size:0x2 data:2byte gAltRev__16CharGuitarString = .sbss:0x808E497A; // type:object size:0x6 data:2byte lbl_808E4980 = .sbss:0x808E4980; // type:object size:0x1 data:byte @@ -80106,8 +80106,8 @@ SymStreakTrackerProgress1 = .bss:0x8097F6FC; // type:object size:0x4 stream = .bss:0x8097F700; // type:object size:0x8 stretch = .bss:0x8097F708; // type:object size:0x4 stretch_scale = .bss:0x8097F70C; // type:object size:0x4 -SymStrictAngDelta = .bss:0x8097F710; // type:object size:0x4 -SymStrictRadiusDelta = .bss:0x8097F714; // type:object size:0x4 +strict_ang_delta = .bss:0x8097F710; // type:object size:0x4 +strict_radius_delta = .bss:0x8097F714; // type:object size:0x4 SymString = .bss:0x8097F718; // type:object size:0x4 data:4byte SymString0 = .bss:0x8097F71C; // type:object size:0x4 SymString0Fret = .bss:0x8097F720; // type:object size:0x4 @@ -80751,7 +80751,7 @@ y = .bss:0x8098053C; // type:object size:0x4 y_fov = .bss:0x80980540; // type:object size:0x4 data:4byte SymYOffset = .bss:0x80980544; // type:object size:0x4 SymYPerSecond = .bss:0x80980548; // type:object size:0x4 -SymYRadius = .bss:0x8098054C; // type:object size:0xC +y_radius = .bss:0x8098054C; // type:object size:0xC yaw_high = .bss:0x80980558; // type:object size:0x8 yaw_low = .bss:0x80980560; // type:object size:0x4 SymYearFormat = .bss:0x80980564; // type:object size:0x4 data:4byte @@ -81127,7 +81127,7 @@ ambient_color = .bss:0x80980C98; // type:object size:0x4 ambient_fog_owner = .bss:0x80980C9C; // type:object size:0x4 SymAmbientOcclusion = .bss:0x80980CA0; // type:object size:0x4 SymAmount = .bss:0x80980CA4; // type:object size:0x10 -SymAngRadius = .bss:0x80980CB4; // type:object size:0x4 +ang_radius = .bss:0x80980CB4; // type:object size:0x4 angle = .bss:0x80980CB8; // type:object size:0x4 SymAngleOffset = .bss:0x80980CBC; // type:object size:0x4 anim = .bss:0x80980CC0; // type:object size:0x4 @@ -81714,7 +81714,7 @@ SymConnectedControllerSym = .bss:0x809817A8; // type:object size:0x4 SymConnectedControllerType = .bss:0x809817AC; // type:object size:0x4 SymConnectedTriggers = .bss:0x809817B0; // type:object size:0x4 data:4byte SymConnectionStatusChanged = .bss:0x809817B4; // type:object size:0x4 data:4byte -SymConnections = .bss:0x809817B8; // type:object size:0x10 +connections = .bss:0x809817B8; // type:object size:0x10 constrain_wrist = .bss:0x809817C8; // type:object size:0x4 SymConstraints = .bss:0x809817CC; // type:object size:0x4 SymContent = .bss:0x809817D0; // type:object size:0xC data:4byte @@ -83866,7 +83866,7 @@ minus = .bss:0x8098419C; // type:object size:0x4 SymMinvelo = .bss:0x809841A0; // type:object size:0x4 SymMipMapK = .bss:0x809841A4; // type:object size:0x8 SymMirrorCam = .bss:0x809841AC; // type:object size:0x4 -SymMirrorServo = .bss:0x809841B0; // type:object size:0x4 +mirror_servo = .bss:0x809841B0; // type:object size:0x4 SymMirrorX = .bss:0x809841B4; // type:object size:0x4 SymMiss = .bss:0x809841B8; // type:object size:0x4 data:4byte SymMissCount = .bss:0x809841BC; // type:object size:0x4 data:4byte @@ -84886,7 +84886,7 @@ lbl_80985674 = .bss:0x80985674; // type:object size:0x4 lbl_80985678 = .bss:0x80985678; // type:object size:0x8 lbl_80985680 = .bss:0x80985680; // type:object size:0x8 data:4byte lbl_80985688 = .bss:0x80985688; // type:object size:0x8 data:4byte -lbl_80985690 = .bss:0x80985690; // type:object size:0x4 +servo = .bss:0x80985690; // type:object size:0x4 lbl_80985694 = .bss:0x80985694; // type:object size:0x4 data:4byte lbl_80985698 = .bss:0x80985698; // type:object size:0x8 lbl_809856A0 = .bss:0x809856A0; // type:object size:0xC @@ -85287,7 +85287,7 @@ lbl_80987424 = .bss:0x80987424; // type:object size:0xB4 lbl_809874D8 = .bss:0x809874D8; // type:object size:0x4 data:4byte lbl_809874DC = .bss:0x809874DC; // type:object size:0xC lbl_809874E8 = .bss:0x809874E8; // type:object size:0x18 -lbl_80987500 = .bss:0x80987500; // type:object size:0x8 data:4byte +sWaypoints__8Waypoint = .bss:0x80987500; // type:object size:0x8 data:4byte lbl_80987508 = .bss:0x80987508; // type:object size:0x1A8 lbl_809876B0 = .bss:0x809876B0; // type:object size:0x30 data:4byte lbl_809876E0 = .bss:0x809876E0; // type:object size:0x8 data:4byte @@ -85448,7 +85448,7 @@ lbl_809890F8 = .bss:0x809890F8; // type:object size:0x8 data:4byte lbl_80989100 = .bss:0x80989100; // type:object size:0x8 data:4byte lbl_80989108 = .bss:0x80989108; // type:object size:0x18 lbl_80989120 = .bss:0x80989120; // type:object size:0x48 -lbl_80989168 = .bss:0x80989168; // type:object size:0x8 data:4byte +sCurrent__6RndCam = .bss:0x80989168; // type:object size:0x8 data:4byte lbl_80989170 = .bss:0x80989170; // type:object size:0x30 lbl_809891A0 = .bss:0x809891A0; // type:object size:0x4 data:4byte lbl_809891A4 = .bss:0x809891A4; // type:object size:0x4 data:4byte @@ -85642,7 +85642,7 @@ lbl_80992258 = .bss:0x80992258; // type:object size:0x4 data:4byte lbl_8099225C = .bss:0x8099225C; // type:object size:0x4 data:4byte lbl_80992260 = .bss:0x80992260; // type:object size:0x18 lbl_80992278 = .bss:0x80992278; // type:object size:0x2C8 -lbl_80992540 = .bss:0x80992540; // type:object size:0x10 data:4byte +TheRnd = .bss:0x80992540; // type:object size:0x10 data:4byte lbl_80992550 = .bss:0x80992550; // type:object size:0x20 lbl_80992570 = .bss:0x80992570; // type:object size:0x8 data:4byte lbl_80992578 = .bss:0x80992578; // type:object size:0xB0 data:4byte diff --git a/config/SZBE69_B8/objects.json b/config/SZBE69_B8/objects.json index fbb3fdbc..eb3c341c 100644 --- a/config/SZBE69_B8/objects.json +++ b/config/SZBE69_B8/objects.json @@ -190,7 +190,10 @@ "system/char/Char.cpp": "NonMatching", "system/char/Character.cpp": "NonMatching", "system/char/CharBlendBone.cpp": "NonMatching", - "system/char/CharBone.cpp": "NonMatching", + "system/char/CharBone.cpp": { + "status": "Equivalent", + "comment": "regswaps in standalone stlport functions" + }, "system/char/CharBoneDir.cpp": "NonMatching", "system/char/CharBoneOffset.cpp": "Matching", "system/char/CharBones.cpp": "NonMatching", @@ -210,8 +213,14 @@ "system/char/CharEyeDartRuleset.cpp": "Matching", "system/char/CharEyes.cpp": "NonMatching", "system/char/CharFaceServo.cpp": "NonMatching", - "system/char/CharForeTwist.cpp": "NonMatching", - "system/char/CharGuitarString.cpp": "NonMatching", + "system/char/CharForeTwist.cpp": { + "status": "Equivalent", + "comment": "Poll checks out in retail" + }, + "system/char/CharGuitarString.cpp": { + "status": "Equivalent", + "comment": "Poll checks out in retail" + }, "system/char/CharHair.cpp": "NonMatching", "system/char/CharIKFingers.cpp": "NonMatching", "system/char/CharIKFoot.cpp": "NonMatching", @@ -232,28 +241,36 @@ "system/char/CharMeshHide.cpp": "NonMatching", "system/char/CharMirror.cpp": "NonMatching", "system/char/CharNeckTwist.cpp": "NonMatching", - "system/char/CharPollGroup.cpp": "NonMatching", + "system/char/CharPollGroup.cpp": "Matching", "system/char/CharPosConstraint.cpp": "NonMatching", "system/char/CharServoBone.cpp": "NonMatching", "system/char/CharSleeve.cpp": "NonMatching", "system/char/CharTaskMgr.cpp": "Matching", "system/char/CharTransCopy.cpp": "Matching", "system/char/CharTransDraw.cpp": "Matching", - "system/char/CharUpperTwist.cpp": "NonMatching", - "system/char/CharUtl.cpp": "NonMatching", + "system/char/CharUpperTwist.cpp": { + "status": "Equivalent", + "comment": "Poll checks out in retail" + }, + "system/char/CharUtl.cpp": { + "status": "Equivalent", + "comment": "ClipPredict::Predict checks out in retail" + }, "system/char/CharWeightable.cpp": "Matching", "system/char/CharWeightSetter.cpp": "Matching", "system/char/CharacterTest.cpp": "NonMatching", "system/char/ClipCollide.cpp": "NonMatching", "system/char/ClipCompressor.cpp": "Matching", + "system/char/ClipGraphGen.cpp": "NonMatching", "system/char/Waypoint.cpp": "NonMatching", "system/math/strips/Adjacency.cpp": "Matching", "system/math/strips/CustomArray.cpp": "Matching", "system/math/strips/RevisitedRadix.cpp": "NonMatching", - "system/math/strips/Striper.cpp": {"status": "Equivalent", - "comment": "Regswap in ComputeBestStrip__7StriperFUi"}, - + "system/math/strips/Striper.cpp": { + "status": "Equivalent", + "comment": "Regswap in ComputeBestStrip__7StriperFUi" + }, "system/math/Color.cpp": "NonMatching", "system/math/Decibels.cpp": "Matching", "system/math/FileChecksum.cpp": "Matching", diff --git a/src/system/char/CharBone.h b/src/system/char/CharBone.h index b5a3d1e2..bbe498f6 100644 --- a/src/system/char/CharBone.h +++ b/src/system/char/CharBone.h @@ -34,6 +34,12 @@ class CharBone : public Hmx::Object { int ScaleContext() const { return mScaleContext; } CharBones::Type RotationType() const { return mRotation; } int RotationContext() const { return mRotationContext; } + CharBone* Target() const { return mTarget; } + void SetTarget(CharBone* b){ mTarget = b; } + void SetPositionContext(int c){ mPositionContext = c; } + void SetScaleContext(int c){ mScaleContext = c; } + void SetRotationContext(int c){ mRotationContext = c; } + void SetRotationType(CharBones::Type ty){ mRotation = ty; } DECLARE_REVS; NEW_OVERLOAD; diff --git a/src/system/char/CharBones.h b/src/system/char/CharBones.h index 49648524..888edb70 100644 --- a/src/system/char/CharBones.h +++ b/src/system/char/CharBones.h @@ -62,6 +62,8 @@ class CharBones { Zero(); SetWeights(0); } + int TotalSize() const { return mTotalSize; } + void ScaleDown(CharBones&, float) const; static Type TypeOf(Symbol); static const char* SuffixOf(Type); diff --git a/src/system/char/CharClip.h b/src/system/char/CharClip.h index 83722c2a..22469bd2 100644 --- a/src/system/char/CharClip.h +++ b/src/system/char/CharClip.h @@ -29,6 +29,7 @@ class CharClip : public Hmx::Object { ~Transitions(); void Clear(); void Resize(int, const CharClip::NodeVector*); + void RemoveNodes(CharClip*); int Size() const; NodeVector* mNodeStart; // 0x0 @@ -96,6 +97,7 @@ class CharClip : public Hmx::Object { void SetBeatAlignMode(int); void SetRelative(CharClip*); int AllocSize(); + void EvaluateChannel(void*, const void*, float); void LockAndDelete(CharClip**, int, int); float StartBeat() const { return mBeatTrack.front().value; } float EndBeat() const { return mBeatTrack.back().value; } diff --git a/src/system/char/CharCollide.cpp b/src/system/char/CharCollide.cpp index 35baeb93..08a190be 100644 --- a/src/system/char/CharCollide.cpp +++ b/src/system/char/CharCollide.cpp @@ -1,79 +1,146 @@ #include "char/CharCollide.h" +#include "rndobj/Utl.h" +#include "utl/Symbols.h" -CharCollide::CharCollide() : mShape(kSphere), mFlags(0), mMesh(this, 0) { +INIT_REVS(CharCollide) +CharCollide::CharCollide() : mShape(kSphere), mFlags(0), mMesh(this, 0), mMeshYBias(0) { + for(int i = 0; i < 2; i++){ + mOrigLength[i] = 0; + mOrigRadius[i] = 0; + } + CopyOriginalToCur(); + for(int i = 0; i < 8; i++){ + unk_structs[i].unk0 = 0; + unk_structs[i].vec.Zero(); + } + unk148.Reset(); } -// ObjPtr<>::ObjPtr((ObjPtr<> *)(this + 0x98),(Object *)pCVar1,(RndMesh *)0x0); -// pCVar1 = this + 0xb8; -// do { -// RSONotifyModuleLoaded(pCVar1); -// pCVar1 = pCVar1 + 0x10; -// } while (pCVar1 < this + 0x138); -// Transform::Transform(this + 0x148); -// this[0x188] = (CharCollide)0x0; -// iVar3 = 2; -// iVar2 = 0; -// do { -// *(undefined4 *)(this + iVar2 + 0x140) = 0; -// *(undefined4 *)(this + iVar2 + 0x138) = 0; -// iVar3 = iVar3 + -1; -// iVar2 = iVar2 + 4; -// } while (iVar3 != 0); -// fn_804C3484(this); // copy original to cur -// iVar2 = 0; -// iVar3 = 0; -// do { -// *(undefined4 *)(this + iVar3 + 0xb8) = 0; -// Vector3::Zero((Vector3 *)(this + iVar3 + 0xbc)); -// iVar2 = iVar2 + 1; -// iVar3 = iVar3 + 0x10; -// } while (iVar2 < 8); - -// Transform::Reset(this + 0x148); - -// *(undefined4 *)(this + 0xb8) = 0; -// *(float *)(this + 0xc4) = 0.0; -// *(float *)(this + 0xc0) = 0.0; -// *(float *)(this + 0xbc) = 0.0; - -// *(undefined4 *)(this + 0xc8) = 0; -// *(float *)(this + 0xd4) = 0.0; -// *(float *)(this + 0xd0) = 0.0; -// *(float *)(this + 0xcc) = 0.0; - -// *(undefined4 *)(this + 0xd8) = 0; -// *(float *)(this + 0xe4) = 0.0; -// *(float *)(this + 0xe0) = 0.0; -// *(float *)(this + 0xdc) = 0.0; - -// *(undefined4 *)(this + 0xe8) = 0; -// *(float *)(this + 0xf4) = 0.0; -// *(float *)(this + 0xf0) = 0.0; -// *(float *)(this + 0xec) = 0.0; - -// *(undefined4 *)(this + 0xf8) = 0; -// *(float *)(this + 0x104) = 0.0; -// *(float *)(this + 0x100) = 0.0; -// *(float *)(this + 0xfc) = 0.0; - -// *(undefined4 *)(this + 0x108) = 0; -// *(float *)(this + 0x114) = 0.0; -// *(float *)(this + 0x110) = 0.0; -// *(float *)(this + 0x10c) = 0.0; - -// *(undefined4 *)(this + 0x118) = 0; -// *(float *)(this + 0x124) = 0.0; -// *(float *)(this + 0x120) = 0.0; -// *(float *)(this + 0x11c) = 0.0; - -// *(undefined4 *)(this + 0x128) = 0; -// *(float *)(this + 0x134) = 0.0; -// *(float *)(this + 0x130) = 0.0; -// *(float *)(this + 0x12c) = 0.0; - CharCollide::~CharCollide(){ } -SAVE_OBJ(CharCollide, 0x58) \ No newline at end of file +void CharCollide::Highlight(){ + Hmx::Color black(1.0f, 1.0f, 1.0f); + Hmx::Color red(1.0f, 0.0f, 0.0f); + switch(mShape){ + case kPlane: + Plane p(WorldXfm().v, WorldXfm().m.x); + UtilDrawPlane(p, WorldXfm().v, red, 1, 12.0f); + break; + case kSphere: + case kInsideSphere: + UtilDrawSphere(WorldXfm().v, mOrigRadius[0], red); + UtilDrawSphere(WorldXfm().v, mCurRadius[0], black); + break; + case kCigar: + case kInsideCigar: + UtilDrawCigar(WorldXfm(), mOrigRadius, mOrigLength, red, 8); + UtilDrawCigar(WorldXfm(), mCurRadius, mCurLength, black, 8); + break; + default: break; + } + if(mMesh){ + int numspheres = NumSpheres(); + for(int i = 0; i < numspheres * 2; i++){ + UtilDrawSphere(mMesh->VertPos(unk_structs[i].unk0), 0.1f, Hmx::Color(0.0f, 0.0f, 1.0f)); + } + } +} + +SAVE_OBJ(CharCollide, 0x58) + +BEGIN_LOADS(CharCollide) + LOAD_REVS(bs) + ASSERT_REVS(7, 0) + LOAD_SUPERCLASS(Hmx::Object) + LOAD_SUPERCLASS(RndTransformable) + bs >> (int&)mShape; + bs >> mOrigRadius[0]; + if(gRev > 4) bs >> mOrigLength[0]; + if(gRev > 2) bs >> mOrigLength[1]; + if(gRev > 1) bs >> mFlags; + else mFlags = 0; + if(gRev > 3) bs >> mCurRadius[0]; + else mCurRadius[0] = mOrigRadius[0]; + + if(gRev > 5){ + bs >> mOrigRadius[1]; + bs >> mCurRadius[1]; + bs >> mCurLength[0]; + bs >> mCurLength[1]; + bs >> unk148; + bs >> mMesh; + for(int i = 0; i < 8; i++){ + bs >> unk_structs[i].unk0; + bs >> unk_structs[i].vec; + } + bs >> mDigest; + bs >> mMeshYBias; + if(gRev < 7) CopyOriginalToCur(); + } + else { + mOrigRadius[1] = mOrigRadius[0]; + CopyOriginalToCur(); + } +END_LOADS + +BEGIN_COPYS(CharCollide) + COPY_SUPERCLASS(Hmx::Object) + COPY_SUPERCLASS(RndTransformable) + CREATE_COPY(CharCollide) + BEGIN_COPYING_MEMBERS + COPY_MEMBER(mShape) + COPY_MEMBER(mFlags) + memcpy(mOrigRadius, c->mOrigRadius, 8); + memcpy(mOrigLength, c->mOrigLength, 8); + memcpy(mCurRadius, c->mCurRadius, 8); + memcpy(mCurLength, c->mCurLength, 8); + COPY_MEMBER(unk148) + COPY_MEMBER(mMeshYBias) + COPY_MEMBER(mMesh) + END_COPYING_MEMBERS +END_COPYS + +void CharCollide::Deform(){ + +} + +int CharCollide::NumSpheres(){ + if(mShape == kCigar || mShape == kInsideCigar) return 2; + else if (mShape == kSphere || mShape == kInsideSphere) return 1; + else return 0; +} + +void CharCollide::CopyOriginalToCur(){ + memcpy(mCurRadius, mOrigRadius, 8); + memcpy(mCurLength, mOrigLength, 8); +} + + +void CharCollide::SyncShape(){ + f32 t = mCurLength[1]; + if(mCurLength[0] > t){ + mCurLength[0] = mCurLength[1]; + } + CopyOriginalToCur(); +} + +BEGIN_HANDLERS(CharCollide) + HANDLE_SUPERCLASS(RndTransformable) + HANDLE_SUPERCLASS(Hmx::Object) + HANDLE_CHECK(0x221) +END_HANDLERS + +BEGIN_PROPSYNCS(CharCollide) + SYNC_PROP_MODIFY(shape, (int&)mShape, SyncShape()) + SYNC_PROP(flags, mFlags) + SYNC_PROP_MODIFY(radius0, mOrigRadius[0], SyncShape()) + SYNC_PROP_MODIFY(radius1, mOrigRadius[1], SyncShape()) + SYNC_PROP_MODIFY(length0, mOrigLength[0], SyncShape()) + SYNC_PROP_MODIFY(length1, mOrigLength[1], SyncShape()) + SYNC_PROP_MODIFY_ALT(mesh, mMesh, SyncShape()) + SYNC_PROP_MODIFY(mesh_y_bias, mMeshYBias, SyncShape()) + SYNC_SUPERCLASS(RndTransformable) +END_PROPSYNCS \ No newline at end of file diff --git a/src/system/char/CharCollide.h b/src/system/char/CharCollide.h index f7bcdf2f..0d519e72 100644 --- a/src/system/char/CharCollide.h +++ b/src/system/char/CharCollide.h @@ -2,6 +2,7 @@ #define CHAR_CHARCOLLIDE_H #include "rndobj/Trans.h" #include "rndobj/Mesh.h" +#include "math/SHA1.h" #include "obj/ObjPtr_p.h" class CharCollide : public RndTransformable { @@ -14,6 +15,12 @@ class CharCollide : public RndTransformable { kInsideCigar = 4, }; + struct CharCollideStruct { + CharCollideStruct(){} + int unk0; + Vector3 vec; + }; + CharCollide(); OBJ_CLASSNAME(CharCollide) OBJ_SET_TYPE(CharCollide) @@ -25,29 +32,48 @@ class CharCollide : public RndTransformable { virtual ~CharCollide(); virtual void Highlight(); - float GetRadius(const Vector3&, Vector3&) const; + void CopyOriginalToCur(); float Radius() const; Shape GetShape() const { return mShape; } const Vector3& Axis() const; + void SyncShape(); + int NumSpheres(); + void Deform(); + + float GetRadius(const Vector3& v1, Vector3& vout) const { + Subtract(v1, unk1a0, vout); + float ret = mCurRadius[0]; + if(mShape >= kCigar){ + float clamped = Clamp(mCurLength[0], mCurLength[1], unk190 * Dot(vout, unk194)); + ScaleAddEq(vout, unk194, -clamped); + Interp(ret, mCurRadius[1], unk18c * (clamped - mCurLength[0]), ret); + } + else if(mShape == kPlane){ + ret = Dot(vout, unk194); + Scale(unk194, ret, vout); + } + return ret; + } + + DECLARE_REVS; + NEW_OVERLOAD; + DELETE_OVERLOAD; Shape mShape; // 0x90 int mFlags; // 0x94 ObjPtr mMesh; // 0x98 - // float mRadius; - // float mMaxLength; - // float mMinLength; - // float mCurRadius; - - // float mRadius[2]; // 0x138 - // float mLength[2]; // 0x140 - // radius0 at 0x138 - // radius1 at 0x13c - // length0 at 0x140 - // length1 at 0x144 - - - // transform at 0x148 - // mesh y bias at 0x188 + CSHA1::Digest mDigest; // 0xa4 + CharCollideStruct unk_structs[8]; // 0xb8 - 0x134, inclusive + float mOrigRadius[2]; // 0x138 - radius0 at 0x138, radius1 at 0x13c + float mOrigLength[2]; // 0x140 - length0 at 0x140, length1 at 0x144 + Transform unk148; // 0x148 + float mCurRadius[2]; // 0x178 + float mCurLength[2]; // 0x180 + bool mMeshYBias; // 0x188 + float unk18c; + float unk190; + Vector3 unk194; + Vector3 unk1a0; }; #endif diff --git a/src/system/char/CharCuff.cpp b/src/system/char/CharCuff.cpp index a3488e5e..746e34ba 100644 --- a/src/system/char/CharCuff.cpp +++ b/src/system/char/CharCuff.cpp @@ -13,14 +13,23 @@ CharCuff::CharCuff() : mOpenEnd(0), mIgnore(this, kObjListNoNull), mBone(this, 0 mShape[2].offset = 2.0f; mShape[2].radius = 3.5f; - mOuterRadius = 2.6f + 0.5f; + mOuterRadius = mShape[1].radius + 0.5f; } CharCuff::~CharCuff(){ } +float CharCuff::Eccentricity(const Vector2& v) const { + float f1 = v.y * v.y; + float f2 = v.x * v.x; + return std::sqrt((f1 + f2) / (f1 * (1.0f / (mEccentricity * mEccentricity)) + f2)); +} + // fn_804C3D90 - highlight +void CharCuff::Highlight(){ + +} unsigned int BoneMask(std::list& tlist, RndMesh* mesh){ for(int i = 0; i < mesh->mBones.size(); i++){ diff --git a/src/system/char/CharDriver.h b/src/system/char/CharDriver.h index d90fc3e4..ac2a227e 100644 --- a/src/system/char/CharDriver.h +++ b/src/system/char/CharDriver.h @@ -51,6 +51,7 @@ class CharDriver : public RndHighlightable, public CharWeightable, public CharPo void SetClipType(Symbol); bool Starved(); void SetStarved(Symbol); + ObjectDir* ClipDir() const { return mClips; } NEW_OVERLOAD; DELETE_OVERLOAD; diff --git a/src/system/char/CharEyes.cpp b/src/system/char/CharEyes.cpp index b156f66e..fae6f57b 100644 --- a/src/system/char/CharEyes.cpp +++ b/src/system/char/CharEyes.cpp @@ -5,6 +5,7 @@ #include "char/CharInterest.h" #include "obj/DataUtl.h" #include "obj/Task.h" +#include "rndobj/Graph.h" #include "utl/Symbols.h" bool CharEyes::sDisableEyeDart; @@ -70,15 +71,52 @@ float CharEyes::CharInterestState::RefractoryTimeRemaining(){ } } -CharEyes::CharEyes() : mEyes(this), mInterests(this), mFaceServo(this, 0), mCamWeight(this, 0), mViewDirection(this, 0), mHeadLookAt(this, 0), - unkc8(this, 0), unkd4(this, 0) { - +CharEyes::CharEyes() : mEyes(this), mInterests(this), mFaceServo(this, 0), mCamWeight(this, 0), unk58(0,0,0), mDefaultFilterFlags(0), mViewDirection(this, 0), mHeadLookAt(this, 0), mMaxExtrapolation(19.5f), + mMinTargetDist(35.0f), mUpperLidTrackUp(1.0f), mUpperLidTrackDown(1.0f), mLowerLidTrackUp(0.75f), mLowerLidTrackDown(0.75f), mLowerLidTrackRotate(0), mInterestFilterFlags(0), + unka4(0,0,0), unkb4(0), unkc0(0), unkc4(0), unkc5(0), unkc8(this, 0), unkd4(this, 0), unke0(-1), unke4(0), unke8(0), unkec(1.0F), unkf0(0), unkf4(0), unk124(0), unk128(-1.0f), unk12c(-1), + unk13c(0), unk140(-1.0f), unk144(0), unk148(-1.0f), unk14c(-1.0f), unk15c(0), unk15d(1) { + unkb8 = std::cos(0.52359879f); + unk9c = RndOverlay::Find("eye_status", false); } CharEyes::~CharEyes(){ } +void CharEyes::Enter(){ + unka4.Zero(); + unkb4 = 0; + unkbc = 0; + unkb0 = 1.0f; + unkc0 = -1.0f; + unkc4 = 0; + unk124 = 0; + unk128 = -1.0f; + unk12c = -1; + unk13c = 0; + unk140 = -1.0f; + unk144 = 0; + unk148 = -1.0f; + unk14c = -1.0f; + unkc5 = 0; + mInterestFilterFlags = mDefaultFilterFlags; + unk15c = 0; + unke4 = 0; + unkf4 = 0; + RndTransformable* head = GetHead(); + if(head){ + unka4 = head->WorldXfm().m.y; + Normalize(unka4, unka4); + } + for(ObjVector::iterator it = mEyes.begin(); it != mEyes.end(); ++it){ + it->mEye->Enter(); + } + for(ObjVector::iterator it = mInterests.begin(); it != mInterests.end(); ++it){ + it->ResetState(); + } + RndPollable::Enter(); +} + void CharEyes::Exit(){ unkd4 = 0; unke0 = -1; @@ -89,8 +127,132 @@ void CharEyes::Exit(){ RndPollable::Exit(); } +void CharEyes::Highlight(){ +#ifdef VERSION_SZBE69_B8 + if(GetHead()){ + RndGraph* oneframe = RndGraph::GetOneFrame(); + RndTransformable* trans = 0; + for(ObjVector::iterator it = mEyes.begin(); it != mEyes.end(); ++it){ + trans = it->mEye->GetSource(); + if(trans){ + const Transform& tf1 = trans->WorldXfm(); + const Transform& tf2 = trans->WorldXfm(); + Vector3 v100( + tf1.m.y.x * 3.0f + tf2.v.x, + tf1.m.y.y * 3.0f + tf2.v.y, + tf1.m.y.z * 3.0f + tf2.v.z + ); + if(it->mEye->unkb1) + oneframe->AddLine(trans->WorldXfm().v, v100, Hmx::Color(1.0f, 0.0f, 0.0f), true); + else oneframe->AddLine(trans->WorldXfm().v, v100, Hmx::Color(0.0f, 1.0f, 0.0f), true); + } + } + Vector3 v10c(GetHead()->WorldXfm().v); + if(trans){ + float f1 = unkc8 ? unkc8->mMaxViewAngleCos : unkb8; + float f2 = unkb0; + if(unk124){ + oneframe->AddSphere(unk58, unkf8.mMaxRadius, Hmx::Color(0.9f, 0.9f, 0.9f)); + Vector3 v118(unk58.x + unk130.x, unk58.y + unk130.y, unk58.z + unk130.z); + EnforceMinimumTargetDistance(v10c, v118, v118); + oneframe->AddSphere(v118, 0.5f, Hmx::Color(0.0f, 0.0f, 1.0f)); + oneframe->AddLine(trans->WorldXfm().v, v118, f2 < f1 ? Hmx::Color(1.0f, 0.0f, 0.0f) : Hmx::Color(0.2f, 0.2f, 1.0f), true); + } + else { + oneframe->AddLine(trans->WorldXfm().v, unk58, f2 < f1 ? Hmx::Color(1.0f, 0.0f, 0.0f) : Hmx::Color(1.0f, 1.0f, 1.0f), true); + } + if(unk13c){ + oneframe->AddString3D("p blink!", trans->WorldXfm().v, Hmx::Color(1.0f, 1.0f, 1.0f)); + } + } + if(unkd4){ + if(unkd4 != unkc8){ + const char* nametouse = unkc8 ? unkc8->Name() : "GENERATED"; + oneframe->AddString3D(MakeString("focus = '%s' (looking at %s)", unkd4->Name(), nametouse), v10c, Hmx::Color(1.0f, 0.0f, 0.0f)); + } + else { + oneframe->AddString3D(MakeString("focus = '%s'", unkd4->Name()), v10c, Hmx::Color(0.0f, 1.0f, 0.0f)); + } + } + else { + if(unkc8){ + oneframe->AddString3D(MakeString("interest = '%s'", unkc8->Name()), v10c, Hmx::Color(0.0f, 1.0f, 0.0f)); + } + } + if(mInterests.size() != 0){ + // more happens here + } + } +#endif +} + +DECOMP_FORCEACTIVE(CharEyes, "%s", "r=%f") + +void CharEyes::UpdateOverlay(){ + if(unk9c && unk9c->Showing()){ + *unk9c << Dir()->Name() << ": "; + if(unkc8){ + if(unkd4){ + if(streq(unkc8->Name(), unkd4->Name())){ + *unk9c << "Look(FOC) "; + goto lol; + } + } + *unk9c << "Look(" << unkc8->Name() << ") "; + } + else *unk9c << "Look(GEN) "; + lol: + if(unkd4){ + Transform& headxfm = GetHead()->WorldXfm(); + Vector3 v34(headxfm.m.y); + Normalize(v34, v34); + const char* str = unkd4->IsWithinViewCone(headxfm.v, v34) ? "t" : "f"; + *unk9c << "Foc(" << unkd4->Name() << " p(" << unke0 << ") v(" << str << ")) "; + } + else *unk9c << "Foc(NA) "; + *unk9c << "t(" << unkb4 << ") "; + Vector3 v40(GetHead()->WorldXfm().v); + Vector3 v4c; + Vector3 v58(unk58); + RndTransformable* target = GetTarget(); + if(target) v58 = target->WorldXfm().v; + Subtract(v58, v40, v4c); + float len = Length(v4c); + *unk9c << "Dist(" << len << ") "; + if(unk13c) *unk9c << "P Blink! "; + if(unk124) *unk9c << "Dart! "; + if(unkc5) *unk9c << "Close! "; + *unk9c << "\n"; + } +} + +bool CharEyes::EitherEyeClamped(){ + for(ObjVector::iterator it = mEyes.begin(); it != mEyes.end(); ++it){ + if(it->mEye && it->mEye->unkb1) return true; + } + return false; +} + void CharEyes::ClearAllInterestObjects(){ mInterests.clear(); } +void CharEyes::AddInterestObject(CharInterest* interest){ + if(interest){ + CharInterestState state(this); + state.mInterest = interest; + mInterests.push_back(state); + } +} + +bool CharEyes::SetFocusInterest(CharInterest* interest, int i){ + if(unkd4 && unke0 > i) return false; + CharInterest* loc_interest = interest; + unkd4 = interest; + unke0 = i; + if(loc_interest != interest) unke4 = true; + if(!unkd4) unke0 = -1; + return true; +} + // fn_804CCF70 RndTransformable* CharEyes::GetHead(){ if(mViewDirection) return mViewDirection; @@ -218,8 +380,6 @@ BEGIN_COPYS(CharEyes) COPY_MEMBER(mInterests) COPY_MEMBER(mFaceServo) COPY_MEMBER(unka4) - COPY_MEMBER(unka8) - COPY_MEMBER(unkac) COPY_MEMBER(unkb4) COPY_MEMBER(mCamWeight) COPY_MEMBER(mDefaultFilterFlags) diff --git a/src/system/char/CharEyes.h b/src/system/char/CharEyes.h index bd913783..443cb3fa 100644 --- a/src/system/char/CharEyes.h +++ b/src/system/char/CharEyes.h @@ -68,6 +68,9 @@ class CharEyes : public RndHighlightable, public CharWeightable, public CharPoll bool SetFocusInterest(CharInterest*, int); void ToggleInterestsDebugOverlay(); CharInterest* GetCurrentInterest(); + void EnforceMinimumTargetDistance(const Vector3&, const Vector3&, Vector3&); + void UpdateOverlay(); + bool EitherEyeClamped(); DataNode OnToggleForceFocus(DataArray*); DataNode OnToggleInterestOverlay(DataArray*); @@ -87,7 +90,7 @@ class CharEyes : public RndHighlightable, public CharWeightable, public CharPoll ObjVector mInterests; // 0x34 ObjPtr mFaceServo; // 0x40 ObjPtr mCamWeight; // 0x4c - float unk58, unk5c, unk60; + Vector3 unk58; int mDefaultFilterFlags; // 0x64 - mask ObjPtr mViewDirection; // 0x68 ObjPtr mHeadLookAt; // 0x74 @@ -100,7 +103,8 @@ class CharEyes : public RndHighlightable, public CharWeightable, public CharPoll bool mLowerLidTrackRotate; // 0x98 RndOverlay* unk9c; int mInterestFilterFlags; // 0xa0 - also a mask - float unka4, unka8, unkac, unkb0, unkb4, unkb8, unkbc, unkc0; + Vector3 unka4; // 0xa4 + float unkb0, unkb4, unkb8, unkbc, unkc0; bool unkc4, unkc5; ObjPtr unkc8; // 0xc8 ObjPtr unkd4; // 0xd4 @@ -110,7 +114,8 @@ class CharEyes : public RndHighlightable, public CharWeightable, public CharPoll CharEyeDartRuleset::EyeDartRulesetData unkf8; bool unk124; float unk128; - int unk12c, unk130, unk134, unk138; + int unk12c; + Vector3 unk130; bool unk13c; float unk140; int unk144; diff --git a/src/system/char/CharForeTwist.cpp b/src/system/char/CharForeTwist.cpp index f8b5c2f4..ab8770b8 100644 --- a/src/system/char/CharForeTwist.cpp +++ b/src/system/char/CharForeTwist.cpp @@ -18,7 +18,7 @@ void CharForeTwist::Poll(){ float clamp2 = Clamp(-1.0f, 1.0f, Dot(parentxfm.m.x, v98)); float newbias = mBias * DEG2RAD; float tan2res = std::atan2(clamp2, clamped); - float angle = NormalizeAngle(newbias + mOffset * DEG2RAD + tan2res); + float angle = LimitAng(mOffset * DEG2RAD + tan2res + newbias); float finalfloat = angle - newbias; Hmx::Matrix3 m58; m58.RotateAboutX(finalfloat * 0.33333f); diff --git a/src/system/char/CharForeTwist.h b/src/system/char/CharForeTwist.h index 684a3fd9..07457aa3 100644 --- a/src/system/char/CharForeTwist.h +++ b/src/system/char/CharForeTwist.h @@ -12,7 +12,6 @@ class CharForeTwist : public CharPollable, public RndHighlightable { OBJ_SET_TYPE(CharForeTwist); virtual DataNode Handle(DataArray*, bool); virtual void Poll(); - virtual void Enter(); virtual ~CharForeTwist(){} virtual void PollDeps(std::list&, std::list&); virtual bool SyncProperty(DataNode&, DataArray*, int, PropOp); diff --git a/src/system/char/CharGuitarString.cpp b/src/system/char/CharGuitarString.cpp index a5193dd7..6f27868a 100644 --- a/src/system/char/CharGuitarString.cpp +++ b/src/system/char/CharGuitarString.cpp @@ -14,19 +14,20 @@ CharGuitarString::~CharGuitarString(){ } // fn_80507700 - poll +// checks out in retail: https://decomp.me/scratch/Bxu4k void CharGuitarString::Poll(){ if(!mNut || !mBridge || !mBend || !mTarget) return; Transform tf50(mBend->WorldXfm()); - const Vector3& vec = mNut->WorldXfm().v; - const Transform& tf3(mBridge->WorldXfm()); - const Transform& tf4(mTarget->WorldXfm()); - Vector3 v1, v2; - Subtract(tf4.v, vec, v1); // subtract is right standalone (see CharHair) - Subtract(tf3.v, vec, v2); - float clamped = Clamp(0.0f, 1.0f, Dot(v1,v2) / Dot(v2,v2)); // so is Clamp and Dot (see MathFuncs and CharIKHand) + const Vector3& nutvec = mNut->WorldXfm().v; + const Vector3& bridgevec = mBridge->WorldXfm().v; + Transform& tf4(mTarget->WorldXfm()); + Vector3 tmp; + Subtract(tf4.v, nutvec, tmp); + Vector3 tmp2; + Subtract(bridgevec, nutvec, tmp2); + float clamped = Clamp(0.0f, 1.0f, Dot(tmp,tmp2) / Dot(tmp2,tmp2)); if(mOpen) clamped = 0.0f; - Vector3 res; - Interp(vec, tf3.v, clamped, res); + Interp(nutvec, bridgevec, clamped, tf50.v); mBend->SetWorldXfm(tf50); } diff --git a/src/system/char/CharHair.cpp b/src/system/char/CharHair.cpp index 05295fce..9b86852b 100644 --- a/src/system/char/CharHair.cpp +++ b/src/system/char/CharHair.cpp @@ -2,6 +2,7 @@ #include "char/CharCollide.h" #include "rndobj/Trans.h" #include "rndobj/Wind.h" +#include "rndobj/PostProc.h" #include "char/Character.h" #include "math/MathFuncs.h" #include "math/Rot.h" @@ -77,6 +78,13 @@ void CharHair::SetCloth(bool b){ } } +void CharHair::Strand::SetAngle(float angle){ + mAngle = angle; + Hmx::Matrix3 m38; + m38.RotateAboutX(mAngle * DEG2RAD); + Multiply(m38, mBaseMat, mRootMat); +} + CharHair::CharHair() : mStiffness(0.04f), mTorsion(0.1f), mInertia(0.7f), mGravity(1.0f), mWeight(0.5f), mFriction(0.3f), mMinSlack(0.0f), mMaxSlack(0.0f), mStrands(this), mReset(1), mSimulate(1), mUsePostProc(1), mMe(this, 0), mWind(this, 0), mCollide(this, kObjListNoNull), unk6c(0) { @@ -96,6 +104,65 @@ void CharHair::Enter(){ Hookup(); } +void CharHair::FreezePoseRaw(){ + for(int i = 0; i < mStrands.size(); i++){ + Strand& strand = mStrands[i]; + if(strand.Root() && strand.Root()->TransParent()){ + ObjVector& pts = strand.mPoints; + Transform tf48(strand.Root()->TransParent()->WorldXfm()); + Invert(tf48, tf48); + for(int j = 0; j < pts.size(); j++){ + pts[j]; + Multiply(pts[j].pos, tf48, pts[j].unk5c); + } + } + } +} + +void CharHair::FreezePose(){ + bool tmpsim = mSimulate; + Hookup(); + SimulateLoops(200, 60.0f); + mSimulate = tmpsim; + FreezePoseRaw(); +} + +// https://decomp.me/scratch/zTOLT (retail scratch) +void CharHair::DoReset(int reset){ + for(int i = 0; i < mStrands.size(); i++){ + Strand& strand = mStrands[i]; + if(strand.Root() && strand.Root()->TransParent()){ + ObjVector& pts = strand.mPoints; + Transform tf70(strand.Root()->TransParent()->WorldXfm()); + Vector3 v80(strand.Root()->WorldXfm().v); + Vector3 v8c(strand.Root()->WorldXfm().m.x); + for(int j = 0; j < pts.size(); j++){ + Point& pt = pts[j]; + Multiply(pt.unk5c, tf70, pt.pos); + Vector3 v98; + Subtract(pt.pos, v80, v98); + v80 = pt.pos; + Cross(v8c, v98, pt.lastZ); + Normalize(pt.lastZ, pt.lastZ); + Cross(v98, pt.lastZ, v8c); + pt.force.Zero(); + pt.lastFriction.Zero(); + } + } + } + bool tmpsim = mSimulate; + float tmpinert = mInertia; + float tmpfric = mFriction; + mSimulate = true; + mInertia = 0; + mFriction = 0; + SimulateLoops(reset, GetFPS()); + mSimulate = tmpsim; + mFriction = tmpfric; + mInertia = tmpinert; + mReset = 0; +} + void CharHair::SetName(const char* cc, ObjectDir* dir){ Hmx::Object::SetName(cc, dir); mMe = dynamic_cast(dir); @@ -104,6 +171,69 @@ void CharHair::SetName(const char* cc, ObjectDir* dir){ mUsePostProc = pp; } +void CharHair::Poll(){ + if(mMe){ + if(mMe->GetPollState() == Character::kCharSyncObject) Hookup(); + if(mMe->Teleported()) mReset = 1; + if(mMe->MinLod() > 0){ + DoReset(0); + return; + } + } + if(mReset > 0) DoReset(mReset); + if(TheTaskMgr.DeltaSeconds() != 0.0f){ + SimulateLoops(1, GetFPS()); + } + else SimulateZeroTime(); +} + +float CharHair::GetFPS(){ + if(mUsePostProc && RndPostProc::Current() && RndPostProc::Current()->EmulateFPS() > 0){ + float ret = RndPostProc::Current()->EmulateFPS(); + if(ret != 60.0f) ret = 60.0f - ret; + return ret; + } + else return 60.0f; +} + +void CharHair::SimulateLoops(int count, float f){ + if(mSimulate && mStrands.size() != 0){ + for(ObjPtrList::iterator it = mCollide.begin(); it != mCollide.end(); ++it){ + // mystery inlined CharCollide method + } + for(int n = 0; n < count; n++){ + SimulateInternal(f); + } + } +} + +// void __thiscall CharHair::SimulateLoops(CharHair *this,int param_1,float param_2) + +// { +// int iVar1; +// undefined4 local_28; +// undefined4 local_24; +// Symbol aSStack_20 [12]; + +// if ((this[0x40] != (CharHair)0x0) && +// (iVar1 = stlpmtx_std::vector<><>::size((vector<><> *)(this + 0x30)), iVar1 != 0)) { +// local_24 = ObjPtrList<>::begin((ObjPtrList<> *)(this + 0x5c)); +// Symbol::Symbol(aSStack_20,(Symbol *)&local_24); +// while( true ) { +// local_28 = fn_803D0224(this + 0x5c); +// iVar1 = ObjPtrList<>::iterator::operator_!=((iterator *)aSStack_20,&local_28); +// if (iVar1 == 0) break; +// ObjPtrList<>::iterator::operator*((iterator *)aSStack_20); +// fn_804D64EC(); +// ObjPtrList<>::iterator::operator_++((iterator *)aSStack_20); +// } +// for (iVar1 = 0; iVar1 < param_1; iVar1 = iVar1 + 1) { +// fn_804D6590((double)param_2,this); +// } +// } +// return; +// } + #pragma push #pragma dont_inline on // fn_804D6590 diff --git a/src/system/char/CharHair.h b/src/system/char/CharHair.h index bb0856b8..be374a97 100644 --- a/src/system/char/CharHair.h +++ b/src/system/char/CharHair.h @@ -77,6 +77,11 @@ class CharHair : public RndHighlightable, public CharPollable { void Hookup(ObjPtrList&); void SetCloth(bool); void FreezePose(); + void FreezePoseRaw(); + void SimulateLoops(int, float); + void DoReset(int); + float GetFPS(); + void SimulateZeroTime(); DECLARE_REVS; diff --git a/src/system/char/CharIKFoot.cpp b/src/system/char/CharIKFoot.cpp index ddf71e36..a4506782 100644 --- a/src/system/char/CharIKFoot.cpp +++ b/src/system/char/CharIKFoot.cpp @@ -22,6 +22,61 @@ void CharIKFoot::SetName(const char* cc, ObjectDir* dir){ mMe = dynamic_cast(dir); } +// https://decomp.me/scratch/G9HMd retail scratch +void CharIKFoot::DoFSM(Transform& tf){ + if(mMe && mMe->Teleported()) unk94 = 0; + float deltasecs = TheTaskMgr.DeltaSeconds(); + if(deltasecs < 0.0f) deltasecs = 0.0f; + tf.m = mFinger->WorldXfm().m; + tf.v.z = mFinger->WorldXfm().v.z; + bool b2 = false; + unka8.z = tf.v.z; + float vecat = mData->mLocalXfm.v[mDataIndex]; + float f10; + if(vecat >= 1.0f) { + if(vecat > 0.0f){ + if(unk94 == 1) f10 = 0.6f; + else f10 = 0.5f; + } + if(f10 > tf.v.z) b2 = true; + } + else b2 = true; + if(unk94 == 0){ + tf.v = mFinger->WorldXfm().v; + if(b2){ + unka8 = tf.v; + unk94 = 1; + } + } + if(unk94 == 1){ + if(!b2){ + unk94 = 2; + unkb4 = Distance(mFinger->WorldXfm().v, tf.v); + } + else { + Vector3 v3c; + Subtract(mFinger->WorldXfm().v, unka8, v3c); + float len = Length(v3c); + if(len > 0.125f) v3c *= 0.125f / len; + Add(unka8, v3c, tf.v); + return; + } + } + if(unk94 == 2){ + Vector3 v48; + Subtract(mFinger->WorldXfm().v, tf.v, v48); + float len = Length(v48); + unkb4 = Min(-(deltasecs * 25.0f - unkb4), len); + if(unkb4 <= 0.0f) unk94 = 0; + else v48 *= (len - unkb4) / len; + tf.v += v48; + if(b2){ + unka8 = tf.v; + unk94 = 1; + } + } +} + void CharIKFoot::Poll(){ if(!mFinger || !mHand || !mData) return; mTargets.clear(); @@ -31,6 +86,8 @@ void CharIKFoot::Poll(){ mTargets.clear(); } +CharIKHand::IKTarget::IKTarget(ObjPtr o, float f) : mTarget(o), mExtent(f) {} + void CharIKFoot::PollDeps(std::list& l1, std::list& l2){ CharIKHand::PollDeps(l1, l2); } diff --git a/src/system/char/CharIKFoot.h b/src/system/char/CharIKFoot.h index 7d349ebd..9a9aa531 100644 --- a/src/system/char/CharIKFoot.h +++ b/src/system/char/CharIKFoot.h @@ -36,7 +36,7 @@ class CharIKFoot : public CharIKHand { int unk94; ObjPtr mData; // 0x98 int mDataIndex; // 0xa4 - int unk[3]; + Vector3 unka8; // 0xa8 float unkb4; // 0xb4 ObjPtr mMe; // 0xb8 }; diff --git a/src/system/char/CharIKHand.h b/src/system/char/CharIKHand.h index 89548df2..8ec43ae2 100644 --- a/src/system/char/CharIKHand.h +++ b/src/system/char/CharIKHand.h @@ -15,7 +15,7 @@ class CharIKHand : public RndHighlightable, public CharWeightable, public CharPo class IKTarget { public: IKTarget(Hmx::Object* o) : mTarget(o, 0), mExtent(0) {} - IKTarget(const ObjPtr& o, float f) : mTarget(o), mExtent(f) {} + IKTarget(ObjPtr o, float f) ; ObjPtr mTarget; // 0x0 float mExtent; // 0xc }; diff --git a/src/system/char/CharInterest.cpp b/src/system/char/CharInterest.cpp index 995d4512..11faa50f 100644 --- a/src/system/char/CharInterest.cpp +++ b/src/system/char/CharInterest.cpp @@ -1,5 +1,6 @@ #include "char/CharInterest.h" #include "math/MathFuncs.h" +#include "math/Rand.h" #include "obj/Data.h" #include "obj/ObjMacros.h" #include "obj/DataUtl.h" @@ -23,14 +24,18 @@ void CharInterest::SyncMaxViewAngle(){ mMaxViewAngleCos = cos_f(mMaxViewAngle * 0.017453292f); } +// https://decomp.me/scratch/ekyoO retail scratch void CharInterest::Highlight(){ RndGraph* oneframe = RndGraph::GetOneFrame(); oneframe->AddSphere(WorldXfm().v, 1.0f, Hmx::Color(1.0f, 0.0f, 0.0f)); Vector2 vec2; float wts = RndCam::sCurrent->WorldToScreen(WorldXfm().v, vec2); if(wts > 0.0f){ - // fix this part lol - oneframe->AddString(MakeString("%s", Name()), vec2, Hmx::Color()); + vec2.x = vec2.x * TheRnd->Width(); + vec2.y = vec2.y * TheRnd->Height(); + vec2.y += 15.0; + vec2.x -= 30.0; + oneframe->AddString(MakeString("%s", Name()), vec2, Hmx::Color(1.0f,1.0f,1.0f)); } if(mDartOverride){ DataNode* minrad = mDartOverride->Property("min_radius", false); @@ -93,10 +98,53 @@ END_COPYS CharEyeDartRuleset* CharInterest::GetDartRulesetOverride() const { return mDartOverride; } +bool CharInterest::IsWithinViewCone(const Vector3& v1, const Vector3& v2){ + Vector3 v1c; + v1c = WorldXfm().v; + Vector3 v28; + Subtract(v1c, v1, v28); + Normalize(v28, v28); + if(Dot(v2, v28) >= mMaxViewAngleCos) return true; + else return false; +} + bool CharInterest::IsMatchingFilterFlags(int mask){ - if(mCategoryFlags != (mCategoryFlags & mask)) return false; - if(mCategoryFlags == 0) return false; - return true; + return mCategoryFlags & mask && mCategoryFlags != 0; +} + +// retail scratch: https://decomp.me/scratch/JpD0G +float CharInterest::ComputeScore(const Vector3& v1, const Vector3& v2, const Vector3& v3, float f, int i, bool b){ + float neg99 = -0.99f; + bool b2 = false; + if(IsMatchingFilterFlags(i) || (b && mCategoryFlags == 0)){ + b2 = true; + } + if(!b2) return -1.0f; + Vector3 v7c(WorldXfm().v); + Vector3 v88; + Subtract(v7c, v2, v88); + float lensq = LengthSquared(v88); + Normalize(v88, v88); + + float dot = Dot(v1, v88); + float f1 = 0.0f; + if(dot >= mMaxViewAngleCos) f1 = 1.0f; + + float dot2 = Dot(v3, v88); + float f2 = 0.0f; + if(dot2 >= mMaxViewAngleCos) f2 = 1.0f; + + float f7 = -(lensq * f - 1.0f); + if(IsNaN(f7)){ + f7 = 0.2f; + } + + float f4 = f7 + f1 + f2 + neg99; + if(f4 >= 0.0f){ + f4 = f4 + RandomFloat(-0.25f, 0.25); + } + f4 *= mPriority; + return f4; } BEGIN_PROPSYNCS(CharInterest) diff --git a/src/system/char/CharInterest.h b/src/system/char/CharInterest.h index 14258d23..eaf1d31b 100644 --- a/src/system/char/CharInterest.h +++ b/src/system/char/CharInterest.h @@ -23,6 +23,8 @@ class CharInterest : public RndTransformable { void SyncMaxViewAngle(); CharEyeDartRuleset* GetDartRulesetOverride() const; bool IsMatchingFilterFlags(int); + bool IsWithinViewCone(const Vector3&, const Vector3&); + float ComputeScore(const Vector3&, const Vector3&, const Vector3&, float, int, bool); float mMaxViewAngle; // 0x90 float mPriority; // 0x94 diff --git a/src/system/char/CharMirror.cpp b/src/system/char/CharMirror.cpp index 929f10fb..21ceaaa4 100644 --- a/src/system/char/CharMirror.cpp +++ b/src/system/char/CharMirror.cpp @@ -7,6 +7,13 @@ CharMirror::CharMirror() : mServo(this, 0), mMirrorServo(this, 0), mBones(), mOp } +void CharMirror::Poll(){ + float weight = Weight(); + if(weight && mBones.TotalSize() != 0){ + mBones.ScaleDown(*mServo.Ptr(), 1.0f - weight); + } +} + void CharMirror::SetServo(CharServoBone* bone){ if(bone != mServo){ mServo = bone; diff --git a/src/system/char/CharMirror.h b/src/system/char/CharMirror.h index b78b91bb..c94e8bb4 100644 --- a/src/system/char/CharMirror.h +++ b/src/system/char/CharMirror.h @@ -35,10 +35,10 @@ class CharMirror : public CharWeightable, public CharPollable { DECLARE_REVS; DELETE_OVERLOAD; - ObjPtr mServo; - ObjPtr mMirrorServo; - CharBonesAlloc mBones; - std::vector mOps; + ObjPtr mServo; // 0x20 + ObjPtr mMirrorServo; // 0x2c + CharBonesAlloc mBones; // 0x38 + std::vector mOps; // 0xac }; #endif diff --git a/src/system/char/CharNeckTwist.cpp b/src/system/char/CharNeckTwist.cpp index b9daade0..d64cce67 100644 --- a/src/system/char/CharNeckTwist.cpp +++ b/src/system/char/CharNeckTwist.cpp @@ -1,4 +1,5 @@ #include "char/CharNeckTwist.h" +#include "math/Rot.h" #include "utl/Symbols.h" #include "obj/PropSync_p.h" @@ -9,8 +10,22 @@ CharNeckTwist::CharNeckTwist() : mTwist(this, 0), mHead(this, 0) { } void CharNeckTwist::Poll() { - if (mTwist || mHead) return; else { - + if(mHead && mTwist){ + if(mTwist->TransParent()){ + RndTransformable* parent = mTwist->TransParent(); + Transform tf58(mHead->mLocalXfm); + RndTransformable* trans; + for(trans = mHead->TransParent(); trans && trans != parent; trans = trans->TransParent()){ + Multiply(tf58, trans->mLocalXfm, tf58); + } + if(trans){ + Hmx::Quat q68; + Vector3 v78; + MakeRotQuatUnitX(tf58.m.x, q68); + Multiply(tf58.m.y, q68, v78); + mTwist->DirtyLocalXfm().m.RotateAboutX(LimitAng(std::atan2(v78.z, v78.y)) * 0.5f); + } + } } } diff --git a/src/system/char/CharNeckTwist.h b/src/system/char/CharNeckTwist.h index 061a1337..fabd74fb 100644 --- a/src/system/char/CharNeckTwist.h +++ b/src/system/char/CharNeckTwist.h @@ -21,8 +21,8 @@ class CharNeckTwist : public CharPollable { DELETE_OVERLOAD; DECLARE_REVS; - ObjPtr mTwist; - ObjPtr mHead; + ObjPtr mTwist; // 0x8 + ObjPtr mHead; // 0x14 }; #endif diff --git a/src/system/char/CharPollGroup.cpp b/src/system/char/CharPollGroup.cpp index 0bea5770..065697b7 100644 --- a/src/system/char/CharPollGroup.cpp +++ b/src/system/char/CharPollGroup.cpp @@ -87,7 +87,17 @@ END_COPYS // fn_804F59EC - sortpolls void CharPollGroup::SortPolls(){ - // requires another class, CharPollableSorter + CharPollableSorter sorter; + std::vector polls; + polls.reserve(mPolls.size()); + for(ObjPtrList::iterator it = mPolls.begin(); it != mPolls.end(); ++it){ + polls.push_back(*it); + } + sorter.Sort(polls); + mPolls.clear(); + for(int i = 0; i < polls.size(); i++){ + mPolls.push_back(dynamic_cast(polls[i])); + } } BEGIN_HANDLERS(CharPollGroup) diff --git a/src/system/char/CharServoBone.cpp b/src/system/char/CharServoBone.cpp index 4e115547..59cf82c2 100644 --- a/src/system/char/CharServoBone.cpp +++ b/src/system/char/CharServoBone.cpp @@ -2,6 +2,8 @@ #include "char/Character.h" #include "char/CharBoneDir.h" #include "char/Waypoint.h" +#include "char/CharUtl.h" +#include "math/Rot.h" #include "utl/Symbols.h" DECOMP_FORCEACTIVE(CharServoBone, ".cb", "bone_facing_delta.pos", "bone_facing.pos", "bone_pelvis") @@ -31,6 +33,19 @@ void CharServoBone::SetClipType(Symbol sym){ } } +void CharServoBone::ReallocateInternal(){ + CharBonesMeshes::ReallocateInternal(); + mFacingRotDelta = 0; + mFacingPosDelta = (Vector3*)FindPtr("bone_facing_delta.pos"); + if(mFacingPosDelta){ + mFacingPos = (Vector3*)FindPtr("bone_facing.pos"); + mPelvis = CharUtlFindBoneTrans("bone_pelvis", Dir()); + MILO_ASSERT(mFacingPos && mPelvis, 0xB3); + mFacingRot = (float*)FindPtr("bone_facing.rotz"); + mFacingRotDelta = (float*)FindPtr("bone_facing_delta.rotz"); + } +} + void CharServoBone::Enter(){ ZeroDeltas(); mRegulate = 0; @@ -50,6 +65,25 @@ void CharServoBone::SetMoveSelf(bool b){ mDeltaChanged = true; } +void CharServoBone::MoveToFacing(Transform& tf){ + if(*mFacingRot){ + RotateAboutZ(tf.m, *mFacingRot, tf.m); + RotateAboutZ(tf.v, *mFacingRot, tf.v); + Normalize(tf.m, tf.m); + } + tf.v += *mFacingPos; +} + +void CharServoBone::MoveToDeltaFacing(Transform& tf){ + Vector3 v18; + Multiply(*mFacingPosDelta, tf.m, v18); + tf.v += v18; + if(*mFacingRotDelta){ + RotateAboutZ(tf.m, *mFacingRotDelta, tf.m); + Normalize(tf.m, tf.m); + } +} + SAVE_OBJ(CharServoBone, 0x14A) BEGIN_LOADS(CharServoBone) diff --git a/src/system/char/CharServoBone.h b/src/system/char/CharServoBone.h index 5882910a..84843561 100644 --- a/src/system/char/CharServoBone.h +++ b/src/system/char/CharServoBone.h @@ -32,11 +32,13 @@ class CharServoBone : public RndHighlightable, public CharPollable, public CharB void SetClipType(Symbol); void SetMoveSelf(bool); void ZeroDeltas(); + void MoveToFacing(Transform&); + void MoveToDeltaFacing(Transform&); DECLARE_REVS; DELETE_OVERLOAD; - RndEnviron* mPelvis; // 0x74 + RndTransformable* mPelvis; // 0x74 float* mFacingRotDelta; // 0x78 Vector3* mFacingPosDelta; // 0x7c float* mFacingRot; // 0x80 diff --git a/src/system/char/CharSleeve.cpp b/src/system/char/CharSleeve.cpp index 9c6c237b..c5367cd8 100644 --- a/src/system/char/CharSleeve.cpp +++ b/src/system/char/CharSleeve.cpp @@ -1,4 +1,6 @@ #include "char/CharSleeve.h" +#include "rndobj/Utl.h" +#include "rndobj/Rnd.h" #include "utl/Symbols.h" INIT_REVS(CharSleeve); @@ -17,6 +19,75 @@ void CharSleeve::SetName(const char* cc, class ObjectDir* dir){ mMe = dynamic_cast(dir); } +// https://decomp.me/scratch/vVQkq (retail) +void CharSleeve::Poll(){ + if(mSleeve && mSleeve->TransParent()){ + float deltasecs = TheTaskMgr.DeltaSeconds(); + float dvar12 = deltasecs * 60.0f; + float powed = std::pow(1.0f - mStiffness, dvar12 * dvar12); + RndTransformable* sleeveparent = mSleeve->TransParent(); + float absed = std::fabs(mSleeve->mLocalXfm.v.z); + bool b2 = false; + if(mMe && mMe->Teleported()){ + mPos = mSleeve->WorldXfm().v; + Vector3 v9c(0.0f, 0.0f, -(absed + mPosLength)); + float dotted = Dot(v9c, sleeveparent->WorldXfm().m.x); + ClampEq(dotted, -mRange, mRange); + ScaleAddEq(v9c, sleeveparent->WorldXfm().m.x, dotted); + mPos += v9c; + Vector3 va8; + ScaleAdd(sleeveparent->WorldXfm().v, sleeveparent->WorldXfm().m.x, dotted, va8); + Subtract(mPos, va8, v9c); + ScaleToMagnitude(v9c, absed + mPosLength, v9c); + Add(va8, v9c, mPos); + mLastPos = mPos; + b2 = true; + mLastDT = 0; + } + Vector3 vb4(mPos); + if(mLastDT > 0.0f && deltasecs > 0.0f){ + Vector3 vc0; + Subtract(mPos, mLastPos, vc0); + ScaleAddEq(vb4, vc0, (mInertia * deltasecs) / mLastDT); + } + vb4.z += mGravity * deltasecs * dvar12 * -3.858268f; + Vector3 vcc; + Subtract(vb4, sleeveparent->WorldXfm().v, vcc); + float dotted2 = Dot(vcc, sleeveparent->WorldXfm().m.x); + float d4 = dvar12 * (1.0f - (1.0f - powed)); + ClampEq(d4, -mRange, mRange); + ScaleAddEq(vcc, sleeveparent->WorldXfm().m.x, (d4 - dvar12)); + float len = Length(vcc); + float interped = Interp(len, absed, 1.0f - powed); + ClampEq(interped, absed - mNegLength, absed + mPosLength); + ScaleToMagnitude(vcc, len, vcc); + Add(sleeveparent->WorldXfm().v, vcc, vb4); + Transform tf90; + tf90.v = vb4; + Scale(vcc, -1.0f, tf90.m.z); + Cross(tf90.m.z, sleeveparent->WorldXfm().m.x, tf90.m.y); + Normalize(tf90.m.z, tf90.m.z); + Normalize(tf90.m.y, tf90.m.y); + Cross(tf90.m.y, tf90.m.z, tf90.m.x); + mSleeve->SetWorldXfm(tf90); + mLastPos = mPos; + mLastDT = deltasecs; + mPos = vb4; + if(b2) mLastPos = mPos; + if(mTopSleeve){ + float dotcc = Dot(vcc, sleeveparent->WorldXfm().m.x); + ScaleAddEq(vcc, sleeveparent->WorldXfm().m.x, -dotcc); + Add(sleeveparent->WorldXfm().v, vcc, tf90.v); + Scale(vcc, -1.0f, tf90.m.z); + Cross(tf90.m.z, sleeveparent->WorldXfm().m.x, tf90.m.y); + Normalize(tf90.m.z, tf90.m.z); + Normalize(tf90.m.y, tf90.m.y); + Cross(tf90.m.y, tf90.m.z, tf90.m.x); + mTopSleeve->SetWorldXfm(tf90); + } + } +} + void CharSleeve::PollDeps(std::list& changedBy, std::list& change){ if(mSleeve){ changedBy.push_back(mSleeve->mParent); @@ -25,6 +96,16 @@ void CharSleeve::PollDeps(std::list& changedBy, std::listTransParent()) return; + UtilDrawAxes(mSleeve->WorldXfm(), 1.0f, Hmx::Color(0.0f, 1.0f, 0.0f)); + TheRnd->DrawLine(mSleeve->WorldXfm().v, mSleeve->TransParent()->WorldXfm().v, Hmx::Color(0.0f, 1.0f, 0.0f), false); + if(mTopSleeve){ + UtilDrawAxes(mTopSleeve->WorldXfm(), 1.0f, Hmx::Color(0.0f, 1.0f, 1.0f)); + TheRnd->DrawLine(mTopSleeve->WorldXfm().v, mTopSleeve->TransParent()->WorldXfm().v, Hmx::Color(0.0f, 1.0f, 1.0f), false); + } +} + SAVE_OBJ(CharSleeve, 0xE1) void CharSleeve::Load(BinStream& bs){ diff --git a/src/system/char/CharSleeve.h b/src/system/char/CharSleeve.h index b5b53818..292d5d1a 100644 --- a/src/system/char/CharSleeve.h +++ b/src/system/char/CharSleeve.h @@ -25,18 +25,18 @@ class CharSleeve : public RndHighlightable, public CharPollable { DECLARE_REVS; DELETE_OVERLOAD; - ObjPtr mSleeve; - ObjPtr mTopSleeve; - Vector3 mPos; - Vector3 mLastPos; - float mLastDT; - float mInertia; - float mGravity; - float mRange; - float mNegLength; - float mPosLength; - float mStiffness; - ObjPtr mMe; + ObjPtr mSleeve; // 0x10 + ObjPtr mTopSleeve; // 0x1c + Vector3 mPos; // 0x28 + Vector3 mLastPos; // 0x34 + float mLastDT; // 0x40 + float mInertia; // 0x44 + float mGravity; // 0x48 + float mRange; // 0x4c + float mNegLength; // 0x50 + float mPosLength; // 0x54 + float mStiffness; // 0x58 + ObjPtr mMe; // 0x5c }; #endif diff --git a/src/system/char/CharUpperTwist.cpp b/src/system/char/CharUpperTwist.cpp index 7be5e00e..46d9bb16 100644 --- a/src/system/char/CharUpperTwist.cpp +++ b/src/system/char/CharUpperTwist.cpp @@ -1,4 +1,5 @@ #include "char/CharUpperTwist.h" +#include "math/Rot.h" #include "utl/Symbols.h" INIT_REVS(CharUpperTwist) @@ -12,6 +13,25 @@ CharUpperTwist::~CharUpperTwist(){ } // fn_804FAB0C - poll +void CharUpperTwist::Poll(){ + if(!mTwist2 || !mTwist1 || !mUpperArm) return; + Transform& twist2parentworld = mTwist2->TransParent()->WorldXfm(); + Transform& twist2world = mTwist2->WorldXfm(); + Hmx::Quat q; + MakeRotQuat(twist2parentworld.m.x, twist2world.m.x, q); + Vector3 v68; + Multiply(twist2parentworld.m.y, q, v68); + Transform tf48; + tf48.m.x = twist2world.m.x; + tf48.v = mUpperArm->WorldXfm().v; + Interp(v68, twist2world.m.y, 0.333f, tf48.m.y); + LookAt(tf48.m); + mUpperArm->SetWorldXfm(tf48); + tf48.v = mTwist1->WorldXfm().v; + Interp(v68, twist2world.m.y, 0.666f, tf48.m.y); + LookAt(tf48.m); + mTwist1->SetWorldXfm(tf48); +} void CharUpperTwist::PollDeps(std::list& changedBy, std::list& change){ changedBy.push_back(mTwist2); diff --git a/src/system/char/CharUpperTwist.h b/src/system/char/CharUpperTwist.h index c0dee202..a54a01a6 100644 --- a/src/system/char/CharUpperTwist.h +++ b/src/system/char/CharUpperTwist.h @@ -21,9 +21,9 @@ class CharUpperTwist : public CharPollable { DECLARE_REVS; DELETE_OVERLOAD; - ObjPtr mUpperArm; - ObjPtr mTwist1; - ObjPtr mTwist2; + ObjPtr mUpperArm; // 0x8 + ObjPtr mTwist1; // 0x14 + ObjPtr mTwist2; // 0x20 }; #endif diff --git a/src/system/char/CharUtl.cpp b/src/system/char/CharUtl.cpp index 44970e6c..8658042f 100644 --- a/src/system/char/CharUtl.cpp +++ b/src/system/char/CharUtl.cpp @@ -28,7 +28,7 @@ static DataNode OnCharMergeBones(DataArray* da){ bool CharUtlIsAnimatable(RndTransformable* trans){ RndMesh* mesh = dynamic_cast(trans); - if(mesh && !mesh->mBones.empty()) return false; + if(mesh && mesh->NumBones() != 0) return false; if(dynamic_cast(trans)) return false; if(dynamic_cast(trans)) return false; if(dynamic_cast(trans)) return false; @@ -67,39 +67,39 @@ CharBone* GrabBone(CharBone* bone, ObjectDir* dir){ // fn_804FB9C4 void CharUtlMergeBones(ObjectDir* dir1, ObjectDir* dir2, int i){ for(ObjDirItr it(dir1, true); it != 0; ++it){ - if(it->mTarget){ + if(it->Target()){ CharBone* bone = GrabBone(it, dir2); if(bone){ - if(!bone->mTarget){ - const char* name = it->mTarget->Name(); + if(!bone->Target()){ + const char* name = it->Target()->Name(); CharBone* findbone = CharUtlFindBone(name, dir2); if(!findbone) MILO_WARN("could not find target %s in dest, must merge", name); - bone->mTarget = findbone; + bone->SetTarget(findbone); } else { - const char* name = bone->mTarget->Name(); - bool strsmatch = strcmp(it->mTarget->Name(), name) == 0; - if(!strsmatch){ - MILO_WARN("%s has different targets %s v %s, must resolve", it->Name(), it->mTarget->Name(), name); + if(!streq(it->Target()->Name(), bone->Target()->Name())){ + MILO_WARN("%s has different targets %s v %s, must resolve", it->Name(), it->Target()->Name(), bone->Target()->Name()); } } } - if(it->mPositionContext != 0){ - CharBone* bone = GrabBone(it, dir2); - if(bone) it->mPositionContext |= i; - } - if(it->mScaleContext != 0){ - CharBone* bone = GrabBone(it, dir2); - if(bone) it->mScaleContext |= i; - } - if(it->mRotationContext != 0){ - CharBone* bone = GrabBone(it, dir2); - if(bone->mRotation != CharBones::TYPE_END && bone->mRotation != it->mRotation){ + } + if(it->PositionContext() != 0){ + CharBone* bone = GrabBone(it, dir2); + if(bone) bone->SetPositionContext(bone->PositionContext() | i); + } + if(it->ScaleContext() != 0){ + CharBone* bone = GrabBone(it, dir2); + if(bone) bone->SetPositionContext(bone->ScaleContext() | i); + } + if(it->RotationContext() != 0 && it->RotationType() != CharBones::TYPE_END){ + CharBone* bone = GrabBone(it, dir2); + if(bone){ + if(bone->RotationType() != CharBones::TYPE_END && bone->RotationType() != it->RotationType()){ MILO_WARN("bones %s have different rotations, must hand resolve", it->Name()); } else { - bone->mRotation = it->mRotation; - bone->mRotationContext |= i; + bone->SetRotationType(it->RotationType()); + bone->SetRotationContext(bone->RotationContext() | i); } } } @@ -130,6 +130,21 @@ void ClipPredict::SetClip(CharClip* clip){ } } +void ClipPredict::Predict(float f1, float f2){ + Vector3 v34; + float locf; + mClip->EvaluateChannel(&v34, mPosChannel, f1); + mClip->EvaluateChannel(&mLastPos, mPosChannel, f2); + mClip->EvaluateChannel(&locf, mAngChannel, f1); + mClip->EvaluateChannel(&mLastAng, mAngChannel, f2); + float norm = LimitAng(mAng - locf); + Subtract(mLastPos, v34, v34); + RotateAboutZ(v34, norm, v34); + mPos += v34; + float norm1 = LimitAng(mLastAng - locf); + mAng = LimitAng(mAng + norm1); +} + DECOMP_FORCEACTIVE(CharUtl, "tmp_bones") CharBone* CharUtlFindBone(const char* cc, ObjectDir* dir){ diff --git a/src/system/char/CharUtl.h b/src/system/char/CharUtl.h index f06b6bba..c3f2ab94 100644 --- a/src/system/char/CharUtl.h +++ b/src/system/char/CharUtl.h @@ -29,6 +29,7 @@ class ClipPredict { public: ClipPredict(CharClip*, const Vector3&, float); void SetClip(CharClip*); + void Predict(float, float); CharClip* mClip; // 0x0 void* mAngChannel; // 0x4 diff --git a/src/system/char/Character.cpp b/src/system/char/Character.cpp index 85c54808..aa8dd717 100644 --- a/src/system/char/Character.cpp +++ b/src/system/char/Character.cpp @@ -90,7 +90,7 @@ void Character::Terminate(){} Character::Character() : mLods(this), mLastLod(0), mMinLod(0), mShadow(this, 0), mTransGroup(this, 0), mDriver(0), mSelfShadow(0), mSpotCutout(0), mFloorShadow(1), mSphereBase(this, this), mBounding(), mPollState(kCharCreated), mTest(new CharacterTest(this)), - mFrozen(0), mDrawMode(kCharDrawAll), unk1f4(1), mInterestToForce(), unk1fc(this, 0), mDebugDrawInterestObjects(0) { + mFrozen(0), mDrawMode(kCharDrawAll), mTeleported(1), mInterestToForce(), unk1fc(this, 0), mDebugDrawInterestObjects(0) { } @@ -104,7 +104,7 @@ void Character::Enter(){ mMinLod = -1; mFrozen = false; mLastLod = 0; - unk1f4 = true; + mTeleported = true; mInterestToForce = Symbol(); RndDir::Enter(); } @@ -121,7 +121,7 @@ void Character::Poll(){ if(TheLoadMgr.EditMode()) mTest->Poll(); #endif RndDir::Poll(); - unk1f4 = false; + mTeleported = false; mPollState = kCharPolled; } } diff --git a/src/system/char/Character.h b/src/system/char/Character.h index b32a76a7..35fe9b1b 100644 --- a/src/system/char/Character.h +++ b/src/system/char/Character.h @@ -103,6 +103,10 @@ class Character : public RndDir { void SetInterestObjects(const ObjPtrList&, ObjectDir*); void ForceBlink(); void SetDrawMode(DrawMode m){ mDrawMode = m; } + bool Teleported() const { return mTeleported; } + PollState GetPollState() const { return mPollState; } + int MinLod() const { return mMinLod; } + int LastLod() const { return mLastLod; } DataNode OnPlayClip(DataArray*); DataNode OnCopyBoundingSphere(DataArray*); @@ -133,7 +137,7 @@ class Character : public RndDir { CharacterTest* mTest; // 0x1e8 bool mFrozen; // 0x1ec DrawMode mDrawMode; // 0x1f0 - bool unk1f4; // 0x1f4 + bool mTeleported; // 0x1f4 Symbol mInterestToForce; // 0x1f8 ObjPtr unk1fc; // 0x1fc int unk208; // 0x208 diff --git a/src/system/char/CharacterTest.cpp b/src/system/char/CharacterTest.cpp index 6cd33f92..59a82f00 100644 --- a/src/system/char/CharacterTest.cpp +++ b/src/system/char/CharacterTest.cpp @@ -2,10 +2,20 @@ #include "char/Character.h" #include "char/CharDriver.h" #include "char/CharClip.h" +#include "char/CharClipDriver.h" #include "char/CharClipGroup.h" +#include "char/CharForeTwist.h" +#include "char/CharServoBone.h" +#include "char/CharUpperTwist.h" +#include "char/CharUtl.h" #include "char/Waypoint.h" +#include "rndobj/Cam.h" +#include "rndobj/Utl.h" +#include "obj/DirLoader.h" #include "utl/Symbols.h" +#include "utl/Messages.h" +Hmx::Object* gClick; INIT_REVS(CharacterTest) CharacterTest::CharacterTest(class Character* thechar) : mMe(thechar), mDriver(thechar, 0), mClip1(thechar, 0), mClip2(thechar, 0), mFilterGroup(thechar, 0), @@ -26,6 +36,146 @@ CharacterTest::~CharacterTest(){ } } +void CharacterTest::Draw(){ + if(mDriver && (mClip1 || mClip2)) mDriver->Highlight(); + RndTransformable* trans = CharUtlFindBoneTrans("bone_head", mMe); + if(!trans) trans = mMe; + if(mShowScreenSize){ + UtilDrawString(MakeString("lod %d %.3f", mMe->LastLod(), mMe->ComputeScreenSize(RndCam::sCurrent)), trans->WorldXfm().v, Hmx::Color(1.0f, 1.0f, 1.0f)); + } +} + +void CharacterTest::Poll(){ + ObjectDir* clipdir = mDriver ? mDriver->ClipDir() : 0; + if(clipdir && mClip1){ + Hmx::Object* tmp = gClick; + if(!gClick){ + ObjectDir* clickdir = DirLoader::LoadObjects(FilePath(MakeString("%s/char/chartest.milo", FileSystemRoot())), 0, 0); + gClick = clickdir->Find("click_hi.cue", true); + } + gClick = tmp; + float beat = TheTaskMgr.Beat(); + float deltabeat = TheTaskMgr.DeltaBeat(); + if(mMetronome){ + if(std::floor(beat - deltabeat) + 1.0f == std::floor(beat)){ + gClick->Handle(play_msg, true); + } + } + CharClipDriver* drivs = mDriver->mFirst; + if(!drivs) PlayNew(); + else if(mClip2){ + CharClip* drivclip = drivs->mClip; + if(drivclip != mClip1 && drivclip != mClip2 || (drivclip == mClip2 && unk64 < drivs->mBeat)) PlayNew(); + } + else if(drivs->mClip != mClip1) PlayNew(); + if(mZeroTravel){ + // some Transform operation + if(mMe->BoneServo()){ + mMe->BoneServo()->mRegulate = 0; + } + Recenter(); + } + } +} + +void CharacterTest::AddDefaults(){ + if(!mMe->mDriver) mMe->New("main.drv"); + if(!mMe->BoneServo()){ + if(!mMe->Find("bone.servo", false)){ + mMe->New("bone.servo"); + } + mMe->mDriver->SetBones(mMe->Find("bone.servo", true)); + } + if(!mMe->Find("foreTwist_L.ik", false)){ + RndTransformable* lhand = CharUtlFindBoneTrans("bone_L-hand", mMe); + if(lhand){ + RndTransformable* ltwist2 = CharUtlFindBoneTrans("bone_L-foreTwist2", mMe); + if(ltwist2){ + CharForeTwist* ltwist = mMe->New("foreTwist_L.ik"); + ltwist->SetProperty(hand, DataNode(lhand)); + ltwist->SetProperty(twist2, DataNode(ltwist2)); + ltwist->SetProperty(offset, DataNode(90)); + } + } + } + if(!mMe->Find("foreTwist_R.ik", false)){ + RndTransformable* rhand = CharUtlFindBoneTrans("bone_R-hand", mMe); + if(rhand){ + RndTransformable* rtwist2 = CharUtlFindBoneTrans("bone_R-foreTwist2", mMe); + if(rtwist2){ + CharForeTwist* rtwist = mMe->New("foreTwist_R.ik"); + rtwist->SetProperty(hand, DataNode(rhand)); + rtwist->SetProperty(twist2, DataNode(rtwist2)); + rtwist->SetProperty(offset, DataNode(-90)); + } + } + } + if(!mMe->Find("upperTwist_L.ik", false)){ + RndTransformable* lutwist1 = CharUtlFindBoneTrans("bone_L-upperTwist1", mMe); + if(lutwist1){ + RndTransformable* lutwist2 = CharUtlFindBoneTrans("bone_L-upperTwist2", mMe); + if(lutwist2){ + RndTransformable* luarm = CharUtlFindBoneTrans("bone_L-upperArm", mMe); + if(luarm){ + CharUpperTwist* ltwist = mMe->New("upperTwist_L.ik"); + ltwist->SetProperty(twist1, DataNode(lutwist1)); + ltwist->SetProperty(twist2, DataNode(lutwist2)); + ltwist->SetProperty(upper_arm, DataNode(luarm)); + } + } + } + } + if(!mMe->Find("upperTwist_R.ik", false)){ + RndTransformable* rutwist1 = CharUtlFindBoneTrans("bone_R-upperTwist1", mMe); + if(rutwist1){ + RndTransformable* rutwist2 = CharUtlFindBoneTrans("bone_R-upperTwist2", mMe); + if(rutwist2){ + RndTransformable* ruarm = CharUtlFindBoneTrans("bone_R-upperArm", mMe); + if(ruarm){ + CharUpperTwist* rtwist = mMe->New("upperTwist_R.ik"); + rtwist->SetProperty(twist1, DataNode(rutwist1)); + rtwist->SetProperty(twist2, DataNode(rutwist2)); + rtwist->SetProperty(upper_arm, DataNode(ruarm)); + } + } + } + } +} + +void CharacterTest::Walk(){ + if(!mWalkPath.empty()){ + std::vector vec; + for(ObjPtrList::iterator it = mWalkPath.begin(); it != mWalkPath.end(); ++it){ + vec.push_back(*it); + } + } +} + +void CharacterTest::TeleportTo(Waypoint* wp){ + if(wp) mMe->Teleport(wp); +} + +void CharacterTest::SetStartEndBeat(float f1, float f2, int bpm){ + Hmx::Object* miloObj = ObjectDir::Main()->FindObject("milo", false); + if(miloObj){ + DataNode milohandled = miloObj->Handle(Message("cur_anim"), true); + if(milohandled.Type() == kDataObject){ + Hmx::Object* handledObj = milohandled.GetObj(0); + if(handledObj == mMe){ + mMe->mFrozen = 0; // i know this is wrong, just can't figure out the right member atm + miloObj->SetProperty("bpm", DataNode(bpm)); + miloObj->Handle(Message("set_anim_frame", DataNode((f1 * 30.0f) / (bpm / 60.0f)), DataNode((f2 * 30.0f) / (bpm / 60.0f)), DataNode((float)bpm)), true); + } + } + } +} + +void CharacterTest::SetMoveSelf(bool b){ + if(mMe->BoneServo()){ + mMe->BoneServo()->SetMoveSelf(b); + } +} + BEGIN_LOADS(CharacterTest) LOAD_REVS(bs) if(gRev > 0xF){ diff --git a/src/system/char/CharacterTest.h b/src/system/char/CharacterTest.h index 3947cf0d..c1769390 100644 --- a/src/system/char/CharacterTest.h +++ b/src/system/char/CharacterTest.h @@ -8,6 +8,7 @@ class Character; class CharDriver; class CharClip; class CharClipGroup; +class ClipDistMap; class Waypoint; class CharacterTest : public RndOverlay::Callback { @@ -19,6 +20,14 @@ class CharacterTest : public RndOverlay::Callback { void Load(BinStream&); void Poll(); + void Draw(); + void PlayNew(); + void Recenter(); + void AddDefaults(); + void Walk(); + void TeleportTo(Waypoint*); + void SetStartEndBeat(float, float, int); + void SetMoveSelf(bool); NEW_POOL_OVERLOAD(CharacterTest) DELETE_POOL_OVERLOAD(CharacterTest) @@ -38,9 +47,9 @@ class CharacterTest : public RndOverlay::Callback { bool mZeroTravel; // 0x5e bool mShowScreenSize; // 0x5f bool mShowFootExtents; // 0x60 - int unk64; // 0x64 + float unk64; // 0x64 int unk68; // 0x68 - int unk6c; // 0x6c + ClipDistMap* unk6c; // 0x6c RndOverlay* mOverlay; // 0x70 }; diff --git a/src/system/char/ClipCollide.cpp b/src/system/char/ClipCollide.cpp index 0ab5eac4..3e3c7600 100644 --- a/src/system/char/ClipCollide.cpp +++ b/src/system/char/ClipCollide.cpp @@ -3,11 +3,271 @@ #include "char/Character.h" #include "char/Waypoint.h" #include "char/CharClip.h" +#include "char/CharDriver.h" +#include "utl/Symbols.h" + +INIT_REVS(ClipCollide) ClipCollide::ClipCollide() : mReports(), mGraph(0), mChar(this, 0), mCharPath(""), mWaypoint(this, 0), mPosition(Symbol("front")), mClip(this, 0), mWorldLines(0), mMoveCamera(1), mMode() { mGraph = RndGraph::Get(this); } ClipCollide::~ClipCollide(){ - -} \ No newline at end of file + RndGraph::Free(this, false); +} + +void ClipCollide::SyncChar(){ + if(mChar){ + if(!mCharPath.empty()){ + FilePath fp(mCharPath.c_str()); + FilePath curproxy(mChar->ProxyFile()); + if(fp != curproxy){ + mChar->SetProxyFile(fp, false); + } + } + } + SyncWaypoint(); +} + +void ClipCollide::ClearReport(){ + mGraph->Reset(); + mReports.clear(); + mReportString = ""; + SyncMode(); +} + +void ClipCollide::Demonstrate(){ + bool b1 = false; + if(mChar && mWaypoint && mClip) b1 = true; + if(b1){ + SyncWaypoint(); + mChar->mDriver->Play(mClip, 2, -1.0f, 1e+30f, 0.0f); + } +} + +void ClipCollide::SetTypeDef(DataArray* da){ + if(mTypeDef != da){ + Hmx::Object::SetTypeDef(da); + if(da){ + DataArray* modesArr = da->FindArray("modes", true); + mMode = modesArr->Array(1)->Sym(0); + } + } +} + +ObjectDir* ClipCollide::Clips(){ + if(mChar) return mChar->mDriver->ClipDir(); + else return 0; +} + +bool ClipCollide::ValidWaypoint(Waypoint* w){ + static Message vw("valid_waypoint", DataNode(0)); + vw[0] = DataNode(w); + DataNode handled = Handle(vw, true); + if(handled.Type() == kDataUnhandled) return true; + else return handled.Int(0); +} + +bool ClipCollide::ValidClip(CharClip* clip){ + if(!mWaypoint) return true; + else { + static Message vw("valid_clip", DataNode(0), DataNode(0)); + vw[0] = DataNode(clip); + vw[1] = DataNode(mWaypoint); + DataNode handled = Handle(vw, true); + if(handled.Type() == kDataUnhandled) return true; + else return handled.Int(0); + } +} + +void ClipCollide::TestChars(){ + if(mChar){ + DataArray* td = mTypeDef; + if(td){ + DataArray* charsArr = td->FindArray("chars", false); + if(charsArr){ + DataArray* arr = charsArr->Array(1); + for(int i = 0; i < arr->Size(); i++){ + String str(arr->Str(i)); + if(!str.empty()){ + mCharPath = str; + SyncChar(); + TestWaypoints(); + } + } + } + } + } +} + +void ClipCollide::TestWaypoints(){ + if(!mChar) return; + for(ObjDirItr it(Dir(), true); it != 0; ++it){ + if(ValidWaypoint(it)){ + mWaypoint = it; + TestClips(); + } + } +} + +// std::vector mReports; // 0x1c +// RndGraph* mGraph; // 0x24 +// ObjPtr mChar; // 0x28 +// String mCharPath; // 0x34 +// ObjPtr mWaypoint; // 0x40 +// Symbol mPosition; // 0x4c +// ObjPtr mClip; // 0x50 +// String mReportString; // 0x5c +// bool mWorldLines; // 0x68 +// bool mMoveCamera; // 0x69 +// Symbol mMode; // 0x6c + +void ClipCollide::TestClips(){ + if(!mWaypoint || !mChar) return; + for(ObjDirItr it(Clips(), true); it != 0; ++it){ + if(ValidClip(it)){ + const char* directions[4] = { "front", "back", "left", "right" }; + for(int i = 0; i < 4; i++){ + mPosition = directions[i]; + mClip = it; + Collide(); + } + } + } +} + +DataNode ClipCollide::OnVenueName(DataArray* da){ + String str; + Hmx::Object* miloObj = ObjectDir::Main()->Find("milo", true); + if(miloObj){ + Message msg("current_file"); + DataNode handled = miloObj->Handle(msg, true); + char buf[0x100]; + strcpy(buf, handled.Str(0)); + int len = strlen(buf); + char* p = buf + len; + if(buf <= p){ + for(; len != 0; len--, p--){ + if(*p == '\\' || *p == '/'){ + *p = '\0'; + break; + } + } + } + char* p1 = p + (1 - (int)buf); + if(buf <= p){ + for(; p1 != 0; p1--, p--){ + if(*p == '\\' || *p == '/'){ + str = buf; + break; + } + } + } + } + return DataNode(str); +} + +SAVE_OBJ(ClipCollide, 0x19D) + +BEGIN_LOADS(ClipCollide) + LOAD_REVS(bs) + ASSERT_REVS(1, 0) + LOAD_SUPERCLASS(Hmx::Object) + bs >> mChar; + bs >> mCharPath; + bs >> mWaypoint; + bs >> mPosition; + mClip = 0; +END_LOADS + +BEGIN_COPYS(ClipCollide) + COPY_SUPERCLASS(Hmx::Object) + CREATE_COPY(ClipCollide) +END_COPYS + +void ClipCollide::SyncMode(){ + if(!mMode.Null()){ + Message msg("set_mode", DataNode(mMode)); + Handle(msg, true); + } +} + +BEGIN_HANDLERS(ClipCollide) + HANDLE(list_clips, OnListClips) + HANDLE(list_waypoints, OnListWaypoints) + HANDLE(list_report, OnListReport) + HANDLE_ACTION(demonstrate, Demonstrate()) + HANDLE_ACTION(collide, Collide()) + HANDLE_ACTION(test_clips, TestClips()) + HANDLE_ACTION(test_waypoints, TestWaypoints()) + HANDLE_ACTION(test_chars, TestChars()) + HANDLE_ACTION(clear_report, ClearReport()) + HANDLE(venue_name, OnVenueName) + HANDLE_SUPERCLASS(Hmx::Object) + HANDLE_CHECK(0x1DC) +END_HANDLERS + +DataNode ClipCollide::OnListClips(DataArray* da){ + std::list cliplist; + ObjectDir* clipDir = Clips(); + if(clipDir){ + for(ObjDirItr it(clipDir, true); it != 0; ++it){ + if(ValidClip(it)) cliplist.push_back(it); + } + // sort + } + int listsize = 0; + for(std::list::iterator it = cliplist.begin(); it != cliplist.end(); it++) listsize++; + DataArray* arr = new DataArray(listsize); + arr->Node(0) = DataNode((Hmx::Object*)0); + int idx = 1; + for(std::list::iterator it = cliplist.begin(); it != cliplist.end(); it++){ + arr->Node(idx++) = DataNode(*it); + } + DataNode ret(arr, kDataArray); + arr->Release(); + return ret; +} + +DataNode ClipCollide::OnListWaypoints(DataArray* da){ + std::list waylist; + for(ObjDirItr it(Dir(), true); it != 0; ++it){ + if(ValidWaypoint(it)) waylist.push_back(it); + } + // sort + int listsize = 0; + for(std::list::iterator it = waylist.begin(); it != waylist.end(); it++) listsize++; + DataArray* arr = new DataArray(listsize); + arr->Node(0) = DataNode((Hmx::Object*)0); + int idx = 1; + for(std::list::iterator it = waylist.begin(); it != waylist.end(); it++){ + arr->Node(idx++) = DataNode(*it); + } + DataNode ret(arr, kDataArray); + arr->Release(); + return ret; +} + +DataNode ClipCollide::OnListReport(DataArray* da){ + DataArray* arr = new DataArray(mReports.size() + 1); + arr->Node(0) = DataNode(""); + for(int i = 0; i < mReports.size(); i++){ + arr->Node(i + 1) = DataNode(MakeString("%d %s %s %s", i + 1, mReports[i].clip, mReports[i].waypoint->Name(), mReports[i].name)); + } + DataNode ret(arr, kDataArray); + arr->Release(); + return ret; +} + +BEGIN_PROPSYNCS(ClipCollide) + SYNC_PROP_MODIFY_ALT(character, mChar, SyncChar()) + SYNC_PROP_MODIFY_ALT(pick_character, mCharPath, SyncChar()) + SYNC_PROP_MODIFY_ALT(waypoint, mWaypoint, SyncWaypoint()) + SYNC_PROP_MODIFY(position, mPosition, SyncWaypoint()) + SYNC_PROP_MODIFY(mode, mMode, SyncMode()) + SYNC_PROP(clip, mClip) + SYNC_PROP_SET(clips, Clips(), ) + SYNC_PROP_SET(pick_report, mReportString, PickReport(_val.Str(0))) + SYNC_PROP(world_lines, mWorldLines) + SYNC_PROP(move_camera, mMoveCamera) +END_PROPSYNCS \ No newline at end of file diff --git a/src/system/char/ClipCollide.h b/src/system/char/ClipCollide.h index e5c55be0..5ef85830 100644 --- a/src/system/char/ClipCollide.h +++ b/src/system/char/ClipCollide.h @@ -35,17 +35,40 @@ class ClipCollide : public Hmx::Object { virtual void Load(BinStream&); virtual void SetTypeDef(DataArray*); - std::vector mReports; - RndGraph* mGraph; - ObjPtr mChar; - String mCharPath; - ObjPtr mWaypoint; - Symbol mPosition; - ObjPtr mClip; - String mReportString; - bool mWorldLines; - bool mMoveCamera; - Symbol mMode; + void SyncChar(); + void SyncWaypoint(); + void ClearReport(); + void SyncMode(); + void Demonstrate(); + bool ValidWaypoint(Waypoint*); + bool ValidClip(CharClip*); + void TestChars(); + void TestWaypoints(); + void TestClips(); + ObjectDir* Clips(); + void Collide(); + void PickReport(const char*); + + DataNode OnVenueName(DataArray*); + DataNode OnListClips(DataArray*); + DataNode OnListWaypoints(DataArray*); + DataNode OnListReport(DataArray*); + + DECLARE_REVS; + NEW_OVERLOAD; + DELETE_OVERLOAD; + + std::vector mReports; // 0x1c + RndGraph* mGraph; // 0x24 + ObjPtr mChar; // 0x28 + String mCharPath; // 0x34 + ObjPtr mWaypoint; // 0x40 + Symbol mPosition; // 0x4c + ObjPtr mClip; // 0x50 + String mReportString; // 0x5c + bool mWorldLines; // 0x68 + bool mMoveCamera; // 0x69 + Symbol mMode; // 0x6c }; #endif diff --git a/src/system/char/ClipDistMap.h b/src/system/char/ClipDistMap.h new file mode 100644 index 00000000..96f9644c --- /dev/null +++ b/src/system/char/ClipDistMap.h @@ -0,0 +1,37 @@ +#ifndef CHAR_CLIPDISTMAP_H +#define CHAR_CLIPDISTMAP_H +#include "char/CharClip.h" +#include + +class ClipDistMap { +public: + class Node { + public: + }; + + ClipDistMap(CharClip*, CharClip*, float, float, int, const DataArray*); + void FindDists(float, DataArray*); + void FindNodes(float, float, float); + void SetNodes(Node*, Node*); + + CharClip* unk0; + CharClip* unk4; + DataArray* unk8; + int unkc; + int unk10; + int unk14; + int unk18; + int unk1c; + float unk20; + float unk24; + int unk28; + int unk2c; + float unk30; + float unk34; + int unk38; + int unk3c; + int unk40; + std::vector unk44; +}; + +#endif \ No newline at end of file diff --git a/src/system/char/ClipGraphGen.cpp b/src/system/char/ClipGraphGen.cpp new file mode 100644 index 00000000..71304f26 --- /dev/null +++ b/src/system/char/ClipGraphGen.cpp @@ -0,0 +1,74 @@ +#include "char/ClipGraphGen.h" +#include "os/Debug.h" +#include "utl/Symbols.h" + +ClipGraphGenerator::ClipGraphGenerator() : unk1c(0), mDmap(0), mClipA(0), mClipB(0) { + +} + +ClipGraphGenerator::~ClipGraphGenerator(){} + +ClipDistMap* ClipGraphGenerator::GeneratePair(CharClip* c1, CharClip* c2, ClipDistMap::Node* n1, ClipDistMap::Node* n2){ + c1->mTransitions.RemoveNodes(c2); + bool b2 = true; + unk1c = c1->mTypeDef; + bool b1 = true; + if(unk1c){ + if(c2->Type() == c1->Type()) b1 = false; + } + if(!b1 && ((c1->mPlayFlags & 0xF0) != 0x10)) b2 = false; + if(b2) return 0; + else { + DataArray* transarr = unk1c->FindArray("on_transition", false); + if(!transarr) return 0; + else { + static DataNode& a_clip = DataVariable("a_clip"); + static DataNode& b_clip = DataVariable("b_clip"); + mDmap = 0; + a_clip = DataNode(c1); + b_clip = DataNode(c2); + mClipA = c1; + mClipB = c2; + transarr->ExecuteScript(1, this, 0, 1); + ClipDistMap* dmap = mDmap; + mDmap = 0; + if(dmap) dmap->SetNodes(n1, n2); + return dmap; + } + } +} + +BEGIN_HANDLERS(ClipGraphGenerator) + HANDLE(generate_transitions, OnGenerateTransitions) + HANDLE_CHECK(0xC0) +END_HANDLERS + +DataNode ClipGraphGenerator::OnGenerateTransitions(DataArray* da){ + MILO_ASSERT(!mDmap, 0xC6); + MILO_ASSERT(mClipA, 199); + MILO_ASSERT(mClipB, 200); + float max_error = 1e+30f; + da->FindData("max_error", max_error, false); + float beat_align = 0; + da->FindData("beat_align", beat_align, false); + float blend_width = 1.0f; + da->FindData("blend_width", blend_width, false); + float max_facing = 0; + da->FindData("max_facing", max_facing, false); + float max_dist = 0; + da->FindData("max_dist", max_dist, false); + float end_dist = 0; + da->FindData("end_dist", end_dist, false); + DataArray* restrictArr = da->FindArray("restrict", false); + + int bflag = mClipB->mPlayFlags >> 12 & 15; + int aflag = mClipA->mPlayFlags >> 12 & 15; + if(bflag < aflag) aflag = bflag; + if(beat_align < (float)aflag) beat_align = aflag; + + DataArray* boneweightarr = unk1c->FindArray("transition_bone_weights", false); + mDmap = new ClipDistMap(mClipA, mClipB, beat_align, blend_width, 3, boneweightarr); + mDmap->FindDists(max_facing * DEG2RAD, restrictArr); + mDmap->FindNodes(max_error, max_dist, end_dist); + return DataNode(0); +} \ No newline at end of file diff --git a/src/system/char/ClipGraphGen.h b/src/system/char/ClipGraphGen.h new file mode 100644 index 00000000..538ccf36 --- /dev/null +++ b/src/system/char/ClipGraphGen.h @@ -0,0 +1,21 @@ +#ifndef CHAR_CLIPGRAPHGENERATOR_H +#define CHAR_CLIPGRAPHGENERATOR_H +#include "obj/Object.h" +#include "char/ClipDistMap.h" + +class ClipGraphGenerator : public Hmx::Object { +public: + ClipGraphGenerator(); + virtual ~ClipGraphGenerator(); + virtual DataNode Handle(DataArray*, bool); + + ClipDistMap* GeneratePair(CharClip*, CharClip*, ClipDistMap::Node*, ClipDistMap::Node*); + DataNode OnGenerateTransitions(DataArray*); + + DataArray* unk1c; + ClipDistMap* mDmap; // 0x20 + CharClip* mClipA; // 0x24 + CharClip* mClipB; // 0x28 +}; + +#endif diff --git a/src/system/char/Waypoint.cpp b/src/system/char/Waypoint.cpp index 4ca87791..85ea8e5b 100644 --- a/src/system/char/Waypoint.cpp +++ b/src/system/char/Waypoint.cpp @@ -3,19 +3,21 @@ #include "obj/Object.h" #include "rndobj/Mesh.h" #include "rndobj/Trans.h" +#include "math/Rand.h" +#include "math/Rot.h" #include "utl/Symbols.h" -#include "utl/Symbols4.h" INIT_REVS(Waypoint) std::list* Waypoint::sWaypoints; void Waypoint::Init() { - Hmx::Object::RegisterFactory(StaticClassName(), NewObject); + Register(); DataRegisterFunc("waypoint_find", &OnWaypointFind); DataRegisterFunc("waypoint_nearest", &OnWaypointNearest); DataRegisterFunc("waypoint_last", &OnWaypointLast); sWaypoints = new std::list; + TheDebug.AddExitCallback(Waypoint::Terminate); } void Waypoint::Terminate() { @@ -33,15 +35,85 @@ DataNode Waypoint::OnWaypointFind(DataArray* da) { return DataNode(Waypoint::Find(da->Int(1))); } -Waypoint::Waypoint() : mConnections(this) { - +Waypoint::Waypoint() : mFlags(0), mRadius(12.0f), mYRadius(0), mAngRadius(0), pad(0), mStrictAngDelta(0), mStrictRadiusDelta(0), mConnections(this) { + if(RandomFloat() < 0.5f){ + sWaypoints->push_back(this); + } + else sWaypoints->push_back(this); } Waypoint::~Waypoint() { } -void Waypoint::Highlight() { } +void Waypoint::Highlight(){} + +// https://decomp.me/scratch/jaExl - retail scratch +void Waypoint::Constrain(Transform& tf){ + float f1 = 0.0f; + float f2 = mStrictRadiusDelta; + if(f2 > 0.0f){ + if(mYRadius > 0.0f){ + f1 = mYRadius + f2; + } + Vector3 v18; + ShapeDeltaBox(tf.v, mRadius + f2, f1, v18); + tf.v += v18; + } + if(mStrictAngDelta > 0.0f){ + float ang = ShapeDeltaAng(mAngRadius + mStrictAngDelta, GetZAngle(tf.m)); + RotateAboutZ(tf.m, ang, tf.m); + } +} + +void Waypoint::ShapeDelta(const Vector3& v, Vector3& vout){ + ShapeDeltaBox(v, mRadius, mYRadius, vout); +} + +float Waypoint::ShapeDelta(float f){ + return ShapeDeltaAng(mAngRadius, f); +} + +void Waypoint::ShapeDeltaBox(const Vector3& v1, float f1, float f2, Vector3& res){ + Transform& world = WorldXfm(); + if(f2 > 0.0f){ + Subtract(v1, WorldXfm().v, res); + float dotx = Dot(res, world.m.x); + float doty = Dot(res, world.m.y); + float clamped1 = Clamp(-f1, f1, dotx); + float clamped2 = Clamp(-f2, f2, doty); + Scale(world.m.x, clamped1 - dotx, res); + ScaleAddEq(res, world.m.y, clamped2 - doty); + } + else { + Subtract(WorldXfm().v, v1, res); + res.z = 0; + float lensq = LengthSquared(res); + if(lensq <= f1 * f1) res.Zero(); + else res *= 1.0f - (f1 / std::sqrt(lensq)); + } +} + +float Waypoint::ShapeDeltaAng(float f1, float f2){ + float limited = LimitAng(GetZAngle(WorldXfm().m) - f2); + float clamped = Clamp(-f1, f1, limited); + return limited - clamped; +} + +BEGIN_COPYS(Waypoint) + COPY_SUPERCLASS(Hmx::Object) + COPY_SUPERCLASS(RndTransformable) + CREATE_COPY(Waypoint) + BEGIN_COPYING_MEMBERS + COPY_MEMBER(mFlags) + COPY_MEMBER(mConnections) + COPY_MEMBER(mRadius) + COPY_MEMBER(mYRadius) + COPY_MEMBER(mAngRadius) + COPY_MEMBER(mStrictRadiusDelta) + COPY_MEMBER(mStrictAngDelta) + END_COPYING_MEMBERS +END_COPYS SAVE_OBJ(Waypoint, 460) @@ -58,11 +130,11 @@ void Waypoint::Load(BinStream& bs) { } else mRadius = 12; if (gRev > 2) { bs >> mYRadius; - bs >> d; + bs >> mAngRadius; } if (gRev > 3) { bs >> mStrictRadiusDelta; - bs >> e; + bs >> mStrictAngDelta; } } @@ -70,8 +142,9 @@ BEGIN_PROPSYNCS(Waypoint) SYNC_PROP(flags, mFlags) SYNC_PROP(radius, mRadius) SYNC_PROP(y_radius, mYRadius) - + SYNC_PROP_SET(ang_radius, mAngRadius * RAD2DEG, mAngRadius = _val.Float(0) * DEG2RAD) SYNC_PROP(strict_radius_delta, mStrictRadiusDelta) + SYNC_PROP_SET(strict_ang_delta, mStrictAngDelta * RAD2DEG, mStrictAngDelta = _val.Float(0) * DEG2RAD) SYNC_PROP(connections, mConnections) SYNC_SUPERCLASS(RndTransformable) END_PROPSYNCS diff --git a/src/system/char/Waypoint.h b/src/system/char/Waypoint.h index 101aa470..fb3af719 100644 --- a/src/system/char/Waypoint.h +++ b/src/system/char/Waypoint.h @@ -1,35 +1,47 @@ #ifndef CHAR_WAYPOINT_H #define CHAR_WAYPOINT_H - -#include "obj/ObjPtr_p.h" -#include "obj/ObjVector.h" #include "rndobj/Trans.h" +#include "obj/ObjVector.h" #include class Waypoint : public RndTransformable { // 0xe4 +public: Waypoint(); virtual ~Waypoint(); OBJ_CLASSNAME(Waypoint) OBJ_SET_TYPE(Waypoint) virtual void Save(BinStream&); + virtual void Copy(const Hmx::Object*, Hmx::Object::CopyType); virtual void Load(BinStream&); virtual DataNode Handle(DataArray*, bool); virtual bool SyncProperty(DataNode&, DataArray*, int, PropOp); virtual void Highlight(); + void Constrain(Transform&); + void ShapeDelta(const Vector3&, Vector3&); + float ShapeDelta(float); + void ShapeDeltaBox(const Vector3&, float, float, Vector3&); + float ShapeDeltaAng(float, float); + static DataNode OnWaypointFind(DataArray*); static DataNode OnWaypointNearest(DataArray*); static DataNode OnWaypointLast(DataArray*); static Waypoint* Find(int); - int mFlags; - float mRadius, mYRadius, d; - int pad, e; - float mStrictRadiusDelta; - ObjVector, u16> mConnections; // this is an ObjVector :D + int mFlags; // 0x90 + float mRadius; // 0x94 + float mYRadius; // 0x98 + float mAngRadius; // 0x9c + int pad; // 0xa0 + float mStrictAngDelta; // 0xa4 + float mStrictRadiusDelta; // 0xa8 + ObjVector > mConnections; // 0xac static void Init(); static void Terminate(); + static void Register(){ + REGISTER_OBJ_FACTORY(Waypoint); + } NEW_OBJ(Waypoint) diff --git a/src/system/math/Color.h b/src/system/math/Color.h index eac4e031..98e34a21 100644 --- a/src/system/math/Color.h +++ b/src/system/math/Color.h @@ -64,7 +64,8 @@ namespace Hmx { u8 a, b, g, r; }; }; - public: + public: + Color32(){ Clear(); } inline void Clear() { x = -1; } float fr() const { return r * 0.0039215688593685627f;} float fg() const { return g * 0.0039215688593685627f;} diff --git a/src/system/math/MathFuncs.h b/src/system/math/MathFuncs.h index 6e185846..63ce0da8 100644 --- a/src/system/math/MathFuncs.h +++ b/src/system/math/MathFuncs.h @@ -138,6 +138,10 @@ inline float fabs_f(double d){ return __fabs(d); } +inline bool IsFloatZero(float f){ + return fabs_f(f) < 0.0001f; +} + inline float pow_f(double x, double y){ return pow(x, y); } diff --git a/src/system/math/Mtx.h b/src/system/math/Mtx.h index 9aaf5263..85375702 100644 --- a/src/system/math/Mtx.h +++ b/src/system/math/Mtx.h @@ -226,7 +226,9 @@ BinStream& operator>>(BinStream&, TransformNoScale&); class Plane { public: Plane(){} + Plane(const Vector3& v1, const Vector3& v2){ Set(v1, v2); } + void Set(const Vector3&, const Vector3&); float Dot(const Vector3& vec) const { return a * vec.x + b * vec.y + c * vec.z + d; } @@ -277,6 +279,7 @@ void Multiply(const Hmx::Matrix3&, const Vector3&, Vector3&); void Multiply(const Vector3&, const Hmx::Matrix3&, Vector3&); void Multiply(const Transform&, const Transform&, Transform&); void Multiply(const Transform&, const Vector3&, Vector3&); +void Multiply(const Vector3&, const Hmx::Quat&, Vector3&); inline void Transpose(const Hmx::Matrix3& min, Hmx::Matrix3& mout){ mout.Set( @@ -364,4 +367,13 @@ inline void FastInvert(const Transform& tfin, Transform& tfout){ Multiply(vtmp, tfout.m, tfout.v); } +// https://en.wikipedia.org/wiki/Gram%E2%80%93Schmidt_process +// https://gamedev.stackexchange.com/questions/139703/compute-up-and-right-from-a-direction +// Looks similar to C_MTXLookAt from the dolphin SDK. +inline void LookAt(Hmx::Matrix3& mtx){ + Cross(mtx.x, mtx.y, mtx.z); + Normalize(mtx.z, mtx.z); + Cross(mtx.z, mtx.x, mtx.y); +} + #endif diff --git a/src/system/math/Rot.h b/src/system/math/Rot.h index 7049bfee..ea7c73cd 100644 --- a/src/system/math/Rot.h +++ b/src/system/math/Rot.h @@ -21,7 +21,10 @@ void Normalize(const Hmx::Matrix3&, Hmx::Matrix3&); void MakeRotMatrix(const Hmx::Quat&, Hmx::Matrix3&); void Interp(const Hmx::Quat&, const Hmx::Quat&, float, Hmx::Quat&); void RotateAboutX(const Hmx::Matrix3&, float, Hmx::Matrix3&); +void RotateAboutZ(const Hmx::Matrix3&, float, Hmx::Matrix3&); void MakeRotQuat(const Vector3&, const Vector3&, Hmx::Quat&); +void MakeRotQuatUnitX(const Vector3&, Hmx::Quat&); +float GetZAngle(const Hmx::Matrix3&); TextStream& operator<<(TextStream& ts, const Hmx::Quat& v); TextStream& operator<<(TextStream& ts, const Vector3& v); diff --git a/src/system/math/Trig.h b/src/system/math/Trig.h index aacc1098..a16451c9 100644 --- a/src/system/math/Trig.h +++ b/src/system/math/Trig.h @@ -7,17 +7,21 @@ void TrigTableTerminate(); float Lookup(float); // fn_802E2F90 float Sine(float); // fn_802E2F38 float FastSin(float); // fn_802E2FE8 -float Cosine(float); // fn_802DE4D4 -RETAIL_DONT_INLINE_FUNC float DegreesToRadians(float deg) { +// fn_802DE4D4 +inline float Cosine(float f){ + return Sine(f + 1.5707964f); +} + +inline float DegreesToRadians(float deg) { return 0.017453292f * deg; } -RETAIL_DONT_INLINE_FUNC float RadiansToDegrees(float rad) { +inline float RadiansToDegrees(float rad) { return 57.295776f * rad; } -float NormalizeAngle(float); +float LimitAng(float); DataNode DataSin(DataArray*); DataNode DataCos(DataArray*); diff --git a/src/system/math/Vec.h b/src/system/math/Vec.h index eb46d939..5631a625 100644 --- a/src/system/math/Vec.h +++ b/src/system/math/Vec.h @@ -1,12 +1,13 @@ #ifndef MATH_VEC_H #define MATH_VEC_H #include "os/Debug.h" +#include "math/Trig.h" #include "utl/BinStream.h" class Vector2 { public: Vector2(){} - Vector2(float xx, float yy); + Vector2(float xx, float yy) : x(xx), y(yy) {} Vector2(const Vector2& vec) : x(vec.x), y(vec.y) {} RETAIL_DONT_INLINE_CLASS void Set(float xx, float yy){ x = xx; y = yy; } @@ -24,9 +25,7 @@ class Vector2 { float y; }; -RETAIL_DONT_INLINE_FUNC Vector2::Vector2(float xx, float yy) : x(xx), y(yy) {} - -RETAIL_DONT_INLINE_FUNC BinStream& operator>>(BinStream& bs, Vector2& vec){ +inline BinStream& operator>>(BinStream& bs, Vector2& vec){ bs >> vec.x >> vec.y; return bs; } @@ -125,7 +124,7 @@ inline BinStream& operator>>(BinStream& bs, Vector4& vec){ } class Vector4_16_01 { - public: +public: //Vector4_16_01() : x(0.0f), y(0.0f), z(0.0f), w(0.0f) {} u16 x, y, z, w; float GetX() const { return x / 65535.0f;} @@ -314,7 +313,7 @@ inline float LengthSquared(const Vector2& v){ return x * x + y * y; } -RETAIL_DONT_INLINE_FUNC float Dot(const Vector3& v1, const Vector3& v2) { +inline float Dot(const Vector3& v1, const Vector3& v2) { return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; } @@ -376,7 +375,7 @@ inline void ScaleAddEq(Vector3& v1, const Vector3& v2, float f){ v1.z += v2.z * f; } -RETAIL_DONT_INLINE_FUNC void Cross(const Vector3 &v1, const Vector3 &v2, Vector3 &dst) { +inline void Cross(const Vector3 &v1, const Vector3 &v2, Vector3 &dst) { float x1, x2, y2, z1, z2, y1; x2 = v2.x; @@ -451,4 +450,17 @@ inline void Negate(const Vector3& v, Vector3& vres){ vres.Set(-v.x, -v.y, -v.z); } +inline void ScaleToMagnitude(const Vector3& vec, float fl, Vector3& res){ + if(!IsFloatZero(vec.x) || !IsFloatZero(vec.y) || !IsFloatZero(vec.z)){ + Scale(vec, fl / Length(vec), res); + } + else res.Set(0,0,0); +} + +inline void RotateAboutZ(const Vector3& v, float f, Vector3& res){ + float c = Cosine(f); + float s = Sine(f); + res.Set(v.x * c - v.y * s, v.x * s + v.y * c, v.z); +} + #endif diff --git a/src/system/rndobj/Mesh.cpp b/src/system/rndobj/Mesh.cpp index b1db6ded..981d72ab 100644 --- a/src/system/rndobj/Mesh.cpp +++ b/src/system/rndobj/Mesh.cpp @@ -46,8 +46,10 @@ RndMesh::~RndMesh() { } -RndMesh::Vert::Vert() : x(0), y(0), z(0), nx(0), ny(1), nz(0), why(), - unk_0x20(-1), u(0), v(0), unk_0x2C(0), unk_0x2E(0), unk_0x30(0), unk_0x32(0) {} +RndMesh::Vert::Vert() : pos(0,0,0), norm(0,1.0f,0), boneWeights(), + color(), uv(0,0) { + for(int i = 0; i < 4; i++) boneIndices[i] = 0; +} void RndMesh::PreLoadVertices(BinStream& bs) { if (gAltRev > 4) { @@ -183,8 +185,8 @@ void RndMesh::PostLoad(BinStream& bs) { bs >> mBones[0].mOffset >> mBones[1].mOffset >> mBones[2].mOffset >> mBones[3].mOffset; if (gRev < 25) { // incoming headache for (std::vector::iterator it = mVerts.begin(); it != mVerts.end(); it++) { - it->why.Set(1 - it->why.GetX() - it->why.GetY() - it->why.GetZ(), - it->why.GetX(), it->why.GetY(), it->why.GetZ()); + // it->why.Set(1 - it->why.GetX() - it->why.GetY() - it->why.GetZ(), + // it->why.GetX(), it->why.GetY(), it->why.GetZ()); } } } else { @@ -219,13 +221,13 @@ DECOMP_FORCEFUNC(Mesh, RndMesh, NumBones()) #pragma pop BinStream& operator>>(BinStream& bs, RndMesh::Vert& v) { - bs >> v.x >> v.y >> v.z; + bs >> v.pos; if (RndMesh::gRev != 10 && RndMesh::gRev < 23) { int a,b; bs >> a >> b; } - bs >> v.nx >> v.ny >> v.nz; + bs >> v.norm; if (RndMesh::gRev < 20) { int a,b; bs >> b >> a; } - if (RndMesh::gRev > 28) bs >> v.unk_0x2C >> v.unk_0x2E >> v.unk_0x30 >> v.unk_0x32; + if (RndMesh::gRev > 28) bs >> v.boneIndices[0] >> v.boneIndices[1] >> v.boneIndices[2] >> v.boneIndices[3]; if (RndMesh::gRev > 29) { int a,b,c,d; bs >> d >> c >> b >> a; @@ -303,9 +305,9 @@ DataNode RndMesh::OnGetVertNorm(const DataArray* da) { s32 index = da->Int(2); MILO_ASSERT(index >= 0 && index < mVerts.size(), 2446); v = &mVerts[index]; - *da->Var(3) = DataNode(v->nx); - *da->Var(4) = DataNode(v->ny); - *da->Var(5) = DataNode(v->nz); + *da->Var(3) = DataNode(v->norm.x); + *da->Var(4) = DataNode(v->norm.y); + *da->Var(5) = DataNode(v->norm.z); return DataNode(); } @@ -314,9 +316,9 @@ DataNode RndMesh::OnSetVertNorm(const DataArray* da) { s32 index = da->Int(2); MILO_ASSERT(index >= 0 && index < mVerts.size(), 2457); v = &mVerts[index]; - v->nx = da->Float(3); - v->ny = da->Float(4); - v->nz = da->Float(5); + v->norm.x = da->Float(3); + v->norm.y = da->Float(4); + v->norm.z = da->Float(5); Sync(31); return DataNode(); } @@ -326,9 +328,9 @@ DataNode RndMesh::OnGetVertXYZ(const DataArray* da) { s32 index = da->Int(2); MILO_ASSERT(index >= 0 && index < mVerts.size(), 2469); v = &mVerts[index]; - *da->Var(3) = DataNode(v->x); - *da->Var(4) = DataNode(v->y); - *da->Var(5) = DataNode(v->z); + *da->Var(3) = DataNode(v->pos.x); + *da->Var(4) = DataNode(v->pos.y); + *da->Var(5) = DataNode(v->pos.z); return DataNode(); } @@ -337,9 +339,9 @@ DataNode RndMesh::OnSetVertXYZ(const DataArray* da) { s32 index = da->Int(2); MILO_ASSERT(index >= 0 && index < mVerts.size(), 2480); v = &mVerts[index]; - v->x = da->Float(3); - v->y = da->Float(4); - v->z = da->Float(5); + v->pos.x = da->Float(3); + v->pos.y = da->Float(4); + v->pos.z = da->Float(5); Sync(31); return DataNode(); } @@ -349,8 +351,8 @@ DataNode RndMesh::OnGetVertUV(const DataArray* da) { s32 index = da->Int(2); MILO_ASSERT(index >= 0 && index < mVerts.size(), 2492); v = &mVerts[index]; - *da->Var(3) = DataNode(v->u); - *da->Var(4) = DataNode(v->v); + *da->Var(3) = DataNode(v->uv.x); + *da->Var(4) = DataNode(v->uv.y); return DataNode(); } @@ -359,8 +361,8 @@ DataNode RndMesh::OnSetVertUV(const DataArray* da) { s32 index = da->Int(2); MILO_ASSERT(index >= 0 && index < mVerts.size(), 2502); v = &mVerts[index]; - v->u = da->Float(3); - v->v = da->Float(4); + v->uv.x = da->Float(3); + v->uv.y = da->Float(4); Sync(31); return DataNode(); } diff --git a/src/system/rndobj/Mesh.h b/src/system/rndobj/Mesh.h index deebefde..4c311cf9 100644 --- a/src/system/rndobj/Mesh.h +++ b/src/system/rndobj/Mesh.h @@ -29,14 +29,14 @@ class RndBone : public ObjPtr { class RndMesh : public RndDrawable, public RndTransformable { public: class Vert { - public: + public: Vert(); - float x, y, z; // 0x0, 0x4, 0x8 - float nx, ny, nz; // 0xC, 0x10, 0x14 W component gets shadowrealmed on wii - Vector4_16_01 why; // 0x18 the hate format - int unk_0x20; // ???? - float u, v; // 0x24, 0x28 WHY ARE THEY OUT HERE - u16 unk_0x2C, unk_0x2E, unk_0x30, unk_0x32; + Vector3 pos; // 0x0 + Vector3 norm; // 0xc + Vector4_16_01 boneWeights; // 0x18 the hate format + Hmx::Color32 color; // 0x20 + Vector2 uv; // 0x24 + short boneIndices[4]; // 0x28 }; class Face { @@ -52,7 +52,7 @@ class RndMesh : public RndDrawable, public RndTransformable { }; class VertVector : public std::vector { // ??????? - public: + public: void resize(int, bool); void reserve(int, bool); std::vector::iterator begin() { return std::vector::begin(); } @@ -85,6 +85,10 @@ class RndMesh : public RndDrawable, public RndTransformable { virtual void Print(); virtual void OnSync(int); + const Vector3& VertPos(int idx) const { + return mOwner->mVerts[idx].pos; + } + // TODO: figure out what RndMesh's members do VertVector mVerts; // 0xB0 std::vector mFaces; // 0xBC diff --git a/src/system/rndobj/PostProc.h b/src/system/rndobj/PostProc.h index ea86b229..058e9902 100644 --- a/src/system/rndobj/PostProc.h +++ b/src/system/rndobj/PostProc.h @@ -67,6 +67,7 @@ class RndPostProc : public Hmx::Object, public PostProcessor { void LoadRev(BinStream&, int); DataNode OnAllowedNormalMap(const DataArray*); bool BlendPrevious() const; + float EmulateFPS() const { return mEmulateFPS; } static void Reset(); static RndPostProc* sCurrent; @@ -118,7 +119,7 @@ class RndPostProc : public Hmx::Object, public PostProcessor { float mDuration; // 0x138 Vector3 unk13c; - float mEmulateFPS; + float mEmulateFPS; // 0x148 float unk14c; float unk150; diff --git a/src/system/rndobj/Utl.h b/src/system/rndobj/Utl.h index 80364ed7..4f505b34 100644 --- a/src/system/rndobj/Utl.h +++ b/src/system/rndobj/Utl.h @@ -16,6 +16,8 @@ void AttachMesh(RndMesh*, RndMesh*); void UtilDrawSphere(const Vector3&, float, const Hmx::Color&); void UtilDrawString(const char*, const Vector3&, const Hmx::Color&); void UtilDrawAxes(const Transform&, float, const Hmx::Color&); +void UtilDrawCigar(const Transform&, const float*, const float*, const Hmx::Color&, int); +void UtilDrawPlane(const Plane&, const Vector3&, const Hmx::Color&, int, float); void TransformKeys(class RndTransAnim*, const Transform&); MatShaderOptions GetDefaultMatShaderOpts(const Hmx::Object*, RndMat*); void TestTextureSize(ObjectDir*, int, int, int, int, int);