diff options
Diffstat (limited to 'src/KingSystem/Physics/System/physStaticCompoundInfo.cpp')
| -rw-r--r-- | src/KingSystem/Physics/System/physStaticCompoundInfo.cpp | 161 |
1 files changed, 161 insertions, 0 deletions
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 <Havok/Common/Base/Reflection/hkClass.h> +#include <Havok/Common/Base/Reflection/hkClassMember.h> +#include <Havok/Common/Base/Reflection/hkTypeInfo.h> +#include <array> + +#define DEFINE_TYPE_INFO(TYPE) \ + static void cleanupLoadedObject##TYPE(void* p) { \ + static_cast<TYPE*>(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<BodyLayerType>(i); + if (int(getContactLayerForBodyLayerType(type)) == int(layer)) + return type; + } + return BodyLayerType::Invalid; +} + +} // namespace ksys::phys |
