Fix precision in physics supports generation

Lower threshold for dot was (1.0 - threshold) which is incorrect.
Patch changes it to correct version sqrt(1.0 - threshold * threshold)

Co-authored-by: Ricardo Buring <ricardo.buring@gmail.com>
This commit is contained in:
Black-Cat
2023-04-23 19:03:19 +01:00
parent 9f12e7b52d
commit d710af2e97
3 changed files with 25 additions and 23 deletions

View File

@@ -179,7 +179,7 @@ Variant GodotSeparationRayShape2D::get_data() const {
/*********************************************************/
void GodotSegmentShape2D::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const {
if (Math::abs(p_normal.dot(n)) > _SEGMENT_IS_VALID_SUPPORT_THRESHOLD) {
if (Math::abs(p_normal.dot(n)) > segment_is_valid_support_threshold) {
r_supports[0] = a;
r_supports[1] = b;
r_amount = 2;
@@ -308,7 +308,7 @@ void GodotRectangleShape2D::get_supports(const Vector2 &p_normal, Vector2 *r_sup
Vector2 ag;
ag[i] = 1.0;
real_t dp = ag.dot(p_normal);
if (Math::abs(dp) < _SEGMENT_IS_VALID_SUPPORT_THRESHOLD) {
if (Math::abs(dp) <= segment_is_valid_support_threshold) {
continue;
}
@@ -368,10 +368,9 @@ Variant GodotRectangleShape2D::get_data() const {
void GodotCapsuleShape2D::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const {
Vector2 n = p_normal;
real_t d = n.y;
real_t h = height * 0.5 - radius; // half-height of the rectangle part
if (h > 0 && Math::abs(d) < (1.0 - _SEGMENT_IS_VALID_SUPPORT_THRESHOLD)) {
if (h > 0 && Math::abs(n.x) > segment_is_valid_support_threshold) {
// make it flat
n.y = 0.0;
n.normalize();
@@ -384,7 +383,7 @@ void GodotCapsuleShape2D::get_supports(const Vector2 &p_normal, Vector2 *r_suppo
r_supports[1].y -= h;
} else {
n *= radius;
n.y += (d > 0) ? h : -h;
n.y += (n.y > 0) ? h : -h;
r_amount = 1;
*r_supports = n;
}
@@ -506,7 +505,7 @@ void GodotConvexPolygonShape2D::get_supports(const Vector2 &p_normal, Vector2 *r
}
//test segment
if (points[i].normal.dot(p_normal) > _SEGMENT_IS_VALID_SUPPORT_THRESHOLD) {
if (points[i].normal.dot(p_normal) > segment_is_valid_support_threshold) {
r_amount = 2;
r_supports[0] = points[i].pos;
r_supports[1] = points[(i + 1) % point_count].pos;

View File

@@ -32,7 +32,6 @@
#define GODOT_SHAPE_2D_H
#include "servers/physics_server_2d.h"
#define _SEGMENT_IS_VALID_SUPPORT_THRESHOLD 0.99998
class GodotShape2D;
@@ -53,6 +52,10 @@ class GodotShape2D {
HashMap<GodotShapeOwner2D *, int> owners;
protected:
const double segment_is_valid_support_threshold = 0.99998;
const double segment_is_valid_support_threshold_lower =
Math::sqrt(1.0 - segment_is_valid_support_threshold * segment_is_valid_support_threshold);
void configure(const Rect2 &p_aabb);
public:
@@ -95,7 +98,7 @@ public:
}
if (r_amount == 1) {
if (Math::abs(p_normal.dot(p_cast.normalized())) < (1.0 - _SEGMENT_IS_VALID_SUPPORT_THRESHOLD)) {
if (Math::abs(p_normal.dot(p_cast.normalized())) < segment_is_valid_support_threshold_lower) {
//make line because they are parallel
r_amount = 2;
r_supports[1] = r_supports[0] + p_cast;
@@ -105,7 +108,7 @@ public:
}
} else {
if (Math::abs(p_normal.dot(p_cast.normalized())) < (1.0 - _SEGMENT_IS_VALID_SUPPORT_THRESHOLD)) {
if (Math::abs(p_normal.dot(p_cast.normalized())) < segment_is_valid_support_threshold_lower) {
//optimize line and make it larger because they are parallel
if ((r_supports[1] - r_supports[0]).dot(p_cast) > 0) {
//larger towards 1