diff --git a/data/uking_functions.csv b/data/uking_functions.csv index 9565e2f4..13767c74 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -79383,7 +79383,7 @@ 0x0000007100e9419c,_ZN4ksys4phys20contactLayerFromTextERKN4sead14SafeStringBaseIcEE,288,_ZN4ksys4phys20contactLayerFromTextERKN4sead14SafeStringBaseIcEE 0x0000007100e942bc,j_getMaterialType,4,_ZN4ksys4phys14materialToTextENS0_8MaterialE 0x0000007100e942c0,sub_7100E942C0,288,_ZN4ksys4phys16materialFromTextERKN4sead14SafeStringBaseIcEE -0x0000007100e943e0,sub_7100E943E0,288, +0x0000007100e943e0,sub_7100E943E0,288,_ZN4ksys4phys17groundHitFromTextERKN4sead14SafeStringBaseIcEE 0x0000007100e94500,sub_7100E94500,288,_ZN4ksys4phys17floorCodeFromTextERKN4sead14SafeStringBaseIcEE 0x0000007100e94620,sub_7100E94620,288,_ZN4ksys4phys16wallCodeFromTextERKN4sead14SafeStringBaseIcEE 0x0000007100e94740,sub_7100E94740,40, @@ -79394,7 +79394,7 @@ 0x0000007100e94a8c,_ZN4sead15FixedSafeStringILi259EEaSERKNS_14SafeStringBaseIcEE,240,_ZN4sead15FixedSafeStringILi259EEaSERKNS_14SafeStringBaseIcEE 0x0000007100e94b7c,j__ZdlPv_936,4,_ZN4sead19FixedSafeStringBaseIcLi259EED0Ev 0x0000007100e94b80,_ZN4sead19FixedSafeStringBaseIcLi259EEaSERKNS_14SafeStringBaseIcEE,240,_ZN4sead19FixedSafeStringBaseIcLi259EEaSERKNS_14SafeStringBaseIcEE -0x0000007100e94c70,sub_7100E94C70,428, +0x0000007100e94c70,sub_7100E94C70,428,_ZN4ksys4phys9GroundHit5text_Ei 0x0000007100e94e1c,j__ZdlPv_937,4,_ZN4sead15FixedSafeStringILi141EED0Ev 0x0000007100e94e20,_ZN4sead15FixedSafeStringILi141EEaSERKNS_14SafeStringBaseIcEE,240,_ZN4sead15FixedSafeStringILi141EEaSERKNS_14SafeStringBaseIcEE 0x0000007100e94f10,j__ZdlPv_938,4,_ZN4sead19FixedSafeStringBaseIcLi141EED0Ev @@ -83312,20 +83312,20 @@ 0x0000007100f9ecc0,sub_7100F9ECC0,904, 0x0000007100f9f048,sub_7100F9F048,204, 0x0000007100f9f114,sub_7100F9F114,92, -0x0000007100f9f170,sub_7100F9F170,64, -0x0000007100f9f1b0,sub_7100F9F1B0,212, -0x0000007100f9f284,sub_7100F9F284,196, -0x0000007100f9f348,j__ZdlPv_997,4, -0x0000007100f9f34c,sub_7100F9F34C,3092, -0x0000007100f9ff60,sub_7100F9FF60,344, +0x0000007100f9f170,sub_7100F9F170,64,_ZN4ksys4phys14RigidBodyParamC1Ev +0x0000007100f9f1b0,sub_7100F9F1B0,212,_ZN4ksys4phys14RigidBodyParamD1Ev +0x0000007100f9f284,sub_7100F9F284,196,_ZN4ksys4phys14RigidBodyParam4InfoD1Ev +0x0000007100f9f348,j__ZdlPv_997,4,_ZN4ksys4phys14RigidBodyParamD0Ev +0x0000007100f9f34c,sub_7100F9F34C,3092,_ZN4ksys4phys14RigidBodyParam4InfoC1Ev +0x0000007100f9ff60,sub_7100F9FF60,344,_ZN4ksys4phys14RigidBodyParam5parseERKN3agl3utl16ResParameterListEPN4sead4HeapE 0x0000007100fa00b8,sub_7100FA00B8,3684, 0x0000007100fa0f1c,sub_7100FA0F1C,308, 0x0000007100fa1050,sub_7100FA1050,296, -0x0000007100fa1178,sub_7100FA1178,28, -0x0000007100fa1194,sub_7100FA1194,28, -0x0000007100fa11b0,sub_7100FA11B0,8, -0x0000007100fa11b8,sub_7100FA11B8,1324, -0x0000007100fa16e4,j__ZdlPv_998,4, +0x0000007100fa1178,sub_7100FA1178,28,_ZNK4ksys4phys14RigidBodyParam15getContactLayerEv +0x0000007100fa1194,sub_7100FA1194,28,_ZNK4ksys4phys14RigidBodyParam12getGroundHitEv +0x0000007100fa11b0,sub_7100FA11B0,8,_ZNK4ksys4phys14RigidBodyParam13getMotionTypeEv +0x0000007100fa11b8,sub_7100FA11B8,1324,_ZN4ksys4phys14RigidBodyParam4Info9postRead_Ev +0x0000007100fa16e4,j__ZdlPv_998,4,_ZN4ksys4phys14RigidBodyParam4InfoD0Ev 0x0000007100fa16e8,sub_7100FA16E8,4, 0x0000007100fa16ec,sub_7100FA16EC,84, 0x0000007100fa1740,sub_7100FA1740,88, @@ -83791,7 +83791,7 @@ 0x0000007100fb5de4,sub_7100FB5DE4,192, 0x0000007100fb5ea4,sub_7100FB5EA4,16, 0x0000007100fb5eb4,sub_7100FB5EB4,36, -0x0000007100fb5ed8,sub_7100FB5ED8,60, +0x0000007100fb5ed8,sub_7100FB5ED8,60,_ZN4ksys4physL19orGroundHitTypeMaskEjRKN4sead14SafeStringBaseIcEE 0x0000007100fb5f14,sub_7100FB5F14,32, 0x0000007100fb5f34,sub_7100FB5F34,68, 0x0000007100fb5f78,sub_7100FB5F78,36, @@ -84327,7 +84327,7 @@ 0x0000007100fd0690,nullsub_4261,4, 0x0000007100fd0694,j__ZdlPv_1015,4, 0x0000007100fd0698,j__ZdlPv_1016,4, -0x0000007100fd069c,sub_7100FD069C,372, +0x0000007100fd069c,sub_7100FD069C,372,_ZN4ksys4phys18motionTypeFromTextERKN4sead14SafeStringBaseIcEE? 0x0000007100fd0810,sub_7100FD0810,92, 0x0000007100fd086c,sub_7100FD086C,356, 0x0000007100fd09d0,sub_7100FD09D0,76, diff --git a/src/KingSystem/Physics/CMakeLists.txt b/src/KingSystem/Physics/CMakeLists.txt index 969495fe..9ee3d5d6 100644 --- a/src/KingSystem/Physics/CMakeLists.txt +++ b/src/KingSystem/Physics/CMakeLists.txt @@ -7,6 +7,8 @@ target_sources(uking PRIVATE Ragdoll/physRagdollParam.h RigidBody/physEdgeRigidBodyParam.cpp RigidBody/physEdgeRigidBodyParam.h + RigidBody/physRigidBodyParam.cpp + RigidBody/physRigidBodyParam.h SupportBone/physSupportBoneParam.cpp SupportBone/physSupportBoneParam.h System/physCharacterControllerParam.cpp diff --git a/src/KingSystem/Physics/RigidBody/physRigidBodyParam.cpp b/src/KingSystem/Physics/RigidBody/physRigidBodyParam.cpp new file mode 100644 index 00000000..78b63c36 --- /dev/null +++ b/src/KingSystem/Physics/RigidBody/physRigidBodyParam.cpp @@ -0,0 +1,156 @@ +#include "KingSystem/Physics/RigidBody/physRigidBodyParam.h" +#include "KingSystem/Physics/System/physShapeParam.h" + +namespace ksys::phys { + +RigidBodyParam::RigidBodyParam() = default; + +RigidBodyParam::~RigidBodyParam() = default; + +RigidBodyParam::Info::Info() + : rigid_body_name("RigidBody", "rigid_body_name", this), mass(1.0, "mass", this), + volume(0.0, "volume", this), toi(false, "toi", this), + mEnableAutoAddWorld(false, "mEnableAutoAddWorld", this), navmesh("NOT_USE", "navmesh", this), + navmesh_sub_material("Others", "navmesh_sub_material", this), + inertia(sead::Vector3f::ones, "inertia", this), + center_of_mass(sead::Vector3f::zero, "center_of_mass", this), + bounding_center(sead::Vector3f::zero, "bounding_center", this), + bounding_extents(sead::Vector3f::zero, "bounding_extents", this), + contact_point_info(sead::SafeString::cEmptyString, "contact_point_info", this), + collision_info(sead::SafeString::cEmptyString, "collision_info", this), + max_linear_velocity(200.0, "max_linear_velocity", this), + linear_damping(0.0, "linear_damping", this), + max_angular_velocity_rad(200.0, "max_angular_velocity_rad", this), + angular_damping(0.05, "angular_damping", this), max_impulse(-1.0, "max_impulse", this), + col_impulse_scale(1.0, "col_impulse_scale", this), + ignore_normal_for_impulse(false, "ignore_normal_for_impulse", this), + always_character_mass_scaling(false, "always_character_mass_scaling", this), + friction_scale(1.0, "friction_scale", this), + restitution_scale(1.0, "restitution_scale", this), + water_buoyancy_scale(1.0, "water_buoyancy_scale", this), + water_flow_effective_rate(1.0, "water_flow_effective_rate", this), + magne_mass_scaling_factor(1.0, "magne_mass_scaling_factor", this), + motion_type("Fixed", "motion_type", this), + layer(sead::SafeString::cEmptyString, "layer", this), + groundhit(sead::SafeString::cEmptyString, "groundhit", this), + use_ground_hit_type_mask(false, "use_ground_hit_type_mask", this), + ground_hit_type_mask(sead::SafeString::cEmptyString, "ground_hit_type_mask", this), + receiver_type(sead::SafeString::cEmptyString, "receiver_type", this), + no_hit_ground(false, "no_hit_ground", this), no_hit_water(false, "no_hit_water", this), + no_char_standing_on(false, "no_char_standing_on", this), + contact_mask(0, "contact_mask", this), + link_matrix(sead::SafeString::cEmptyString, "link_matrix", this), + link_entity_set(sead::SafeString::cEmptyString, "link_entity_set", this), + link_entity_body(sead::SafeString::cEmptyString, "link_entity_body", this), + use_entity_shape(false, "use_entity_shape", this), shape_num(0, "shape_num", this) {} + +RigidBodyParam::Info::~Info() = default; + +bool RigidBodyParam::parse(const agl::utl::ResParameterList& res_list, sead::Heap* heap) { + if (!res_list) + return false; + + info.applyResParameterObj(res_list.getResParameterObj(0), nullptr); + + const int num_shapes = info.shape_num.ref(); + if (num_shapes < 1) + return true; + + shapes.allocBufferAssert(num_shapes, heap); + for (int i = 0; i < num_shapes; ++i) { + if (!shapes[i].parse(res_list.getResParameterObj(i + 1), heap)) + return false; + } + + return true; +} + +ContactLayer RigidBodyParam::getContactLayer() const { + return contactLayerFromText(*info.layer); +} + +GroundHit RigidBodyParam::getGroundHit() const { + return groundHitFromText(*info.groundhit); +} + +MotionType RigidBodyParam::getMotionType() const { + return motionTypeFromText(*info.motion_type); +} + +// TODO: move this to another translation unit (figure out where this belongs) +[[gnu::noinline]] static u32 orGroundHitTypeMask(u32 mask, const sead::SafeString& type) { + mask |= (0x100 << groundHitFromText(type)) & 0xffff00; + return mask; +} + +namespace { +constexpr const char* navmesh_types[] = { + "NOT_USE", + "STATIC_CUTTING", + "STATIC_WALKABLE_AND_CUTTING", + "STATIC_WALKABLE_AND_CUTTING_CGO", + "STATIC_DEPENDS_ON_WALL_CODE", + "STATIC_ENEMY_ONLY", + "STATIC_NPC_ONLY", + "STATIC_LOW_CEILING", + "STATIC_GIANT_NO_ENTRY_PAINT", + "STATIC_CUTTING_CARVER", + "STATIC_AIR_WALL_FOR_HORSE", + "STATIC_FENCE_FOR_HORSE", + "STATIC_CUTTING_LARGE", + "STATIC_CURSE", + "DYNAMIC_OBSTACLE", + "DYNAMIC_SILHOUETTE_AND_OBSTACLE", + "DYNAMIC_WITHOUT_TOLERANCE", + "MATERIAL_PAINT_AND_OBSTACLE", + "MATERIAL_PAINT", + "MATERIAL_WITHOUT_TOLERANCE", +}; + +struct NavMeshSubMaterialInfo { + sead::SafeString name; + NavMeshSubMaterial value; +}; +} // namespace + +void RigidBodyParam::Info::postRead_() { + for (int i = 0; i < int(std::size(navmesh_types)); ++i) { + if (*navmesh == navmesh_types[i]) { + navmesh_val = NavMeshType(i); + break; + } + } + + navmesh_sub_material_val = NavMeshSubMaterial::None; + const NavMeshSubMaterialInfo sub_material_info[] = { + {"LiftableByEnemy", NavMeshSubMaterial::LiftableByEnemy}, + {"Fire", NavMeshSubMaterial::Fire}, + {"Curse", NavMeshSubMaterial::Curse}, + {"NPCOnly", NavMeshSubMaterial::NPCOnly}, + {"GiantNoEntry", NavMeshSubMaterial::GiantNoEntry}, + {"Pass", NavMeshSubMaterial::Pass}, + }; + for (int i = 0; i < int(std::size(sub_material_info)); ++i) { + if (*navmesh_sub_material == sub_material_info[i].name) { + navmesh_sub_material_val = sub_material_info[i].value; + break; + } + } + + if (*use_ground_hit_type_mask && !ground_hit_type_mask->isEmpty()) { + ground_hit_type_mask_val = 0; + + sead::FixedSafeString<64> type_str; + auto it = ground_hit_type_mask->tokenBegin(","); + const auto end = ground_hit_type_mask->tokenEnd(","); + while (end != it) { + it.getAndForward(&type_str); + if (!type_str.isEmpty()) + ground_hit_type_mask_val = orGroundHitTypeMask(ground_hit_type_mask_val, type_str); + } + } else { + ground_hit_type_mask_val = 0; + } +} + +} // namespace ksys::phys diff --git a/src/KingSystem/Physics/RigidBody/physRigidBodyParam.h b/src/KingSystem/Physics/RigidBody/physRigidBodyParam.h new file mode 100644 index 00000000..4804ecd1 --- /dev/null +++ b/src/KingSystem/Physics/RigidBody/physRigidBodyParam.h @@ -0,0 +1,160 @@ +#pragma once + +#include +#include +#include +#include +#include +#include "KingSystem/Physics/System/physDefines.h" +#include "KingSystem/Utils/Types.h" + +namespace ksys::phys { + +// TODO: maybe move this to NavMesh/? +enum class NavMeshType { + NOT_USE, + STATIC_CUTTING, + STATIC_WALKABLE_AND_CUTTING, + STATIC_WALKABLE_AND_CUTTING_CGO, + STATIC_DEPENDS_ON_WALL_CODE, + STATIC_ENEMY_ONLY, + STATIC_NPC_ONLY, + STATIC_LOW_CEILING, + STATIC_GIANT_NO_ENTRY_PAINT, + STATIC_CUTTING_CARVER, + STATIC_AIR_WALL_FOR_HORSE, + STATIC_FENCE_FOR_HORSE, + STATIC_CUTTING_LARGE, + STATIC_CURSE, + DYNAMIC_OBSTACLE, + DYNAMIC_SILHOUETTE_AND_OBSTACLE, + DYNAMIC_WITHOUT_TOLERANCE, + MATERIAL_PAINT_AND_OBSTACLE, + MATERIAL_PAINT, + MATERIAL_WITHOUT_TOLERANCE, +}; + +enum class NavMeshSubMaterial { + LiftableByEnemy = 0xf, + Fire = 0x10, + Curse = 0x11, + NPCOnly = 0x12, + GiantNoEntry = 0x13, + Pass = 0x14, + None = 0x15, +}; + +struct ShapeParam; + +struct RigidBodyParamView { + SEAD_RTTI_BASE(RigidBodyParamView) +public: + const char* name; + u32 _10; + MotionType motion_type; + float mass; + sead::Vector3f inertia; + sead::Vector3f center_of_mass; + float linear_damping; + float angular_damping; + u8 _3c[8]; + float max_linear_velocity; + float max_angular_velocity_rad; + float max_impulse; + float col_impulse_scale; + float friction_scale; + float restitution_scale; + float water_buoyancy_scale; + float water_flow_effective_rate; + float magne_mass_scaling_factor; + bool gap68; + bool toi; + bool always_character_mass_scaling; + bool gap6B[13]; + ContactLayer contact_layer; + GroundHit groundhit; + u32 info_5e0; + u32 contact_mask; + u32 flags; + bool ignore_normal_for_impulse; + bool no_hit_ground; + bool no_hit_water; + bool no_char_standing_on; +}; +KSYS_CHECK_SIZE_NX150(RigidBodyParamView, 0x90); + +struct RigidBodyParam : agl::utl::ParameterList { + struct Info : agl::utl::ParameterObj { + Info(); + ~Info() override; + + agl::utl::Parameter rigid_body_name; + agl::utl::Parameter mass; + agl::utl::Parameter volume; + agl::utl::Parameter toi; + agl::utl::Parameter mEnableAutoAddWorld; + agl::utl::Parameter navmesh; + agl::utl::Parameter navmesh_sub_material; + agl::utl::Parameter inertia; + agl::utl::Parameter center_of_mass; + agl::utl::Parameter bounding_center; + agl::utl::Parameter bounding_extents; + agl::utl::Parameter contact_point_info; + agl::utl::Parameter collision_info; + agl::utl::Parameter max_linear_velocity; + agl::utl::Parameter linear_damping; + agl::utl::Parameter max_angular_velocity_rad; + agl::utl::Parameter angular_damping; + agl::utl::Parameter max_impulse; + agl::utl::Parameter col_impulse_scale; + agl::utl::Parameter ignore_normal_for_impulse; + agl::utl::Parameter always_character_mass_scaling; + agl::utl::Parameter friction_scale; + agl::utl::Parameter restitution_scale; + agl::utl::Parameter water_buoyancy_scale; + agl::utl::Parameter water_flow_effective_rate; + agl::utl::Parameter magne_mass_scaling_factor; + agl::utl::Parameter motion_type; + agl::utl::Parameter layer; + agl::utl::Parameter groundhit; + agl::utl::Parameter use_ground_hit_type_mask; + agl::utl::Parameter ground_hit_type_mask; + agl::utl::Parameter receiver_type; + agl::utl::Parameter no_hit_ground; + agl::utl::Parameter no_hit_water; + agl::utl::Parameter no_char_standing_on; + agl::utl::Parameter contact_mask; + agl::utl::Parameter link_matrix; + agl::utl::Parameter link_entity_set; + agl::utl::Parameter link_entity_body; + agl::utl::Parameter use_entity_shape; + agl::utl::Parameter shape_num; + NavMeshType navmesh_val = NavMeshType::NOT_USE; + NavMeshSubMaterial navmesh_sub_material_val = NavMeshSubMaterial::None; + u32 ground_hit_type_mask_val = 0; + + protected: + void postRead_() override; + }; + + RigidBodyParam(); + ~RigidBodyParam() override; + RigidBodyParam(const RigidBodyParam&) = delete; + auto operator=(const RigidBodyParam&) = delete; + + bool parse(const agl::utl::ResParameterList& res_list, sead::Heap* heap); + + // TODO: types and names + void* createRigidBody(void* x, sead::Heap* heap, bool y); + bool getParams(RigidBodyParamView* view) const; + void* createEntityShape(void* x, void* y, sead::Heap* heap); + + ContactLayer getContactLayer() const; + GroundHit getGroundHit() const; + MotionType getMotionType() const; + + Info info; + sead::Buffer shapes; +}; + +} // namespace ksys::phys diff --git a/src/KingSystem/Physics/System/physDefines.cpp b/src/KingSystem/Physics/System/physDefines.cpp index 8114dc87..03be03a1 100644 --- a/src/KingSystem/Physics/System/physDefines.cpp +++ b/src/KingSystem/Physics/System/physDefines.cpp @@ -26,6 +26,18 @@ Material materialFromText(const sead::SafeString& text) { return 0; } +const char* groundHitToText(GroundHit hit) { + return hit.text(); +} + +GroundHit groundHitFromText(const sead::SafeString& text) { + for (auto hit : GroundHit()) { + if (text == hit.text()) + return hit; + } + return GroundHit::HitAll; +} + const char* floorCodeToText(FloorCode code) { return code.text(); } @@ -50,4 +62,15 @@ WallCode wallCodeFromText(const sead::SafeString& text) { return 0; } +// NON_MATCHING: duplicated branches? +MotionType motionTypeFromText(const sead::SafeString& text) { + if (text == "Dynamic") + return MotionType::Dynamic; + if (text == "Fixed") + return MotionType::Fixed; + if (text == "Keyframed") + return MotionType::Keyframed; + return MotionType::Unknown; +} + } // namespace ksys::phys diff --git a/src/KingSystem/Physics/System/physDefines.h b/src/KingSystem/Physics/System/physDefines.h index 7baedbee..51fe8bd5 100644 --- a/src/KingSystem/Physics/System/physDefines.h +++ b/src/KingSystem/Physics/System/physDefines.h @@ -103,6 +103,26 @@ Misc,\ GrudgeSlow ) +SEAD_ENUM(GroundHit, +Player,\ +Animal,\ +NPC,\ +Camera,\ +AttackHitPlayer,\ +AttackHitEnemy,\ +Arrow,\ +Bomb,\ +Magnet,\ +CameraBody,\ +IK,\ +Grudge,\ +MovingTrolley,\ +LineOfSight,\ +Giant,\ +HitAll,\ +Ignore +) + SEAD_ENUM(FloorCode, None,\ Return,\ @@ -132,16 +152,28 @@ NoDashUpAndNoClimb,\ IceMakerBlock ) +enum class MotionType { + Dynamic = 0, + Fixed = 1, + Keyframed = 2, + Unknown = 3, +}; + const char* contactLayerToText(ContactLayer layer); ContactLayer contactLayerFromText(const sead::SafeString& text); const char* materialToText(Material material); Material materialFromText(const sead::SafeString& text); +const char* groundHitToText(GroundHit hit); +GroundHit groundHitFromText(const sead::SafeString& text); + const char* floorCodeToText(FloorCode code); FloorCode floorCodeFromText(const sead::SafeString& text); const char* wallCodeToText(WallCode code); WallCode wallCodeFromText(const sead::SafeString& text); +MotionType motionTypeFromText(const sead::SafeString& text); + } // namespace ksys::phys