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.
This commit is contained in:
Luke Hubmayer-Werner 2021-01-17 14:38:08 +10:30
parent 4b014bec31
commit c215c1e80b
2 changed files with 47 additions and 29 deletions

View File

@ -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:

View File

@ -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: