summaryrefslogtreecommitdiff
path: root/src/KingSystem
diff options
context:
space:
mode:
authorLéo Lam <leo@leolam.fr>2021-04-22 19:03:46 +0200
committerLéo Lam <leo@leolam.fr>2021-04-22 19:37:58 +0200
commit136f20427d6b346da488ec84f39b5c6aeaffd24e (patch)
treea8f5740cbc11c50dfd16a505b1f565997ae62267 /src/KingSystem
parentf6e4643808bdec31d2e2bf1b3d3a0ce0b456e348 (diff)
ksys/phys: Implement ParamSet and res::Physics
Diffstat (limited to 'src/KingSystem')
-rw-r--r--src/KingSystem/Physics/System/physParamSet.cpp145
-rw-r--r--src/KingSystem/Physics/System/physParamSet.h19
-rw-r--r--src/KingSystem/Resource/resResourcePhysics.cpp14
-rw-r--r--src/KingSystem/Resource/resResourcePhysics.h13
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