diff --git a/lib/hkStubs/CMakeLists.txt b/lib/hkStubs/CMakeLists.txt index 19003e72..32952a7e 100644 --- a/lib/hkStubs/CMakeLists.txt +++ b/lib/hkStubs/CMakeLists.txt @@ -17,6 +17,7 @@ add_library(hkStubs OBJECT Havok/Common/Base/Memory/Allocator/hkMemoryAllocator.h Havok/Common/Base/Memory/Allocator/Lifo/hkLifoAllocator.h Havok/Common/Base/Memory/Router/hkMemoryRouter.h + Havok/Common/Base/Memory/Util/hkMemUtil.h Havok/Common/Base/Object/hkBaseObject.h Havok/Common/Base/Object/hkReferencedObject.cpp @@ -73,6 +74,7 @@ add_library(hkStubs OBJECT Havok/Physics2012/Dynamics/Entity/hkpEntity.h Havok/Physics2012/Dynamics/Entity/hkpRigidBody.h + Havok/Physics2012/Dynamics/World/hkpPhysicsSystem.h Havok/Physics2012/Dynamics/World/hkpWorld.cpp Havok/Physics2012/Dynamics/World/hkpWorld.h Havok/Physics2012/Dynamics/World/hkpWorldCinfo.cpp @@ -81,6 +83,8 @@ add_library(hkStubs OBJECT Havok/Physics2012/Dynamics/World/hkpWorldObject.h Havok/Physics2012/Dynamics/World/Memory/hkpWorldMemoryAvailableWatchDog.h Havok/Physics2012/Dynamics/World/Memory/Default/hkpDefaultWorldMemoryWatchDog.h + + Havok/Physics2012/Utilities/Serialize/hkpPhysicsData.h ) target_compile_options(hkStubs PRIVATE -fno-exceptions) diff --git a/lib/hkStubs/Havok/Common/Base/Container/Array/hkArray.h b/lib/hkStubs/Havok/Common/Base/Container/Array/hkArray.h index c80c5f74..1db2335e 100644 --- a/lib/hkStubs/Havok/Common/Base/Container/Array/hkArray.h +++ b/lib/hkStubs/Havok/Common/Base/Container/Array/hkArray.h @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -188,6 +189,27 @@ inline void hkArrayBase::_clearAndDeallocate(hkMemoryAllocator& allocator) { m_capacityAndFlags = DONT_DEALLOCATE_FLAG; } +template +inline void hkArrayBase::removeAt(int index) { + hkArrayUtil::destruct(&m_data[index], 1); + m_size--; + if (m_size != index) + hkMemUtil::memCpyOneAligned(m_data + index, m_data + m_size); +} + +template +inline void hkArrayBase::removeAtAndCopy(int index) { + removeAtAndCopy(index, 1); +} + +template +inline void hkArrayBase::removeAtAndCopy(int index, int numToRemove) { + hkArrayUtil::destruct(m_data + index, numToRemove); + m_size -= numToRemove; + hkMemUtil::memCpy(m_data + index, m_data + index + numToRemove, + (m_size - index) * sizeof(T)); +} + template inline void hkArrayBase::popBack(int numElemsToRemove) { hkArrayUtil::destruct(m_data + m_size - numElemsToRemove, numElemsToRemove); diff --git a/lib/hkStubs/Havok/Common/Base/Container/String/hkStringPtr.h b/lib/hkStubs/Havok/Common/Base/Container/String/hkStringPtr.h index b6a1eddd..35fabb72 100644 --- a/lib/hkStubs/Havok/Common/Base/Container/String/hkStringPtr.h +++ b/lib/hkStubs/Havok/Common/Base/Container/String/hkStringPtr.h @@ -11,6 +11,7 @@ public: }; hkStringPtr(); + explicit hkStringPtr(hkFinishLoadedObjectFlag f); inline const char* cString() const; inline operator const char*() const; diff --git a/lib/hkStubs/Havok/Common/Base/Memory/Util/hkMemUtil.h b/lib/hkStubs/Havok/Common/Base/Memory/Util/hkMemUtil.h new file mode 100644 index 00000000..e59d326b --- /dev/null +++ b/lib/hkStubs/Havok/Common/Base/Memory/Util/hkMemUtil.h @@ -0,0 +1,61 @@ +#pragma once + +#include + +namespace hkMemUtil { + +template +struct TypeFromAlign; + +template <> +struct TypeFromAlign<1> { + using type = char; +}; + +template <> +struct TypeFromAlign<2> { + using type = hkInt16; +}; + +template <> +struct TypeFromAlign<4> { + using type = hkInt32; +}; + +template <> +struct TypeFromAlign<8> { + using type = hkInt64; +}; + +template +struct TypeFromAlign : public TypeFromAlign {}; + +template +HK_FORCE_INLINE void memCpyOneAligned(void* dst, const void* src); + +template +HK_FORCE_INLINE void memCpy(void* dst, const void* src, int nbytes); + +void memCpy(void* dst, const void* src, int nbytes); +void memCpyBackwards(void* dst, const void* src, int nbytes); +void memMove(void* dst, const void* src, int nbytes); +void memSet(void* dst, int c, int n); + +template +inline void memCpyOneAligned(void* dst, const void* src) { + using CopyType = typename TypeFromAlign::type; + unsigned int i = 0; + do { + static_cast(dst)[i] = static_cast(src)[i]; + } while (++i < ELEMENTSIZE / sizeof(CopyType)); +} + +template +inline void memCpy(void* dst, const void* src, int nbytes) { + using CopyType = typename TypeFromAlign::type; + for (int i = 0, j = 0; i < nbytes; i += sizeof(CopyType), ++j) { + static_cast(dst)[j] = static_cast(src)[j]; + } +} + +} // namespace hkMemUtil diff --git a/lib/hkStubs/Havok/Physics2012/Dynamics/World/hkpPhysicsSystem.h b/lib/hkStubs/Havok/Physics2012/Dynamics/World/hkpPhysicsSystem.h new file mode 100644 index 00000000..51c04d31 --- /dev/null +++ b/lib/hkStubs/Havok/Physics2012/Dynamics/World/hkpPhysicsSystem.h @@ -0,0 +1,115 @@ +#pragma once + +#include + +class hkTransform; +class hkpRigidBody; +class hkpConstraintInstance; +class hkpAction; +class hkpPhantom; + +class hkpPhysicsSystem : public hkReferencedObject { +public: + HK_DECLARE_CLASS_ALLOCATOR(hkpPhysicsSystem) + HK_DECLARE_REFLECTION() + + hkpPhysicsSystem(); + + explicit hkpPhysicsSystem(hkFinishLoadedObjectFlag f) + : hkReferencedObject(f), m_rigidBodies(f), m_constraints(f), m_actions(f), m_phantoms(f), + m_name(f) {} + + ~hkpPhysicsSystem() override; + + enum CloneConstraintMode { + CLONE_SHALLOW_IF_NOT_CONSTRAINED_TO_WORLD = 0, + CLONE_DEEP_WITH_MOTORS = 1, + CLONE_FORCE_SHALLOW = 2, + CLONE_DEFAULT = 0, + }; + + virtual hkpPhysicsSystem* clone(CloneConstraintMode cloneMode = CLONE_DEFAULT) const; + + void removeAll(); + + void copy(const hkpPhysicsSystem& toCopy); + + void addRigidBody(hkpRigidBody* rb); + void addPhantom(hkpPhantom* p); + void addConstraint(hkpConstraintInstance* c); + void addAction(hkpAction* a); + + void removeRigidBody(int i); + void removePhantom(int i); + void removeConstraint(int i); + void removeAction(int i); + + void removeNullPhantoms(); + + inline const hkArray& getRigidBodies() const; + inline const hkArray& getPhantoms() const; + inline const hkArray& getConstraints() const; + inline const hkArray& getActions() const; + + inline const char* getName() const; + inline void setName(const char* name); + + inline hkUlong getUserData() const; + inline void setUserData(hkUlong d); + + inline hkBool isActive() const; + inline void setActive(hkBool active); + + virtual hkBool hasContacts() { return false; } + + void transform(const hkTransform& transformation); + +protected: + hkArray m_rigidBodies; + hkArray m_constraints; + hkArray m_actions; + hkArray m_phantoms; + hkStringPtr m_name; + hkUlong m_userData; + hkBool m_active; +}; + +inline const hkArray& hkpPhysicsSystem::getRigidBodies() const { + return m_rigidBodies; +} + +inline const hkArray& hkpPhysicsSystem::getPhantoms() const { + return m_phantoms; +} + +inline const hkArray& hkpPhysicsSystem::getConstraints() const { + return m_constraints; +} + +inline const hkArray& hkpPhysicsSystem::getActions() const { + return m_actions; +} + +inline const char* hkpPhysicsSystem::getName() const { + return m_name; +} + +inline void hkpPhysicsSystem::setName(const char* name) { + m_name = name; +} + +inline hkUlong hkpPhysicsSystem::getUserData() const { + return m_userData; +} + +inline void hkpPhysicsSystem::setUserData(hkUlong d) { + m_userData = d; +} + +inline hkBool hkpPhysicsSystem::isActive() const { + return m_active; +} + +inline void hkpPhysicsSystem::setActive(hkBool active) { + m_active = active; +} diff --git a/lib/hkStubs/Havok/Physics2012/Utilities/Serialize/hkpPhysicsData.h b/lib/hkStubs/Havok/Physics2012/Utilities/Serialize/hkpPhysicsData.h new file mode 100644 index 00000000..4a29df4b --- /dev/null +++ b/lib/hkStubs/Havok/Physics2012/Utilities/Serialize/hkpPhysicsData.h @@ -0,0 +1,78 @@ +#pragma once + +#include +#include +#include + +class hkpRigidBody; +class hkpWorld; + +class hkpPhysicsData : public hkReferencedObject { +public: + HK_DECLARE_CLASS_ALLOCATOR(hkpPhysicsData) + HK_DECLARE_REFLECTION() + + hkpPhysicsData(); + explicit hkpPhysicsData(hkFinishLoadedObjectFlag f) : hkReferencedObject(f), m_systems(f) {} + + ~hkpPhysicsData() override; + + inline hkpWorldCinfo* getWorldCinfo(); + inline void setWorldCinfo(hkpWorldCinfo* info); + + inline void addPhysicsSystem(hkpPhysicsSystem* system); + inline void removePhysicsSystem(int i); + inline const hkArray& getPhysicsSystems() const; + + hkpPhysicsSystem* findPhysicsSystemByName(const char* name) const; + /// Look for a rigid body by name (case insensitive) + hkpRigidBody* findRigidBodyByName(const char* name) const; + + void populateFromWorld(const hkpWorld* world, bool saveContactPoints = false); + + hkpWorld* createWorld(hkBool registerAllAgents = true); + + struct SplitPhysicsSystemsOutput { + HK_DECLARE_CLASS_ALLOCATOR(hkpPhysicsData::SplitPhysicsSystemsOutput) + + hkpPhysicsSystem* m_unconstrainedFixedBodies; + hkpPhysicsSystem* m_unconstrainedKeyframedBodies; + hkpPhysicsSystem* m_unconstrainedMovingBodies; + hkpPhysicsSystem* m_phantoms; + hkArray m_constrainedSystems; + }; + + static void splitPhysicsSystems(const hkpPhysicsSystem* inputSystemConst, + SplitPhysicsSystemsOutput& output); + +protected: + hkpWorldCinfo* m_worldCinfo; + hkArray m_systems; +}; + +inline hkpWorldCinfo* hkpPhysicsData::getWorldCinfo() { + return m_worldCinfo; +} + +inline void hkpPhysicsData::setWorldCinfo(hkpWorldCinfo* info) { + if (info != nullptr) + info->addReference(); + if (m_worldCinfo != nullptr) + m_worldCinfo->removeReference(); + + m_worldCinfo = info; +} + +inline void hkpPhysicsData::addPhysicsSystem(hkpPhysicsSystem* system) { + system->addReference(); + m_systems.pushBack(system); +} + +inline void hkpPhysicsData::removePhysicsSystem(int i) { + m_systems[i]->removeReference(); + m_systems.removeAt(i); +} + +inline const hkArray& hkpPhysicsData::getPhysicsSystems() const { + return m_systems; +}