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
|
#pragma once
#include <container/seadBuffer.h>
#include <container/seadListImpl.h>
#include <container/seadPtrArray.h>
#include <prim/seadNamable.h>
#include "KingSystem/Physics/physDefines.h"
namespace ksys::phys {
struct CollidingBodies;
class ContactLayerCollisionInfo;
/// Container for ContactLayerCollisionInfo instances that pertain to a contact layer
/// paired with other layers.
class ContactLayerCollisionInfoGroup : public sead::INamable {
public:
class CollidingBodiesIterator;
struct CollidingBodiesRange;
struct LayerInfo {
ContactLayer layer;
/// Is `layer` greater than the layer of the group?
bool layer_gt;
/// Is `layer` lower or equal to the layer of the group?
bool layer_le;
};
static ContactLayerCollisionInfoGroup* make(sead::Heap* heap, ContactLayer layer, int capacity,
const sead::SafeString& name);
static void free(ContactLayerCollisionInfoGroup* group);
ContactLayerCollisionInfoGroup(ContactLayer layer, const sead::SafeString& name);
virtual ~ContactLayerCollisionInfoGroup();
/// @param capacity The maximum number of layers that can be added to this group.
void init(sead::Heap* heap, int capacity);
void finalize();
/// Add (mLayer, layer) to the list of layer pairs in this group.
void addLayer(ContactLayer layer);
/// Call this to ensure that all layer pairs in this group are being tracked by
/// the relevant contact listener. This may be necessary if the listener has been reset.
void ensureLayersAreTracked();
CollidingBodiesIterator collidingBodiesBegin() const;
CollidingBodiesIterator collidingBodiesEnd() const;
CollidingBodiesRange getCollidingBodies() const;
const sead::PtrArray<ContactLayerCollisionInfo>& getCollisionInfo() const {
return mCollisionInfoInstances;
}
static constexpr size_t getListNodeOffset() {
return offsetof(ContactLayerCollisionInfoGroup, mListNode);
}
private:
ContactLayer mLayer;
sead::PtrArray<ContactLayerCollisionInfo> mCollisionInfoInstances;
sead::Buffer<LayerInfo> mLayers;
sead::ListNode mListNode;
};
class ContactLayerCollisionInfoGroup::CollidingBodiesIterator {
public:
enum class IsStart : bool { Yes = true, No = false };
CollidingBodiesIterator(const ContactLayerCollisionInfoGroup* group, int index, IsStart start);
~CollidingBodiesIterator();
const LayerInfo& getLayerInfo() const { return mGroup->mLayers[mInfoIndex]; }
const CollidingBodies& operator*() const { return *mCollidingBodiesEntry; }
const CollidingBodies* operator->() const { return mCollidingBodiesEntry; }
CollidingBodiesIterator& operator++();
bool operator==(const CollidingBodiesIterator& other) const {
return mInfoIndex == other.mInfoIndex &&
mCollidingBodiesEntry == other.mCollidingBodiesEntry;
}
bool operator!=(const CollidingBodiesIterator& other) const { return !operator==(other); }
private:
void initIterator(const ContactLayerCollisionInfoGroup* group);
const ContactLayerCollisionInfoGroup* mGroup{};
ContactLayerCollisionInfo* mInfo{};
/// The current CollidingBodies pair within the current ContactLayerCollisionInfo (mInfo).
const CollidingBodies* mCollidingBodiesEntry{};
int mInfoIndex{};
};
struct ContactLayerCollisionInfoGroup::CollidingBodiesRange {
auto begin() const { return group->collidingBodiesBegin(); }
auto end() const { return group->collidingBodiesEnd(); }
const ContactLayerCollisionInfoGroup* group;
};
inline ContactLayerCollisionInfoGroup::CollidingBodiesIterator
ContactLayerCollisionInfoGroup::collidingBodiesBegin() const {
return {this, 0, CollidingBodiesIterator::IsStart::Yes};
}
inline ContactLayerCollisionInfoGroup::CollidingBodiesIterator
ContactLayerCollisionInfoGroup::collidingBodiesEnd() const {
return {this, mCollisionInfoInstances.size(), CollidingBodiesIterator::IsStart::No};
}
inline ContactLayerCollisionInfoGroup::CollidingBodiesRange
ContactLayerCollisionInfoGroup::getCollidingBodies() const {
return {this};
}
} // namespace ksys::phys
|