Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/modules/godot_physics_3d/godot_shape_3d.h
10277 views
1
/**************************************************************************/
2
/* godot_shape_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 "core/math/geometry_3d.h"
34
#include "core/templates/local_vector.h"
35
#include "servers/physics_server_3d.h"
36
37
class GodotShape3D;
38
39
class GodotShapeOwner3D {
40
public:
41
virtual void _shape_changed() = 0;
42
virtual void remove_shape(GodotShape3D *p_shape) = 0;
43
44
virtual ~GodotShapeOwner3D() {}
45
};
46
47
class GodotShape3D {
48
RID self;
49
AABB aabb;
50
bool configured = false;
51
real_t custom_bias = 0.0;
52
53
HashMap<GodotShapeOwner3D *, int> owners;
54
55
protected:
56
void configure(const AABB &p_aabb);
57
58
public:
59
enum FeatureType {
60
FEATURE_POINT,
61
FEATURE_EDGE,
62
FEATURE_FACE,
63
FEATURE_CIRCLE,
64
};
65
66
virtual real_t get_volume() const { return aabb.get_volume(); }
67
68
_FORCE_INLINE_ void set_self(const RID &p_self) { self = p_self; }
69
_FORCE_INLINE_ RID get_self() const { return self; }
70
71
virtual PhysicsServer3D::ShapeType get_type() const = 0;
72
73
_FORCE_INLINE_ const AABB &get_aabb() const { return aabb; }
74
_FORCE_INLINE_ bool is_configured() const { return configured; }
75
76
virtual bool is_concave() const { return false; }
77
78
virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const = 0;
79
virtual Vector3 get_support(const Vector3 &p_normal) const;
80
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const = 0;
81
virtual Vector3 get_closest_point_to(const Vector3 &p_point) const = 0;
82
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal, int &r_face_index, bool p_hit_back_faces) const = 0;
83
virtual bool intersect_point(const Vector3 &p_point) const = 0;
84
virtual Vector3 get_moment_of_inertia(real_t p_mass) const = 0;
85
86
virtual void set_data(const Variant &p_data) = 0;
87
virtual Variant get_data() const = 0;
88
89
_FORCE_INLINE_ void set_custom_bias(real_t p_bias) { custom_bias = p_bias; }
90
_FORCE_INLINE_ real_t get_custom_bias() const { return custom_bias; }
91
92
void add_owner(GodotShapeOwner3D *p_owner);
93
void remove_owner(GodotShapeOwner3D *p_owner);
94
bool is_owner(GodotShapeOwner3D *p_owner) const;
95
const HashMap<GodotShapeOwner3D *, int> &get_owners() const;
96
97
GodotShape3D() {}
98
virtual ~GodotShape3D();
99
};
100
101
class GodotConcaveShape3D : public GodotShape3D {
102
public:
103
virtual bool is_concave() const override { return true; }
104
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const override { r_amount = 0; }
105
106
// Returns true to stop the query.
107
typedef bool (*QueryCallback)(void *p_userdata, GodotShape3D *p_convex);
108
109
virtual void cull(const AABB &p_local_aabb, QueryCallback p_callback, void *p_userdata, bool p_invert_backface_collision) const = 0;
110
111
GodotConcaveShape3D() {}
112
};
113
114
class GodotWorldBoundaryShape3D : public GodotShape3D {
115
Plane plane;
116
117
void _setup(const Plane &p_plane);
118
119
public:
120
Plane get_plane() const;
121
122
virtual real_t get_volume() const override { return Math::INF; }
123
virtual PhysicsServer3D::ShapeType get_type() const override { return PhysicsServer3D::SHAPE_WORLD_BOUNDARY; }
124
virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const override;
125
virtual Vector3 get_support(const Vector3 &p_normal) const override;
126
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const override { r_amount = 0; }
127
128
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal, int &r_face_index, bool p_hit_back_faces) const override;
129
virtual bool intersect_point(const Vector3 &p_point) const override;
130
virtual Vector3 get_closest_point_to(const Vector3 &p_point) const override;
131
virtual Vector3 get_moment_of_inertia(real_t p_mass) const override;
132
133
virtual void set_data(const Variant &p_data) override;
134
virtual Variant get_data() const override;
135
136
GodotWorldBoundaryShape3D();
137
};
138
139
class GodotSeparationRayShape3D : public GodotShape3D {
140
real_t length = 1.0;
141
bool slide_on_slope = false;
142
143
void _setup(real_t p_length, bool p_slide_on_slope);
144
145
public:
146
real_t get_length() const;
147
bool get_slide_on_slope() const;
148
149
virtual real_t get_volume() const override { return 0.0; }
150
virtual PhysicsServer3D::ShapeType get_type() const override { return PhysicsServer3D::SHAPE_SEPARATION_RAY; }
151
virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const override;
152
virtual Vector3 get_support(const Vector3 &p_normal) const override;
153
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const override;
154
155
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal, int &r_face_index, bool p_hit_back_faces) const override;
156
virtual bool intersect_point(const Vector3 &p_point) const override;
157
virtual Vector3 get_closest_point_to(const Vector3 &p_point) const override;
158
159
virtual Vector3 get_moment_of_inertia(real_t p_mass) const override;
160
161
virtual void set_data(const Variant &p_data) override;
162
virtual Variant get_data() const override;
163
164
GodotSeparationRayShape3D();
165
};
166
167
class GodotSphereShape3D : public GodotShape3D {
168
real_t radius = 0.0;
169
170
void _setup(real_t p_radius);
171
172
public:
173
real_t get_radius() const;
174
175
virtual real_t get_volume() const override { return 4.0 / 3.0 * Math::PI * radius * radius * radius; }
176
177
virtual PhysicsServer3D::ShapeType get_type() const override { return PhysicsServer3D::SHAPE_SPHERE; }
178
179
virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const override;
180
virtual Vector3 get_support(const Vector3 &p_normal) const override;
181
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const override;
182
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal, int &r_face_index, bool p_hit_back_faces) const override;
183
virtual bool intersect_point(const Vector3 &p_point) const override;
184
virtual Vector3 get_closest_point_to(const Vector3 &p_point) const override;
185
186
virtual Vector3 get_moment_of_inertia(real_t p_mass) const override;
187
188
virtual void set_data(const Variant &p_data) override;
189
virtual Variant get_data() const override;
190
191
GodotSphereShape3D();
192
};
193
194
class GodotBoxShape3D : public GodotShape3D {
195
Vector3 half_extents;
196
void _setup(const Vector3 &p_half_extents);
197
198
public:
199
_FORCE_INLINE_ Vector3 get_half_extents() const { return half_extents; }
200
virtual real_t get_volume() const override { return 8 * half_extents.x * half_extents.y * half_extents.z; }
201
202
virtual PhysicsServer3D::ShapeType get_type() const override { return PhysicsServer3D::SHAPE_BOX; }
203
204
virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const override;
205
virtual Vector3 get_support(const Vector3 &p_normal) const override;
206
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const override;
207
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal, int &r_face_index, bool p_hit_back_faces) const override;
208
virtual bool intersect_point(const Vector3 &p_point) const override;
209
virtual Vector3 get_closest_point_to(const Vector3 &p_point) const override;
210
211
virtual Vector3 get_moment_of_inertia(real_t p_mass) const override;
212
213
virtual void set_data(const Variant &p_data) override;
214
virtual Variant get_data() const override;
215
216
GodotBoxShape3D();
217
};
218
219
class GodotCapsuleShape3D : public GodotShape3D {
220
real_t height = 0.0;
221
real_t radius = 0.0;
222
223
void _setup(real_t p_height, real_t p_radius);
224
225
public:
226
_FORCE_INLINE_ real_t get_height() const { return height; }
227
_FORCE_INLINE_ real_t get_radius() const { return radius; }
228
229
virtual real_t get_volume() const override { return 4.0 / 3.0 * Math::PI * radius * radius * radius + (height - radius * 2.0) * Math::PI * radius * radius; }
230
231
virtual PhysicsServer3D::ShapeType get_type() const override { return PhysicsServer3D::SHAPE_CAPSULE; }
232
233
virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const override;
234
virtual Vector3 get_support(const Vector3 &p_normal) const override;
235
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const override;
236
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal, int &r_face_index, bool p_hit_back_faces) const override;
237
virtual bool intersect_point(const Vector3 &p_point) const override;
238
virtual Vector3 get_closest_point_to(const Vector3 &p_point) const override;
239
240
virtual Vector3 get_moment_of_inertia(real_t p_mass) const override;
241
242
virtual void set_data(const Variant &p_data) override;
243
virtual Variant get_data() const override;
244
245
GodotCapsuleShape3D();
246
};
247
248
class GodotCylinderShape3D : public GodotShape3D {
249
real_t height = 0.0;
250
real_t radius = 0.0;
251
252
void _setup(real_t p_height, real_t p_radius);
253
254
public:
255
_FORCE_INLINE_ real_t get_height() const { return height; }
256
_FORCE_INLINE_ real_t get_radius() const { return radius; }
257
258
virtual real_t get_volume() const override { return height * Math::PI * radius * radius; }
259
260
virtual PhysicsServer3D::ShapeType get_type() const override { return PhysicsServer3D::SHAPE_CYLINDER; }
261
262
virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const override;
263
virtual Vector3 get_support(const Vector3 &p_normal) const override;
264
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const override;
265
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal, int &r_face_index, bool p_hit_back_faces) const override;
266
virtual bool intersect_point(const Vector3 &p_point) const override;
267
virtual Vector3 get_closest_point_to(const Vector3 &p_point) const override;
268
269
virtual Vector3 get_moment_of_inertia(real_t p_mass) const override;
270
271
virtual void set_data(const Variant &p_data) override;
272
virtual Variant get_data() const override;
273
274
GodotCylinderShape3D();
275
};
276
277
struct GodotConvexPolygonShape3D : public GodotShape3D {
278
Geometry3D::MeshData mesh;
279
LocalVector<int> extreme_vertices;
280
LocalVector<LocalVector<int>> vertex_neighbors;
281
282
void _setup(const Vector<Vector3> &p_vertices);
283
284
public:
285
const Geometry3D::MeshData &get_mesh() const { return mesh; }
286
287
virtual PhysicsServer3D::ShapeType get_type() const override { return PhysicsServer3D::SHAPE_CONVEX_POLYGON; }
288
289
virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const override;
290
virtual Vector3 get_support(const Vector3 &p_normal) const override;
291
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const override;
292
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal, int &r_face_index, bool p_hit_back_faces) const override;
293
virtual bool intersect_point(const Vector3 &p_point) const override;
294
virtual Vector3 get_closest_point_to(const Vector3 &p_point) const override;
295
296
virtual Vector3 get_moment_of_inertia(real_t p_mass) const override;
297
298
virtual void set_data(const Variant &p_data) override;
299
virtual Variant get_data() const override;
300
301
GodotConvexPolygonShape3D();
302
};
303
304
struct _Volume_BVH;
305
struct GodotFaceShape3D;
306
307
struct GodotConcavePolygonShape3D : public GodotConcaveShape3D {
308
// always a trimesh
309
310
struct Face {
311
Vector3 normal;
312
int indices[3] = {};
313
};
314
315
Vector<Face> faces;
316
Vector<Vector3> vertices;
317
318
struct BVH {
319
AABB aabb;
320
int left = 0;
321
int right = 0;
322
323
int face_index = 0;
324
};
325
326
Vector<BVH> bvh;
327
328
struct _CullParams {
329
AABB aabb;
330
QueryCallback callback = nullptr;
331
void *userdata = nullptr;
332
const Face *faces = nullptr;
333
const Vector3 *vertices = nullptr;
334
const BVH *bvh = nullptr;
335
GodotFaceShape3D *face = nullptr;
336
};
337
338
struct _SegmentCullParams {
339
Vector3 from;
340
Vector3 to;
341
Vector3 dir;
342
const Face *faces = nullptr;
343
const Vector3 *vertices = nullptr;
344
const BVH *bvh = nullptr;
345
GodotFaceShape3D *face = nullptr;
346
347
Vector3 result;
348
Vector3 normal;
349
int face_index = -1;
350
real_t min_d = 1e20;
351
int collisions = 0;
352
};
353
354
bool backface_collision = false;
355
356
void _cull_segment(int p_idx, _SegmentCullParams *p_params) const;
357
bool _cull(int p_idx, _CullParams *p_params) const;
358
359
void _fill_bvh(_Volume_BVH *p_bvh_tree, BVH *p_bvh_array, int &p_idx);
360
361
void _setup(const Vector<Vector3> &p_faces, bool p_backface_collision);
362
363
public:
364
Vector<Vector3> get_faces() const;
365
366
virtual PhysicsServer3D::ShapeType get_type() const override { return PhysicsServer3D::SHAPE_CONCAVE_POLYGON; }
367
368
virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const override;
369
virtual Vector3 get_support(const Vector3 &p_normal) const override;
370
371
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal, int &r_face_index, bool p_hit_back_faces) const override;
372
virtual bool intersect_point(const Vector3 &p_point) const override;
373
virtual Vector3 get_closest_point_to(const Vector3 &p_point) const override;
374
375
virtual void cull(const AABB &p_local_aabb, QueryCallback p_callback, void *p_userdata, bool p_invert_backface_collision) const override;
376
377
virtual Vector3 get_moment_of_inertia(real_t p_mass) const override;
378
379
virtual void set_data(const Variant &p_data) override;
380
virtual Variant get_data() const override;
381
382
GodotConcavePolygonShape3D();
383
};
384
385
struct GodotHeightMapShape3D : public GodotConcaveShape3D {
386
Vector<real_t> heights;
387
int width = 0;
388
int depth = 0;
389
Vector3 local_origin;
390
391
// Accelerator.
392
struct Range {
393
real_t min = 0.0;
394
real_t max = 0.0;
395
};
396
LocalVector<Range> bounds_grid;
397
int bounds_grid_width = 0;
398
int bounds_grid_depth = 0;
399
400
static const int BOUNDS_CHUNK_SIZE = 16;
401
402
_FORCE_INLINE_ const Range &_get_bounds_chunk(int p_x, int p_z) const {
403
return bounds_grid[(p_z * bounds_grid_width) + p_x];
404
}
405
406
_FORCE_INLINE_ real_t _get_height(int p_x, int p_z) const {
407
return heights[(p_z * width) + p_x];
408
}
409
410
_FORCE_INLINE_ void _get_point(int p_x, int p_z, Vector3 &r_point) const {
411
r_point.x = p_x - 0.5 * (width - 1.0);
412
r_point.y = _get_height(p_x, p_z);
413
r_point.z = p_z - 0.5 * (depth - 1.0);
414
}
415
416
void _get_cell(const Vector3 &p_point, int &r_x, int &r_y, int &r_z) const;
417
418
void _build_accelerator();
419
420
template <typename ProcessFunction>
421
bool _intersect_grid_segment(ProcessFunction &p_process, const Vector3 &p_begin, const Vector3 &p_end, int p_width, int p_depth, const Vector3 &offset, Vector3 &r_point, Vector3 &r_normal) const;
422
423
void _setup(const Vector<real_t> &p_heights, int p_width, int p_depth, real_t p_min_height, real_t p_max_height);
424
425
public:
426
Vector<real_t> get_heights() const;
427
int get_width() const;
428
int get_depth() const;
429
430
virtual PhysicsServer3D::ShapeType get_type() const override { return PhysicsServer3D::SHAPE_HEIGHTMAP; }
431
432
virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const override;
433
virtual Vector3 get_support(const Vector3 &p_normal) const override;
434
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal, int &r_face_index, bool p_hit_back_faces) const override;
435
virtual bool intersect_point(const Vector3 &p_point) const override;
436
437
virtual Vector3 get_closest_point_to(const Vector3 &p_point) const override;
438
virtual void cull(const AABB &p_local_aabb, QueryCallback p_callback, void *p_userdata, bool p_invert_backface_collision) const override;
439
440
virtual Vector3 get_moment_of_inertia(real_t p_mass) const override;
441
442
virtual void set_data(const Variant &p_data) override;
443
virtual Variant get_data() const override;
444
445
GodotHeightMapShape3D();
446
};
447
448
//used internally
449
struct GodotFaceShape3D : public GodotShape3D {
450
Vector3 normal; //cache
451
Vector3 vertex[3];
452
bool backface_collision = false;
453
bool invert_backface_collision = false;
454
455
virtual PhysicsServer3D::ShapeType get_type() const override { return PhysicsServer3D::SHAPE_CONCAVE_POLYGON; }
456
457
const Vector3 &get_vertex(int p_idx) const { return vertex[p_idx]; }
458
459
virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const override;
460
virtual Vector3 get_support(const Vector3 &p_normal) const override;
461
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const override;
462
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal, int &r_face_index, bool p_hit_back_faces) const override;
463
virtual bool intersect_point(const Vector3 &p_point) const override;
464
virtual Vector3 get_closest_point_to(const Vector3 &p_point) const override;
465
466
virtual Vector3 get_moment_of_inertia(real_t p_mass) const override;
467
468
virtual void set_data(const Variant &p_data) override {}
469
virtual Variant get_data() const override { return Variant(); }
470
471
GodotFaceShape3D();
472
};
473
474
struct GodotMotionShape3D : public GodotShape3D {
475
GodotShape3D *shape = nullptr;
476
Vector3 motion;
477
478
virtual PhysicsServer3D::ShapeType get_type() const override { return PhysicsServer3D::SHAPE_CONVEX_POLYGON; }
479
480
virtual void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const override {
481
Vector3 cast = p_transform.basis.xform(motion);
482
real_t mina, maxa;
483
real_t minb, maxb;
484
Transform3D ofsb = p_transform;
485
ofsb.origin += cast;
486
shape->project_range(p_normal, p_transform, mina, maxa);
487
shape->project_range(p_normal, ofsb, minb, maxb);
488
r_min = MIN(mina, minb);
489
r_max = MAX(maxa, maxb);
490
}
491
492
virtual Vector3 get_support(const Vector3 &p_normal) const override {
493
Vector3 support = shape->get_support(p_normal);
494
if (p_normal.dot(motion) > 0) {
495
support += motion;
496
}
497
return support;
498
}
499
500
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const override { r_amount = 0; }
501
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal, int &r_face_index, bool p_hit_back_faces) const override { return false; }
502
virtual bool intersect_point(const Vector3 &p_point) const override { return false; }
503
virtual Vector3 get_closest_point_to(const Vector3 &p_point) const override { return p_point; }
504
505
virtual Vector3 get_moment_of_inertia(real_t p_mass) const override { return Vector3(); }
506
507
virtual void set_data(const Variant &p_data) override {}
508
virtual Variant get_data() const override { return Variant(); }
509
510
GodotMotionShape3D() { configure(AABB()); }
511
};
512
513