Add lever and jump pad components with activation logic
This commit is contained in:
210
addons/rmsmartshape/shapes/quad.gd
Normal file
210
addons/rmsmartshape/shapes/quad.gd
Normal file
@@ -0,0 +1,210 @@
|
||||
@tool
|
||||
extends RefCounted
|
||||
class_name SS2D_Quad
|
||||
|
||||
enum ORIENTATION { COLINEAR = 0, CCW, CW }
|
||||
enum CORNER { NONE = 0, OUTER, INNER }
|
||||
|
||||
var pt_a: Vector2
|
||||
var pt_b: Vector2
|
||||
var pt_c: Vector2
|
||||
var pt_d: Vector2
|
||||
|
||||
var tg_a : Vector2
|
||||
var tg_b : Vector2
|
||||
var tg_c : Vector2
|
||||
var tg_d : Vector2
|
||||
|
||||
var bn_a : Vector2
|
||||
var bn_b : Vector2
|
||||
var bn_c : Vector2
|
||||
var bn_d : Vector2
|
||||
|
||||
var texture: Texture2D = null
|
||||
var color: Color = Color(1.0, 1.0, 1.0, 1.0)
|
||||
|
||||
var is_tapered: bool = false
|
||||
var ignore_weld_next: bool = false
|
||||
var flip_texture: bool = false
|
||||
# Deprecated, should remove control_point_index
|
||||
var control_point_index: int
|
||||
var fit_texture := SS2D_Material_Edge.FITMODE.SQUISH_AND_STRETCH
|
||||
|
||||
# Contains value from CORNER enum
|
||||
var corner: int = 0
|
||||
|
||||
|
||||
# Will return two quads split down the middle of this one
|
||||
func bisect() -> Array[SS2D_Quad]:
|
||||
var delta: Vector2 = pt_d - pt_a
|
||||
var delta_normal := delta.normalized()
|
||||
var quad_left: SS2D_Quad = duplicate()
|
||||
var quad_right: SS2D_Quad = duplicate()
|
||||
var mid_point := Vector2(get_length_average(), 0.0) * delta_normal
|
||||
quad_left.pt_d = pt_a + mid_point
|
||||
quad_left.pt_c = pt_b + mid_point
|
||||
quad_right.pt_a = pt_d - mid_point
|
||||
quad_right.pt_b = pt_c - mid_point
|
||||
return [quad_left, quad_right]
|
||||
|
||||
|
||||
func _to_string() -> String:
|
||||
return "[Quad] A:%s B:%s C:%s D:%s | Corner: %s" % [pt_a, pt_b, pt_c, pt_d, corner]
|
||||
|
||||
|
||||
func matches_quad(q: SS2D_Quad) -> bool:
|
||||
return (
|
||||
texture == q.texture
|
||||
and color == q.color
|
||||
and flip_texture == q.flip_texture
|
||||
and fit_texture == q.fit_texture
|
||||
)
|
||||
|
||||
|
||||
func duplicate() -> SS2D_Quad:
|
||||
var q := SS2D_Quad.new()
|
||||
q.pt_a = pt_a
|
||||
q.pt_b = pt_b
|
||||
q.pt_c = pt_c
|
||||
q.pt_d = pt_d
|
||||
|
||||
q.texture = texture
|
||||
q.color = color
|
||||
|
||||
q.flip_texture = flip_texture
|
||||
q.control_point_index = control_point_index
|
||||
|
||||
q.corner = corner
|
||||
return q
|
||||
|
||||
|
||||
func update_tangents() -> void:
|
||||
tg_a = (pt_d-pt_a).normalized()
|
||||
tg_b = (pt_c-pt_b).normalized()
|
||||
tg_c = tg_b
|
||||
tg_d = tg_a
|
||||
|
||||
bn_a = (pt_b - pt_a).normalized()
|
||||
bn_b = bn_a
|
||||
bn_c = (pt_c - pt_d).normalized()
|
||||
bn_d = bn_c
|
||||
|
||||
|
||||
func _init(
|
||||
a: Vector2 = Vector2.ZERO,
|
||||
b: Vector2 = Vector2.ZERO,
|
||||
c: Vector2 = Vector2.ZERO,
|
||||
d: Vector2 = Vector2.ZERO,
|
||||
t: Texture2D = null,
|
||||
f: bool = false
|
||||
) -> void:
|
||||
pt_a = a
|
||||
pt_b = b
|
||||
pt_c = c
|
||||
pt_d = d
|
||||
|
||||
texture = t
|
||||
flip_texture = f
|
||||
|
||||
|
||||
func get_rotation() -> float:
|
||||
return SS2D_NormalRange.get_angle_from_vector(pt_c - pt_a)
|
||||
|
||||
|
||||
## Given three colinear points p, q, r, the function checks if
|
||||
## point q lies on line segment 'pr'.
|
||||
func on_segment(p: Vector2, q: Vector2, r: Vector2) -> bool:
|
||||
return (
|
||||
(q.x <= maxf(p.x, r.x))
|
||||
and (q.x >= minf(p.x, r.x))
|
||||
and (q.y <= maxf(p.y, r.y))
|
||||
and (q.y >= minf(p.y, r.y))
|
||||
)
|
||||
|
||||
|
||||
## Returns CCW, CW, or colinear.[br]
|
||||
## see https://www.geeksforgeeks.org/check-if-two-given-line-segments-intersect/
|
||||
func get_orientation(a: Vector2, b: Vector2, c: Vector2) -> ORIENTATION:
|
||||
var val := (float(b.y - a.y) * (c.x - b.x)) - (float(b.x - a.x) * (c.y - b.y))
|
||||
if val > 0:
|
||||
return ORIENTATION.CW
|
||||
elif val < 0:
|
||||
return ORIENTATION.CCW
|
||||
return ORIENTATION.COLINEAR
|
||||
|
||||
|
||||
## Return true if line segments p1q1 and p2q2 intersect.
|
||||
func edges_intersect(p1: Vector2, q1: Vector2, p2: Vector2, q2: Vector2) -> bool:
|
||||
var o1 := get_orientation(p1, q1, p2)
|
||||
var o2 := get_orientation(p1, q1, q2)
|
||||
var o3 := get_orientation(p2, q2, p1)
|
||||
var o4 := get_orientation(p2, q2, q1)
|
||||
# General case
|
||||
if (o1 != o2) and (o3 != o4):
|
||||
return true
|
||||
|
||||
# Special Cases
|
||||
# p1 , q1 and p2 are colinear and p2 lies on segment p1q1
|
||||
if (o1 == 0) and on_segment(p1, p2, q1):
|
||||
return true
|
||||
|
||||
# p1 , q1 and q2 are colinear and q2 lies on segment p1q1
|
||||
if (o2 == 0) and on_segment(p1, q2, q1):
|
||||
return true
|
||||
|
||||
# p2 , q2 and p1 are colinear and p1 lies on segment p2q2
|
||||
if (o3 == 0) and on_segment(p2, p1, q2):
|
||||
return true
|
||||
|
||||
# p2 , q2 and q1 are colinear and q1 lies on segment p2q2
|
||||
if (o4 == 0) and on_segment(p2, q1, q2):
|
||||
return true
|
||||
|
||||
return false
|
||||
|
||||
|
||||
func self_intersects() -> bool:
|
||||
return edges_intersect(pt_a, pt_d, pt_b, pt_c) or edges_intersect(pt_a, pt_b, pt_d, pt_c)
|
||||
|
||||
|
||||
func render_lines(ci: CanvasItem) -> void:
|
||||
ci.draw_line(pt_a, pt_b, color)
|
||||
ci.draw_line(pt_b, pt_c, color)
|
||||
ci.draw_line(pt_c, pt_d, color)
|
||||
ci.draw_line(pt_d, pt_a, color)
|
||||
|
||||
|
||||
func render_points(rad: float, intensity: float, ci: CanvasItem) -> void:
|
||||
ci.draw_circle(pt_a, rad, Color(intensity, 0, 0))
|
||||
ci.draw_circle(pt_b, rad, Color(0, 0, intensity))
|
||||
ci.draw_circle(pt_c, rad, Color(0, intensity, 0))
|
||||
ci.draw_circle(pt_d, rad, Color(intensity, 0, intensity))
|
||||
|
||||
|
||||
func get_height_average() -> float:
|
||||
return (get_height_left() + get_height_right()) / 2.0
|
||||
|
||||
|
||||
func get_height_left() -> float:
|
||||
return pt_a.distance_to(pt_b)
|
||||
|
||||
|
||||
func get_height_right() -> float:
|
||||
return pt_d.distance_to(pt_c)
|
||||
|
||||
|
||||
## Returns the difference in height between the left and right sides.
|
||||
func get_height_difference() -> float:
|
||||
return get_height_left() - get_height_right()
|
||||
|
||||
|
||||
func get_length_average() -> float:
|
||||
return (get_length_top() + get_length_bottom()) / 2.0
|
||||
|
||||
|
||||
func get_length_top() -> float:
|
||||
return pt_d.distance_to(pt_a)
|
||||
|
||||
|
||||
func get_length_bottom() -> float:
|
||||
return pt_c.distance_to(pt_b)
|
Reference in New Issue
Block a user