How to do a soft aceleration algorythm?

Hi everyone, I was looking for a way to do an algorythm to move an object smoothly, for example when we apply keyframes in an animation in blender, the first frames are acellerated to the center, and the lasts are desacelerated. Another example when we put a “time” value in the “Edit Object=>Track to Actuator” like the first blend file I attached to the post(Tidus.blend, WASD to move the character, and you will be able to see that soft movement on the camera controlled by the “time” value in the actuator of the camera).

I was trying do that by my self, using logarythms and exponential formulas, I got to this (the second attached file) but it’s really bad, it works, slow in my computer, even decreasing FPS sometimes!, I looked in the blender source code, looking for that algorythm in the animation and the game actuators section, but i didn’t find it.(just press P, and you will see that bad smooth acceleration effect, you can see the script to see how does it work, and you can change the cube properties “frame” and “final” to change the quantity of “frames” that take the cube to reach the “final” location)

So.. I ask you gods of maths and algorythms, how the pros do that? haha, where can I find what i’m looking for, how is it called? really i don’t know even how is it called, so i don’t know how to search for it in google. Thanks to all! and sorry for my english/spelling/etc.

PD: I can’t upload the Tidus.blend file so I post the link to dropbox of that file:

Attachments

prueba Script aceleracion.blend (489 KB)

I beleive Blender uses something similar to a Hermite spline for interpolating between keyframes. Here’s a script that will move an object that has a timer property called “timer” using such a spline.

import bge

cont = bge.logic.getCurrentController()
obj = cont.owner

MOVE_TIME = 2.0

def hermite_spline(x, p0, p1, m0, m1):
    """
    Spline with f(0) = p0, f(1) = p1, slope at f(0) = m0, slope at f(1) = m1
    """
    return (2*x**3 - 3*x**2 + 1)*p0 + (x**3 - 2*x**2 + x)*m0 + (-2*x**3 + 3*x**2)*p1 + (x**3 - x**2)*m1

t = min(1.0, obj['timer'] / MOVE_TIME)
newX = hermite_spline(t, 0, 5, 0, 0)
obj.worldPosition.x = newX

Cuberoot might be interesting to use, since it holds a similar shape to the curves for the animation.



You will most likely have to move its orgin though so its in the center of your animation frames.


import bge
cont = bge.logic.getCurrentController()
own = cont.owner
if own['NavPoint']!="Empty":
    Vec2 = own.getVectTo(own['NavPoint'])
    Distance = Vec2[0]
    if Distance >= Dthreshold1 and Distance < Dthreshold2:
        if own.localLinearVelocity.x<Speed1:
            own.applyForce(Vec2[1]*own.mass*15, 0)
            own.alignAxisToVect(Vec2[1],.5)



Thanks to all! Im gonna Try this things and tell you how is it was.

Why not just use basics physics equations since that is what you’re describing? :stuck_out_tongue: Technically speaking, the underlying math is Calculus which deals with calculating rates of change. Personally, anytime I hear the word “smoothing” or “curve”, I think of Calculus lol.

Remember:

  • velocity = change in position (with respect to time)
  • acceleration = change in velocity (with respect to time)

Every frame, you’d adjust the velocity and calculate a new position from it. To make things simple, we can assume constant acceleration, i.e. change the velocity by the same amount each frame. Acceleration would adjust the “smoothness” so to speak.


import bge
import time

def run(cont):
    
    obj = cont.owner
    
    # Assuming you set obj['t'] somewhere; should not be zero or 
    # you'll get a huge initial displacement and your cube will be
    # in a land far far away.
    # 
    # Also assume initial velocity equals 0:
    # obj['vel'] = 0.0
    #
    # This only needs to be set once for constant acceleration:
    # obj['acc'] = 1.0

    # Adjust velocity by acceleration
    obj['vel'] += obj['acc']


    # Calculate delta time
    # i.e. time elapsed since last frame
    t = time.perf_counter()
    dt = t - obj['t']


    # Save current time for next frame
    obj['t'] = t


    # Calculate displacement (simplified equation):
    # velocity * time = units obj will have moved in that time
    # velocity (units/sec) * time (sec) = displacement (units)
    s = obj['vel'] * dt


    # Note, the above calculates a relative displacement so we add s, not set s
    obj.worldPosition.x += s

    # For completeness, you'd calculate s for each axis"
    # obj.worldPosition.y + = sy
    # obj.worldPosition.z + = sz
    #
    # You could also simplify everything by using a Vector.


You can use other equations if you want an object to move slower/faster to a specific point over a certain amount of time.

You might have noticed that when you add keyframes to an animation, the default key type is a bezier one. You can edit them as you like with the curve editor. An action can have several different keyframe types. These are “pre-calculated” values. There is no need to perform heavy cslculations while playing.

I do not know the formula of slow-parent.

Slow parent is a simple lerp I believe, not time-dependant

Hi!, Mahalin i think about that, that’s find when you have to use it on a cube or another object, I can use keyframes as Monster says, but i don’t want to move a cube, i wan’t to mimic the “Track to” actuator behavior, so i have to rotate a camera, not necesarilly move it.

All these things i want to use for the camera script that is in Tidus.blend, to have a configurable Camera script with lots of options like smoothnes on movement, first person mode, and so on. Well, i’m know trying that formulas. So i’m gonna to post the camera script when I can make it work. Thanks for the replies and sorry for my english/spelling/etc.

EDIT: I finally prove the formula of Mobious, Amazing man, that is what i was wanting for!!! thank you!, this is the comparisson between doing with the script (S Key) or animation (A Key), it works almost equal, well i can’t know well, but really similar, i have to debug with prints and so on, but i don’t care, visually it works equal!, i’m gonna to study well that formula and try to implement it on the camera rotation and that things, meanwhile here is the comparisson:

Attachments

prueba Script aceleracion.blend (496 KB)