3
votes

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>
2
Also, read the comments that pertain to the proper use of OrbitControls in the three.js example threejs.org/examples/misc_controls_orbit.html.WestLangley
removing position:absolute seems to work jsfiddle.net/madhawa_R/akmcv7Lh/69 . but i don't know why it's not working.and is there any reason to set position to absolute??you may use container elementMadhawa Priyashantha

2 Answers

8
votes
controls = new THREE.OrbitControls(camera);

needs to be

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

The result is on this block.

2
votes

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 defualt, and the OrbitControl target property (a Vector3D) seems to also default that same point (0,0,0)