diff options
| author | Léo Lam <leo@leolam.fr> | 2021-12-30 00:39:17 +0100 |
|---|---|---|
| committer | Léo Lam <leo@leolam.fr> | 2022-01-03 23:53:40 +0100 |
| commit | eb16cbaf55931853533d4e0ed2c71e643bc54c33 (patch) | |
| tree | 9efe14bece5cd25dd801c79328f41b93002c1966 /src/KingSystem/Physics/System | |
| parent | 75a270118adfc1e4838cd776a8b2adb11dad06f0 (diff) | |
ksys/phys: Add MaterialMask
Diffstat (limited to 'src/KingSystem/Physics/System')
| -rw-r--r-- | src/KingSystem/Physics/System/physDefines.h | 4 | ||||
| -rw-r--r-- | src/KingSystem/Physics/System/physMaterialMask.cpp | 80 | ||||
| -rw-r--r-- | src/KingSystem/Physics/System/physMaterialMask.h | 85 | ||||
| -rw-r--r-- | src/KingSystem/Physics/System/physMemSystem.h | 10 |
4 files changed, 178 insertions, 1 deletions
diff --git a/src/KingSystem/Physics/System/physDefines.h b/src/KingSystem/Physics/System/physDefines.h index 6ea54cda..4c8d045b 100644 --- a/src/KingSystem/Physics/System/physDefines.h +++ b/src/KingSystem/Physics/System/physDefines.h @@ -113,6 +113,10 @@ Misc,\ GrudgeSlow ) +constexpr bool isInvalidMaterial(Material::ValueType mat) { + return mat >= Material::size(); +} + SEAD_ENUM(GroundHit, Player,\ Animal,\ diff --git a/src/KingSystem/Physics/System/physMaterialMask.cpp b/src/KingSystem/Physics/System/physMaterialMask.cpp new file mode 100644 index 00000000..9a2072a6 --- /dev/null +++ b/src/KingSystem/Physics/System/physMaterialMask.cpp @@ -0,0 +1,80 @@ +#include "KingSystem/Physics/System/physMaterialMask.h" +#include "KingSystem/Physics/System/physMaterialTable.h" +#include "KingSystem/Physics/System/physMemSystem.h" + +namespace ksys::phys { + +MaterialMask::MaterialMask() = default; + +MaterialMask::MaterialMask(MaterialMaskData data) : mData(data) {} + +MaterialMask::MaterialMask(Material mat, FloorCode floor, WallCode wall, bool flag) { + mData.material.Init(mat); + mData.floor.Init(floor); + mData.wall.Init(wall); + mData.setFlag(flag); +} + +MaterialMask::MaterialMask(Material mat, const char* submat_name, FloorCode floor, WallCode wall, + bool flag) + : mSubMaterialNameCache(submat_name) { + auto submat_idx = getSubMaterialIdx(mat, submat_name); + if (!MaterialMaskData::isValidSubMaterialIdx(submat_idx)) + submat_idx = 0; + mData.raw = {}; + mData.material.Init(mat); + mData.sub_material.Init(submat_idx); + mData.floor.Init(floor); + mData.wall.Init(wall); + mData.setFlag(flag); +} + +MaterialMask::MaterialMask(Material mat, int submat_idx, FloorCode floor, WallCode wall, bool flag) + : mSubMaterialNameCache(getSubMaterialName(mat, submat_idx).cstr()) { + mData.raw = {}; + mData.material.Init(mat); + mData.sub_material.Init(submat_idx); + mData.floor.Init(floor); + mData.wall.Init(wall); + mData.setFlag(flag); +} + +MaterialMask::~MaterialMask() = default; + +const char* MaterialMask::getMaterialName() const { + const Material material = getMaterial(); + if (isInvalidMaterial(material.value())) + return "Incorrent"; // sic + return materialToText(material); +} + +const char* MaterialMask::getSubMaterialName() const { + if (mSubMaterialNameCache != nullptr) + return mSubMaterialNameCache; + + mSubMaterialNameCache = getSubMaterialName(getMaterial(), getSubMaterialIdx()).cstr(); + return mSubMaterialNameCache; +} + +int MaterialMask::getSubMaterialIdx(Material mat, const sead::SafeString& submat_name) { + return MemSystem::instance()->getMaterialTable()->getSubMaterialIdx(mat, submat_name); +} + +const sead::SafeString& MaterialMask::getSubMaterialName(Material mat, int submat_idx) { + return MemSystem::instance()->getMaterialTable()->getSubMaterial(mat, submat_idx); +} + +int MaterialMask::getNumSubMaterials(Material mat) { + return MemSystem::instance()->getMaterialTable()->getNumSubMaterials(mat); +} + +const sead::SafeString& MaterialMask::getSubMaterialName(int mat, int submat_idx) { + return getSubMaterialName(Material(mat), submat_idx); +} + +void MaterialMask::setMaterial(Material mat) { + mData.material = {}; + mData.material.SetUnsafe(mat); +} + +} // namespace ksys::phys diff --git a/src/KingSystem/Physics/System/physMaterialMask.h b/src/KingSystem/Physics/System/physMaterialMask.h new file mode 100644 index 00000000..de60c316 --- /dev/null +++ b/src/KingSystem/Physics/System/physMaterialMask.h @@ -0,0 +1,85 @@ +#pragma once + +#include <basis/seadTypes.h> +#include <prim/seadSafeString.h> +#include "KingSystem/Physics/System/physDefines.h" +#include "KingSystem/Utils/BitField.h" + +namespace ksys::phys { + +union MaterialMaskData { + constexpr explicit MaterialMaskData(u32 raw_ = 0) : raw(raw_) {} + constexpr MaterialMaskData(const MaterialMaskData&) = default; + constexpr MaterialMaskData& operator=(const MaterialMaskData& other) { + raw = other.raw; + return *this; + } + + static constexpr bool isValidSubMaterialIdx(int idx) { + return u32(idx) < (1 << decltype(sub_material)::NumBits()); + } + + void setFlag(bool b) { + if (!b) + clearFlag(); + else + setFlag(); + } + void setFlag() { flag = 1; } + void clearFlag() { flag = 0; } + + u32 raw; + util::BitField<0, 6, u32> material; + util::BitField<6, 4, int, u32> sub_material; + util::BitField<10, 5, u32> floor; + util::BitField<15, 5, u32> wall; + // TODO: rename + util::BitField<23, 1, u32> flag_23; + // TODO: rename once we figure out what this flag is + util::BitField<31, 1, u32> flag; +}; +static_assert(sizeof(MaterialMaskData) == sizeof(u32)); + +class MaterialMask { +public: + MaterialMask(); + explicit MaterialMask(MaterialMaskData data); + MaterialMask(Material mat, FloorCode floor, WallCode wall, bool flag); + MaterialMask(Material mat, const char* submat_name, FloorCode floor, WallCode wall, bool flag); + MaterialMask(Material mat, int submat_idx, FloorCode floor, WallCode wall, bool flag); + MaterialMask(const MaterialMask& other) : mData(other.mData) {} + + // XXX: this doesn't need to be virtual. + virtual ~MaterialMask(); + + MaterialMask& operator=(const MaterialMask& other) { + mData = other.mData; + mSubMaterialNameCache = nullptr; + return *this; + } + + MaterialMaskData& getData() { return mData; } + const MaterialMaskData& getData() const { return mData; } + u32 getRawData() const { return mData.raw; } + Material getMaterial() const { return Material::ValueType(mData.material.Value()); } + int getSubMaterialIdx() const { return mData.sub_material; } + + const char* getMaterialName() const; + const char* getSubMaterialName() const; + + void setMaterial(Material mat); + void clearSubMaterialNameCache() { mSubMaterialNameCache = nullptr; } + + static int getSubMaterialIdx(Material mat, const sead::SafeString& submat_name); + static const sead::SafeString& getSubMaterialName(Material mat, int submat_idx); + static int getNumSubMaterials(Material mat); + static const sead::SafeString& getSubMaterialName(int mat, int submat_idx); + +private: + MaterialMaskData mData{}; + /// Fetching the name of a sub-material from the MaterialTable is an expensive operation, + /// so it is only done once and the result is cached. + mutable const char* mSubMaterialNameCache{}; +}; + +} // namespace ksys::phys diff --git a/src/KingSystem/Physics/System/physMemSystem.h b/src/KingSystem/Physics/System/physMemSystem.h index 4b2d3dca..cdaaba5e 100644 --- a/src/KingSystem/Physics/System/physMemSystem.h +++ b/src/KingSystem/Physics/System/physMemSystem.h @@ -9,9 +9,11 @@ namespace ksys::phys { class ContactMgr; class GroupFilter; +class MaterialTable; class RigidBody; class RigidContactPoints; class RigidContactPointsEx; +class SystemData; class SystemGroupHandler; // FIXME: obviously incomplete. Also this should be moved to its own header @@ -28,6 +30,8 @@ public: GroupFilter* getGroupFilter(ContactLayerType type) const; ContactMgr* getContactMgr() const { return mContactMgr; } RigidBodyRequestMgr* getRigidBodyRequestMgr() const { return mRigidBodyRequestMgr; } + SystemData* getSystemData() const { return mSystemData; } + MaterialTable* getMaterialTable() const { return mMaterialTable; } RigidContactPoints* allocContactPoints(sead::Heap* heap, int num, const sead::SafeString& name, int a, int b, int c) const; @@ -48,7 +52,11 @@ private: void* _150; void* _158; RigidBodyRequestMgr* mRigidBodyRequestMgr; - u8 _168[0x480 - 0x168]; + void* _168; + void* mRigidBodyDividedMeshShapeMgr; + SystemData* mSystemData; + MaterialTable* mMaterialTable; + u8 _188[0x480 - 0x188]; }; KSYS_CHECK_SIZE_NX150(MemSystem, 0x480); |
