ksys/phys: Start adding ClosestPointQuery and iterator stuff

This commit is contained in:
Léo Lam
2022-03-06 22:50:15 +01:00
parent 6229e5d41a
commit 62959cc554
12 changed files with 249 additions and 16 deletions
+5
View File
@@ -103,6 +103,10 @@ target_sources(uking PRIVATE
System/physCharacterControllerParam.cpp
System/physCharacterControllerParam.h
System/physClosestPointQuery.cpp
System/physClosestPointQuery.h
System/physClosestPointQueryWithInfo.cpp
System/physClosestPointQueryWithInfo.h
System/physCollisionInfo.cpp
System/physCollisionInfo.h
System/physContactInfoParam.cpp
@@ -142,6 +146,7 @@ target_sources(uking PRIVATE
physDefines.h
physConversions.h
physHeapUtil.h
physLayerMaskBuilder.h
physMaterialMask.cpp
physMaterialMask.h
)
@@ -0,0 +1,43 @@
#include "KingSystem/Physics/System/physClosestPointQuery.h"
#include "KingSystem/Physics/RigidBody/physRigidBody.h"
#include "KingSystem/Physics/System/physQueryContactPointInfo.h"
#include "KingSystem/Physics/physDefines.h"
#include "KingSystem/Physics/physLayerMaskBuilder.h"
namespace ksys::phys {
ClosestPointQuery::ClosestPointQuery(RigidBody* body, QueryContactPointInfo* contact_point_info)
: mBody(body), mContactPointInfo(contact_point_info) {
reset();
}
ClosestPointQuery::~ClosestPointQuery() = default;
void ClosestPointQuery::reset() {
mIsSuccess = false;
_18 = 0;
}
void ClosestPointQuery::setLayerMasks(const LayerMaskBuilder& builder) {
auto* info = mContactPointInfo;
for (int i = 0; i < NumContactLayerTypes; ++i) {
info->mSubscribedLayers[i] = builder.getMasks()[i].layers;
info->mLayerMask2[i] = builder.getMasks()[i].layers2;
}
}
bool ClosestPointQuery::isSuccess() const {
return mIsSuccess;
}
void ClosestPointQuery::setLayerMasksAndBodyCollisionFilterInfo(const LayerMaskBuilder& builder) {
EntityCollisionMask mask;
mask.data.query_custom_receiver_layer_mask =
builder.getMasks()[int(ContactLayerType::Entity)].layers;
mask.data.layer = ContactLayer::EntityQueryCustomReceiver;
mBody->setCollisionFilterInfo(mask.raw);
setLayerMasks(builder);
}
} // namespace ksys::phys
@@ -0,0 +1,39 @@
#pragma once
#include <basis/seadTypes.h>
#include <math/seadMatrix.h>
#include <prim/seadRuntimeTypeInfo.h>
namespace ksys::phys {
class LayerMaskBuilder;
class RigidBody;
class QueryContactPointInfo;
class ClosestPointQuery {
SEAD_RTTI_BASE(ClosestPointQuery)
public:
ClosestPointQuery(RigidBody* body, QueryContactPointInfo* contact_point_info);
virtual ~ClosestPointQuery();
RigidBody* getBody() const { return mBody; }
QueryContactPointInfo* getContactPointInfo() const { return mContactPointInfo; }
void setLayerMasks(const LayerMaskBuilder& builder);
void setLayerMasksAndBodyCollisionFilterInfo(const LayerMaskBuilder& builder);
// 0x0000007100fb0850
bool execute(bool unk);
bool isSuccess() const;
protected:
void reset();
RigidBody* mBody{};
QueryContactPointInfo* mContactPointInfo{};
u32 _18{};
bool mIsSuccess = false;
sead::Matrix34f mMtx = sead::Matrix34f::ident;
};
} // namespace ksys::phys
@@ -0,0 +1,22 @@
#include "KingSystem/Physics/System/physClosestPointQueryWithInfo.h"
#include "KingSystem/Physics/System/physQueryContactPointInfo.h"
#include "KingSystem/Physics/System/physSystem.h"
namespace ksys::phys {
ClosestPointQueryWithInfo::ClosestPointQueryWithInfo(RigidBody* body, int num_points,
const sead::SafeString& name, int a,
LowPriority low_priority)
: ClosestPointQuery(body, nullptr) {
mStatus = Status::_1;
auto* heap = System::instance()->getPhysicsTempHeap(low_priority);
mContactPointInfo = QueryContactPointInfo::make(heap, num_points, name, a, 0);
}
ClosestPointQueryWithInfo::~ClosestPointQueryWithInfo() {
if (mStatus == Status::_1 || mStatus == Status::_3) {
QueryContactPointInfo::free(mContactPointInfo);
}
}
} // namespace ksys::phys
@@ -0,0 +1,26 @@
#pragma once
#include "KingSystem/Physics/System/physClosestPointQuery.h"
#include "KingSystem/Physics/System/physSystem.h"
namespace ksys::phys {
// A ClosestPointQuery with an owned QueryContactPointInfo.
class ClosestPointQueryWithInfo : public ClosestPointQuery {
SEAD_RTTI_OVERRIDE(ClosestPointQueryWithInfo, ClosestPointQuery)
public:
enum class Status {
_1 = 1,
_2 = 2,
_3 = 3,
};
ClosestPointQueryWithInfo(RigidBody* body, int num_points, const sead::SafeString& name, int a,
LowPriority low_priority);
~ClosestPointQueryWithInfo() override;
protected:
Status mStatus{};
};
} // namespace ksys::phys
@@ -136,7 +136,7 @@ public:
auto begin() const { return Iterator(mPoints, mNumContactPoints); }
auto end() const { return Iterator(mPoints, mNumContactPoints, Iterator::IsEnd::Yes); }
private:
protected:
friend class ContactMgr;
Points mPoints;
@@ -1,4 +1,5 @@
#include "KingSystem/Physics/System/physQueryContactPointInfo.h"
#include "KingSystem/Physics/System/physContactMgr.h"
namespace ksys::phys {
@@ -16,4 +17,14 @@ void QueryContactPointInfo::free(QueryContactPointInfo* info) {
QueryContactPointInfo::~QueryContactPointInfo() = default;
void QueryContactPointInfo::Iterator::getPointPosition(sead::Vector3f* out, Point point) const {
out->e = getPoint()->position.e;
}
sead::Vector3f QueryContactPointInfo::Iterator::getPointPosition(Point point) const {
sead::Vector3f pos;
getPointPosition(&pos, point);
return pos;
}
} // namespace ksys::phys
@@ -6,12 +6,25 @@ namespace ksys::phys {
class QueryContactPointInfo : public ContactPointInfo {
public:
class Iterator : public ContactPointInfo::Iterator {
public:
using ContactPointInfo::Iterator::Iterator;
void getPointPosition(sead::Vector3f* out, Point point) const override;
sead::Vector3f getPointPosition(Point point) const override;
};
static QueryContactPointInfo* make(sead::Heap* heap, int num_points,
const sead::SafeString& name, int a, int b);
static void free(QueryContactPointInfo* info);
using ContactPointInfo::ContactPointInfo;
~QueryContactPointInfo() override;
auto begin() const { return Iterator(mPoints, mNumContactPoints); }
auto end() const { return Iterator(mPoints, mNumContactPoints, Iterator::IsEnd::Yes); }
friend class ClosestPointQuery;
};
} // namespace ksys::phys
@@ -25,6 +25,11 @@ enum class IsIndoorStage {
Yes,
};
enum class LowPriority : bool {
Yes = true,
No = false,
};
class System {
SEAD_SINGLETON_DISPOSER(System)
System();
@@ -72,6 +77,9 @@ public:
void lockWorld(ContactLayerType type, void* a = nullptr, int b = 0, bool c = false);
void unlockWorld(ContactLayerType type, void* a = nullptr, int b = 0, bool c = false);
// 0x0000007101216cec
sead::Heap* getPhysicsTempHeap(LowPriority low_priority) const;
private:
u8 _28[0x64 - 0x28];
float _64 = 1.0 / 30.0;
+2
View File
@@ -13,6 +13,8 @@ enum class ContactLayerType {
Invalid,
};
constexpr int NumContactLayerTypes = 2;
SEAD_ENUM(ContactLayer,
EntityObject,\
EntitySmallObject,\
@@ -0,0 +1,64 @@
#pragma once
#include <container/seadSafeArray.h>
#include <prim/seadBitFlag.h>
#include "KingSystem/Physics/physDefines.h"
namespace ksys::phys {
class LayerMaskBuilder {
public:
struct Masks {
sead::BitFlag32 layers;
// TODO: rename
sead::BitFlag32 layers2;
};
LayerMaskBuilder() = default;
// XXX: this doesn't need to be virtual...
virtual ~LayerMaskBuilder() = default;
LayerMaskBuilder& addLayer(ContactLayer layer);
LayerMaskBuilder& removeLayer(ContactLayer layer);
bool hasLayer(ContactLayer layer) const;
// TODO: rename
LayerMaskBuilder& addLayer2(ContactLayer layer);
LayerMaskBuilder& removeLayer2(ContactLayer layer);
bool hasLayer2(ContactLayer layer) const;
const auto& getMasks() const { return mMasks; }
private:
sead::SafeArray<Masks, NumContactLayerTypes> mMasks;
};
inline LayerMaskBuilder& LayerMaskBuilder::addLayer(ContactLayer layer) {
mMasks[int(getContactLayerType(layer))].layers.set(makeContactLayerMask(layer));
return *this;
}
inline LayerMaskBuilder& LayerMaskBuilder::removeLayer(ContactLayer layer) {
mMasks[int(getContactLayerType(layer))].layers.reset(makeContactLayerMask(layer));
return *this;
}
inline bool LayerMaskBuilder::hasLayer(ContactLayer layer) const {
return (mMasks[int(getContactLayerType(layer))].layers & makeContactLayerMask(layer)) != 0;
}
inline LayerMaskBuilder& LayerMaskBuilder::addLayer2(ContactLayer layer) {
mMasks[int(getContactLayerType(layer))].layers2.set(makeContactLayerMask(layer));
return *this;
}
inline LayerMaskBuilder& LayerMaskBuilder::removeLayer2(ContactLayer layer) {
mMasks[int(getContactLayerType(layer))].layers2.reset(makeContactLayerMask(layer));
return *this;
}
inline bool LayerMaskBuilder::hasLayer2(ContactLayer layer) const {
return (mMasks[int(getContactLayerType(layer))].layers2 & makeContactLayerMask(layer)) != 0;
}
} // namespace ksys::phys