Search code examples
javascriptthree.jscoordinate-transformation

threejs: Move camera to position inside another object


I'm trying to move the camera controlled by trackballControl into the position of an object.

Right now it's working but as you can see in my fiddle, each time the camera changes position it also changes the z which isn't what I want.

I'm trying to keep the same position but only rotate the globe into the position of the cube.

Here is my code so far

var camera, scene, renderer, controls, cubeMesh;

document.querySelector('button').onclick = function () {
    camera.position.copy(cubeMesh.position);
    camera.lookAt(controls.target);
};

var initLights = function () {

    var light = new THREE.DirectionalLight(0xffffff);
    light.position.set(1, 1, 1);
    scene.add(light);
    var light = new THREE.DirectionalLight(0x002288);
    light.position.set(-1, -1, -1);
    scene.add(light);
    var light = new THREE.AmbientLight(0x222222);
    scene.add(light);
};

var init = function () {
    renderer = new THREE.WebGLRenderer({antialias: false});
    renderer.setSize(window.innerWidth, window.innerHeight);
    camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000);
    camera.position.z = 300;
    scene = new THREE.Scene();

    controls = new THREE.TrackballControls(camera);
    controls.target.set(0, 0, 0);
    controls.rotateSpeed = 2;

    document.body.appendChild(renderer.domElement);


    var sphereGeom = new THREE.SphereGeometry(100, 32, 32);
    var sphereMat = new THREE.MeshPhongMaterial({
        color: 0xfb3550,
        flatShading: true
    });
    var sphereMesh = new THREE.Mesh(sphereGeom, sphereMat);

    //cube
    var cubeDim = 20;
    var cubeGeom = new THREE.BoxGeometry(cubeDim, cubeDim, cubeDim);
    var cubeMat = new THREE.MeshPhongMaterial({
        color: 0x7cf93e,
        flatShading: true
    });
    cubeMesh = new THREE.Mesh(cubeGeom, cubeMat);


    var spherical = new THREE.Spherical();
    spherical.set(100 + cubeDim / 2, 0.4, 0);
    cubeMesh.position.setFromSpherical(spherical);

    var zero = new THREE.Vector3(0, 0, 0);
    cubeMesh.lookAt(zero);


    scene.add(sphereMesh);
    sphereMesh.add(cubeMesh);

    initLights();
};

var render = function () {

    renderer.render(scene, camera);
};

var animate = function () {
    requestAnimationFrame(animate);
    controls.update();
    render();
};


init();
animate()

You can test it in my fiddle here


Solution

  • Here is a fiddle where the camera is zoomed a little bit out by clicking the button. JS Fiddle

    var camera, scene, renderer, controls, cubeMesh;
    
    document.querySelector('button').onclick = function () {
            let x = cubeMesh.position.x
        let y = cubeMesh.position.y
        let z = cubeMesh.position.z
        camera.position.x = 0
        camera.position.y = y + 200
        camera.position.z = z + 100
        camera.lookAt(controls.target);
    };
    
    var initLights = function () {
    
        var light = new THREE.DirectionalLight(0xffffff);
        light.position.set(1, 1, 1);
        scene.add(light);
        var light = new THREE.DirectionalLight(0x002288);
        light.position.set(-1, -1, -1);
        scene.add(light);
        var light = new THREE.AmbientLight(0x222222);
        scene.add(light);
    };
    
    var init = function () {
        renderer = new THREE.WebGLRenderer({antialias: false});
        renderer.setSize(window.innerWidth, window.innerHeight);
        camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000);
        camera.position.z = 300;
        scene = new THREE.Scene();
    
        controls = new THREE.TrackballControls(camera);
        controls.target.set(0, 0, 0);
        controls.rotateSpeed = 2;
    
        document.body.appendChild(renderer.domElement);
    
    
        var sphereGeom = new THREE.SphereGeometry(100, 32, 32);
        var sphereMat = new THREE.MeshPhongMaterial({
            color: 0xfb3550,
            flatShading: true
        });
        var sphereMesh = new THREE.Mesh(sphereGeom, sphereMat);
    
        //cube
        var cubeDim = 20;
        var cubeGeom = new THREE.BoxGeometry(cubeDim, cubeDim, cubeDim);
        var cubeMat = new THREE.MeshPhongMaterial({
            color: 0x7cf93e,
            flatShading: true
        });
        cubeMesh = new THREE.Mesh(cubeGeom, cubeMat);
    
    
        var spherical = new THREE.Spherical();
        spherical.set(100 + cubeDim / 2, 0.4, 0);
        cubeMesh.position.setFromSpherical(spherical);
    
        var zero = new THREE.Vector3(0, 0, 0);
        cubeMesh.lookAt(zero);
    
    
        scene.add(sphereMesh);
        sphereMesh.add(cubeMesh);
    
        initLights();
    };
    
    var render = function () {
            console.log(camera.position)
        renderer.render(scene, camera);
    };
    
    var animate = function () {
        requestAnimationFrame(animate);
        controls.update();
        render();
    };
    
    
    init();
    animate()