From 141783d90f852cf008b0d11c907f14296633a6f0 Mon Sep 17 00:00:00 2001 From: Aaron Franke Date: Fri, 21 Apr 2023 01:28:55 -0500 Subject: [PATCH] [3.x] Expose `determinant` in Transform2D, rename internal method --- core/math/transform_2d.cpp | 6 +++--- core/math/transform_2d.h | 2 +- core/variant_call.cpp | 2 ++ doc/classes/Transform2D.xml | 7 +++++++ drivers/gles2/rasterizer_canvas_base_gles2.cpp | 2 +- drivers/gles3/rasterizer_canvas_base_gles3.cpp | 2 +- editor/plugins/canvas_item_editor_plugin.cpp | 2 +- modules/gdnative/gdnative/transform2d.cpp | 5 +++++ modules/gdnative/gdnative_api.json | 7 +++++++ modules/gdnative/include/gdnative/transform2d.h | 2 ++ scene/main/viewport.cpp | 4 ++-- 11 files changed, 32 insertions(+), 9 deletions(-) diff --git a/core/math/transform_2d.cpp b/core/math/transform_2d.cpp index 4f70a478779..806c35e8863 100644 --- a/core/math/transform_2d.cpp +++ b/core/math/transform_2d.cpp @@ -44,7 +44,7 @@ Transform2D Transform2D::inverse() const { } void Transform2D::affine_invert() { - real_t det = basis_determinant(); + real_t det = determinant(); #ifdef MATH_CHECKS ERR_FAIL_COND(det == 0); #endif @@ -93,7 +93,7 @@ Transform2D::Transform2D(real_t p_rot, const Vector2 &p_pos) { } Size2 Transform2D::get_scale() const { - real_t det_sign = SGN(basis_determinant()); + real_t det_sign = SGN(determinant()); return Size2(elements[0].length(), det_sign * elements[1].length()); } @@ -217,7 +217,7 @@ Transform2D Transform2D::rotated(real_t p_angle) const { return copy; } -real_t Transform2D::basis_determinant() const { +real_t Transform2D::determinant() const { return elements[0].x * elements[1].y - elements[0].y * elements[1].x; } diff --git a/core/math/transform_2d.h b/core/math/transform_2d.h index 6227a5d5d2a..e9b36eafca7 100644 --- a/core/math/transform_2d.h +++ b/core/math/transform_2d.h @@ -79,7 +79,7 @@ struct _NO_DISCARD_CLASS_ Transform2D { void translate(real_t p_tx, real_t p_ty); void translate(const Vector2 &p_translation); - real_t basis_determinant() const; + real_t determinant() const; Size2 get_scale() const; void set_scale(const Size2 &p_scale); diff --git a/core/variant_call.cpp b/core/variant_call.cpp index 59dd56aeb97..918553af659 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -886,6 +886,7 @@ struct _VariantCall { VCALL_PTR1R(Transform2D, translated); VCALL_PTR2R(Transform2D, interpolate_with); VCALL_PTR1R(Transform2D, is_equal_approx); + VCALL_PTR0R(Transform2D, determinant); static void _call_Transform2D_xform(Variant &r_ret, Variant &p_self, const Variant **p_args) { switch (p_args[0]->type) { @@ -2151,6 +2152,7 @@ void register_variant_methods() { ADDFUNC1R(TRANSFORM2D, TRANSFORM2D, Transform2D, translated, VECTOR2, "offset", varray()); ADDFUNC1R(TRANSFORM2D, NIL, Transform2D, xform, NIL, "v", varray()); ADDFUNC1R(TRANSFORM2D, NIL, Transform2D, xform_inv, NIL, "v", varray()); + ADDFUNC0R(TRANSFORM2D, REAL, Transform2D, determinant, varray()); ADDFUNC1R(TRANSFORM2D, VECTOR2, Transform2D, basis_xform, VECTOR2, "v", varray()); ADDFUNC1R(TRANSFORM2D, VECTOR2, Transform2D, basis_xform_inv, VECTOR2, "v", varray()); ADDFUNC2R(TRANSFORM2D, TRANSFORM2D, Transform2D, interpolate_with, TRANSFORM2D, "transform", REAL, "weight", varray()); diff --git a/doc/classes/Transform2D.xml b/doc/classes/Transform2D.xml index f7f1cb394a2..043f6d1b2f5 100644 --- a/doc/classes/Transform2D.xml +++ b/doc/classes/Transform2D.xml @@ -60,6 +60,13 @@ This method does not account for translation (the origin vector). + + + + Returns the determinant of the basis matrix. If the basis is uniformly scaled, then its determinant equals the square of the scale factor. + A negative determinant means the basis was flipped, so one part of the scale is negative. A zero determinant means the basis isn't invertible, and is usually considered invalid. + + diff --git a/drivers/gles2/rasterizer_canvas_base_gles2.cpp b/drivers/gles2/rasterizer_canvas_base_gles2.cpp index bd592809dbc..0040a05d71b 100644 --- a/drivers/gles2/rasterizer_canvas_base_gles2.cpp +++ b/drivers/gles2/rasterizer_canvas_base_gles2.cpp @@ -837,7 +837,7 @@ void RasterizerCanvasBaseGLES2::canvas_light_shadow_buffer_update(RID p_buffer, VS::CanvasOccluderPolygonCullMode transformed_cull_cache = instance->cull_cache; if (transformed_cull_cache != VS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED && - (p_light_xform.basis_determinant() * instance->xform_cache.basis_determinant()) < 0) { + (p_light_xform.determinant() * instance->xform_cache.determinant()) < 0) { transformed_cull_cache = (transformed_cull_cache == VS::CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE) ? VS::CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE : VS::CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE; diff --git a/drivers/gles3/rasterizer_canvas_base_gles3.cpp b/drivers/gles3/rasterizer_canvas_base_gles3.cpp index d50c655ba85..832e6739eaa 100644 --- a/drivers/gles3/rasterizer_canvas_base_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_base_gles3.cpp @@ -895,7 +895,7 @@ void RasterizerCanvasBaseGLES3::canvas_light_shadow_buffer_update(RID p_buffer, VS::CanvasOccluderPolygonCullMode transformed_cull_cache = instance->cull_cache; if (transformed_cull_cache != VS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED && - (p_light_xform.basis_determinant() * instance->xform_cache.basis_determinant()) < 0) { + (p_light_xform.determinant() * instance->xform_cache.determinant()) < 0) { transformed_cull_cache = (transformed_cull_cache == VS::CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE) ? VS::CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE : VS::CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE; diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 85ab7821a4d..4d2760c694e 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -1623,7 +1623,7 @@ void CanvasItemEditor::_solve_IK(Node2D *leaf_node, Point2 target_position) { Point2 current = (joints_list[node_id - 1]->get_global_position() - joints_list[node_id]->get_global_position()).normalized(); Point2 target = (joints_pos[node_id - 1] - joints_list[node_id]->get_global_position()).normalized(); float rot = current.angle_to(target); - if (joints_list[node_id]->get_global_transform().basis_determinant() < 0) { + if (joints_list[node_id]->get_global_transform().determinant() < 0) { rot = -rot; } joints_list[node_id]->rotate(rot); diff --git a/modules/gdnative/gdnative/transform2d.cpp b/modules/gdnative/gdnative/transform2d.cpp index d59b71173d3..6b4bfd3c236 100644 --- a/modules/gdnative/gdnative/transform2d.cpp +++ b/modules/gdnative/gdnative/transform2d.cpp @@ -93,6 +93,11 @@ godot_vector2 GDAPI godot_transform2d_get_scale(const godot_transform2d *p_self) return dest; } +godot_real GDAPI godot_transform2d_determinant(const godot_transform2d *p_self) { + const Transform2D *self = (const Transform2D *)p_self; + return self->determinant(); +} + godot_transform2d GDAPI godot_transform2d_orthonormalized(const godot_transform2d *p_self) { godot_transform2d dest; const Transform2D *self = (const Transform2D *)p_self; diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json index 2e7e315940a..c8827a3b6ef 100644 --- a/modules/gdnative/gdnative_api.json +++ b/modules/gdnative/gdnative_api.json @@ -4431,6 +4431,13 @@ ["const godot_transform2d *", "p_self"] ] }, + { + "name": "godot_transform2d_determinant", + "return_type": "godot_real", + "arguments": [ + ["const godot_transform2d *", "p_self"] + ] + }, { "name": "godot_transform2d_orthonormalized", "return_type": "godot_transform2d", diff --git a/modules/gdnative/include/gdnative/transform2d.h b/modules/gdnative/include/gdnative/transform2d.h index cb02158e70a..4b997fbad39 100644 --- a/modules/gdnative/include/gdnative/transform2d.h +++ b/modules/gdnative/include/gdnative/transform2d.h @@ -74,6 +74,8 @@ godot_vector2 GDAPI godot_transform2d_get_origin(const godot_transform2d *p_self godot_vector2 GDAPI godot_transform2d_get_scale(const godot_transform2d *p_self); +godot_real GDAPI godot_transform2d_determinant(const godot_transform2d *p_self); + godot_transform2d GDAPI godot_transform2d_orthonormalized(const godot_transform2d *p_self); godot_transform2d GDAPI godot_transform2d_rotated(const godot_transform2d *p_self, const godot_real p_phi); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 78e17f498c8..83694541ae2 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -1786,8 +1786,8 @@ Control *Viewport::_gui_find_control_at_pos(CanvasItem *p_node, const Point2 &p_ } Transform2D matrix = p_xform * p_node->get_transform(); - // matrix.basis_determinant() == 0.0f implies that node does not exist on scene - if (matrix.basis_determinant() == 0.0f) { + // matrix.determinant() == 0.0f implies that node does not exist on scene + if (matrix.determinant() == 0.0f) { return nullptr; }