Reverting controls['target'] back to (0, 0, 0) after a tween

You want to go back to 0,0,0 with controls.target but you don’t want it to jump there? You’ll need to tween the target back to 0,0,0 which both @PavelBoytchev and @seanwasere have given examples for… I’d suggest setting up a minimal codepen or jsfiddle that demonstrates the issue your having.

1 Like

Here is my local code taken from the example above. You just need to redefine the JavaScript files and the monkey’s location. You doubleclick on a point and move your mouse and it jumps.

<html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <meta name="author" content="Sean Bradley" />
        <title>Three.js TypeScript Tutorials by Sean Bradley : https://sbcode.net/threejs</title>
        <link rel="stylesheet" href="/stylesheets/style.css" />
        <style>
            body {
                overflow: hidden;
                margin: 0px;
                user-select: none;
            }

            a {
                color: #ffffff;
            }

            #progressBar {
                width: 500px;
                height: 24px;
                position: absolute;
                left: 50%;
                top: 25px;
                margin-left: -250px;
            }

            #instructions {
                color: white;
                position: absolute;
                left: 50%;
                top: 10px;
                margin-left: -250px;
                font-family: monospace;
            }
        </style>
    </head>

    <body oncontextmenu="return false;">
        <a href="/view_source/tween-orbit.html" id="vwSrcLink" target="_blank">&lt;&gt;</a>
        <progress value="0" max="100" id="progressBar"></progress>
        <div id="instructions">
            Double click anywhere on the floor or monkey head to tween the camera target.
        </div>
        <script type="module">
            import * as THREE from '/JavaScript/Others/ThreeJS/build/three.module.js';
            import { OrbitControls } from '/JavaScript/Others/ThreeJS/examples/jsm/controls/OrbitControls.js'
            import Stats from '/JavaScript/Others/ThreeJS/examples/jsm/libs/stats.module.js'
            import { GLTFLoader } from '/JavaScript/Others/ThreeJS/examples/jsm/loaders/GLTFLoader.js'
            import { TWEEN } from '/JavaScript/Others/ThreeJS/examples/jsm/libs/tween.module.min.js'

            const scene = new THREE.Scene()

            const axesHelper = new THREE.AxesHelper()
            scene.add(axesHelper)

            const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
            camera.position.set(-0.6, 0.45, 2)

            const renderer = new THREE.WebGLRenderer()
            renderer.physicallyCorrectLights = true
            renderer.shadowMap.enabled = true
            renderer.setSize(window.innerWidth, window.innerHeight)
            document.body.appendChild(renderer.domElement)

            const controls = new OrbitControls(camera, renderer.domElement)
            controls.enableDamping = true
            controls.autoRotate = true;

            const raycaster = new THREE.Raycaster()
            const sceneMeshes = []

            const loader = new GLTFLoader()
            loader.load(
                'monkey.glb',
                function (gltf) {
                    gltf.scene.traverse(function (child) {
                        if (child.isMesh) {
                            const m = child
                            if (m.name === 'Suzanne') {
                                m.castShadow = true
                            } else {
                                // floor
                                m.receiveShadow = true
                            }

                            sceneMeshes.push(m)
                        }
                        if (child.isLight) {
                            const l = child
                            l.castShadow = true
                            l.shadow.bias = -0.001
                        }
                    })
                    scene.add(gltf.scene)
                },
                (xhr) => {
                    console.log((xhr.loaded / xhr.total) * 100 + '% loaded')
                },
                (error) => {
                    console.log(error)
                }
            )

            function onDoubleClick(event) {
                raycaster.setFromCamera(
                    {
                        x: (event.clientX / renderer.domElement.clientWidth) * 2 - 1,
                        y: -(event.clientY / renderer.domElement.clientHeight) * 2 + 1,
                    },
                    camera
                )

                const intersects = raycaster.intersectObjects(sceneMeshes, false)

                if (intersects.length > 0) {
                    const p = intersects[0].point
                    axesHelper.position.copy(p)
                    new TWEEN.Tween(camera.quaternion)
                        .to(
                            {
                                x: 0.2,
                                y: 0.3,
                                z: 0.1,
                            },
                            500
                        )
                        .easing(TWEEN.Easing.Cubic.Out)                        
                        .start()
                }
            }

            function onWindowResize() {
                camera.aspect = window.innerWidth / window.innerHeight
                camera.updateProjectionMatrix()
                renderer.setSize(window.innerWidth, window.innerHeight)
                render()
            }

            renderer.domElement.addEventListener('dblclick', onDoubleClick, false)
            window.addEventListener('resize', onWindowResize, false)

            const stats = Stats()
            document.body.appendChild(stats.dom)

            function animate() {
                requestAnimationFrame(animate)

             //   controls.update()

                TWEEN.update()

                render()

                stats.update()
            }

            function render() {
                renderer.render(scene, camera)
            }

            animate()
        </script>
    </body>
</html>

I believe the issue if with the OrbitControls and tweening of the camera, which don’t go too well together. So I doubt there is a fix for this. Just have to tween something else other then the camera.

You have dug yourself deep into a rabbit hole of misunderstanding.

Your problems are self inflicted by your insistence on changing the cameras quaternion while trying to use the OrbitControls at the same time. None of the examples I’ve supplied do this.

You need to find an example on the internet that does exactly what you want it to do. Don’t post paragraphs of ifs, and thens, and buts. Just share the link that works exactly the way you want it to.

When you find it, it may not even be using the OrbitControls, let alone trying to modify the cameras quaternion directly while the OrbitControls is enabled. Even the way you are changing the quaternion is wrong. It has 4 components (x,y,z,w), and they need to be normalised.

If you want to modify what the camera is looking at, and you want to use the orbit controls at the same time, then you need to modify the orbitControls target.

E.g. (from Using tween.js with OrbitControls - Three.js Tutorials),

        const p = intersects[0].point
        new TWEEN.Tween(controls.target)
            .to(
                {
                    x: p.x,
                    y: p.y,
                    z: p.z,
                },
                500
            )
            .easing(TWEEN.Easing.Cubic.Out)
            .start()

Now go and find that example that works exactly the way you imagine it to.