Nikolai Arsenov
Nikolai Arsenov

Reputation: 464

Three.js - rotating a camera around a point

I have my custom Navigation control similar to Trackball but with additional functionality. One of the features I want to implement is the specifying center of rotation of the camera and when we pan a camera, the rotation maintained around the specified point.

Here is the code of my update() function:

update(): this {
    const camera = this.camera
    if (this._enabled && camera && this._isInvalid) {
        const cameraObject = camera.object
        // validate all navigation changes
        {
            const {
                offset,
                panOffset,
                axis,
                tempVector3,
                tempSpherical,
                deltaRotation,
                deltaPan,
                quaternion
            } = this.computeHelpers

            // offset vector from eye to target
            offset.subVectors(this._eye, this._target)

            // apply rotation
            if (deltaRotation.isInvalid) {
                const { x: theta, y: phi } = deltaRotation.get()
                // rotate around screen-space y-axis
                if (theta) {
                    axis.set(0, 1, 0).applyQuaternion(cameraObject.quaternion)
                    quaternion.setFromAxisAngle(axis, theta)
                    offset.applyQuaternion(quaternion)
                    this._up.applyQuaternion(quaternion)
                }
                // rotate around screen-space x-axis
                if (phi) {
                    axis.set(1, 0, 0).applyQuaternion(cameraObject.quaternion)
                    quaternion.setFromAxisAngle(axis, phi)
                    offset.applyQuaternion(quaternion)
                    this._up.applyQuaternion(quaternion)
                }
                // mark compute objects as valid
                deltaRotation.set({ x: 0, y: 0 })
                deltaRotation.isInvalid = false
            }

            // apply panning
            if (deltaPan.isInvalid) {
                cameraObject.updateMatrix()
                const matrix = cameraObject.matrix
                const { x: deltaPanX, y: deltaPanY } = deltaPan.get()

                // pan screen space x-direction
                {
                    tempVector3
                        // get x-column of local transform matrix
                        .setFromMatrixColumn(matrix, 0)
                        .multiplyScalar(deltaPanX)
                    panOffset.add(tempVector3)
                }
                // pan screen space y-direction
                {
                    tempVector3
                        // get y-column of local transform matrix
                        .setFromMatrixColumn(matrix, 1)
                        .multiplyScalar(-deltaPanY)
                    panOffset.add(tempVector3)
                }
                this._target.add(panOffset)

                // mark compute objects as valid
                panOffset.set(0, 0, 0)
                deltaPan.set({ x: 0, y: 0 })
                deltaPan.isInvalid = false
            }

            // assemble new eye (camera) position
            this._eye.addVectors(offset, this._target)
            this._eyeSpherical.setFromVector3(this._eye)
            this._direction.copy(this._eye).normalize()
        }

        // update camera position
        cameraObject.position.copy(this._eye)
        cameraObject.up.copy(this._up)
        cameraObject.lookAt(this._target)

        // mark the controller as valid
        this._isInvalid = false
    }
    return this
}

How can I apply the translation?

Expected result: enter image description here

Thanks a lot in advance

Upvotes: 1

Views: 253

Answers (0)

Related Questions