mirror of
https://gitlab.com/open-fpsz/open-fpsz.git
synced 2026-07-16 00:44:50 +00:00
94 lines
3 KiB
GDScript
94 lines
3 KiB
GDScript
# This file is part of open-fpsz.
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
class_name Trail3D extends MeshInstance3D
|
|
|
|
var _points = [] # 3D points of trail
|
|
var _widths = [] # Calculated widths of trail
|
|
var _lifespans = [] # Trail point lifespans
|
|
|
|
@export var _trail_enabled : bool = true # Is trail shown?
|
|
|
|
@export var _from_width : float = 0.5 # Starting width
|
|
@export var _to_width : float = 0.0 # Ending width
|
|
|
|
@export_range(0.5, 1.5) var _scale_acceleration : float = 1.0 # Scaling speed
|
|
|
|
@export var _motion_delta : float = 0.1 # Smoothness of trail
|
|
@export var _lifespan : float = 1.0 # Duration of trail
|
|
|
|
@export var _start_color : Color = Color(1.0, 1.0, 1.0, 1.0) # Start color
|
|
@export var _end_color : Color = Color(1.0, 1.0, 1.0, 1.0) # End color
|
|
|
|
var _old_pos : Vector3 # Previous pos
|
|
|
|
func _append_point():
|
|
_points.append(get_global_transform().origin)
|
|
_widths.append([
|
|
get_global_transform().basis.x * _from_width,
|
|
get_global_transform().basis.x * _from_width - get_global_transform().basis.x * _to_width
|
|
])
|
|
_lifespans.append(0.0)
|
|
|
|
func _remove_point(i):
|
|
_points.remove_at(i)
|
|
_widths.remove_at(i)
|
|
_lifespans.remove_at(i)
|
|
|
|
func _ready():
|
|
_old_pos = get_global_transform().origin
|
|
mesh = ImmediateMesh.new()
|
|
|
|
func _process(delta):
|
|
if(_old_pos - get_global_transform().origin).length() > _motion_delta and _trail_enabled:
|
|
_append_point() # Create new point
|
|
_old_pos = get_global_transform().origin # Update previous position to current position coordinates
|
|
|
|
# Update the lifespan
|
|
var p = 0
|
|
var max_points = _points.size()
|
|
while p < max_points:
|
|
_lifespans[p] += delta
|
|
if _lifespans[p] > _lifespan:
|
|
_remove_point(p)
|
|
p -= 1
|
|
if (p < 0): p = 0
|
|
|
|
max_points = _points.size()
|
|
p += 1
|
|
|
|
mesh.clear_surfaces()
|
|
|
|
# If less than 2 points, stop rendering trail
|
|
if _points.size() < 2:
|
|
return
|
|
|
|
# Render new mesh for each point
|
|
mesh.surface_begin(Mesh.PRIMITIVE_TRIANGLE_STRIP)
|
|
|
|
for i in range(_points.size()):
|
|
var t = float(i) / (_points.size() - 1.0)
|
|
var curr_color = _start_color.lerp(_end_color, 1 - t)
|
|
mesh.surface_set_color(curr_color)
|
|
|
|
var curr_width = _widths[i][0] - pow(1 - t, _scale_acceleration) * _widths[i][1]
|
|
|
|
var t0 = i / _points.size()
|
|
var t1 = t
|
|
|
|
mesh.surface_set_uv(Vector2(t0, 0))
|
|
mesh.surface_add_vertex(to_local(_points[i] + curr_width))
|
|
mesh.surface_set_uv(Vector2(t1, 1))
|
|
mesh.surface_add_vertex(to_local(_points[i] - curr_width))
|
|
mesh.surface_end()
|