How to properly use BABYLON.Vector3.SmoothToRef

How would i substitute SmoothToRef for Lerp…

Lerp uses a gradient value 0 to 1 for the lerp amount but SmoothToRef seems to have a deltaTime and a lerpTime…

How would i use SmoothToRef instead of Lerp… More specific… what exactly is deltaTime and lerpTime and maybe a small example playground in properly using SmoothToRef to smoothy move and object like you would with LERP

Please :slight_smile:

SmoothToRef is identical to lerp :slight_smile: the only diff is the gradient is computed for you for deltaTime and lerpTime.

lerpTime is the total time of the lerp (meaning lerp from 0 to 1 in lerpTime)

deltaTime is the current time in the lerp (meaning elapsed time since lerp started at 0)

 /**
  * Smooth interpolation between two vectors using Slerp
  * @param source source vector
  * @param goal goal vector
  * @param deltaTime current interpolation frame
  * @param lerpTime total interpolation time
  * @param result the smoothed vector
  */
  public static SmoothToRef(source: Vector3, goal: Vector3, deltaTime: number, lerpTime: number, result: Vector3) {
     Vector3.SlerpToRef(source, goal, lerpTime === 0 ? 1 : deltaTime / lerpTime, result);
  }
1 Like

Sorry @sebavan … I still dont get how to use it.

So if i am trying to move from current position to target position in an update loop.
i would do something like

transform.position = Vector3.Lerp(transform.position, targetPosition, deltaTime * speedFactor)

So how would i move an object with SmoothToRef… what am i supposed to pass for deltaTime and lerpTime each frame… How would i know what the total lerp time is… I am just stepping per frame… I dont get it :frowning:

you d do :slight_smile:

const animationDuration = 5000;
let deltaTime = 0;
onbeforerender = () => {
    deltaTime += engine.deltaTime
    transform.position = Vector3.Lerp(transform.position, targetPosition, deltaTime, animationDuration)
}

@MackeyK24 Here is a playground that uses it. Granted I think it’s a tad more complicated of an example since it has all these other components to it. But basically, you want to pass the fraction of time that has passed. In the example here that number is generated by the vector3InterpolateFunction of animation.

Like seb has mentioned you instead can get scene.deltaTime or engine.getDeltaTime() to get that amount.

1 Like

So its like ticking a tween or something… Where i have to know the TOTAL DURATION of the smoothing operation… What happens after the 5000 animationDuration… Its still being called every frame so happens when 5000 expired… does its STOP moving even though its still in the update loop ???

Do you have a playground reference to maybe show what you’re trying to achieve? :slight_smile:

1 Like

It looks like if you go past the total duration then the amount delta/duration will be clamped to 1 after it gets passed to SlerpToRef.

Also, I think a big difference between these and Lerp is that Lerp works well for example to animate position along a straight line from start position to end position, while Smooth/Slerp works well to animate rotation from start rotation to end rotation.

For example if you Slerp position from (0, 0, 0) to (10, 0, 0) it won’t move in a straight line, there will be a curve to the movement…

Just adding some math background to anyone who wants to know more about the difference between lerp and slerp:

Slerp is Spherical linear interpolation and its designed to avoid some issues when interpolating orientations:

On the second image you can see that if you linearly interpolate between v1 and v2, they won’t cover equal sections of the circumference, which looks weird, so Slerp solves that :smiley:

2 Likes

I am updating Remote Network Entities for my new built in Colyseus Multiplayer Support.

The toolkit now has a Colyseus Network Entity script component that is like the UNET NetworkTransform in Unity.

Is has support to auto sync the remote network entity position and rotation…

LERP has a bit of EASING at the end of the LERP… To be expected when using the current position as the starting point for the LERP.

So i was looking for more of a Unity Style Move Towards function like they have in Unity to smoothly move around the remote network entities in the scene.

So i made a few Unity Style Move Towards helper functions in the babylon.manager.js utility class:

        public static MoveTowardsVector2(current:BABYLON.Vector2, target:BABYLON.Vector2, maxDistanceDelta:number):BABYLON.Vector2 {
            const result:BABYLON.Vector2 = new BABYLON.Vector2(0.0, 0.0);
            BABYLON.Utilities.MoveTowardsVector2ToRef(current, target, maxDistanceDelta, result);
            return result;
        }
        public static MoveTowardsVector2ToRef(current:BABYLON.Vector2, target:BABYLON.Vector2, maxDistanceDelta:number, result:BABYLON.Vector2):void {
            const toVector_x:number = target.x - current.x;
            const toVector_y:number = target.y - current.y;
            const sqDist:number = toVector_x * toVector_x + toVector_y * toVector_y;
            if (sqDist == 0 || (maxDistanceDelta >= 0 && sqDist <= maxDistanceDelta * maxDistanceDelta)) {
                result.set(target.x, target.y);
            } else {
                const dist:number = Math.sqrt(sqDist);
                result.set((current.x + toVector_x / dist * maxDistanceDelta), (current.y + toVector_y / dist * maxDistanceDelta));
            }
        }

        public static MoveTowardsVector3(current:BABYLON.Vector3, target:BABYLON.Vector3, maxDistanceDelta:number):BABYLON.Vector3 {
            const result:BABYLON.Vector3 = new BABYLON.Vector3(0.0, 0.0, 0.0);
            BABYLON.Utilities.MoveTowardsVector3ToRef(current, target, maxDistanceDelta, result);
            return result;
        }
        public static MoveTowardsVector3ToRef(current:BABYLON.Vector3, target:BABYLON.Vector3, maxDistanceDelta:number, result:BABYLON.Vector3):void {
            const toVector_x:number = target.x - current.x;
            const toVector_y:number = target.y - current.y;
            const toVector_z:number = target.z - current.z;
            const sqDist:number = toVector_x * toVector_x + toVector_y * toVector_y + toVector_z * toVector_z;
            if (sqDist == 0 || (maxDistanceDelta >= 0 && sqDist <= maxDistanceDelta * maxDistanceDelta)) {
                result.set(target.x, target.y, target.z);
            } else {
                const dist:number = Math.sqrt(sqDist);
                result.set((current.x + toVector_x / dist * maxDistanceDelta), (current.y + toVector_y / dist * maxDistanceDelta), (current.z + toVector_z / dist * maxDistanceDelta));
            }
        }

        public static MoveTowardsVector4(current:BABYLON.Vector4, target:BABYLON.Vector4, maxDistanceDelta:number):BABYLON.Vector4 {
            const result:BABYLON.Vector4 = new BABYLON.Vector4(0.0, 0.0, 0.0, 0.0);
            BABYLON.Utilities.MoveTowardsVector4ToRef(current, target, maxDistanceDelta, result);
            return result;
        }
        public static MoveTowardsVector4ToRef(current:BABYLON.Vector4, target:BABYLON.Vector4, maxDistanceDelta:number, result:BABYLON.Vector4):void {
            const toVector_x:number = target.x - current.x;
            const toVector_y:number = target.y - current.y;
            const toVector_z:number = target.z - current.z;
            const toVector_w:number = target.w - current.w;
            const sqDist:number = (toVector_x * toVector_x + toVector_y * toVector_y + toVector_z * toVector_z + toVector_w * toVector_w);
            if (sqDist == 0 || (maxDistanceDelta >= 0 && sqDist <= maxDistanceDelta * maxDistanceDelta)) {
                result.set(target.x, target.y, target.z, target.w);
            } else {
                const dist:number = Math.sqrt(sqDist);
                result.set((current.x + toVector_x / dist * maxDistanceDelta), (current.y + toVector_y / dist * maxDistanceDelta), (current.z + toVector_z / dist * maxDistanceDelta), (current.w + toVector_w / dist * maxDistanceDelta));
            }
        }

In case anyone needs to SMOOTH LERP without the easing like in Unity :slight_smile:

2 Likes