Android Code Snippet [LibGDX CatMullRomSpline] Constant Speed Progress Calculator

Discussion in 'Code Snippets' started by wonder, May 24, 2019.

  1. wonder

    wonder Expert Licensed User

    Hi!

    If you ever encounter the problem described on the link below, you can use this class to solve this problem:
    https://stackoverflow.com/questions/32665262/libgdx-path-catmullromspline-constant-speed

    Class Module: ConstSpeedProgressCalculator
    Code:
    Private Sub Class_Globals
        
    Private ref                 As Reflector
        
    Private derivative_average  As Float
        
    Private path_completion     As Float
        
    Private derivative          As lgMathVector2
    End Sub

    Public Sub Initialize(spline As lgMathCatmullRomSpline, samples As Int)
        ref.Target = spline.InternalObject
        
    Dim out As lgMathVector2
        
    Dim f = 0 As Float
        
    Do While f < 1
            out = DerivativeAt(out, f)
            derivative_average = derivative_average + out.len
            f = f + (
    1 / samples)
        
    Loop
        derivative_average = derivative_average / samples
    End Sub

    Public Sub Update(speed As Float, deltatime As Float, reset_automatically As Boolean)
        derivative = DerivativeAt(derivative, path_completion)
        path_completion = path_completion + (derivative_average * speed * deltatime / derivative.len)
        
    If reset_automatically Then path_completion = path_completion Mod 1
    End Sub

    Public Sub getPathCompletion As Float
        
    Return path_completion
    End Sub

    Public Sub Reset
        path_completion = 
    0
    End Sub

    Private Sub DerivativeAt(out As lgMathVector2, completion As Float) As lgMathVector2
        
    Return ref.RunMethod4("derivativeAt"Array(out, completion), Array As String("java.lang.Object""java.lang.float"))
    End Sub

    Usage:

    1. Declare the ProgressCalculator instance as a global (recommended):
    Code:
    Sub Process_Globals
        ...
        
    Private ProgressCalculator As ConstSpeedProgressCalculator
        ...
    End Sub

    2. Initialize the class right after you initialize the spline.
    Code:
    ProgressCalculator.Initialize(mySpline, 100'more samples = smoother result

    3. Replace, on your update method (or whatever it's named), the usual:
    Code:
    progress = progress + (lGdx.graphics.DeltaTime * speed) 'Value between 0 and 1
    with:
    Code:
    ProgressCalculator.Update(speed, lGdx.graphics.DeltaTime, False'or True
    progress = ProgressCalculator.PathCompletion 'Value between 0 and 1

    Code:
    ...

    Sub InitializeSpline(s As lgMathCatmullRomSplineAs Boolean
        
    If nodes.Length < 4 Then Return False
        s.Initialize(Utils.MathVec2Array(nodes), 
    False)
        
    Return True
    End Sub

    Sub InitializePathPreview As Boolean
        preview_timestamp = 
    0
        preview_completion = 
    0
        preview_path_complete = 
    False
        active_path = Paths.get(SelectedPath.Number)
        nodes = Utils.ExtrapolatedPath(active_path.nodes)
        
    Dim result = InitializeSpline(preview_spline) As Boolean
        
    If result Then preview_progress_calc.Initialize(preview_spline, 100)
        
    Return result
    End Sub

    Sub DrawPathPreview(shape_renderer As lgShapeRenderer, viewport As Rect)
        
    If SelectedPath.IsUpdated(TrueThen InitializePathPreview
     
        
    If Not(active_path.IsInitialized)          _
        
    Or Not(active_path.Settings.IsInitialized) _
        
    Or active_path.Settings.Size == 0          _
        
    Or SelectedPath.Number < 0                 _
        
    Or nodes.Length < 4 Then Return            _
        
    '-------------------------------------------
     
        
    Dim speed = Utils.ToNumber(active_path.Settings.Get          ("speed"        )) * 0.5  As Double
        
    Dim itrpl = Maps.Interpolation.Get(active_path.Settings.Get  ("interpolation"))        As lgMathInterpolation
     
        
    If preview_path_complete Then
            preview_timestamp = 
    0
            preview_completion = 
    0
            preview_progress_calc.Reset
            preview_path_complete = 
    False
        
    End If
     
        
    Dim delay = 300 * 1 / speed As Int
        
    Dim shape_size As Double
        
    Dim multiplier As Double
        
    Dim min_shape_size = Constants.ENDNODE_RADIUS / 3 As Double
        
    If preview_completion >= 1 Then
            ApplyPreviewPathDelay(delay)
            multiplier = 
    Min(delay, DateTime.Now - preview_timestamp) / delay
            shape_size = min_shape_size + ((Constants.ENDNODE_RADIUS - min_shape_size) * multiplier)
            preview_spline_motion.Set(active_path.LastNode.x, active_path.LastNode.y)
        
    Else
            multiplier = 
    0
            shape_size = min_shape_size
            preview_progress_calc.Update(speed, volume.LibGDX.Graphics.DeltaTime, 
    False)
            preview_completion = preview_progress_calc.PathCompletion
            preview_spline.ValueAt(preview_spline_motion, itrpl.apply(preview_completion))
        
    End If
     
        shape_renderer.Begin(shape_renderer.SHAPETYPE_Filled)
            shape_renderer.SetColorRGBA(
    1.00.00.01.0 * (1 - multiplier))
            shape_renderer.Circle(                          _
                viewport.CenterX + preview_spline_motion.x, _
                viewport.CenterY + preview_spline_motion.y, _
                shape_size                                  _
            )
        shape_renderer.End
    End Sub

    Sub ApplyPreviewPathDelay(delay As Int)
        
    If preview_timestamp == 0 Then
            preview_timestamp = 
    DateTime.now
        
    else if DateTime.Now - preview_timestamp >= delay Then
            preview_timestamp = 
    0
            preview_path_complete = 
    True
        
    End If
    End Sub

    ...
     
    Last edited: May 29, 2019
    José J. Aguilar likes this.
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice