Animating ArcRotateCamera using quaternion


I learnt something new today. That it’s better to use quaternions when animating rotation because it will choose the quickest path to the end position.

At the moment I have been animating my camera using something like this.

public animateAlphaBetaRadius(alphaBetaRadius: Vector3): Promise<Vector3> {
  return new Promise(resolve => {
    const duration = 60
    Animation.CreateAndStartAnimation('camera-alpha', this, 'alpha', 60, duration, this.alpha, alphaBetaRadius.x, 0, this.animationEasing)
    Animation.CreateAndStartAnimation('camera-beta', this, 'beta', 60, duration, this.beta, alphaBetaRadius.y, 0, this.animationEasing)
    Animation.CreateAndStartAnimation('camera-radius', this, 'radius', 60, duration, this.radius, alphaBetaRadius.z, 0, this.animationEasing, () => { resolve(alphaBetaRadius) }, )

Where this is a method that is implemented on a custom ArcRotateCamera that inherits from the original.

And I’ve been having troubles with if the user has rotated a couple of spins around the model, the alpha will contain the radians of all the spins too. So now when I animate back to the first spin, the camera will go crazy and animate the spins back.

My question is.
Would it be possible to still take take alpha, beta, radius as a Vector3 parameter, but then convert that
into a quaternion which I then somehow can animate the camera with?

That way I wouldn’t have to run three animations in parallel. And also the rotation would take the shortest route there.

Ps. you can see the problem on this project.
try rotating the camera and then click on one of the icons and it will animate there, but spin like crazy…

Other option is to detect before creating the animation if you want to go to alpha or Math.PI - alpha. YOu can just evaluate both distance and pick the smaller?

Radius is out of scope as it does not imapct the rotation.

1 Like

I solved it like this for now.

private normalizeAlpha(alpha: number): number {
    const oneRotation = Math.PI * 2
    const rotations = Math.floor(alpha / oneRotation)
    const radiansToRemove = rotations > 1 ? rotations * oneRotation : 0
    const normalizedAlpha = alpha - radiansToRemove
    return normalizedAlpha

Which I then apply on both the start and destination value of the alpha animation.

it solves the spinning problem, But I feel like there should be a simpler way…

How do you guys animate the camera?

well like you as it really depends on the use case :smiley: