summaryrefslogtreecommitdiff
path: root/src/KingSystem/Physics/System/physClosestPointQueryWithInfo.cpp
blob: 65f34b6800127b7d762f77b33683732495b0eccf (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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#include "KingSystem/Physics/System/physClosestPointQueryWithInfo.h"
#include "KingSystem/Physics/RigidBody/Shape/Sphere/physSphereRigidBody.h"
#include "KingSystem/Physics/RigidBody/Shape/Sphere/physSphereShape.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);
    }
}

SphereBasedClosestPointQuery::SphereBasedClosestPointQuery(
    const sead::Vector3f& position, float sphere_radius, ContactLayer layer, GroundHit ground_hit,
    SystemGroupHandler* group_handler, int num_points, const sead::SafeString& name, int a,
    LowPriority low_priority)
    : ClosestPointQueryWithInfo(nullptr, num_points, name, a, low_priority) {
    auto* heap = System::instance()->getPhysicsTempHeap(low_priority);

    SphereParam sphere_param;
    sphere_param.name = sead::SafeString::cEmptyString.cstr();
    sphere_param.radius = sphere_radius;
    sphere_param.contact_layer = layer;
    sphere_param.groundhit = ground_hit;
    sphere_param.motion_type = MotionType::Fixed;
    sphere_param._90 = true;
    sphere_param.system_group_handler = group_handler;
    makeAndSetSphere(&sphere_param, heap, position);
}

SphereBasedClosestPointQuery::SphereBasedClosestPointQuery(
    const sead::Vector3f& position, float sphere_radius, ContactLayer layer,
    const LayerMaskBuilder& layer_mask_builder, int num_points, const sead::SafeString& name, int a,
    LowPriority low_priority)
    : ClosestPointQueryWithInfo(nullptr, num_points, name, a, low_priority) {
    auto* heap = System::instance()->getPhysicsTempHeap(low_priority);

    SphereParam sphere_param;
    sphere_param.name = sead::SafeString::cEmptyString.cstr();
    sphere_param.radius = sphere_radius;
    sphere_param.contact_layer = layer;
    sphere_param.motion_type = MotionType::Fixed;
    sphere_param._90 = true;
    makeAndSetSphere(&sphere_param, heap, position, &layer_mask_builder);
}

SphereBasedClosestPointQuery::SphereBasedClosestPointQuery(
    const sead::Vector3f& position, float sphere_radius, const SensorCollisionMask& mask,
    SystemGroupHandler* group_handler, int num_points, const sead::SafeString& name, int a,
    LowPriority low_priority)
    : ClosestPointQueryWithInfo(nullptr, num_points, name, a, low_priority) {
    auto* heap = System::instance()->getPhysicsTempHeap(low_priority);

    SphereParam sphere_param;
    sphere_param.name = sead::SafeString::cEmptyString.cstr();
    sphere_param.radius = sphere_radius;
    sphere_param.contact_layer = ContactLayer::SensorCustomReceiver;
    sphere_param.groundhit = GroundHit::HitAll;
    sphere_param.receiver_mask = mask;
    sphere_param.motion_type = MotionType::Fixed;
    sphere_param.system_group_handler = group_handler;
    sphere_param._90 = true;
    makeAndSetSphere(&sphere_param, heap, position);
}

SphereBasedClosestPointQuery::SphereBasedClosestPointQuery(RigidBody* sphere,
                                                           const sead::Vector3f& position,
                                                           int num_points,
                                                           const sead::SafeString& name, int a,
                                                           LowPriority low_priority)
    : ClosestPointQueryWithInfo(sphere, num_points, name, a, low_priority) {
    [[maybe_unused]] auto* heap = System::instance()->getPhysicsTempHeap(low_priority);
    mSphere = sphere;
    mMtx.setTranslation(position);
}

SphereBasedClosestPointQuery::~SphereBasedClosestPointQuery() {
    if (mStatus == Status::_2 || mStatus == Status::_3) {
        delete mSphere;
    }
}

void SphereBasedClosestPointQuery::makeAndSetSphere(RigidBodyInstanceParam* sphere_param,
                                                    sead::Heap* heap,
                                                    const sead::Vector3f& position,
                                                    const LayerMaskBuilder* layer_mask_builder) {
    mSphere = SphereRigidBody::make(sphere_param, heap);
    mBody = mSphere;

    if (layer_mask_builder != nullptr) {
        setLayerMasksAndBodyCollisionFilterInfo(*layer_mask_builder);
    }

    if (mBody) {
        mMtx.setTranslation(position);
        mStatus = Status::_3;
    }
}

}  // namespace ksys::phys