efarley
efarley

Reputation: 8661

THREE.js Orbit Controls not working

I am attempting to learn THREE and so far things are going well. I'm working to create a simple project building a golf ball on a golf tee. Eventually I'll put it inside a skybox and use some shaders to create the appearance of dimples in the ball.

For now I've been able to create the ball and the tee and get the camera and lights set up. I'm now attempting to add some orbit controls so I can rotate, pan and zoom around the scene. I added the orbitControls script and set it up how I see in the examples online. However when I attempt to orbit my camera snaps to the either 1,0,0 0,1,0 or 0,0,1 and eventually the scene completely fails and I end up looking along 0,0 with no object visible.

Here's my code in it's entirety

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <title>3D Sandbox</title>
        <style>
            html, body {
                margin: 0px;
            }
            canvas {
                background-color: #999;
                position: absolute;
                height: 100vh;
                width: 100vw;
                overflow: hidden;
            }
        </style>
    </head>
    <body>
        <script src='/three.js'></script>
        <script src="/orbitControls.js"></script>
        <script type='text/javascript'>
            let scene, 
                camera, 
                controls,
                renderer,
                height = window.innerHeight,
                width = window.innerWidth;

            window.addEventListener('load', init, false);

            function init () {
                createScene();
                createCamera();
                createLights();
                createBall();
                createTee();
                render();
                animate();
            }

            function createScene () {
                let grid;

                scene = new THREE.Scene();

                renderer = new THREE.WebGLRenderer({ 
                    antialias: true,
                    alpha: true
                });
                renderer.setSize(width, height);
                document.body.appendChild(renderer.domElement);

                grid = new THREE.GridHelper(100, 5);
                scene.add(grid);
            }

            function createCamera () {
                camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 1000);
                camera.position.z = 50;
                camera.position.y = 13;
                camera.up = new THREE.Vector3(0,1,0);
                //camera.lookAt(new THREE.Vector3(0,13,0));

                controls = new THREE.OrbitControls(camera);
                controls.target = new THREE.Vector3(0, 13, 0);
                controls.addEventListener('change', render);
            }

            function createLights () {
                let directionalLight, ambientLight;

                directionalLight = new THREE.DirectionalLight(0x404040, 4);
                directionalLight.position.set(0, 2000, 2000);
                directionalLight.target.position.set(0, 2, 0);
                scene.add(directionalLight);

                ambientLight = new THREE.AmbientLight(0x404040, 2);
                scene.add(ambientLight);
            }

            function createBall () {
                let ballGeom, ballMaterial, ball;

                ballGeom = new THREE.SphereGeometry(5, 32, 32);
                ballMaterial = new THREE.MeshPhongMaterial({
                    color: 0xFFFFFF
                });
                ball = new THREE.Mesh(ballGeom, ballMaterial);
                ball.position.y = 13.3;

                scene.add(ball);
            }

            function createTee () {
                let tee, stemGeom, stem, bevelGeom, bevel, topGeom, top, teeMat;

                tee = new THREE.Object3D();
                teeMat = new THREE.MeshPhongMaterial({
                    color: 0x0000FF
                });

                stemGeom = new THREE.CylinderGeometry(.9, 0.75, 7);
                stem = new THREE.Mesh(stemGeom, teeMat);
                tee.add(stem);

                bevelGeom = new THREE.CylinderGeometry(1.5, .9, 2);
                bevel = new THREE.Mesh(bevelGeom, teeMat);
                bevel.position.y = 3.75;
                tee.add(bevel);

                topGeom = new THREE.CylinderGeometry(1.5, 1.5, .25);
                top = new THREE.Mesh(topGeom, teeMat);
                top.position.y = 4.875;
                tee.add(top);

                tee.position.y = 3.5;
                scene.add(tee);
            }

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

            function animate() {
              requestAnimationFrame( animate );
              controls.update();
              render();
            }
        </script>
    </body>
</html>

Upvotes: 5

Views: 18142

Answers (2)

Nate Anderson
Nate Anderson

Reputation: 21064

In my case, the camera position was the same as OrbitControl target, and this made my OrbitControl seem "broken" (different symptoms than OP -- my OrbitControl just wouldn't work at all.)

As mentioned in this github comment, camera position and OrbitControl target cannot be the same; I repositioned my camera to fix this (camera.position.z = 10).

Remember, the camera (like any Object3D) is positioned at (0,0,0) by default, and the OrbitControl target property (a Vector3D) seems to also default that same point (0,0,0)

Upvotes: 14

user01
user01

Reputation: 901

controls = new THREE.OrbitControls(camera);

needs to be

controls = new THREE.OrbitControls(camera, renderer.domElement);

The result is on this block.

Upvotes: 8

Related Questions