1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
#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/Physics/physDefines.h"
#include "KingSystem/Physics/physLayerMaskBuilder.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; }
// TODO: rename
bool testContactPointDistance(float distance) const { return get30() == 0 || distance <= 0; }
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(getContactLayerBaseRelativeValue(layer));
}
// TODO: rename
bool isLayerInMask2(ContactLayer layer) const {
const auto type = getContactLayerType(layer);
return mLayerMask2[int(type)].isOnBit(getContactLayerBaseRelativeValue(layer));
}
void setLayerMasks(const LayerMaskBuilder& builder) {
for (int i = 0; i < NumContactLayerTypes; ++i) {
mSubscribedLayers[i] = builder.getMasks()[i].layers;
mLayerMask2[i] = builder.getMasks()[i].layers2;
}
}
public:
// For internal use by the physics system.
sead::Atomic<int>& getNumContactPoints() { return mNumContactPoints; }
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
|