blob: ac4384a7c87b49946e45eae578624af5507906ff (
plain)
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
|
#pragma once
#include <container/seadOffsetList.h>
#include <container/seadSafeArray.h>
#include <prim/seadBitFlag.h>
#include <prim/seadNamable.h>
#include <prim/seadSafeString.h>
#include <thread/seadMutex.h>
#include "KingSystem/Physics/physDefines.h"
namespace ksys::phys {
class RigidBody;
struct CollidingBodies {
RigidBody* bodies[2];
sead::ListNode list_node;
static constexpr size_t getListNodeOffset() { return offsetof(CollidingBodies, list_node); }
};
class CollisionInfoBase {
public:
CollisionInfoBase() = default;
virtual ~CollisionInfoBase() = default;
sead::BitFlag32& getLayerMask(ContactLayerType layer_type);
const sead::BitFlag32& getLayerMask(ContactLayerType layer_type) const;
void enableLayer(ContactLayer layer);
void disableLayer(ContactLayer layer);
bool isLayerEnabled(ContactLayer layer) const;
void lock();
void unlock();
private:
// One layer mask for layer type (entity/sensor).
sead::SafeArray<sead::BitFlag32, 2> mLayerMasks;
sead::Mutex mMutex{nullptr,
sead::IDisposer::HeapNullOption::DoNotAppendDisposerIfNoHeapSpecified};
};
class CollisionInfo : public CollisionInfoBase, public sead::INamable {
public:
static CollisionInfo* make(sead::Heap* heap, const sead::SafeString& name);
static void free(CollisionInfo* info);
explicit CollisionInfo(const sead::SafeString& name);
~CollisionInfo() override;
sead::OffsetList<CollidingBodies>& getCollidingBodies() { return mCollidingBodies; }
const sead::OffsetList<CollidingBodies>& getCollidingBodies() const { return mCollidingBodies; }
bool isLinked() const { return mListNode.isLinked(); }
static constexpr size_t getListNodeOffset() { return offsetof(CollisionInfo, mListNode); }
private:
sead::OffsetList<CollidingBodies> mCollidingBodies;
sead::ListNode mListNode;
};
inline sead::BitFlag32& CollisionInfoBase::getLayerMask(ContactLayerType layer_type) {
return mLayerMasks[int(layer_type)];
}
inline const sead::BitFlag32& CollisionInfoBase::getLayerMask(ContactLayerType layer_type) const {
return mLayerMasks[int(layer_type)];
}
inline void CollisionInfoBase::enableLayer(ContactLayer layer) {
const u32 mask = makeContactLayerMask(layer);
getLayerMask(getContactLayerType(layer)).set(mask);
}
inline void CollisionInfoBase::disableLayer(ContactLayer layer) {
getLayerMask(getContactLayerType(layer)).resetBit(getContactLayerBaseRelativeValue(layer));
}
inline bool CollisionInfoBase::isLayerEnabled(ContactLayer layer) const {
const auto& mask = getLayerMask(getContactLayerType(layer));
return mask.isOnBit(getContactLayerBaseRelativeValue(layer));
}
inline void CollisionInfoBase::lock() {
mMutex.lock();
}
inline void CollisionInfoBase::unlock() {
mMutex.unlock();
}
} // namespace ksys::phys
|