#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