diff options
| author | Léo Lam <leo@leolam.fr> | 2021-04-22 19:03:46 +0200 |
|---|---|---|
| committer | Léo Lam <leo@leolam.fr> | 2021-04-22 19:37:58 +0200 |
| commit | 136f20427d6b346da488ec84f39b5c6aeaffd24e (patch) | |
| tree | a8f5740cbc11c50dfd16a505b1f565997ae62267 /src/KingSystem | |
| parent | f6e4643808bdec31d2e2bf1b3d3a0ce0b456e348 (diff) | |
ksys/phys: Implement ParamSet and res::Physics
Diffstat (limited to 'src/KingSystem')
| -rw-r--r-- | src/KingSystem/Physics/System/physParamSet.cpp | 145 | ||||
| -rw-r--r-- | src/KingSystem/Physics/System/physParamSet.h | 19 | ||||
| -rw-r--r-- | src/KingSystem/Resource/resResourcePhysics.cpp | 14 | ||||
| -rw-r--r-- | src/KingSystem/Resource/resResourcePhysics.h | 13 |
4 files changed, 189 insertions, 2 deletions
diff --git a/src/KingSystem/Physics/System/physParamSet.cpp b/src/KingSystem/Physics/System/physParamSet.cpp index 3155a3eb..3af09949 100644 --- a/src/KingSystem/Physics/System/physParamSet.cpp +++ b/src/KingSystem/Physics/System/physParamSet.cpp @@ -1 +1,146 @@ #include "KingSystem/Physics/System/physParamSet.h" +#include "KingSystem/Physics/Cloth/physClothParam.h" +#include "KingSystem/Physics/Ragdoll/physRagdollParam.h" +#include "KingSystem/Physics/RigidBody/physEdgeRigidBodyParam.h" +#include "KingSystem/Physics/RigidBody/physRigidBodyParam.h" +#include "KingSystem/Physics/RigidBody/physRigidBodySetParam.h" +#include "KingSystem/Physics/SupportBone/physSupportBoneParam.h" +#include "KingSystem/Physics/System/physCharacterControllerParam.h" +#include "KingSystem/Physics/System/physContactInfoParam.h" +#include "KingSystem/Resource/resResourcePhysics.h" + +namespace ksys::phys { + +ParamSet::ParamSet() + : use_rigid_body_set_num(0, "use_rigid_body_set_num", &obj), + use_character_controller(false, "use_character_controller", &obj), + use_ragdoll(false, "use_ragdoll", &obj), use_support_bone(false, "use_support_bone", &obj), + use_cloth(false, "use_cloth", &obj), use_contact_info(false, "use_contact_info", &obj), + use_system_group_handler(true, "use_system_group_handler", &obj), + use_edge_rigid_body_num(false, "use_edge_rigid_body_num", &obj) {} + +ParamSet::~ParamSet() { + finalize(); +} + +bool ParamSet::parse(res::Physics* bphysics, agl::utl::ResParameterArchive archive, + sead::Heap* heap) { + if (!archive.isValid()) + return false; + + if (!doParse(bphysics, archive, heap)) { + finalize(); + return false; + } + + return true; +} + +template <typename T> +static void safeDelete(T*& ptr) { + if (!ptr) + return; + delete ptr; + ptr = nullptr; +} + +void ParamSet::finalize() { + rigid_body_sets.freeBuffer(); + safeDelete(character_controller); + safeDelete(contact_info); + safeDelete(cloth_set); + safeDelete(ragdoll); + safeDelete(support_bone); + safeDelete(edge_rigid_body_set); + *use_rigid_body_set_num = 0; + *use_ragdoll = false; + *use_cloth = false; + *use_support_bone = false; + *use_edge_rigid_body_num = 0; +} + +bool ParamSet::doParse(res::Physics* bphysics, agl::utl::ResParameterArchive archive, + sead::Heap* heap) { + const auto ParamSet = archive.getRootList().getResParameterList(0); + if (ParamSet.getResParameterObjNum() < 1) + return false; + + const auto header_obj = ParamSet.getResParameterObj(0); + obj.applyResParameterObj(header_obj); + + const int num_rigid_body_sets = *use_rigid_body_set_num; + if (num_rigid_body_sets > 0) { + rigid_body_sets.allocBufferAssert(num_rigid_body_sets, heap); + + const auto RigidBodySet = agl::utl::getResParameterList(ParamSet, "RigidBodySet"); + if (!RigidBodySet) + return false; + + for (auto it = RigidBodySet.listBegin(), end = RigidBodySet.listEnd(); it != end; ++it) { + if (!rigid_body_sets[it.getIndex()].parse(it.getList(), heap)) + return false; + } + } + + if (*use_character_controller) { + character_controller = new (heap) CharacterControllerParam; + if (!character_controller->parse( + agl::utl::getResParameterList(ParamSet, "CharacterController"), heap)) { + return false; + } + } + + if (*use_contact_info) { + contact_info = new (heap) ContactInfoParam; + if (!contact_info->parse(agl::utl::getResParameterList(ParamSet, "RigidContactInfo"), heap)) + return false; + } + + if (*use_support_bone) { + support_bone = new (heap) SupportBoneParam; + addObj(support_bone, "SupportBone"); + } + + if (*use_ragdoll) { + ragdoll = new (heap) RagdollParam; + addObj(ragdoll, "Ragdoll"); + } + + if (*use_cloth) { + cloth_set = new (heap) ClothSetParam; + const auto list = agl::utl::getResParameterList(ParamSet, "Cloth"); + if (list) { + addList(cloth_set, "Cloth"); + if (!cloth_set->parse(list, heap)) + return false; + } + } + + if (*use_edge_rigid_body_num > 0) { + edge_rigid_body_set = new (heap) EdgeRigidBodySetParam; + edge_rigid_body_set->parse(*use_edge_rigid_body_num, heap); + addList(edge_rigid_body_set, "EdgeRigidBody"); + } + + applyResParameterList(ParamSet); + + num_rigid_bodies_with_link_matrix = 0; + for (int set_idx = 0; set_idx < num_rigid_body_sets; ++set_idx) { + auto& set = rigid_body_sets[set_idx]; + + const int num_rigid_bodies = set.getNumRigidBodies(); + for (int body_idx = 0; body_idx < num_rigid_bodies; ++body_idx) { + if (!set.rigid_bodies[body_idx].info.link_matrix->isEmpty()) + ++num_rigid_bodies_with_link_matrix; + } + } + + bphysics->addList(this, "ParamSet"); + return true; +} + +RigidBodySetParam& ParamSet::getRigidBodySet(int idx) { + return rigid_body_sets[idx]; +} + +} // namespace ksys::phys diff --git a/src/KingSystem/Physics/System/physParamSet.h b/src/KingSystem/Physics/System/physParamSet.h index b0f791a6..450a1cb1 100644 --- a/src/KingSystem/Physics/System/physParamSet.h +++ b/src/KingSystem/Physics/System/physParamSet.h @@ -5,6 +5,10 @@ #include <agl/Utils/aglParameterObj.h> #include <container/seadBuffer.h> +namespace ksys::res { +class Physics; +} + namespace ksys::phys { struct RigidBodySetParam; @@ -16,13 +20,22 @@ struct ContactInfoParam; struct EdgeRigidBodySetParam; struct ParamSet : public agl::utl::ParameterList { + ParamSet(); + ~ParamSet() override; + ParamSet(const ParamSet&) = delete; + auto operator=(const ParamSet&) = delete; + + bool parse(res::Physics* bphysics, agl::utl::ResParameterArchive archive, sead::Heap* heap); + + RigidBodySetParam& getRigidBodySet(int idx); + sead::Buffer<RigidBodySetParam> rigid_body_sets{}; CharacterControllerParam* character_controller{}; ClothSetParam* cloth_set{}; RagdollParam* ragdoll{}; SupportBoneParam* support_bone{}; ContactInfoParam* contact_info{}; - EdgeRigidBodySetParam* edge_rigid_body_sets{}; + EdgeRigidBodySetParam* edge_rigid_body_set{}; agl::utl::ParameterObj obj; agl::utl::Parameter<int> use_rigid_body_set_num; @@ -34,6 +47,10 @@ struct ParamSet : public agl::utl::ParameterList { agl::utl::Parameter<bool> use_system_group_handler; agl::utl::Parameter<int> use_edge_rigid_body_num; int num_rigid_bodies_with_link_matrix = 0; + +private: + void finalize(); + bool doParse(res::Physics* bphysics, agl::utl::ResParameterArchive archive, sead::Heap* heap); }; } // namespace ksys::phys diff --git a/src/KingSystem/Resource/resResourcePhysics.cpp b/src/KingSystem/Resource/resResourcePhysics.cpp index 89054e81..88591fb9 100644 --- a/src/KingSystem/Resource/resResourcePhysics.cpp +++ b/src/KingSystem/Resource/resResourcePhysics.cpp @@ -1 +1,15 @@ #include "KingSystem/Resource/resResourcePhysics.h" + +namespace ksys::res { + +void Physics::doCreate_(u8* buffer, u32 buffer_size, sead::Heap* heap) {} + +bool Physics::parse_(u8* data, size_t size, sead::Heap* heap) { + if (!data) + return true; + + mParamSet.parse(this, agl::utl::ResParameterArchive{data}, heap); + return true; +} + +} // namespace ksys::res diff --git a/src/KingSystem/Resource/resResourcePhysics.h b/src/KingSystem/Resource/resResourcePhysics.h index fb95e0c1..5eef2cfd 100644 --- a/src/KingSystem/Resource/resResourcePhysics.h +++ b/src/KingSystem/Resource/resResourcePhysics.h @@ -1,13 +1,24 @@ #pragma once +#include "KingSystem/Physics/System/physParamSet.h" #include "KingSystem/Resource/resResource.h" #include "KingSystem/Utils/ParamIO.h" namespace ksys::res { -// TODO class Physics : public ParamIO, public Resource { SEAD_RTTI_OVERRIDE(Physics, Resource) +public: + Physics() : ParamIO("physics", 0) {} + + phys::ParamSet& getParamSet() { return mParamSet; } + + void doCreate_(u8* buffer, u32 buffer_size, sead::Heap* heap) override; + bool parse_(u8* data, size_t size, sead::Heap* heap) override; + bool needsParse() const override { return true; } + +private: + phys::ParamSet mParamSet; }; } // namespace ksys::res |
