Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/modules/jolt_physics/objects/jolt_area_3d.h
10278 views
1
/**************************************************************************/
2
/* jolt_area_3d.h */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#pragma once
32
33
#include "jolt_shaped_object_3d.h"
34
35
#include "servers/physics_server_3d.h"
36
37
class JoltBody3D;
38
class JoltSoftBody3D;
39
40
class JoltArea3D final : public JoltShapedObject3D {
41
public:
42
typedef PhysicsServer3D::AreaSpaceOverrideMode OverrideMode;
43
44
private:
45
struct BodyIDHasher {
46
static uint32_t hash(const JPH::BodyID &p_id) { return hash_fmix32(p_id.GetIndexAndSequenceNumber()); }
47
};
48
49
struct ShapeIDPair {
50
JPH::SubShapeID other;
51
JPH::SubShapeID self;
52
53
ShapeIDPair(JPH::SubShapeID p_other, JPH::SubShapeID p_self) :
54
other(p_other), self(p_self) {}
55
56
static uint32_t hash(const ShapeIDPair &p_pair) {
57
uint32_t hash = hash_murmur3_one_32(p_pair.other.GetValue());
58
hash = hash_murmur3_one_32(p_pair.self.GetValue(), hash);
59
return hash_fmix32(hash);
60
}
61
62
friend bool operator==(const ShapeIDPair &p_lhs, const ShapeIDPair &p_rhs) {
63
return (p_lhs.other == p_rhs.other) && (p_lhs.self == p_rhs.self);
64
}
65
};
66
67
struct ShapeIndexPair {
68
int other = -1;
69
int self = -1;
70
71
ShapeIndexPair() = default;
72
73
ShapeIndexPair(int p_other, int p_self) :
74
other(p_other), self(p_self) {}
75
76
static uint32_t hash(const ShapeIndexPair &p_pair) {
77
uint32_t hash = hash_murmur3_one_32(p_pair.other);
78
hash = hash_murmur3_one_32(p_pair.self, hash);
79
return hash_fmix32(hash);
80
}
81
82
friend bool operator==(const ShapeIndexPair &p_lhs, const ShapeIndexPair &p_rhs) {
83
return (p_lhs.other == p_rhs.other) && (p_lhs.self == p_rhs.self);
84
}
85
};
86
87
struct Overlap {
88
HashMap<ShapeIDPair, ShapeIndexPair, ShapeIDPair> shape_pairs;
89
HashMap<ShapeIndexPair, int, ShapeIndexPair> ref_counts;
90
LocalVector<ShapeIndexPair> pending_added;
91
LocalVector<ShapeIndexPair> pending_removed;
92
RID rid;
93
ObjectID instance_id;
94
};
95
96
typedef HashMap<JPH::BodyID, Overlap, BodyIDHasher> OverlapsById;
97
98
SelfList<JoltArea3D> call_queries_element;
99
100
OverlapsById bodies_by_id;
101
OverlapsById areas_by_id;
102
103
Vector3 gravity_vector = Vector3(0, -1, 0);
104
105
Callable body_monitor_callback;
106
Callable area_monitor_callback;
107
108
float priority = 0.0f;
109
float gravity = 9.8f;
110
float point_gravity_distance = 0.0f;
111
float linear_damp = 0.1f;
112
float angular_damp = 0.1f;
113
114
OverrideMode gravity_mode = PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED;
115
OverrideMode linear_damp_mode = PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED;
116
OverrideMode angular_damp_mode = PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED;
117
118
bool monitorable = false;
119
bool point_gravity = false;
120
121
virtual JPH::BroadPhaseLayer _get_broad_phase_layer() const override;
122
virtual JPH::ObjectLayer _get_object_layer() const override;
123
124
virtual JPH::EMotionType _get_motion_type() const override { return JPH::EMotionType::Kinematic; }
125
126
bool _should_sleep() const { return !is_monitoring(); }
127
128
virtual void _add_to_space() override;
129
130
void _enqueue_call_queries();
131
void _dequeue_call_queries();
132
133
void _add_shape_pair(Overlap &p_overlap, const JPH::BodyID &p_body_id, const JPH::SubShapeID &p_other_shape_id, const JPH::SubShapeID &p_self_shape_id);
134
bool _remove_shape_pair(Overlap &p_overlap, const JPH::SubShapeID &p_other_shape_id, const JPH::SubShapeID &p_self_shape_id);
135
136
void _flush_events(OverlapsById &p_objects, const Callable &p_callback);
137
138
void _report_event(const Callable &p_callback, PhysicsServer3D::AreaBodyStatus p_status, const RID &p_other_rid, ObjectID p_other_instance_id, int p_other_shape_index, int p_self_shape_index) const;
139
140
void _notify_body_entered(const JPH::BodyID &p_body_id);
141
void _notify_body_exited(const JPH::BodyID &p_body_id);
142
143
void _remove_all_overlaps();
144
145
void _update_sleeping();
146
void _update_group_filter();
147
void _update_default_gravity();
148
149
virtual void _space_changing() override;
150
virtual void _space_changed() override;
151
void _events_changed();
152
void _body_monitoring_changed();
153
void _area_monitoring_changed();
154
void _monitorable_changed();
155
void _gravity_changed();
156
157
public:
158
JoltArea3D();
159
160
bool is_default_area() const;
161
void set_default_area(bool p_value);
162
163
void set_transform(Transform3D p_transform);
164
165
Variant get_param(PhysicsServer3D::AreaParameter p_param) const;
166
void set_param(PhysicsServer3D::AreaParameter p_param, const Variant &p_value);
167
168
bool has_body_monitor_callback() const { return body_monitor_callback.is_valid(); }
169
void set_body_monitor_callback(const Callable &p_callback);
170
171
bool has_area_monitor_callback() const { return area_monitor_callback.is_valid(); }
172
void set_area_monitor_callback(const Callable &p_callback);
173
174
bool is_monitoring_bodies() const { return has_body_monitor_callback(); }
175
bool is_monitoring_areas() const { return has_area_monitor_callback(); }
176
bool is_monitoring() const { return is_monitoring_bodies() || is_monitoring_areas(); }
177
178
bool is_monitorable() const { return monitorable; }
179
void set_monitorable(bool p_monitorable);
180
181
bool can_monitor(const JoltBody3D &p_other) const;
182
bool can_monitor(const JoltSoftBody3D &p_other) const;
183
bool can_monitor(const JoltArea3D &p_other) const;
184
185
virtual bool can_interact_with(const JoltBody3D &p_other) const override;
186
virtual bool can_interact_with(const JoltSoftBody3D &p_other) const override;
187
virtual bool can_interact_with(const JoltArea3D &p_other) const override;
188
189
virtual Vector3 get_velocity_at_position(const Vector3 &p_position) const override;
190
191
virtual bool reports_contacts() const override { return false; }
192
193
bool is_point_gravity() const { return point_gravity; }
194
void set_point_gravity(bool p_enabled);
195
196
float get_priority() const { return priority; }
197
void set_priority(float p_priority) { priority = p_priority; }
198
199
float get_gravity() const { return gravity; }
200
void set_gravity(float p_gravity);
201
202
float get_point_gravity_distance() const { return point_gravity_distance; }
203
void set_point_gravity_distance(float p_distance);
204
205
float get_linear_damp() const { return linear_damp; }
206
void set_area_linear_damp(float p_damp) { linear_damp = p_damp; }
207
208
float get_angular_damp() const { return angular_damp; }
209
void set_area_angular_damp(float p_damp) { angular_damp = p_damp; }
210
211
OverrideMode get_gravity_mode() const { return gravity_mode; }
212
void set_gravity_mode(OverrideMode p_mode);
213
214
OverrideMode get_linear_damp_mode() const { return linear_damp_mode; }
215
void set_linear_damp_mode(OverrideMode p_mode) { linear_damp_mode = p_mode; }
216
217
OverrideMode get_angular_damp_mode() const { return angular_damp_mode; }
218
void set_angular_damp_mode(OverrideMode p_mode) { angular_damp_mode = p_mode; }
219
220
Vector3 get_gravity_vector() const { return gravity_vector; }
221
void set_gravity_vector(const Vector3 &p_vector);
222
223
Vector3 compute_gravity(const Vector3 &p_position) const;
224
225
void body_shape_entered(const JPH::BodyID &p_body_id, const JPH::SubShapeID &p_other_shape_id, const JPH::SubShapeID &p_self_shape_id);
226
bool body_shape_exited(const JPH::BodyID &p_body_id, const JPH::SubShapeID &p_other_shape_id, const JPH::SubShapeID &p_self_shape_id);
227
228
void area_shape_entered(const JPH::BodyID &p_body_id, const JPH::SubShapeID &p_other_shape_id, const JPH::SubShapeID &p_self_shape_id);
229
bool area_shape_exited(const JPH::BodyID &p_body_id, const JPH::SubShapeID &p_other_shape_id, const JPH::SubShapeID &p_self_shape_id);
230
231
bool shape_exited(const JPH::BodyID &p_body_id, const JPH::SubShapeID &p_other_shape_id, const JPH::SubShapeID &p_self_shape_id);
232
void body_exited(const JPH::BodyID &p_body_id, bool p_notify = true);
233
void area_exited(const JPH::BodyID &p_body_id);
234
235
void call_queries();
236
237
virtual bool has_custom_center_of_mass() const override { return false; }
238
virtual Vector3 get_center_of_mass_custom() const override { return Vector3(); }
239
};
240
241