summaryrefslogtreecommitdiff
path: root/src/KingSystem/Physics/System/physStaticCompoundInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/KingSystem/Physics/System/physStaticCompoundInfo.cpp')
-rw-r--r--src/KingSystem/Physics/System/physStaticCompoundInfo.cpp161
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