From faaf48d6a764529f8b4e2a058a5380296904a0c6 Mon Sep 17 00:00:00 2001 From: Rob Kelly Date: Fri, 7 Mar 2025 18:18:50 -0700 Subject: [PATCH] Refactored generic geometric utilities out of GunkBody --- src/util/geometry_tools.gd | 25 +++++++++++++++++++++++++ src/util/geometry_tools.gd.uid | 1 + src/world/gunk_body/gunk_body.gd | 27 ++------------------------- 3 files changed, 28 insertions(+), 25 deletions(-) create mode 100644 src/util/geometry_tools.gd create mode 100644 src/util/geometry_tools.gd.uid diff --git a/src/util/geometry_tools.gd b/src/util/geometry_tools.gd new file mode 100644 index 0000000..8589f68 --- /dev/null +++ b/src/util/geometry_tools.gd @@ -0,0 +1,25 @@ +class_name GeometryTools +## Utilities for specialized geometric operations. + + +## Transform cartesian coordinates to barycentric wrt the given triangle. +static func barycentric(p: Vector3, a: Vector3, b: Vector3, c: Vector3) -> Vector3: + var v0 := b - a + var v1 := c - a + var v2 := p - a + var d00 := v0.dot(v0) + var d01 := v0.dot(v1) + var d11 := v1.dot(v1) + var d20 := v2.dot(v0) + var d21 := v2.dot(v1) + var denom := d00 * d11 - d01 * d01 + var v := (d11 * d20 - d01 * d21) / denom + var w := (d00 * d21 - d01 * d20) / denom + var u := 1.0 - v - w + return Vector3(u, v, w) + + +## Is the given point on the planar triangle defined by v1, v2, and v3? +static func is_in_triangle(point: Vector3, v1: Vector3, v2: Vector3, v3: Vector3) -> bool: + var bc := barycentric(point, v1, v2, v3) + return (bc.x > 0 and bc.x < 1) and (bc.y > 0 and bc.y < 1) and (bc.z > 0 and bc.z < 1) diff --git a/src/util/geometry_tools.gd.uid b/src/util/geometry_tools.gd.uid new file mode 100644 index 0000000..0233ed5 --- /dev/null +++ b/src/util/geometry_tools.gd.uid @@ -0,0 +1 @@ +uid://cgh4qc5whocql diff --git a/src/world/gunk_body/gunk_body.gd b/src/world/gunk_body/gunk_body.gd index 2f95c52..dba6680 100644 --- a/src/world/gunk_body/gunk_body.gd +++ b/src/world/gunk_body/gunk_body.gd @@ -118,29 +118,6 @@ func get_clear_total() -> float: return total -## Transform cartesian coordinates to barycentric wrt the given triangle. -func _barycentric(p: Vector3, a: Vector3, b: Vector3, c: Vector3) -> Vector3: - var v0 := b - a - var v1 := c - a - var v2 := p - a - var d00 := v0.dot(v0) - var d01 := v0.dot(v1) - var d11 := v1.dot(v1) - var d20 := v2.dot(v0) - var d21 := v2.dot(v1) - var denom := d00 * d11 - d01 * d01 - var v := (d11 * d20 - d01 * d21) / denom - var w := (d00 * d21 - d01 * d20) / denom - var u := 1.0 - v - w - return Vector3(u, v, w) - - -## Is the given point on the planar triangle defined by v1, v2, and v3? -func _is_in_triangle(point: Vector3, v1: Vector3, v2: Vector3, v3: Vector3) -> bool: - var bc := _barycentric(point, v1, v2, v3) - return (bc.x > 0 and bc.x < 1) and (bc.y > 0 and bc.y < 1) and (bc.z > 0 and bc.z < 1) - - ## Get the index of the mesh face on which the given point+normal lies. ## ## Returns -1 if the given point+normal does not lie on a mesh face within tolerance. @@ -156,7 +133,7 @@ func _get_face(point: Vector3, normal: Vector3) -> int: var v1 := meshtool.get_vertex(meshtool.get_face_vertex(i, 0)) var v2 := meshtool.get_vertex(meshtool.get_face_vertex(i, 1)) var v3 := meshtool.get_vertex(meshtool.get_face_vertex(i, 2)) - if _is_in_triangle(point, v1, v2, v3): + if GeometryTools.is_in_triangle(point, v1, v2, v3): min_i = i min_sdist = sdist return min_i @@ -175,7 +152,7 @@ func _get_uv(point: Vector3, normal: Vector3) -> Vector2: var v1 := meshtool.get_vertex(fv0) var v2 := meshtool.get_vertex(fv1) var v3 := meshtool.get_vertex(fv2) - var bc := _barycentric(point, v1, v2, v3) # TODO memoize + var bc := GeometryTools.barycentric(point, v1, v2, v3) # TODO memoize var uv1 := meshtool.get_vertex_uv(fv0) var uv2 := meshtool.get_vertex_uv(fv1) var uv3 := meshtool.get_vertex_uv(fv2)