From 89322a8d0cb0c1aaab509ab653a9368a2ae5dea9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Mon, 28 Sep 2026 03:39:31 +0200 Subject: ksys/phys: rearrange the folder layout to match link order A folder's files are linked before its subfolders, and the rigid body files are linked as one flat sequence. ListShape is the one file that does not fit this order. | Old | New | |---|---| | RigidBody/Shape//physShape.cpp | RigidBody/Shape/physShape.cpp | | RigidBody/Shape//physRigidBody.cpp | RigidBody/physRigidBody.cpp | | RigidBody/Shape/List/physListShapeRigidBody.cpp | RigidBody/physRigidBodyListShape.cpp | | physHavokMemoryAllocator.cpp | System/physHavokMemoryAllocator.cpp | | StaticCompound/physStaticCompound{,Mgr,RigidBodyGroup,Util}.cpp | System/ | | StaticCompound/physStaticCompound{Info,Autogen}.cpp | System/physStaticCompoundInfo.cpp | The original has the type infos' cleanup functions just before StaticCompoundInfo's functions, so the merged file defines the reflection data first, with plain static cleanup functions as in Havok's generated reflection code. Template instantiations would be emitted after the rest of the file. (AI assisted using Claude Fable 5.1 and Claude Opus 5.5) --- .../Physics/System/physStaticCompoundInfo.cpp | 161 +++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 src/KingSystem/Physics/System/physStaticCompoundInfo.cpp (limited to 'src/KingSystem/Physics/System/physStaticCompoundInfo.cpp') diff --git a/src/KingSystem/Physics/System/physStaticCompoundInfo.cpp b/src/KingSystem/Physics/System/physStaticCompoundInfo.cpp new file mode 100644 index 00000000..920255be --- /dev/null +++ b/src/KingSystem/Physics/System/physStaticCompoundInfo.cpp @@ -0,0 +1,161 @@ +#include "KingSystem/Physics/System/physStaticCompoundInfo.h" +#include +#include +#include +#include + +#define DEFINE_TYPE_INFO(TYPE) \ + static void cleanupLoadedObject##TYPE(void* p) { \ + static_cast(p)->~TYPE(); \ + } \ + const hkTypeInfo TYPE##_TypeInfo(#TYPE, "!" #TYPE, nullptr, cleanupLoadedObject##TYPE, \ + nullptr, sizeof(TYPE)) + +namespace ksys::phys { + +// Reflection data is normally autogenerated with a Havok script and type parser, +// but considering we only have 3 classes it's easier to just write the data manually. + +// ShapeInfo + +static constexpr hkClassMember ShapeInfo_Members[] = { + {"ActorInfoIndex", nullptr, nullptr, hkClassMember::Type::TYPE_INT32, + hkClassMember::Type::TYPE_VOID, 0, 0, 0, nullptr}, + {"InstanceId", nullptr, nullptr, hkClassMember::Type::TYPE_INT32, + hkClassMember::Type::TYPE_VOID, 0, 0, 4, nullptr}, + {"BodyGroup", nullptr, nullptr, hkClassMember::Type::TYPE_INT8, hkClassMember::Type::TYPE_VOID, + 0, 0, 8, nullptr}, + {"BodyLayerType", nullptr, nullptr, hkClassMember::Type::TYPE_UINT8, + hkClassMember::Type::TYPE_VOID, 0, 0, 9, nullptr}, +}; + +const hkClass ShapeInfo_Class{ + "ShapeInfo", + nullptr, + sizeof(ShapeInfo), + nullptr, + 0, + nullptr, + 0, + ShapeInfo_Members, + std::size(ShapeInfo_Members), +}; + +const hkClass& ShapeInfo::staticClass() { + return ShapeInfo_Class; +} + +DEFINE_TYPE_INFO(ShapeInfo); + +// ActorInfo + +static constexpr hkClassMember ActorInfo_Members[] = { + {"HashId", nullptr, nullptr, hkClassMember::Type::TYPE_UINT32, hkClassMember::Type::TYPE_VOID, + 0, 0, 0, nullptr}, + {"SRTHash", nullptr, nullptr, hkClassMember::Type::TYPE_INT32, hkClassMember::Type::TYPE_VOID, + 0, 0, 4, nullptr}, + {"ShapeInfoStart", nullptr, nullptr, hkClassMember::Type::TYPE_INT32, + hkClassMember::Type::TYPE_VOID, 0, 0, 8, nullptr}, + {"ShapeInfoEnd", nullptr, nullptr, hkClassMember::Type::TYPE_INT32, + hkClassMember::Type::TYPE_VOID, 0, 0, 0xc, nullptr}, +}; + +const hkClass ActorInfo_Class{ + "ActorInfo", + nullptr, + sizeof(ActorInfo), + nullptr, + 0, + nullptr, + 0, + ActorInfo_Members, + std::size(ActorInfo_Members), +}; + +const hkClass& ActorInfo::staticClass() { + return ActorInfo_Class; +} + +DEFINE_TYPE_INFO(ActorInfo); + +// StaticCompoundInfo + +static constexpr hkClassMember StaticCompoundInfo_Members[] = { + {"Offset", nullptr, nullptr, hkClassMember::Type::TYPE_UINT32, hkClassMember::Type::TYPE_VOID, + 0, 0, 0, nullptr}, + {"ActorInfo", &ActorInfo_Class, nullptr, hkClassMember::Type::TYPE_ARRAY, + hkClassMember::Type::TYPE_STRUCT, 0, 0, 8, nullptr}, + {"ShapeInfo", &ShapeInfo_Class, nullptr, hkClassMember::Type::TYPE_ARRAY, + hkClassMember::Type::TYPE_STRUCT, 0, 0, 0x18, nullptr}, +}; + +const hkClass StaticCompoundInfo_Class{ + "StaticCompoundInfo", + nullptr, + sizeof(StaticCompoundInfo), + nullptr, + 0, + nullptr, + 0, + StaticCompoundInfo_Members, + std::size(StaticCompoundInfo_Members), +}; + +const hkClass& StaticCompoundInfo::staticClass() { + return StaticCompoundInfo_Class; +} + +DEFINE_TYPE_INFO(StaticCompoundInfo); + +int StaticCompoundInfo::getActorIdx(u32 hash_id, u32 srt_hash) const { + for (int i = 0; i < m_ActorInfo.getSize(); ++i) { + const auto& info = m_ActorInfo[i]; + if (info.m_HashId == hash_id && u32(info.m_SRTHash) == srt_hash) + return i; + } + return -1; +} + +int StaticCompoundInfo::getShapeInfoStart(int actor_idx) const { + if (actor_idx < 0 || actor_idx >= m_ActorInfo.getSize()) + return -1; + return m_ActorInfo[actor_idx].m_ShapeInfoStart; +} + +int StaticCompoundInfo::getShapeInfoEnd(int actor_idx) const { + if (actor_idx < 0 || actor_idx >= m_ActorInfo.getSize()) + return -1; + return m_ActorInfo[actor_idx].m_ShapeInfoEnd; +} + +const ShapeInfo* StaticCompoundInfo::getShapeInfo(int shape_idx) const { + if (shape_idx < 0 || shape_idx >= m_ShapeInfo.getSize()) + return nullptr; + return &m_ShapeInfo[shape_idx]; +} + +static ContactLayer getContactLayerForBodyLayerType(BodyLayerType type) { + ContactLayer map[NumBodyLayerTypes]; + map[int(BodyLayerType::EntityGround)] = ContactLayer::EntityGround; + map[int(BodyLayerType::EntityGroundSmooth)] = ContactLayer::EntityGroundSmooth; + map[int(BodyLayerType::EntityGroundRough)] = ContactLayer::EntityGroundRough; + map[int(BodyLayerType::EntityObject)] = ContactLayer::EntityObject; + map[int(BodyLayerType::EntityGroundObject)] = ContactLayer::EntityGroundObject; + map[int(BodyLayerType::EntityTree)] = ContactLayer::EntityTree; + map[int(BodyLayerType::SensorInDoor)] = ContactLayer::SensorInDoor; + map[int(BodyLayerType::EntityNoHit)] = ContactLayer::EntityNoHit; + map[int(BodyLayerType::EntityWallForClimb)] = ContactLayer::EntityWallForClimb; + map[int(BodyLayerType::EntityWater)] = ContactLayer::EntityWater; + return map[int(type)]; +} + +BodyLayerType getBodyLayerType(ContactLayer layer) { + for (int i = 0; i < NumBodyLayerTypes; ++i) { + auto type = static_cast(i); + if (int(getContactLayerForBodyLayerType(type)) == int(layer)) + return type; + } + return BodyLayerType::Invalid; +} + +} // namespace ksys::phys -- cgit v1.2.3