Mike
Mike

Reputation: 8877

How can I change the focal point of the camera in THREEJS to an existing object?

I have a scene taken from a THREEJS example (https://threejs.org/examples/webgl_loader_fbx.html) that imports and shows a threejs.json scene. The scene works fine; I have a grid and my model placed on top of that grid.

When I drag my mouse and zoom, the camera is pointing at the centre of my screen. However, the model is at the bottom of the scene, so is often outside of the camera.

How can I set the camera's centre to be the model I have placed?

I tried adding camera.lookAt(new THREE.Vector3( 0, 0, 0 )) but it made no difference to the camera's centre, no matter what I change the values to.

Below is my code:

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>three.js webgl - FBX loader</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <style>
            body {
                font-family: Monospace;
                background-color: #000;
                color: #fff;
                margin: 0px;
                overflow: hidden;
            }
            #info {
                color: #fff;
                position: absolute;
                top: 10px;
                width: 100%;
                text-align: center;
                z-index: 100;
                display:block;
            }
            #info a, .button { color: #f00; font-weight: bold; text-decoration: underline; cursor: pointer }
        </style>
    </head>

    <body>
        <div id="info">
            Test
        </div>

        <script src="js/three.js"></script>

        <script src="js/controls/OrbitControls.js"></script>

        <script src="js/loaders/FBXLoader.js"></script>

        <script src="js/Detector.js"></script>
        <script src="js/libs/stats.min.js"></script>

        <script>

            if ( ! Detector.webgl ) Detector.addGetWebGLMessage();

            var container, stats, controls;
            var camera, scene, renderer;
            var w = 1920;
            var h = 1080;

            var clock = new THREE.Clock();

            var mixers = [];

            init();

            function init() {

                container = document.createElement( 'div' );
                document.body.appendChild( container );

                camera = new THREE.PerspectiveCamera( 45, (window.innerWidth / window.innerHeight), 2, 2000 );

                scene = new THREE.Scene();

                // grid
                var gridHelper = new THREE.GridHelper( 14, 28, 0x303030, 0x303030 );
                gridHelper.position.set( 0, - 0.04, 0 );
                scene.add( gridHelper );

                // stats
                stats = new Stats();
                container.appendChild( stats.dom );

                // model
                var manager = new THREE.LoadingManager();
                manager.onProgress = function( item, loaded, total ) {

                    console.log( item, loaded, total );

                };

                var onProgress = function( xhr ) {

                    if ( xhr.lengthComputable ) {

                        var percentComplete = xhr.loaded / xhr.total * 100;
                        console.log( Math.round( percentComplete, 2 ) + '% downloaded' );

                    }

                };

                var onError = function( xhr ) {
                };

                // BEGIN Clara.io JSON loader code
                var objectLoader = new THREE.ObjectLoader();
                objectLoader.load("carport-scene.json", function ( obj ) {
                    scene.add( obj );
                } );
                // END Clara.io JSON loader code

                renderer = new THREE.WebGLRenderer();
                renderer.setPixelRatio( window.devicePixelRatio );
                renderer.setSize( window.innerWidth, window.innerHeight );
                renderer.setClearColor( 0x0000ff );
                container.appendChild( renderer.domElement );

                // controls, camera
                controls = new THREE.OrbitControls( camera, renderer.domElement );
                controls.target.set( 0, 12, 0 );
                camera.position.set( 25, 0, 25 );
                //camera.lookAt(new THREE.Vector3( 100, 100, 100 ));
                controls.update();

                window.addEventListener( 'resize', onWindowResize, false );

                animate();

            }

            function onWindowResize() {

                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();

                renderer.setSize( window.innerWidth, window.innerHeight );

            }

            //

            function animate() {

                requestAnimationFrame( animate );

                if ( mixers.length > 0 ) {

                    for ( var i = 0; i < mixers.length; i ++ ) {

                        mixers[ i ].update( clock.getDelta() );

                    }

                }

                stats.update();

                render();

            }

            function render() {

                renderer.render( scene, camera );

            }

        </script>

    </body>
</html>

I have created a gif illustrating the issue: http://g.recordit.co/APLcyJKj01.gif

Upvotes: 0

Views: 2024

Answers (3)

This code work:

camera.lookAt(new THREE.Vector3( 0, 0, 0 ));

but you are using:

<script src="js/controls/OrbitControls.js"></script>

And that library automatically returns to the position given by:

//x,y,z
controls.target.set( 0, 0, 0 );

Upvotes: 0

prisoner849
prisoner849

Reputation: 17596

If you know position of your object, then you can do

controls.target = your_object.position; // or any THREE.Vector3()

also, add

controls.update();

in your animation function

Upvotes: 0

Mike
Mike

Reputation: 8877

Fixed it by updating the controls.target.set( 0, 0, 0 ); line. Looks like this is the target of the rotation control.

Upvotes: 1

Related Questions