|
@@ -178,17 +178,17 @@ bool CollisionSolver3DSW::soft_body_query_callback(uint32_t p_node_index, void *
|
|
|
transform_B.origin = query_cinfo.node_transform.xform(node_position);
|
|
|
|
|
|
query_cinfo.contact_info.node_index = p_node_index;
|
|
|
- solve_static(query_cinfo.shape_A, query_cinfo.transform_A, query_cinfo.shape_B, transform_B, soft_body_contact_callback, &query_cinfo.contact_info);
|
|
|
+ bool collided = solve_static(query_cinfo.shape_A, query_cinfo.transform_A, query_cinfo.shape_B, transform_B, soft_body_contact_callback, &query_cinfo.contact_info);
|
|
|
|
|
|
#ifdef DEBUG_ENABLED
|
|
|
++query_cinfo.node_query_count;
|
|
|
#endif
|
|
|
|
|
|
- // Continue with the query.
|
|
|
- return false;
|
|
|
+ // Stop at first collision if contacts are not needed.
|
|
|
+ return (collided && !query_cinfo.contact_info.result_callback);
|
|
|
}
|
|
|
|
|
|
-void CollisionSolver3DSW::soft_body_concave_callback(void *p_userdata, Shape3DSW *p_convex) {
|
|
|
+bool CollisionSolver3DSW::soft_body_concave_callback(void *p_userdata, Shape3DSW *p_convex) {
|
|
|
_SoftBodyQueryInfo &query_cinfo = *(_SoftBodyQueryInfo *)(p_userdata);
|
|
|
|
|
|
query_cinfo.shape_A = p_convex;
|
|
@@ -210,9 +210,14 @@ void CollisionSolver3DSW::soft_body_concave_callback(void *p_userdata, Shape3DSW
|
|
|
|
|
|
query_cinfo.soft_body->query_aabb(shape_aabb, soft_body_query_callback, &query_cinfo);
|
|
|
|
|
|
+ bool collided = (query_cinfo.contact_info.contact_count > 0);
|
|
|
+
|
|
|
#ifdef DEBUG_ENABLED
|
|
|
++query_cinfo.convex_query_count;
|
|
|
#endif
|
|
|
+
|
|
|
+ // Stop at first collision if contacts are not needed.
|
|
|
+ return (collided && !query_cinfo.contact_info.result_callback);
|
|
|
}
|
|
|
|
|
|
bool CollisionSolver3DSW::solve_soft_body(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result) {
|
|
@@ -286,17 +291,20 @@ struct _ConcaveCollisionInfo {
|
|
|
Vector3 close_A, close_B;
|
|
|
};
|
|
|
|
|
|
-void CollisionSolver3DSW::concave_callback(void *p_userdata, Shape3DSW *p_convex) {
|
|
|
+bool CollisionSolver3DSW::concave_callback(void *p_userdata, Shape3DSW *p_convex) {
|
|
|
_ConcaveCollisionInfo &cinfo = *(_ConcaveCollisionInfo *)(p_userdata);
|
|
|
cinfo.aabb_tests++;
|
|
|
|
|
|
bool collided = collision_solver(cinfo.shape_A, *cinfo.transform_A, p_convex, *cinfo.transform_B, cinfo.result_callback, cinfo.userdata, cinfo.swap_result, nullptr, cinfo.margin_A, cinfo.margin_B);
|
|
|
if (!collided) {
|
|
|
- return;
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
cinfo.collided = true;
|
|
|
cinfo.collisions++;
|
|
|
+
|
|
|
+ // Stop at first collision if contacts are not needed.
|
|
|
+ return !cinfo.result_callback;
|
|
|
}
|
|
|
|
|
|
bool CollisionSolver3DSW::solve_concave(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, real_t p_margin_A, real_t p_margin_B) {
|
|
@@ -413,19 +421,18 @@ bool CollisionSolver3DSW::solve_static(const Shape3DSW *p_shape_A, const Transfo
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void CollisionSolver3DSW::concave_distance_callback(void *p_userdata, Shape3DSW *p_convex) {
|
|
|
+bool CollisionSolver3DSW::concave_distance_callback(void *p_userdata, Shape3DSW *p_convex) {
|
|
|
_ConcaveCollisionInfo &cinfo = *(_ConcaveCollisionInfo *)(p_userdata);
|
|
|
cinfo.aabb_tests++;
|
|
|
- if (cinfo.collided) {
|
|
|
- return;
|
|
|
- }
|
|
|
|
|
|
Vector3 close_A, close_B;
|
|
|
cinfo.collided = !gjk_epa_calculate_distance(cinfo.shape_A, *cinfo.transform_A, p_convex, *cinfo.transform_B, close_A, close_B);
|
|
|
|
|
|
if (cinfo.collided) {
|
|
|
- return;
|
|
|
+ // No need to process any more result.
|
|
|
+ return true;
|
|
|
}
|
|
|
+
|
|
|
if (!cinfo.tested || close_A.distance_squared_to(close_B) < cinfo.close_A.distance_squared_to(cinfo.close_B)) {
|
|
|
cinfo.close_A = close_A;
|
|
|
cinfo.close_B = close_B;
|
|
@@ -433,6 +440,7 @@ void CollisionSolver3DSW::concave_distance_callback(void *p_userdata, Shape3DSW
|
|
|
}
|
|
|
|
|
|
cinfo.collisions++;
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
bool CollisionSolver3DSW::solve_distance_plane(const Shape3DSW *p_shape_A, const Transform3D &p_transform_A, const Shape3DSW *p_shape_B, const Transform3D &p_transform_B, Vector3 &r_point_A, Vector3 &r_point_B) {
|