#pragma once #include #include #include #include #include #include "KingSystem/Physics/RigidBody/Shape/physShape.h" #include "KingSystem/Physics/physDefines.h" #include "KingSystem/Utils/Types.h" namespace ksys::phys { struct ShapeParamObj; class SystemGroupHandler; class RigidBody; // 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 RigidBodyInstanceParam { SEAD_RTTI_BASE(RigidBodyInstanceParam) public: RigidBodyInstanceParam() = default; explicit RigidBodyInstanceParam(ShapeType type) : shape_type(type) {} const char* name = "no name"; ShapeType shape_type = ShapeType::Unknown; MotionType motion_type = MotionType::Dynamic; float mass = 1.0f; sead::Vector3f inertia = sead::Vector3f::ones; sead::Vector3f center_of_mass = sead::Vector3f::zero; float linear_damping = 0.0f; float angular_damping = 0.05f; f32 gravity_factor = 1.0f; f32 time_factor = 1.0f; float max_linear_velocity = 200.0f; float max_angular_velocity_rad = 200.0f; float max_impulse = -1.0f; float col_impulse_scale = 1.0f; float friction_scale = 1.0f; float restitution_scale = 1.0f; float water_buoyancy_scale = 1.0f; float water_flow_effective_rate = 1.0f; float magne_mass_scaling_factor = 1.0f; bool enable_deactivation = true; bool toi = false; bool always_character_mass_scaling = false; SystemGroupHandler* system_group_handler = nullptr; ContactLayer contact_layer = ContactLayer::EntityObject; GroundHit groundhit = GroundHit::HitAll; u32 groundhit_mask = 0; u32 contact_mask = 0; SensorCollisionMask receiver_mask{SensorCollisionMask::CustomReceiverTag{}}; bool ignore_normal_for_impulse = false; bool no_hit_ground = false; bool no_hit_water = false; bool no_char_standing_on = false; bool _90 = false; bool isDynamicSensor() const { return getContactLayerType(contact_layer) == ContactLayerType::Sensor && motion_type == MotionType::Dynamic; } }; KSYS_CHECK_SIZE_NX150(RigidBodyInstanceParam, 0x98); 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_mask = 0; protected: void postRead_() override; }; enum class CreateFixedBoxWithNoCollision : bool { Yes = true, No = false, }; RigidBodyParam(); ~RigidBodyParam() override; RigidBodyParam(const RigidBodyParam&) = delete; auto operator=(const RigidBodyParam&) = delete; bool parse(const agl::utl::ResParameterList& res_list, sead::Heap* heap); void makeInstanceParam(RigidBodyInstanceParam* param) const; RigidBody* createRigidBody( SystemGroupHandler* group_handler, sead::Heap* heap, CreateFixedBoxWithNoCollision no_collision = CreateFixedBoxWithNoCollision::No) const; /// @param linked_body Must be a RigidBodyFromShape. RigidBody* createEntityShapeBody(RigidBody* linked_body, SystemGroupHandler* group_handler, sead::Heap* heap) const; ContactLayer getContactLayer() const; GroundHit getGroundHit() const; MotionType getMotionType() const; ShapeType getShapeType() const; Info info; sead::Buffer shapes; }; } // namespace ksys::phys