ksys/phys: Add RayCastRequestMgr

This commit is contained in:
Léo Lam 2022-03-21 00:45:06 +01:00
parent 509d557731
commit ec37bc0018
No known key found for this signature in database
GPG Key ID: 0DF30F9081000741
11 changed files with 286 additions and 43 deletions

View File

@ -84065,30 +84065,30 @@ Address,Quality,Size,Name
0x0000007100fc5368,O,000204,_ZNK4ksys4phys16RayCastBodyQuery27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE
0x0000007100fc5434,O,000092,_ZNK4ksys4phys16RayCastBodyQuery18getRuntimeTypeInfoEv
0x0000007100fc5490,O,000140,_ZNK4sead15RuntimeTypeInfo6DeriveIN4ksys4phys7RayCastEE9isDerivedEPKNS0_9InterfaceE
0x0000007100fc551c,U,000076,phys::RayCastDerived2::ctor
0x0000007100fc5568,U,000004,phys::RayCastDerived2::dtor
0x0000007100fc556c,U,000036,phys::RayCastDerived2::dtord
0x0000007100fc5590,U,000028,phys::RayCastDerived2::x_0
0x0000007100fc55ac,U,000024,phys::RayCastDerived2::x_1
0x0000007100fc55c4,U,000016,phys::RayCastDerived2::x_2
0x0000007100fc55d4,U,000020,phys::RayCastDerived2::x_3
0x0000007100fc55e8,U,000016,phys::RayCastDerived2::x_4
0x0000007100fc55f8,U,000204,phys::RayCastDerived2::rtti1
0x0000007100fc56c4,U,000092,phys::RayCastDerived2::rtti2
0x0000007100fc5720,U,000104,RayCastRequestMgr::ctor
0x0000007100fc5788,U,000020,RayCastRequestMgr::dtor
0x0000007100fc579c,U,000052,RayCastRequestMgr::dtord
0x0000007100fc57d0,U,000256,RayCastRequestMgr::init
0x0000007100fc58d0,U,000148,RayCastRequestMgr::processRequests
0x0000007100fc5964,U,000204,RayCastRequestMgr::clearRequests
0x0000007100fc5a30,U,000136,RayCastRequestMgr::eraseRequest
0x0000007100fc5ab8,U,000184,RayCastRequestMgr::submitRequest
0x0000007100fc5b70,U,000352,RayCastRequestMgr::x_0
0x0000007100fc5cd0,U,000020,RayCastRequestMgr::x_1
0x0000007100fc5ce4,U,000020,RayCastRequestMgr::x_2
0x0000007100fc5cf8,U,000068,RayCastRequestMgr::triggerRequestProcessingOnWorker
0x0000007100fc5d3c,U,000052,sead_delegate_fn
0x0000007100fc5d70,U,000092,sead_delegate_fn_0
0x0000007100fc551c,O,000076,_ZN4ksys4phys17RayCastForRequestC1EPNS0_17RayCastRequestMgrE
0x0000007100fc5568,O,000004,_ZN4ksys4phys17RayCastForRequestD1Ev
0x0000007100fc556c,O,000036,_ZN4ksys4phys17RayCastForRequestD0Ev
0x0000007100fc5590,O,000028,_ZN4ksys4phys17RayCastForRequest12allocRequestEPNS0_18SystemGroupHandlerENS0_9GroundHitE
0x0000007100fc55ac,O,000024,_ZN4ksys4phys17RayCastForRequest13submitRequestENS0_16ContactLayerTypeE
0x0000007100fc55c4,O,000016,_ZNK4ksys4phys17RayCastForRequest15isRequestQueuedEv
0x0000007100fc55d4,O,000020,_ZN4ksys4phys17RayCastForRequest7releaseEv
0x0000007100fc55e8,O,000016,_ZNK4ksys4phys17RayCastForRequest17isRequestFinishedEv
0x0000007100fc55f8,O,000204,_ZNK4ksys4phys17RayCastForRequest27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE
0x0000007100fc56c4,O,000092,_ZNK4ksys4phys17RayCastForRequest18getRuntimeTypeInfoEv
0x0000007100fc5720,O,000104,_ZN4ksys4phys17RayCastRequestMgrC1Ev
0x0000007100fc5788,O,000020,_ZN4ksys4phys17RayCastRequestMgrD1Ev
0x0000007100fc579c,O,000052,_ZN4ksys4phys17RayCastRequestMgrD0Ev
0x0000007100fc57d0,O,000256,_ZN4ksys4phys17RayCastRequestMgr4initEPN4sead4HeapEi
0x0000007100fc58d0,O,000148,_ZN4ksys4phys17RayCastRequestMgr15processRequestsEPv
0x0000007100fc5964,O,000204,_ZN4ksys4phys17RayCastRequestMgr13clearRequestsEv
0x0000007100fc5a30,O,000136,_ZN4ksys4phys17RayCastRequestMgr14releaseRequestERNS0_17RayCastForRequestE
0x0000007100fc5ab8,O,000184,_ZN4ksys4phys17RayCastRequestMgr12allocRequestEPNS0_18SystemGroupHandlerENS0_9GroundHitE
0x0000007100fc5b70,O,000352,_ZN4ksys4phys17RayCastRequestMgr13submitRequestERNS0_17RayCastForRequestENS0_16ContactLayerTypeE
0x0000007100fc5cd0,O,000020,_ZNK4ksys4phys17RayCastRequestMgr15isRequestQueuedERKNS0_17RayCastForRequestE
0x0000007100fc5ce4,O,000020,_ZNK4ksys4phys17RayCastRequestMgr17isRequestFinishedERKNS0_17RayCastForRequestE
0x0000007100fc5cf8,O,000068,_ZN4ksys4phys17RayCastRequestMgr25scheduleRequestProcessingEv
0x0000007100fc5d3c,O,000052,_ZN4sead10Delegate1RIN4ksys4phys17RayCastRequestMgrEPvbE6invokeES4_
0x0000007100fc5d70,O,000092,_ZNK4sead10Delegate1RIN4ksys4phys17RayCastRequestMgrEPvbE5cloneEPNS_4HeapE
0x0000007100fc5dcc,U,000032,
0x0000007100fc5dec,U,000092,phys::RigidBodyDividedMeshShapeMgr::makeInstance
0x0000007100fc5e48,U,000812,phys::RigidBodyDividedMeshShapeMgr::ctor

Can't render this file because it is too large.

@ -1 +1 @@
Subproject commit fa370e87acb11df1805de89078b0bf9007b616e8
Subproject commit 1b66e825d1927254c191028523645541b13c7eab

View File

@ -7,23 +7,12 @@
#include "KingSystem/Map/mapAutoPlacementFlowMgr.h"
#include "KingSystem/Map/mapAutoPlacementMgr.h"
#include "KingSystem/Physics/RigidBody/physRigidBody.h"
#include "KingSystem/Physics/System/physRayCast.h"
#include "KingSystem/Physics/System/physRayCastForRequest.h"
#include "KingSystem/Utils/Byaml/Byaml.h"
#include "KingSystem/World/worldWeatherMgr.h"
namespace ksys::map {
// TODO: this phys::RayCast derived class should be moved to phys::
struct Raycast : phys::RayCast {
Raycast();
~Raycast() override;
static Raycast* create(void*, u32);
void sub_7100FC55AC(u32);
void release();
};
AutoPlacement::AutoPlacement() = default;
AutoPlacement::~AutoPlacement() = default;
@ -284,11 +273,11 @@ void PlacementThing::stepRaycast() {
switch (mState) {
case State::Uninitialized:
mRaycast = Raycast::create(nullptr, 1);
mRaycast = phys::RayCastForRequest::allocRequest(nullptr, phys::GroundHit::Animal);
next = mRaycast != nullptr ? State::Initialized : State::Invalid;
break;
case State::LayersDone:
mRaycast->sub_7100FC55AC(0);
mRaycast->submitRequest(phys::ContactLayerType::Entity);
next = State::RaycastDone;
break;
case State::PlacementDone:

View File

@ -11,6 +11,7 @@
#include "KingSystem/Utils/Types.h"
namespace ksys::phys {
class RayCastForRequest;
class RigidBody;
} // namespace ksys::phys
@ -20,8 +21,6 @@ class AutoPlacement;
struct AutoPlacementFlowRes;
class PlacementThing;
struct Raycast;
struct PlacementGroup {
sead::SafeString a;
u32 _10;
@ -75,7 +74,7 @@ public:
private:
friend class AutoPlacement;
Raycast* mRaycast{};
phys::RayCastForRequest* mRaycast{};
u8 _8880{};
u8 mUnderwater{};
sead::Vector3f mVec1{};

View File

@ -147,6 +147,10 @@ target_sources(uking PRIVATE
System/physRayCast.h
System/physRayCastBodyQuery.cpp
System/physRayCastBodyQuery.h
System/physRayCastForRequest.cpp
System/physRayCastForRequest.h
System/physRayCastRequestMgr.cpp
System/physRayCastRequestMgr.h
System/physSensorContactListener.cpp
System/physSensorContactListener.h
System/physSensorGroupFilter.cpp

View File

@ -0,0 +1,34 @@
#include "KingSystem/Physics/System/physRayCastForRequest.h"
#include "KingSystem/Physics/System/physRayCastRequestMgr.h"
#include "KingSystem/Physics/System/physSystem.h"
namespace ksys::phys {
RayCastForRequest::RayCastForRequest(RayCastRequestMgr* mgr)
: RayCast(nullptr, GroundHit::HitAll), mMgr(mgr) {}
RayCastForRequest::~RayCastForRequest() = default;
RayCastForRequest* RayCastForRequest::allocRequest(SystemGroupHandler* group_handler,
GroundHit ground_hit) {
return System::instance()->allocRayCastRequest(group_handler, ground_hit);
}
bool RayCastForRequest::submitRequest(ContactLayerType layer_type) {
return mMgr->submitRequest(*this, layer_type);
}
bool RayCastForRequest::isRequestQueued() const {
return mMgr->isRequestQueued(*this);
}
void RayCastForRequest::release() {
mRigidBodyHitCallback = nullptr;
mMgr->releaseRequest(*this);
}
bool RayCastForRequest::isRequestFinished() const {
return mMgr->isRequestFinished(*this);
}
} // namespace ksys::phys

View File

@ -0,0 +1,36 @@
#pragma once
#include <container/seadTList.h>
#include "KingSystem/Physics/System/physRayCast.h"
#include "KingSystem/Utils/Types.h"
namespace ksys::phys {
class RayCastRequestMgr;
/// A RayCast that is used by RayCastRequestMgr to process raycast requests.
class RayCastForRequest : public RayCast {
SEAD_RTTI_OVERRIDE(RayCastForRequest, RayCast)
public:
static RayCastForRequest* allocRequest(SystemGroupHandler* group_handler = nullptr,
GroundHit ground_hit = GroundHit::HitAll);
explicit RayCastForRequest(RayCastRequestMgr* mgr);
~RayCastForRequest() override;
bool submitRequest(ContactLayerType layer_type);
bool isRequestQueued() const;
bool isRequestFinished() const;
/// This must be called after you're finished using this RayCast.
void release();
private:
friend class RayCastRequestMgr;
RayCastRequestMgr* mMgr{};
sead::TListNode<RayCastForRequest*> mListNode{this};
ContactLayerType mRequestContactLayerType = ContactLayerType::Entity;
};
} // namespace ksys::phys

View File

@ -0,0 +1,127 @@
#include "KingSystem/Physics/System/physRayCastRequestMgr.h"
#include <cmath>
#include <prim/seadScopedLock.h>
#include "KingSystem/Framework/frmWorkerSupportThreadMgr.h"
#include "KingSystem/Physics/System/physRayCastForRequest.h"
#include "KingSystem/ksys.h"
namespace ksys::phys {
RayCastRequestMgr::RayCastRequestMgr() = default;
RayCastRequestMgr::~RayCastRequestMgr() = default;
void RayCastRequestMgr::init(sead::Heap* heap, int pool_size) {
mLargestRecordedQueueSize = 0;
for (auto it = mQueuedList.robustBegin(); it != mQueuedList.robustEnd(); it++)
mQueuedList.erase(&*it);
for (int i = 0; i < pool_size; ++i) {
auto* ray_cast = new (heap, 0x10) RayCastForRequest(this);
mFreeList.pushBack(&ray_cast->mListNode);
}
mWorkerFunction.bind(this, &RayCastRequestMgr::processRequests);
}
bool RayCastRequestMgr::processRequests(void*) {
for (int i = 0; i < mBatchSize; ++i) {
mCS.lock();
auto* request = mQueuedList.popFront();
if (!request) {
mCS.unlock();
return true;
}
request->mList = nullptr;
mCS.unlock();
request->mData->worldRayCast(request->mData->mRequestContactLayerType);
}
return true;
}
void RayCastRequestMgr::clearRequests() {
{
auto lock = sead::makeScopedLock(mCS);
while (!mQueuedList.isEmpty()) {
auto* request = mQueuedList.popFront();
if (!request)
continue;
auto* ray_cast = request->mData;
request->mList = nullptr;
releaseRequest(*ray_cast);
}
}
mLargestRecordedQueueSize = 0;
}
void RayCastRequestMgr::releaseRequest(RayCastForRequest& ray_cast) {
auto lock = sead::makeScopedLock(mCS);
ray_cast.mRigidBodyHitCallback = nullptr;
mFreeList.pushBack(&ray_cast.mListNode);
}
RayCastForRequest* RayCastRequestMgr::allocRequest(SystemGroupHandler* group_handler,
GroundHit ground_hit) {
auto lock = sead::makeScopedLock(mCS);
auto* request = mFreeList.popFront();
if (!request)
return nullptr;
request->mList = nullptr;
if (request->mData->_98) {
mFreeList.pushBack(request);
return nullptr;
}
request->mData->reset();
request->mData->mGroupHandler = group_handler;
request->mData->setGroundHit(ground_hit);
request->mData->mNormalCheckingMode = RayCast::NormalCheckingMode::_0;
return request->mData;
}
static bool isVectorInvalid(const sead::Vector3f& vec) {
for (int i = 0; i < 3; ++i) {
if (std::isnan(vec.e[i]))
return true;
}
return false;
}
bool RayCastRequestMgr::submitRequest(RayCastForRequest& ray_cast, ContactLayerType layer_type) {
if (isVectorInvalid(ray_cast.mFrom) || isVectorInvalid(ray_cast.mTo))
return false;
if (ray_cast.mListNode.isLinked())
return false;
auto lock = sead::makeScopedLock(mCS);
ray_cast.mRequestContactLayerType = layer_type;
mQueuedList.pushBack(&ray_cast.mListNode);
if (mQueuedList.size() > mLargestRecordedQueueSize)
mLargestRecordedQueueSize = mQueuedList.size();
return true;
}
bool RayCastRequestMgr::isRequestQueued(const RayCastForRequest& ray_cast) const {
return ray_cast.mListNode.mList == &mQueuedList;
}
bool RayCastRequestMgr::isRequestFinished(const RayCastForRequest& ray_cast) const {
return ray_cast.mListNode.mList == &mFreeList;
}
void RayCastRequestMgr::scheduleRequestProcessing() {
if (!isGameOver())
frm::WorkerSupportThreadMgr::instance()->submitRequest(5, &mWorkerFunction);
}
} // namespace ksys::phys

View File

@ -0,0 +1,42 @@
#pragma once
#include <container/seadTList.h>
#include <hostio/seadHostIONode.h>
#include <thread/seadCriticalSection.h>
#include "KingSystem/Physics/physDefines.h"
#include "KingSystem/Utils/Thread/Task.h"
namespace ksys::phys {
class RayCastForRequest;
class SystemGroupHandler;
class RayCastRequestMgr : public sead::hostio::Node {
public:
RayCastRequestMgr();
virtual ~RayCastRequestMgr();
void init(sead::Heap* heap, int pool_size);
void clearRequests();
void releaseRequest(RayCastForRequest& ray_cast);
RayCastForRequest* allocRequest(SystemGroupHandler* group_handler, GroundHit ground_hit);
bool submitRequest(RayCastForRequest& ray_cast, ContactLayerType layer_type);
bool isRequestQueued(const RayCastForRequest& ray_cast) const;
bool isRequestFinished(const RayCastForRequest& ray_cast) const;
void scheduleRequestProcessing();
private:
bool processRequests(void*);
sead::CriticalSection mCS;
sead::TList<RayCastForRequest*> mQueuedList;
sead::TList<RayCastForRequest*> mFreeList;
util::TaskDelegateT<RayCastRequestMgr> mWorkerFunction;
/// The number of requests to process per batch.
int mBatchSize = 1;
int mLargestRecordedQueueSize = 0;
};
} // namespace ksys::phys

View File

@ -17,6 +17,7 @@ class ContactLayerCollisionInfoGroup;
class ContactMgr;
class GroupFilter;
class MaterialTable;
class RayCastForRequest;
class RigidBody;
class RigidBodyRequestMgr;
class ContactPointInfo;
@ -40,7 +41,6 @@ class System {
public:
float get64() const { return _64; }
float getTimeFactor() const { return mTimeFactor; }
GroupFilter* getGroupFilter(ContactLayerType type) const;
ContactMgr* getContactMgr() const { return mContactMgr; }
RigidBodyRequestMgr* getRigidBodyRequestMgr() const { return mRigidBodyRequestMgr; }
SystemData* getSystemData() const { return mSystemData; }
@ -94,6 +94,13 @@ public:
void unlockWorld(ContactLayerType type, const char* description = nullptr, int b = 0,
OnlyLockIfNeeded only_lock_if_needed = OnlyLockIfNeeded::No);
// 0x0000007101216ac8
GroupFilter* getGroupFilter(ContactLayerType type) const;
// 0x0000007101216ae8
RayCastForRequest* allocRayCastRequest(SystemGroupHandler* group_handler = nullptr,
GroundHit ground_hit = GroundHit::HitAll);
// TODO: rename
// 0x0000007101216c60
void setEntityContactListenerField90(bool value);

View File

@ -6,6 +6,11 @@ class Heap;
namespace ksys {
// 0x0000007100f3a4e4
bool isGameOver();
// 0x0000007100f3a4f0
void setIsGameOver(bool is_game_over);
void initBaseProcMgr(sead::Heap* heap);
} // namespace ksys