How to rotate camera from worldDirection to another vector without lookAt method

I am trying to rotate camera around all axises and. lookAt methos uses camera.up vector, and when camera rotates above 180 and under -180 degress camera.up vector keep camera orientation. I expect camera works like spaceship rotation.

How to implement rotation like lookAt function?

I apply object quaternion(spaceship model) to camera. Then use lookAt method, but it works not expected when rotation around local x axis of the ship.

    const cameraOffset = new Vector3(0, 2, 3)

    cameraOffset.applyQuaternion(this.ship.quaternion)
    cameraOffset.add(this.ship.position)

// camera position
    this.position.lerp(cameraOffset, 0.1)
    this.tjsObject.position.copy(this.position)
    const cameraLookAt = new Vector3(0, 1, -5)

    cameraLookAt.applyQuaternion(this.ship.quaternion)
    cameraLookAt.add(this.ship.position)

    this.lookAt.lerp(cameraLookAt, 0.1)
    this.tjsObject.lookAt(this.lookAt)

Given a normalized vector to the target and -Camera.getWorldDirection, the function Quaternion.setFromUnitVectors should create a quaternion that will perform the rotation.

  update() {
    const cameraOffset = new Vector3(0, 2, 5)
    const cameraLookAt = new Vector3(0, 1, -5)

    cameraOffset.applyQuaternion(this.ship.quaternion)
    cameraOffset.add(this.ship.position)

    cameraLookAt.applyQuaternion(this.ship.quaternion)
    cameraLookAt.add(this.ship.position)

    const f = new Vector3()
    this.tjsObject.getWorldDirection(f)

    f.normalize()
    cameraLookAt.normalize()

    const q = new Quaternion()
    q.setFromUnitVectors(f, cameraLookAt)

    // interpolate camera position
    this.position.lerp(cameraOffset, 0.1)
    this.tjsObject.position.copy(this.position)

    // interpolate camera rotation
    this.tjsObject.quaternion.slerp(q, 0.1)
  }

But it works like this now :frowning:

But if i slerp to ship 3d object quaternion it works like expected, but without lookAt custom vector unfortunately.

change

 this.tjsObject.quaternion.slerp(q, 0.1)

to

this.tjsObject.quaternion.slerp(this.ship.quaternion, 0.1)

but as i say above there is no camera custom lookAt vector now

I think the question is how to make lookAt function without .up vector.I think cameraLookAt vector calculates properly, because with three.js lookAt function it works as expected.

I don’t understand what that means. The up vector defines the object’s roll in the final orientation, so all 3d objects must have one.

Assuming that tjsObject is the camera, I think vector f should be negated, since cameras look out their negative z axes.

Also, cameraLookAt appears to just be a world position; you need a new normalized vector from the camera’s world position to the cameraLookAt world position called cameraLookAtDirection or something and then use that and vector f to calculate the quaternion.

It might help to add a debug orbit camera to your scene with a button to toggle between the cameras so you can drop debug axes helpers to see if your positions and rotations come out like you expect.

1 Like

Thanks. I’ll try to calculate cameraLookAtDirection and rotate vector