ksys/phys: Finish StaticCompound

This commit is contained in:
Léo Lam
2022-03-25 19:29:27 +01:00
parent 4b2c55b82b
commit 82a5319200
8 changed files with 182 additions and 44 deletions
+18 -8
View File
@@ -1,9 +1,10 @@
#include "KingSystem/Map/mapPlacementMap.h"
#include <prim/seadScopedLock.h>
#include <thread/seadReadWriteLock.h>
#include "Game/DLC/aocManager.h"
#include "KingSystem/Map/mapObject.h"
#include "KingSystem/Physics/StaticCompound/physStaticCompound.h"
#include "KingSystem/Physics/StaticCompound/physStaticCompoundRigidBodyGroup.h"
#include "KingSystem/Resource/resLoadRequest.h"
namespace ksys::map {
@@ -36,15 +37,15 @@ PlacementMap::PlacementMap() {
PlacementMap::~PlacementMap() {
mRoutes.freeBuffer();
for (auto& r : mRes) {
r.cleanup();
for (auto& resource : mRes) {
resource.cleanup();
}
}
bool PlacementMap::clearStaticCompoundActorId(int idx) {
const auto lock = sead::makeScopedLock(mCs);
const auto& resource = mRes[idx].mRes.getResource();
if (auto* sc = sead::DynamicCast<phys::StaticCompound>(resource)) {
if (sc->calledFromMapDtor()) {
if (sc->isAnyRigidBodyAddedToWorld()) {
return false;
}
mRes[idx].mRes.requestUnload();
@@ -220,7 +221,7 @@ PlacementMap::MapObjStatus PlacementMap::x_2(int hksc_idx) {
auto* resource = handle->getResource();
auto* sc = sead::DynamicCast<phys::StaticCompound>(resource);
sc->sub_7100FCAD0C(mMat);
sc->applyExtraTransforms(mMat);
for (int i = mParsedNumStaticObjs; i <= mNumStaticObjs; i++) {
updateObjectCollisionAndId(hksc_idx, mPa->getStaticObj_0(i));
}
@@ -262,8 +263,8 @@ void PlacementMap::doDisableObjStaticCompound(Object* obj, bool disable) {
int PlacementMap::doSomethingStaticCompound(int hksc_idx) {
auto* resource = mRes[hksc_idx].mRes.getResource();
if (auto* sc = sead::DynamicCast<phys::StaticCompound>(resource)) {
if (!sc->calledFromMapDtor() && !sc->x_3()) {
sc->x_4();
if (!sc->isAnyRigidBodyAddedToWorld() && !sc->isAnyRigidBodyAddedOrBeingAddedToWorld()) {
sc->addToWorld();
}
}
return 1;
@@ -302,7 +303,7 @@ void PlacementMap::cleanupPhysics() {
for (int i = 0; i < 4; i++) {
auto resource = mRes[i].mRes.getResource();
if (auto* sc = sead::DynamicCast<phys::StaticCompound>(resource)) {
sc->cleanUp();
sc->removeFromWorldImmediately();
}
mRes[i].mRes.requestUnload2();
mRes[i].mStatus = HkscRes::Status::_0;
@@ -383,4 +384,13 @@ void PlacementMap::unloadHksc(int hksc_idx) {
mRes[hksc_idx].mRes.requestUnload();
}
void PlacementMap::HkscRes::cleanup() {
auto* r = mRes.getResource();
if (auto sc = sead::DynamicCast<phys::StaticCompound>(r)) {
if (sc->isAnyRigidBodyAddedToWorld()) {
sc->removeFromWorldImmediately();
}
}
}
} // namespace ksys::map
+7 -9
View File
@@ -9,14 +9,19 @@
#include <prim/seadSafeString.h>
#include "KingSystem/Map/mapPlacementActors.h"
#include "KingSystem/Map/mapPlacementMapMgr.h"
#include "KingSystem/Physics/StaticCompound/physStaticCompound.h"
#include "KingSystem/Resource/resHandle.h"
#include "KingSystem/Resource/resResource.h"
#include "KingSystem/System/Patrol.h"
#include "KingSystem/Utils/Types.h"
namespace ksys::phys {
class StaticCompound;
class StaticCompoundRigidBodyGroup;
} // namespace ksys::phys
namespace ksys::map {
class Object;
class PlacementMapMgr;
class PlacementActors;
@@ -35,14 +40,7 @@ class PlacementMap {
HkscRes() = default;
~HkscRes() = default;
void cleanup() {
auto* r = mRes.getResource();
if (auto sc = sead::DynamicCast<phys::StaticCompound>(r)) {
if (sc->calledFromMapDtor()) {
sc->cleanUp();
}
}
}
void cleanup();
res::Handle mRes;
Status mStatus;
@@ -2,10 +2,15 @@
#include <Havok/Common/Serialize/Util/hkNativePackfileUtils.h>
#include <Havok/Common/Serialize/Util/hkRootLevelContainer.h>
#include <Havok/Physics2012/Utilities/Serialize/hkpPhysicsData.h>
#include <heap/seadHeapMgr.h>
#include <prim/seadScopedLock.h>
#include "KingSystem/Physics/StaticCompound/physStaticCompoundInfo.h"
#include "KingSystem/Physics/StaticCompound/physStaticCompoundMgr.h"
#include "KingSystem/Physics/StaticCompound/physStaticCompoundRigidBodyGroup.h"
#include "KingSystem/Physics/System/physSystem.h"
#include "KingSystem/Utils/Debug.h"
#include "KingSystem/Utils/HeapUtil.h"
#include "KingSystem/Utils/SafeDelete.h"
namespace ksys::phys {
@@ -15,7 +20,29 @@ constexpr int NumBodyGroups = 16 + 1;
StaticCompound::StaticCompound() = default;
StaticCompound::~StaticCompound() {
// FIXME
System::instance()->getStaticCompoundMgr()->removeStaticCompound(this);
mFlags.reset(Flag::Initialised);
{
sead::ScopedCurrentHeapSetter heap_setter{mHeap};
mFieldBodyGroups.freeBuffer();
mMapObjects.freeBuffer();
}
if (mContainerBuffer) {
hkNativePackfileUtils::unloadInPlace(mContainerBuffer, mContainerBufferSize);
mContainerBuffer = nullptr;
mContainerBufferSize = 0;
}
if (mBuffer) {
hkNativePackfileUtils::unloadInPlace(mBuffer, mBufferSize);
mBuffer = nullptr;
mBufferSize = 0;
mStaticCompoundInfo = nullptr;
}
util::safeDeleteHeap(mHeap);
}
void StaticCompound::doCreate_(u8* buffer, u32 buffer_size, sead::Heap* parent_heap) {
@@ -62,6 +89,75 @@ void StaticCompound::doCreate_(u8* buffer, u32 buffer_size, sead::Heap* parent_h
mHeap->adjust();
}
bool StaticCompound::finishParsing_() {
mFlags.set(Flag::Initialised);
mMapObjects.fill(nullptr);
for (int i = 0, n = mFieldBodyGroups.size(); i < n; ++i)
mFieldBodyGroups[i].enableAllInstancesAndShapeKeys();
System::instance()->getStaticCompoundMgr()->addStaticCompound(this);
return true;
}
bool StaticCompound::m7_() {
if (isAnyRigidBodyAddedToWorld() || isAnyRigidBodyAddedOrBeingAddedToWorld()) {
removeFromWorld();
// We cannot unload this resource immediately.
return false;
}
System::instance()->getStaticCompoundMgr()->removeStaticCompound(this);
mFlags.reset(Flag::Initialised);
return true;
}
bool StaticCompound::isAnyRigidBodyAddedToWorld() const {
auto lock = sead::makeScopedLock(mCS);
for (int i = 0, n = mFieldBodyGroups.size(); i < n; ++i) {
if (mFieldBodyGroups[i].isAnyRigidBodyAddedToWorld())
return true;
}
return false;
}
bool StaticCompound::isAnyRigidBodyAddedOrBeingAddedToWorld() const {
auto lock = sead::makeScopedLock(mCS);
for (int i = 0, n = mFieldBodyGroups.size(); i < n; ++i) {
if (mFieldBodyGroups[i].isAnyRigidBodyBeingAddedToWorld() ||
mFieldBodyGroups[i].isAnyRigidBodyAddedToWorld()) {
return true;
}
}
return false;
}
void StaticCompound::removeFromWorld() {
auto lock = sead::makeScopedLock(mCS);
for (int i = 0, n = mFieldBodyGroups.size(); i < n; ++i)
mFieldBodyGroups[i].removeFromWorld();
}
void StaticCompound::addToWorld() {
auto lock = sead::makeScopedLock(mCS);
resetExtraTransformsAndApply();
for (int i = 0, n = mFieldBodyGroups.size(); i < n; ++i)
mFieldBodyGroups[i].addToWorld();
}
void StaticCompound::removeFromWorldImmediately() {
auto lock = sead::makeScopedLock(mCS);
for (int i = 0, n = mFieldBodyGroups.size(); i < n; ++i)
mFieldBodyGroups[i].removeFromWorldImmediately();
}
int StaticCompound::setMapObject(u32 hash_id, u32 srt_hash, map::Object* object) {
int idx = mStaticCompoundInfo->getActorIdx(hash_id, srt_hash);
if (idx >= 0 && idx < mMapObjects.size())
@@ -98,6 +194,30 @@ bool StaticCompound::disableCollision(int actor_idx, bool x) {
return true;
}
void StaticCompound::processUpdates() {
for (int i = 0, n = mFieldBodyGroups.size(); i < n; ++i)
mFieldBodyGroups[i].processUpdates();
}
void StaticCompound::recomputeTransformMatrix() {
for (int i = 0, n = mFieldBodyGroups.size(); i < n; ++i)
mFieldBodyGroups[i].recomputeTransformMatrix();
}
void StaticCompound::applyExtraTransforms(const sead::Matrix34f& mtx) {
if (mtx == mMtx)
return;
mMtx = mtx;
for (int i = 0, n = mFieldBodyGroups.size(); i < n; ++i)
mFieldBodyGroups[i].applyExtraTransforms();
}
void StaticCompound::resetExtraTransformsAndApply() {
for (int i = 0, n = mFieldBodyGroups.size(); i < n; ++i)
mFieldBodyGroups[i].resetExtraTransformsAndApply();
}
StaticCompoundRigidBodyGroup* StaticCompound::getFieldBodyGroup(int idx) {
return &mFieldBodyGroups[idx];
}
@@ -27,11 +27,23 @@ public:
StaticCompound();
~StaticCompound() override;
bool isAnyRigidBodyAddedToWorld() const;
bool isAnyRigidBodyAddedOrBeingAddedToWorld() const;
void removeFromWorld();
void addToWorld();
void removeFromWorldImmediately();
int setMapObject(u32 hash_id, u32 srt_hash, map::Object* object);
map::Object* getMapObject(int shape_idx) const;
bool disableCollision(int actor_idx, bool x);
void processUpdates();
void recomputeTransformMatrix();
void applyExtraTransforms(const sead::Matrix34f& mtx);
void resetExtraTransformsAndApply();
int getNumFieldBodyGroups() const { return mFieldBodyGroups.size(); }
StaticCompoundRigidBodyGroup* getFieldBodyGroup(int idx);
bool hasFieldBodyGroup(StaticCompoundRigidBodyGroup* group) const;
@@ -41,13 +53,6 @@ public:
bool finishParsing_() override;
bool m7_() override;
void cleanUp();
bool calledFromMapDtor();
int getNumFieldBodyGroups() const { return mFieldBodyGroups.size(); }
bool x_3();
void x_4();
StaticCompound* sub_7100FCAD0C(sead::Matrix34f& mtx);
private:
enum class Flag {
Initialised = 1 << 0,
@@ -64,7 +69,7 @@ private:
sead::FixedSafeString<32> mName;
sead::Matrix34f mMtx = sead::Matrix34f::ident;
sead::Buffer<map::Object*> mMapObjects{};
sead::CriticalSection mCS;
mutable sead::CriticalSection mCS;
};
KSYS_CHECK_SIZE_NX150(StaticCompound, 0x140);
@@ -17,6 +17,11 @@ public:
bool init();
// 0x0000007100fcb554
void addStaticCompound(StaticCompound* sc);
// 0x0000007100fcb5e0
void removeStaticCompound(StaticCompound* sc);
SystemGroupHandler* getGroupHandler() const { return mGroupHandler; }
// TODO: more functions
@@ -180,7 +180,7 @@ void StaticCompoundRigidBodyGroup::resetExtraTransforms() {
}
}
void StaticCompoundRigidBodyGroup::resetMatricesAndUpdateTransform() {
void StaticCompoundRigidBodyGroup::resetExtraTransformsAndApply() {
resetExtraTransforms();
mPendingTransformChanges = 0;
@@ -58,7 +58,7 @@ public:
void enableAllInstancesAndShapeKeys();
void resetExtraTransforms();
void resetMatricesAndUpdateTransform();
void resetExtraTransformsAndApply();
void applyExtraTransforms();
void recomputeTransformMatrix();