Merge pull request #45 from MonsterDruide1/SupportBoneResource

Support bone resource
This commit is contained in:
Léo Lam 2021-08-02 01:16:59 +02:00 committed by GitHub
commit 85000e3c7c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 411 additions and 26 deletions

View File

@ -93670,30 +93670,30 @@ Address,Quality,Size,Name
0x0000007101228a24,O,000208,_ZN4ksys4phys16SupportBoneParamC1Ev
0x0000007101228af4,O,000048,_ZN4ksys4phys16SupportBoneParamD2Ev
0x0000007101228b24,O,000004,_ZN4ksys4phys16SupportBoneParamD0Ev
0x0000007101228b28,U,000876,
0x0000007101228e94,U,000164,
0x0000007101228f38,U,000688,
0x00000071012291e8,U,000172,
0x0000007101229294,U,000172,
0x0000007101229340,U,000180,
0x00000071012293f4,U,000064,
0x0000007101229434,U,003872,
0x000000710122a354,U,000388,
0x000000710122a4d8,U,000064,
0x000000710122a518,U,000492,
0x000000710122a704,U,000036,
0x000000710122a728,U,000004,j__ZdlPv_1248
0x000000710122a72c,U,000040,
0x000000710122a754,U,000004,j__ZdlPv_1249
0x000000710122a758,U,000056,
0x000000710122a790,U,000004,j__ZdlPv_1250
0x000000710122a794,U,000040,
0x000000710122a7bc,U,000004,j__ZdlPv_1251
0x000000710122a7c0,U,000296,
0x000000710122a8e8,U,000048,
0x000000710122a918,U,000004,j__ZdlPv_1252
0x000000710122a91c,U,000056,
0x000000710122a954,U,000088,
0x0000007101228b28,O,000876,_ZN4ksys4phys19SupportBoneResourceC1Ev
0x0000007101228e94,O,000164,_ZN4ksys4phys19SupportBoneResourceD1Ev
0x0000007101228f38,O,000688,_ZN4ksys4phys19SupportBoneResource11freeBuffersEv
0x00000071012291e8,O,000172,_ZThn32_N4ksys4phys19SupportBoneResourceD1Ev
0x0000007101229294,O,000172,_ZN4ksys4phys19SupportBoneResourceD0Ev
0x0000007101229340,O,000180,_ZThn32_N4ksys4phys19SupportBoneResourceD0Ev
0x00000071012293f4,O,000064,_ZN4ksys4phys19SupportBoneResource9doCreate_EPhjPN4sead4HeapE
0x0000007101229434,O,003872,_ZN4ksys4phys19SupportBoneResource4initEN3agl3utl19ResParameterArchiveEPN4sead4HeapE
0x000000710122a354,O,000388,_ZN4ksys4phys19SupportBoneResource25getSupportBoneIndexByNameERKN4sead14SafeStringBaseIcEE
0x000000710122a4d8,O,000064,_ZN4ksys4phys19SupportBoneResource28somethingGetLinearConnectionEjf
0x000000710122a518,O,000492,_ZN4ksys4phys19SupportBoneResource30getInterpolatedConnectionCurveEjf
0x000000710122a704,O,000036,_ZN4ksys4phys19SupportBoneResource4BoneD2Ev
0x000000710122a728,O,000004,_ZN4ksys4phys19SupportBoneResource4BoneD0Ev
0x000000710122a72c,O,000040,_ZN4ksys4phys19SupportBoneResource16ConnectionLinearD2Ev
0x000000710122a754,O,000004,_ZN4ksys4phys19SupportBoneResource16ConnectionLinearD0Ev
0x000000710122a758,O,000056,_ZN4ksys4phys19SupportBoneResource15ConnectionCurveD2Ev
0x000000710122a790,O,000004,_ZN4ksys4phys19SupportBoneResource15ConnectionCurveD0Ev
0x000000710122a794,O,000040,_ZN4ksys4phys19SupportBoneResource12OutputSingleD2Ev
0x000000710122a7bc,O,000004,_ZN4ksys4phys19SupportBoneResource12OutputSingleD0Ev
0x000000710122a7c0,O,000296,_ZN4ksys4phys25uninlineAllocDoubleBufferEPN4sead6BufferINS0_19SupportBoneResource12OutputDoubleEEEiPNS1_4HeapEi
0x000000710122a8e8,O,000048,_ZN4ksys4phys19SupportBoneResource12OutputDoubleD2Ev
0x000000710122a918,O,000004,_ZN4ksys4phys19SupportBoneResource12OutputDoubleD0Ev
0x000000710122a91c,O,000056,_ZN4ksys4phys19SupportBoneResource11SupportBoneD2Ev
0x000000710122a954,O,000088,_ZN4ksys4phys19SupportBoneResource11SupportBoneD0Ev
0x000000710122a9ac,U,000904,
0x000000710122ad34,U,000628,
0x000000710122afa8,U,000064,
@ -97076,7 +97076,7 @@ Address,Quality,Size,Name
0x0000007101309094,U,000004,nullsub_4856
0x0000007101309098,U,000644,
0x000000710130931c,U,000004,j__ZdlPv_1325
0x0000007101309320,U,000668,
0x0000007101309320,O,000668,_ZN4ksys4phys19SupportBoneResource8BaseBone9postRead_Ev
0x00000071013095bc,U,000048,
0x00000071013095ec,U,000492,
0x00000071013097d8,U,000056,

Can't render this file because it is too large.

@ -1 +1 @@
Subproject commit 0367e0ef1726f670c24c69d13cc2ce079ee02693
Subproject commit 207ccfb3f530a0e329c30791c290ec274c52bf4f

View File

@ -13,6 +13,9 @@ target_sources(uking PRIVATE
RigidBody/physRigidBodySetParam.h
SupportBone/physSupportBoneParam.cpp
SupportBone/physSupportBoneParam.h
SupportBone/physSupportBoneResource.cpp
SupportBone/physSupportBoneResource.h
SupportBone/physSupportBoneResourceMainBone.cpp
System/physCharacterControllerParam.cpp
System/physCharacterControllerParam.h
System/physContactInfoParam.cpp

View File

@ -0,0 +1,254 @@
#include "KingSystem/Physics/SupportBone/physSupportBoneResource.h"
#include <cmath>
namespace ksys::phys {
SupportBoneResource::Bone::~Bone() = default;
SupportBoneResource::BaseBone::BaseBone()
: bone(-1, "bone", "bone", this), aim(sead::Vector3f::ez, "aim", "aim", this),
up(sead::Vector3f::ey, "up", "up", this), space(-1, "space", "space", this),
base_rotate(sead::Quatf::unit, "base_rotate", "base_rotate", this),
base_translate(sead::Vector3f::zero, "base_translate", "base_translate", this) {}
SupportBoneResource::SupportBone::SupportBone()
: bendH(-1, "bendH", "bendH", this), bendV(-1, "bendV", "bendV", this),
roll(-1, "roll", "roll", this), translateX(-1, "translateX", "translateX", this),
translateY(-1, "translateY", "translateY", this),
translateZ(-1, "translateZ", "translateZ", this) {}
SupportBoneResource::SupportBoneResource()
: IParameterIO("physsb", 0), mBoneNum(0, "bone_num", "bone_num", &mSupportBoneHeader),
mConnectionLinearNum(0, "connection_linear_num", "connection_linear_num",
&mSupportBoneHeader),
mConnectionCurveNum(0, "connection_curve_num", "connection_curve_num", &mSupportBoneHeader),
mOutputSingleNum(0, "output_single_num", "output_single_num", &mSupportBoneHeader),
mOutputDoubleNum(0, "output_double_num", "output_double_num", &mSupportBoneHeader),
// labels have two underscores instead of a single one
mMainBoneNum(0, "main_bone_num", "main_bone__num" /* sic */, &mSupportBoneHeader),
mSupportBoneNum(0, "support_bone_num", "support_bone__num" /* sic */, &mSupportBoneHeader) {
addObj(&mSupportBoneHeader, "support_bone_header");
addList(&mSupportBoneData, "support_bone_data");
}
SupportBoneResource::~SupportBoneResource() {
freeBuffers();
}
void SupportBoneResource::freeBuffers() {
boneBuffer.freeBuffer();
mConnectionLinearBuffer.freeBuffer();
mConnectionCurveBuffer.freeBuffer();
mOutputSingleBuffer.freeBuffer();
mOutputDoubleBuffer.freeBuffer();
mMainBoneBuffer.freeBuffer();
mSupportBoneBuffer.freeBuffer();
}
bool uninlineAllocDoubleBuffer(sead::Buffer<ksys::phys::SupportBoneResource::OutputDouble>* buffer,
int size, sead::Heap* heap, s32 alignment = sizeof(void*)) {
return buffer->allocBufferAssert(size, heap, alignment);
}
void SupportBoneResource::doCreate_(u8* data, u32 actualFileSize, sead::Heap* heap) {
init(agl::utl::ResParameterArchive(data), heap);
}
float SupportBoneResource::somethingGetLinearConnection(u32 a2, float a3) {
sead::Vector2f slope_intercept = mConnectionLinearBuffer[a2].slope_intercept.ref();
float result = slope_intercept.x * a3 + slope_intercept.y;
return std::isnan(result) ? 0.0f : result;
}
int SupportBoneResource::getSupportBoneIndexByName(const sead::SafeString& name) {
s32 support_bone_num = mSupportBoneNum.ref();
for (s32 i = 0; i < support_bone_num; i++) {
int bone_index = mSupportBoneBuffer[i].bone.ref();
sead::SafeString bone_name = boneBuffer[bone_index].name.ref().cstr();
if (name == bone_name)
return i;
}
return -1;
}
bool SupportBoneResource::init(agl::utl::ResParameterArchive archive, sead::Heap* heap) {
agl::utl::ResParameterList param_list = archive.getRootList();
const auto support_bone_list = param_list.getResParameterList(0);
mSupportBoneHeader.applyResParameterObj(param_list.getResParameterObj(0));
int bone_num = mBoneNum.ref();
if (bone_num < 1)
return false;
mSupportBoneData.addList(&mBoneList, "bone_list");
boneBuffer.allocBufferAssert(bone_num, heap);
for (int i = 0; i < bone_num; i++) {
auto bone_name = sead::FormatFixedSafeString<32>("bone_%d", i);
mBoneList.addObj(&boneBuffer[i], bone_name);
boneBuffer[i].name.init(sead::FixedSafeString<64>::cEmptyString, "name", "name",
&boneBuffer[i]);
}
int connection_linear_num = mConnectionLinearNum.ref();
if (connection_linear_num > 0) {
mSupportBoneData.addList(&mConnectionLinearList, "connection_linear_list");
mConnectionLinearBuffer.allocBufferAssert(connection_linear_num, heap);
for (int i = 0; i < connection_linear_num; i++) {
auto connection_name = sead::FormatFixedSafeString<32>("connection_linear_%d", i);
mConnectionLinearList.addObj(&mConnectionLinearBuffer[i], connection_name);
mConnectionLinearBuffer[i].bone_attribute.init(
0, "bone_attribute", "bone_attribute",
&mConnectionLinearBuffer[i]); // initialised with 0 instead of -1
mConnectionLinearBuffer[i].slope_intercept.init(
{1, -1}, "slope_intercept", "slope_intercept", &mConnectionLinearBuffer[i]);
}
}
int connection_curve_num = mConnectionCurveNum.ref();
if (connection_curve_num > 0) {
mSupportBoneData.addList(&mConnectionCurveList, "connection_curve_list");
mConnectionCurveBuffer.allocBufferAssert(connection_curve_num, heap);
for (int i = 0; i < connection_curve_num; i++) {
auto connection_name = sead::FormatFixedSafeString<32>("connection_curve_%d", i);
mConnectionCurveList.addObj(&mConnectionCurveBuffer[i], connection_name);
mConnectionCurveBuffer[i].bone_attribute.init(-1, "bone_attribute", "bone_attribute",
&mConnectionCurveBuffer[i]);
mConnectionCurveBuffer[i].constant_in.init(true, "constant_in", "constant_in",
&mConnectionCurveBuffer[i]);
mConnectionCurveBuffer[i].constant_out.init(true, "constant_out", "constant_out",
&mConnectionCurveBuffer[i]);
mConnectionCurveBuffer[i].key0.init({0, 0, 1, 1}, "key_0", "key_0",
&mConnectionCurveBuffer[i]);
mConnectionCurveBuffer[i].key1.init({0.5, 0.5, 1, 1}, "key_1", "key_1",
&mConnectionCurveBuffer[i]);
mConnectionCurveBuffer[i].key2.init({1, 1, 1, 1}, "key_2", "key_2",
&mConnectionCurveBuffer[i]);
}
}
int output_single_num = mOutputSingleNum.ref();
if (output_single_num > 0) {
mSupportBoneData.addList(&mOutputSingleList, "output_single_list");
mOutputSingleBuffer.allocBufferAssert(output_single_num, heap);
for (int i = 0; i < output_single_num; i++) {
auto output_name = sead::FormatFixedSafeString<32>("output_single_%d", i);
mOutputSingleList.addObj(&mOutputSingleBuffer[i], output_name);
mOutputSingleBuffer[i].connection.init(0, "connection", "connection",
&mOutputSingleBuffer[i]);
mOutputSingleBuffer[i].weight.init(0, "weight", "weight", &mOutputSingleBuffer[i]);
}
}
int output_double_num = mOutputDoubleNum.ref();
if (output_double_num > 0) {
mSupportBoneData.addList(&mOutputDoubleList, "output_double_list");
uninlineAllocDoubleBuffer(&mOutputDoubleBuffer, output_double_num, heap);
for (int i = 0; i < output_double_num; i++) {
auto output_name = sead::FormatFixedSafeString<32>("output_double_%d", i);
mOutputDoubleList.addObj(&mOutputDoubleBuffer[i], output_name);
mOutputDoubleBuffer[i].connection_0.init(0, "connection_0", "connection_0",
&mOutputDoubleBuffer[i]);
mOutputDoubleBuffer[i].weight_0.init(0, "weight_0", "weight_0",
&mOutputDoubleBuffer[i]);
mOutputDoubleBuffer[i].connection_1.init(0, "connection_1", "connection_1",
&mOutputDoubleBuffer[i]);
mOutputDoubleBuffer[i].weight_1.init(0, "weight_1", "weight_1",
&mOutputDoubleBuffer[i]);
}
}
int main_bone_num = mMainBoneNum.ref();
if (main_bone_num < 1)
return false;
mSupportBoneData.addList(&mMainBoneList, "main_bone_list");
mMainBoneBuffer.allocBufferAssert(main_bone_num, heap);
for (int i = 0; i < main_bone_num; i++) {
auto name = sead::FormatFixedSafeString<32>("main_bone_%d", i);
mMainBoneList.addObj(&mMainBoneBuffer[i], name);
}
int support_bone_num = mSupportBoneNum.ref();
if (support_bone_num < 1)
return false;
mSupportBoneData.addList(&mSupportBoneList, "support_bone_list");
mSupportBoneBuffer.allocBufferAssert(support_bone_num, heap);
for (int i = 0; i < support_bone_num; i++) {
auto name = sead::FormatFixedSafeString<32>("support_bone_%d", i);
mSupportBoneList.addObj(&mSupportBoneBuffer[i], name);
}
mSupportBoneData.applyResParameterList(support_bone_list);
return true;
}
inline float cubicHermiteInterpolate(const sead::Vector4f& key1, const sead::Vector4f& key2,
float lookup) {
if (key1.x == key2.x) {
return key2.y;
}
float diff = key2.x - key1.x;
float t = (lookup - key1.x) / diff;
float h00 = (2 * t * t * t) - (3 * t * t) + 1;
float h01 = (-2 * t * t * t) + (3 * t * t);
float h10 = (t * t * t) - (2 * t * t) + t;
float h10_scaled = h10 * diff;
float h11 = (t * t * t) - (t * t);
float h11_scaled = h11 * diff;
return (h00 * key1.y) + (h01 * key2.y) + (h10_scaled * key1.w) + (h11_scaled * key2.z);
}
float SupportBoneResource::getInterpolatedConnectionCurve(u32 index, float lookup) {
auto& connection_curve = mConnectionCurveBuffer[index];
float result;
float x0 = connection_curve.key0->x; // lowest (always minus pi?)
float x1 = connection_curve.key1->x; // middle (0 in most cases)
float x2 = connection_curve.key2->x; // highest
if (x0 == lookup) {
result = connection_curve.key0->y;
} else if (x1 == lookup) {
result = connection_curve.key1->y;
} else if (x2 == lookup) {
result = connection_curve.key2->y;
} else if (x0 > lookup) {
result = connection_curve.key0->y;
if (!connection_curve.constant_in.ref())
result -= (x0 - lookup) * connection_curve.key0->z;
} else if (x1 > lookup) {
result = cubicHermiteInterpolate(connection_curve.key0.ref(), connection_curve.key1.ref(),
lookup);
} else if (x2 > lookup) {
result = cubicHermiteInterpolate(connection_curve.key1.ref(), connection_curve.key2.ref(),
lookup);
} else {
if (!connection_curve.constant_out.ref())
result = connection_curve.key2->y + ((lookup - x2) * connection_curve.key2->z);
else
result = connection_curve.key2->y;
}
return std::isnan(result) ? 0.0f : result;
}
void SupportBoneResource::BaseBone::postRead_() {
sead::Vector3f aim_local = aim.ref();
sead::Vector3f up_local = up.ref();
aim_local.normalize();
side = sead::cross(aim_local, up_local);
// XXX: this looks like a hack. Why does this not match without an inline function?
[&] { side.normalize(); }();
up_local = sead::cross(side, aim_local);
up_local.normalize();
up = up_local;
aim = aim_local;
base_rotate->normalize();
base_rotate->invert(&reverse_rotate);
}
} // namespace ksys::phys

View File

@ -0,0 +1,120 @@
#pragma once
#include <agl/Utils/aglParameter.h>
#include <agl/Utils/aglParameterIO.h>
#include <agl/Utils/aglParameterList.h>
#include <agl/Utils/aglParameterObj.h>
#include <container/seadBuffer.h>
#include <resource/seadResource.h>
#include "KingSystem/Utils/Types.h"
namespace ksys::phys {
class SupportBoneResource : public sead::DirectResource, agl::utl::IParameterIO {
public:
struct Bone : public agl::utl::ParameterObj {
~Bone();
agl::utl::Parameter<sead::FixedSafeString<64>> name;
};
struct ConnectionLinear : public agl::utl::ParameterObj {
agl::utl::Parameter<int> bone_attribute; // TODO enum?
agl::utl::Parameter<sead::Vector2f> slope_intercept;
};
struct ConnectionCurve : public agl::utl::ParameterObj {
~ConnectionCurve() = default;
agl::utl::Parameter<int> bone_attribute; // TODO enum?
agl::utl::Parameter<bool> constant_in;
agl::utl::Parameter<bool> constant_out;
agl::utl::Parameter<sead::Vector4f> key0;
agl::utl::Parameter<sead::Vector4f> key1;
agl::utl::Parameter<sead::Vector4f> key2;
};
struct OutputSingle : public agl::utl::ParameterObj {
agl::utl::Parameter<int> connection;
agl::utl::Parameter<float> weight;
};
struct OutputDouble : public agl::utl::ParameterObj {
~OutputDouble() = default;
agl::utl::Parameter<int> connection_0;
agl::utl::Parameter<float> weight_0;
agl::utl::Parameter<int> connection_1;
agl::utl::Parameter<float> weight_1;
};
struct BaseBone : public agl::utl::ParameterObj {
BaseBone();
~BaseBone();
void postRead_() override;
agl::utl::Parameter<int> bone;
agl::utl::Parameter<sead::Vector3f> aim;
agl::utl::Parameter<sead::Vector3f> up;
agl::utl::Parameter<int> space;
agl::utl::Parameter<sead::Quatf> base_rotate;
agl::utl::Parameter<sead::Vector3f> base_translate;
sead::Quatf reverse_rotate;
sead::Vector3<float> side;
};
struct MainBone : public BaseBone {
MainBone();
};
struct SupportBone : public BaseBone {
SupportBone();
~SupportBone() = default;
agl::utl::Parameter<int> bendH;
agl::utl::Parameter<int> bendV;
agl::utl::Parameter<int> roll;
agl::utl::Parameter<int> translateX;
agl::utl::Parameter<int> translateY;
agl::utl::Parameter<int> translateZ;
};
SupportBoneResource();
~SupportBoneResource();
void freeBuffers();
int getSupportBoneIndexByName(const sead::SafeString& name);
virtual void doCreate_(u8* data, u32 actualFileSize, sead::Heap* heap);
bool init(agl::utl::ResParameterArchive archive, sead::Heap* heap);
float getInterpolatedConnectionCurve(u32 index, float lookup);
float somethingGetLinearConnection(u32 a2, float a3);
private:
agl::utl::ParameterObj mSupportBoneHeader;
agl::utl::ParameterList mSupportBoneData;
agl::utl::Parameter<int> mBoneNum;
agl::utl::ParameterList mBoneList;
sead::Buffer<SupportBoneResource::Bone> boneBuffer;
agl::utl::Parameter<int> mConnectionLinearNum;
agl::utl::ParameterList mConnectionLinearList;
sead::Buffer<SupportBoneResource::ConnectionLinear> mConnectionLinearBuffer;
agl::utl::Parameter<int> mConnectionCurveNum;
agl::utl::ParameterList mConnectionCurveList;
sead::Buffer<SupportBoneResource::ConnectionCurve> mConnectionCurveBuffer;
agl::utl::Parameter<int> mOutputSingleNum;
agl::utl::ParameterList mOutputSingleList;
sead::Buffer<SupportBoneResource::OutputSingle> mOutputSingleBuffer;
agl::utl::Parameter<int> mOutputDoubleNum;
agl::utl::ParameterList mOutputDoubleList;
sead::Buffer<SupportBoneResource::OutputDouble> mOutputDoubleBuffer;
agl::utl::Parameter<int> mMainBoneNum;
agl::utl::ParameterList mMainBoneList;
sead::Buffer<SupportBoneResource::MainBone> mMainBoneBuffer;
agl::utl::Parameter<int> mSupportBoneNum;
agl::utl::ParameterList mSupportBoneList;
sead::Buffer<SupportBoneResource::SupportBone> mSupportBoneBuffer;
};
KSYS_CHECK_SIZE_NX150(SupportBoneResource, 0x5B0);
} // namespace ksys::phys

View File

@ -0,0 +1,8 @@
#include "KingSystem/Physics/SupportBone/physSupportBoneResource.h"
namespace ksys::phys {
SupportBoneResource::MainBone::MainBone() = default;
SupportBoneResource::BaseBone::~BaseBone() = default;
} // namespace ksys::phys