mirror of
https://github.com/zeldaret/botw
synced 2026-06-04 02:46:17 -04:00
148 lines
4.3 KiB
C++
148 lines
4.3 KiB
C++
#pragma once
|
|
|
|
#include <basis/seadTypes.h>
|
|
#include <container/seadBuffer.h>
|
|
#include <container/seadListImpl.h>
|
|
#include <container/seadSafeArray.h>
|
|
#include <cstddef>
|
|
#include <math/seadVector.h>
|
|
#include <prim/seadBitFlag.h>
|
|
#include <prim/seadDelegate.h>
|
|
#include <prim/seadNamable.h>
|
|
#include <prim/seadSafeString.h>
|
|
#include <thread/seadAtomic.h>
|
|
#include "KingSystem/Physics/RigidBody/physRigidBody.h"
|
|
#include "KingSystem/Utils/Types.h"
|
|
|
|
namespace ksys::phys {
|
|
|
|
struct ContactPoint;
|
|
|
|
class ContactPointInfoBase : public sead::INamable {
|
|
public:
|
|
using Points = sead::Buffer<ContactPoint*>;
|
|
|
|
// FIXME: parameter names
|
|
ContactPointInfoBase(const sead::SafeString& name, int a, int b, int c)
|
|
: sead::INamable(name), _2c(a), _30(b), _34(c) {}
|
|
virtual ~ContactPointInfoBase() = default;
|
|
virtual void freePoints() = 0;
|
|
|
|
u32 get30() const { return _30; }
|
|
void set30(u32 value) { _30 = value; }
|
|
|
|
u32 get34() const { return _34; }
|
|
void set34(u32 value) { _34 = value; }
|
|
|
|
bool isLayerSubscribed(ContactLayer layer) const {
|
|
const auto type = getContactLayerType(layer);
|
|
return mSubscribedLayers[int(type)].isOnBit(int(getContactLayerBaseRelativeValue(layer)));
|
|
}
|
|
|
|
// TODO: rename
|
|
bool isLayerInMask2(ContactLayer layer) const {
|
|
const auto type = getContactLayerType(layer);
|
|
return mLayerMask2[int(type)].isOnBit(int(getContactLayerBaseRelativeValue(layer)));
|
|
}
|
|
|
|
public:
|
|
// For internal use by the physics system.
|
|
|
|
bool isLinked() const { return mListNode.isLinked(); }
|
|
|
|
static constexpr size_t getListNodeOffset() {
|
|
return offsetof(ContactPointInfoBase, mListNode);
|
|
}
|
|
|
|
protected:
|
|
friend class ContactMgr;
|
|
|
|
sead::Atomic<int> mNumContactPoints;
|
|
sead::SafeArray<sead::BitFlag32, 2> mSubscribedLayers;
|
|
// TODO: rename
|
|
sead::SafeArray<sead::BitFlag32, 2> mLayerMask2;
|
|
u32 _2c{};
|
|
u32 _30{};
|
|
u32 _34{};
|
|
sead::ListNode mListNode{};
|
|
};
|
|
|
|
class ContactPointInfo : public ContactPointInfoBase {
|
|
public:
|
|
enum class ShouldDisableContact : bool {
|
|
Yes = true,
|
|
No = false,
|
|
};
|
|
|
|
struct Event {
|
|
RigidBody* body;
|
|
const sead::Vector3f* position;
|
|
const sead::Vector3f* separating_normal;
|
|
const RigidBody::CollisionMasks* collision_masks;
|
|
};
|
|
|
|
class Iterator {
|
|
public:
|
|
enum class IsEnd : bool { Yes = true };
|
|
|
|
enum class Point {
|
|
BodyA,
|
|
BodyB,
|
|
Midpoint,
|
|
};
|
|
|
|
Iterator(const Points& points, int count);
|
|
Iterator(const Points& points, int count, IsEnd is_end);
|
|
|
|
Iterator& operator++() {
|
|
++mIdx;
|
|
return *this;
|
|
}
|
|
|
|
virtual void getPointPosition(sead::Vector3f* out, Point point) const;
|
|
virtual sead::Vector3f getPointPosition(Point point) const;
|
|
|
|
const ContactPoint* getPoint() const { return mPoints[mIdx]; }
|
|
const ContactPoint* operator*() const { return getPoint(); }
|
|
|
|
friend bool operator==(const Iterator& lhs, const Iterator& rhs) {
|
|
return lhs.mIdx == rhs.mIdx;
|
|
}
|
|
friend bool operator!=(const Iterator& lhs, const Iterator& rhs) {
|
|
return !operator==(lhs, rhs);
|
|
}
|
|
|
|
private:
|
|
int mIdx = 0;
|
|
const ContactPoint* const* mPoints = nullptr;
|
|
int mPointsNum = 0;
|
|
const ContactPoint* const* mPointsStart = nullptr;
|
|
};
|
|
|
|
using ContactCallback = sead::IDelegate2R<ShouldDisableContact*, const Event&, bool>;
|
|
|
|
static ContactPointInfo* make(sead::Heap* heap, int num, const sead::SafeString& name, int a,
|
|
int b, int c);
|
|
static void free(ContactPointInfo* instance);
|
|
|
|
ContactPointInfo(const sead::SafeString& name, int a, int b, int c);
|
|
~ContactPointInfo() override;
|
|
void freePoints() override;
|
|
virtual void allocPoints(sead::Heap* heap, int num);
|
|
|
|
ContactCallback* getContactCallback() const { return mContactCallback; }
|
|
void setContactCallback(ContactCallback* cb) { mContactCallback = cb; }
|
|
|
|
auto begin() const { return Iterator(mPoints, mNumContactPoints); }
|
|
auto end() const { return Iterator(mPoints, mNumContactPoints, Iterator::IsEnd::Yes); }
|
|
|
|
protected:
|
|
friend class ContactMgr;
|
|
|
|
Points mPoints;
|
|
ContactCallback* mContactCallback{};
|
|
};
|
|
KSYS_CHECK_SIZE_NX150(ContactPointInfo, 0x60);
|
|
|
|
} // namespace ksys::phys
|