From c215c1e80bbc08116691f9b46126c54b03cf4ac6 Mon Sep 17 00:00:00 2001 From: Luke Hubmayer-Werner Date: Sun, 17 Jan 2021 14:38:08 +1030 Subject: [PATCH] Switch slides from screenspace to unit circle space Makes Curve2D calculations much nicer, at the potential cost of adding multiplies to the Chord path. Also added an optimisation of sorts for Complex slides. --- scripts/NoteHandler.gd | 39 +++++++++++++++++++-------------------- singletons/Note.gd | 37 ++++++++++++++++++++++++++++--------- 2 files changed, 47 insertions(+), 29 deletions(-) diff --git a/scripts/NoteHandler.gd b/scripts/NoteHandler.gd index e993a4b..a042d84 100644 --- a/scripts/NoteHandler.gd +++ b/scripts/NoteHandler.gd @@ -180,23 +180,22 @@ func make_slide_trail_mesh(note) -> ArrayMesh: var size := GameTheme.sprite_size2 * sqrt(2) var color := GameTheme.COLOR_DOUBLE_SLIDE if note.double_hit else GameTheme.COLOR_SLIDE - # First we need to determine how many arrows to leave. - var trail_length : int = int(floor(note.get_slide_length() * slide_arrows_per_unit_length)) - vertices.resize(3*trail_length) - uvs.resize(3*trail_length) - colors.resize(3*trail_length) - for i in trail_length: - var u = GameTheme.UV_ARRAY_SLIDE_ARROW if i%3 else GameTheme.UV_ARRAY_SLIDE_ARROW2 - for j in 3: - uvs[i*3+j] = u[j] - colors[i*3+j] = Color(color.r, color.g, color.b, (1.0+float(i))/float(trail_length)) - - for i in trail_length: - var angle : float = note.get_angle((i+1)/float(trail_length)) - var offset : Vector2 = note.get_position((i+1)/float(trail_length)) - vertices[i*3] = offset - vertices[i*3+1] = offset + polar2cartesian(size, angle+PI*0.75) - vertices[i*3+2] = offset + polar2cartesian(size, angle-PI*0.75) + match note.get_points(): + [var positions, var angles]: + var trail_length : int = len(positions) + vertices.resize(3*trail_length) + uvs.resize(3*trail_length) + colors.resize(3*trail_length) + for i in trail_length: + var u = GameTheme.UV_ARRAY_SLIDE_ARROW if i%3 else GameTheme.UV_ARRAY_SLIDE_ARROW2 + for j in 3: + uvs[i*3+j] = u[j] + colors[i*3+j] = Color(color.r, color.g, color.b, (1.0+float(i))/float(trail_length)) + var angle : float = angles[i] + var offset : Vector2 = positions[i] * GameTheme.receptor_ring_radius + vertices[i*3] = offset + vertices[i*3+1] = offset + polar2cartesian(size, angle+PI*0.75) + vertices[i*3+2] = offset + polar2cartesian(size, angle-PI*0.75) arrays[Mesh.ARRAY_VERTEX] = vertices arrays[Mesh.ARRAY_TEX_UV] = uvs @@ -381,7 +380,7 @@ func _draw(): trail_alpha = min(1.0, (position-GameTheme.INNER_NOTE_CIRCLE_RATIO)/(1-GameTheme.INNER_NOTE_CIRCLE_RATIO*2)) else: var trail_progress : float = clamp((t - note.time_hit - GameTheme.SLIDE_DELAY)/(note.duration - GameTheme.SLIDE_DELAY), 0.0, 1.0) - var star_pos : Vector2 = note.get_position(trail_progress) + var star_pos : Vector2 = note.get_position(trail_progress) * GameTheme.receptor_ring_radius var star_angle : float = note.get_angle(trail_progress) make_star_mesh(mesh, star_pos, 1.33, star_angle) if note.progress != INF: @@ -417,8 +416,8 @@ func _input(event): for i in range(len(active_slide_trails)-1, -1, -1): # Iterate backwards as we are potentially deleting entries var note = active_slide_trails[i] - var center = note.get_position(note.progress) - var center2 = note.get_position(min(note.progress+0.06, 1.0)) + var center = note.get_position(note.progress) * GameTheme.receptor_ring_radius + var center2 = note.get_position(min(note.progress+0.06, 1.0)) * GameTheme.receptor_ring_radius if ((pos - center).length_squared() < Rules.SLIDE_RADIUS2) or ((pos - center2).length_squared() < Rules.SLIDE_RADIUS2): note.progress += 0.09 if note.progress >= 1.0: diff --git a/singletons/Note.gd b/singletons/Note.gd index 4ea94f5..815d407 100644 --- a/singletons/Note.gd +++ b/singletons/Note.gd @@ -123,8 +123,8 @@ class NoteSlide extends NoteBase: # Fancy charts have naked slides which necess func update_slide_variables(): match slide_type: Note.SlideType.CHORD, Note.SlideType.CHORD_TRIPLE: - values.start = GameTheme.RADIAL_UNIT_VECTORS[column] * GameTheme.receptor_ring_radius - values.end = GameTheme.RADIAL_UNIT_VECTORS[column_release] * GameTheme.receptor_ring_radius + values.start = GameTheme.RADIAL_UNIT_VECTORS[column] + values.end = GameTheme.RADIAL_UNIT_VECTORS[column_release] values.angle = (values.end - values.start).angle() Note.SlideType.ARC_CW: values.start_a = GameTheme.RADIAL_COL_ANGLES[column] @@ -138,23 +138,42 @@ class NoteSlide extends NoteBase: # Fancy charts have naked slides which necess values.end_a -= TAU Note.SlideType.COMPLEX: values.curve2d = Curve2D.new() - values.curve2d.bake_interval = 0.005 # TODO: play around with this + values.curve2d.bake_interval = 0.1 # TODO: play around with this func get_position(progress: float) -> Vector2: match slide_type: Note.SlideType.CHORD, Note.SlideType.CHORD_TRIPLE: return lerp(values.start, values.end, progress) - Note.SlideType.ARC_CW: + Note.SlideType.ARC_CW, Note.SlideType.ARC_ACW: var circle_angle : float = lerp(values.start_a, values.end_a, progress) - return polar2cartesian(GameTheme.receptor_ring_radius, circle_angle) - Note.SlideType.ARC_ACW: - var circle_angle : float = lerp(values.start_a, values.end_a, progress) - return polar2cartesian(GameTheme.receptor_ring_radius, circle_angle) + return polar2cartesian(1.0, circle_angle) Note.SlideType.COMPLEX: progress *= values.curve2d.get_baked_length() - return values.curve2d.interpolate_baked(progress) * GameTheme.receptor_ring_radius + return values.curve2d.interpolate_baked(progress) return Vector2(0.0, 0.0) + func get_points(per_radius: float = 10.0) -> Array: + # Returns PoolVector2Array positions, PoolRealArray angles + match slide_type: + Note.SlideType.COMPLEX: + var interval = 1.0/per_radius + if values.curve2d.bake_interval != interval: + values.curve2d.set_bake_interval(interval) # Setting this, even to the same value triggers a new bake + var positions: PoolVector2Array = values.curve2d.get_baked_points() + var angles = [] + for i in len(positions)-1: + angles.append((positions[i+1]-positions[i]).angle()) + positions.remove(0) # Don't need an arrow pointing at the start position + return [positions, PoolRealArray(angles)] + _: + var trail_length : int = int(floor(get_slide_length() * per_radius)) + var angles = [] + var positions = [] + for i in trail_length: + angles.append(get_angle((i+1)/float(trail_length))) + positions.append(get_position((i+1)/float(trail_length))) + return [PoolVector2Array(positions), PoolRealArray(angles)] + func get_angle(progress: float) -> float: match slide_type: Note.SlideType.CHORD, Note.SlideType.CHORD_TRIPLE: