summaryrefslogtreecommitdiff
path: root/servers/physics_2d
diff options
context:
space:
mode:
Diffstat (limited to 'servers/physics_2d')
-rw-r--r--servers/physics_2d/godot_body_pair_2d.cpp5
-rw-r--r--servers/physics_2d/godot_broad_phase_2d_bvh.cpp16
-rw-r--r--servers/physics_2d/godot_broad_phase_2d_bvh.h29
-rw-r--r--servers/physics_2d/godot_collision_object_2d.h2
-rw-r--r--servers/physics_2d/godot_collision_solver_2d_sat.cpp4
-rw-r--r--servers/physics_2d/godot_physics_server_2d.cpp13
-rw-r--r--servers/physics_2d/godot_shape_2d.cpp6
-rw-r--r--servers/physics_2d/godot_space_2d.cpp12
8 files changed, 46 insertions, 41 deletions
diff --git a/servers/physics_2d/godot_body_pair_2d.cpp b/servers/physics_2d/godot_body_pair_2d.cpp
index 1986191cc3..2bf1e5a1d4 100644
--- a/servers/physics_2d/godot_body_pair_2d.cpp
+++ b/servers/physics_2d/godot_body_pair_2d.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "godot_body_pair_2d.h"
+
#include "godot_collision_solver_2d.h"
#include "godot_space_2d.h"
@@ -303,7 +304,7 @@ bool GodotBodyPair2D::setup(real_t p_step) {
bool valid = false;
for (int i = 0; i < contact_count; i++) {
Contact &c = contacts[i];
- if (c.normal.dot(direction) > -CMP_EPSILON) { //greater (normal inverted)
+ if (c.normal.dot(direction) > -CMP_EPSILON) { // Greater (normal inverted).
continue;
}
valid = true;
@@ -321,7 +322,7 @@ bool GodotBodyPair2D::setup(real_t p_step) {
bool valid = false;
for (int i = 0; i < contact_count; i++) {
Contact &c = contacts[i];
- if (c.normal.dot(direction) < CMP_EPSILON) { //less (normal ok)
+ if (c.normal.dot(direction) < CMP_EPSILON) { // Less (normal ok).
continue;
}
valid = true;
diff --git a/servers/physics_2d/godot_broad_phase_2d_bvh.cpp b/servers/physics_2d/godot_broad_phase_2d_bvh.cpp
index 5a96dae8ca..06f035a506 100644
--- a/servers/physics_2d/godot_broad_phase_2d_bvh.cpp
+++ b/servers/physics_2d/godot_broad_phase_2d_bvh.cpp
@@ -32,7 +32,9 @@
#include "godot_collision_object_2d.h"
GodotBroadPhase2D::ID GodotBroadPhase2DBVH::create(GodotCollisionObject2D *p_object, int p_subindex, const Rect2 &p_aabb, bool p_static) {
- ID oid = bvh.create(p_object, true, p_aabb, p_subindex, !p_static, 1 << p_object->get_type(), p_static ? 0 : 0xFFFFF); // Pair everything, don't care?
+ uint32_t tree_id = p_static ? TREE_STATIC : TREE_DYNAMIC;
+ uint32_t tree_collision_mask = p_static ? TREE_FLAG_DYNAMIC : (TREE_FLAG_STATIC | TREE_FLAG_DYNAMIC);
+ ID oid = bvh.create(p_object, true, tree_id, tree_collision_mask, p_aabb, p_subindex); // Pair everything, don't care?
return oid + 1;
}
@@ -41,8 +43,9 @@ void GodotBroadPhase2DBVH::move(ID p_id, const Rect2 &p_aabb) {
}
void GodotBroadPhase2DBVH::set_static(ID p_id, bool p_static) {
- GodotCollisionObject2D *it = bvh.get(p_id - 1);
- bvh.set_pairable(p_id - 1, !p_static, 1 << it->get_type(), p_static ? 0 : 0xFFFFF, false); // Pair everything, don't care?
+ uint32_t tree_id = p_static ? TREE_STATIC : TREE_DYNAMIC;
+ uint32_t tree_collision_mask = p_static ? TREE_FLAG_DYNAMIC : (TREE_FLAG_STATIC | TREE_FLAG_DYNAMIC);
+ bvh.set_tree(p_id - 1, tree_id, tree_collision_mask, false);
}
void GodotBroadPhase2DBVH::remove(ID p_id) {
@@ -56,7 +59,8 @@ GodotCollisionObject2D *GodotBroadPhase2DBVH::get_object(ID p_id) const {
}
bool GodotBroadPhase2DBVH::is_static(ID p_id) const {
- return !bvh.is_pairable(p_id - 1);
+ uint32_t tree_id = bvh.get_tree_id(p_id - 1);
+ return tree_id == 0;
}
int GodotBroadPhase2DBVH::get_subindex(ID p_id) const {
@@ -64,11 +68,11 @@ int GodotBroadPhase2DBVH::get_subindex(ID p_id) const {
}
int GodotBroadPhase2DBVH::cull_segment(const Vector2 &p_from, const Vector2 &p_to, GodotCollisionObject2D **p_results, int p_max_results, int *p_result_indices) {
- return bvh.cull_segment(p_from, p_to, p_results, p_max_results, p_result_indices);
+ return bvh.cull_segment(p_from, p_to, p_results, p_max_results, nullptr, 0xFFFFFFFF, p_result_indices);
}
int GodotBroadPhase2DBVH::cull_aabb(const Rect2 &p_aabb, GodotCollisionObject2D **p_results, int p_max_results, int *p_result_indices) {
- return bvh.cull_aabb(p_aabb, p_results, p_max_results, p_result_indices);
+ return bvh.cull_aabb(p_aabb, p_results, p_max_results, nullptr, 0xFFFFFFFF, p_result_indices);
}
void *GodotBroadPhase2DBVH::_pair_callback(void *self, uint32_t p_A, GodotCollisionObject2D *p_object_A, int subindex_A, uint32_t p_B, GodotCollisionObject2D *p_object_B, int subindex_B) {
diff --git a/servers/physics_2d/godot_broad_phase_2d_bvh.h b/servers/physics_2d/godot_broad_phase_2d_bvh.h
index d77e0574eb..b11ad0e75e 100644
--- a/servers/physics_2d/godot_broad_phase_2d_bvh.h
+++ b/servers/physics_2d/godot_broad_phase_2d_bvh.h
@@ -38,7 +38,34 @@
#include "core/math/vector2.h"
class GodotBroadPhase2DBVH : public GodotBroadPhase2D {
- BVH_Manager<GodotCollisionObject2D, true, 128, Rect2, Vector2> bvh;
+ template <class T>
+ class UserPairTestFunction {
+ public:
+ static bool user_pair_check(const T *p_a, const T *p_b) {
+ // return false if no collision, decided by masks etc
+ return p_a->interacts_with(p_b);
+ }
+ };
+
+ template <class T>
+ class UserCullTestFunction {
+ public:
+ static bool user_cull_check(const T *p_a, const T *p_b) {
+ return true;
+ }
+ };
+
+ enum Tree {
+ TREE_STATIC = 0,
+ TREE_DYNAMIC = 1,
+ };
+
+ enum TreeFlag {
+ TREE_FLAG_STATIC = 1 << TREE_STATIC,
+ TREE_FLAG_DYNAMIC = 1 << TREE_DYNAMIC,
+ };
+
+ BVH_Manager<GodotCollisionObject2D, 2, true, 128, UserPairTestFunction<GodotCollisionObject2D>, UserCullTestFunction<GodotCollisionObject2D>, Rect2, Vector2> bvh;
static void *_pair_callback(void *, uint32_t, GodotCollisionObject2D *, int, uint32_t, GodotCollisionObject2D *, int);
static void _unpair_callback(void *, uint32_t, GodotCollisionObject2D *, int, uint32_t, GodotCollisionObject2D *, int, void *);
diff --git a/servers/physics_2d/godot_collision_object_2d.h b/servers/physics_2d/godot_collision_object_2d.h
index 1e9baad8d9..19d6e91561 100644
--- a/servers/physics_2d/godot_collision_object_2d.h
+++ b/servers/physics_2d/godot_collision_object_2d.h
@@ -180,7 +180,7 @@ public:
return p_other->collision_layer & collision_mask;
}
- _FORCE_INLINE_ bool interacts_with(GodotCollisionObject2D *p_other) const {
+ _FORCE_INLINE_ bool interacts_with(const GodotCollisionObject2D *p_other) const {
return collision_layer & p_other->collision_mask || p_other->collision_layer & collision_mask;
}
diff --git a/servers/physics_2d/godot_collision_solver_2d_sat.cpp b/servers/physics_2d/godot_collision_solver_2d_sat.cpp
index a965795bee..ded3ff356b 100644
--- a/servers/physics_2d/godot_collision_solver_2d_sat.cpp
+++ b/servers/physics_2d/godot_collision_solver_2d_sat.cpp
@@ -41,10 +41,6 @@ struct _CollectorCallback2D {
Vector2 *sep_axis = nullptr;
_FORCE_INLINE_ void call(const Vector2 &p_point_A, const Vector2 &p_point_B) {
- /*
- if (normal.dot(p_point_A) >= normal.dot(p_point_B))
- return;
- */
if (swap) {
callback(p_point_B, p_point_A, userdata);
} else {
diff --git a/servers/physics_2d/godot_physics_server_2d.cpp b/servers/physics_2d/godot_physics_server_2d.cpp
index 5e099e27ec..a9b499c6b5 100644
--- a/servers/physics_2d/godot_physics_server_2d.cpp
+++ b/servers/physics_2d/godot_physics_server_2d.cpp
@@ -1188,14 +1188,6 @@ void GodotPhysicsServer2D::free(RID p_rid) {
} else if (body_owner.owns(p_rid)) {
GodotBody2D *body = body_owner.get_or_null(p_rid);
- /*
- if (body->get_state_query())
- _clear_query(body->get_state_query());
-
- if (body->get_direct_state_query())
- _clear_query(body->get_direct_state_query());
- */
-
body_set_space(p_rid, RID());
while (body->get_shape_count()) {
@@ -1208,11 +1200,6 @@ void GodotPhysicsServer2D::free(RID p_rid) {
} else if (area_owner.owns(p_rid)) {
GodotArea2D *area = area_owner.get_or_null(p_rid);
- /*
- if (area->get_monitor_query())
- _clear_query(area->get_monitor_query());
- */
-
area->set_space(nullptr);
while (area->get_shape_count()) {
diff --git a/servers/physics_2d/godot_shape_2d.cpp b/servers/physics_2d/godot_shape_2d.cpp
index 1e8799a727..b5dbb8a2dd 100644
--- a/servers/physics_2d/godot_shape_2d.cpp
+++ b/servers/physics_2d/godot_shape_2d.cpp
@@ -544,12 +544,6 @@ bool GodotConvexPolygonShape2D::intersect_segment(const Vector2 &p_begin, const
bool inters = false;
for (int i = 0; i < point_count; i++) {
- //hmm.. no can do..
- /*
- if (d.dot(points[i].normal)>=0)
- continue;
- */
-
Vector2 res;
if (!Geometry2D::segment_intersects_segment(p_begin, p_end, points[i].pos, points[(i + 1) % point_count].pos, &res)) {
diff --git a/servers/physics_2d/godot_space_2d.cpp b/servers/physics_2d/godot_space_2d.cpp
index 5c2bda340b..04b8d3c741 100644
--- a/servers/physics_2d/godot_space_2d.cpp
+++ b/servers/physics_2d/godot_space_2d.cpp
@@ -888,6 +888,9 @@ bool GodotSpace2D::test_body_motion(GodotBody2D *p_body, const PhysicsServer2D::
// Allowed depth can't be lower than motion length, in order to handle contacts at low speed.
rcd.min_allowed_depth = MIN(motion_length, min_contact_depth);
+ body_aabb.position += p_parameters.motion * unsafe;
+ int amount = _cull_aabb_for_body(p_body, body_aabb);
+
int from_shape = best_shape != -1 ? best_shape : 0;
int to_shape = best_shape != -1 ? best_shape + 1 : p_body->get_shape_count();
@@ -899,10 +902,6 @@ bool GodotSpace2D::test_body_motion(GodotBody2D *p_body, const PhysicsServer2D::
Transform2D body_shape_xform = ugt * p_body->get_shape_transform(j);
GodotShape2D *body_shape = p_body->get_shape(j);
- body_aabb.position += p_parameters.motion * unsafe;
-
- int amount = _cull_aabb_for_body(p_body, body_aabb);
-
for (int i = 0; i < amount; i++) {
const GodotCollisionObject2D *col_obj = intersection_query_results[i];
if (p_parameters.exclude_bodies.has(col_obj->get_self())) {
@@ -996,11 +995,8 @@ bool GodotSpace2D::test_body_motion(GodotBody2D *p_body, const PhysicsServer2D::
return collided;
}
+// Assumes a valid collision pair, this should have been checked beforehand in the BVH or octree.
void *GodotSpace2D::_broadphase_pair(GodotCollisionObject2D *A, int p_subindex_A, GodotCollisionObject2D *B, int p_subindex_B, void *p_self) {
- if (!A->interacts_with(B)) {
- return nullptr;
- }
-
GodotCollisionObject2D::Type type_A = A->get_type();
GodotCollisionObject2D::Type type_B = B->get_type();
if (type_A > type_B) {