threejs:将摄像机移动到另一个对象内

时间:2017-10-29 12:34:04

标签: javascript three.js coordinate-transformation

我正在尝试将trackballControl控制的相机移动到物体的位置。

现在它正常工作,但正如你在我的fiddle中看到的那样,每次相机改变位置时,它也会改变z,这不是我想要的。

我正在努力保持positionrotate全球cube的位置{/ 1}}。

到目前为止,这是我的代码

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()

您可以在fiddle这里

进行测试

2 个答案:

答案 0 :(得分:2)

这是一个小提琴,通过单击按钮可以将相机缩小一点。 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()

答案 1 :(得分:2)

您必须将相机目标设置为您想要查看的位置。

var newTarget = new THREE.Vector3(0, 0, 0);
newTarget.copy(cubeMesh.position);
camera.lookAt(newTarget);

并且必须通过相机THREE.TrackballControls通知THREE.TrackballControls.update更新:

document.querySelector('button').onclick = function () {
    var newTarget = new THREE.Vector3(0, 0, 0);
    newTarget.copy(cubeMesh.position);
    controls.reset();
    camera.lookAt(newTarget)
    camera.updateProjectionMatrix();
    controls.update();
};


如果当前摄像机位置应保持不重置,则必须从摄像机的世界矩阵读取位置,并且必须将摄像机的初始位置设置为当前位置:

document.querySelector('button').onclick = function () 
    var newPosition = new THREE.Vector3(0, 0, 0);
    newPosition.applyMatrix4( camera.matrixWorld );
    var newTarget = new THREE.Vector3(0, 0, 0);
    newTarget.copy(cubeMesh.position);
    controls.reset();
    camera.position.copy(newPosition);
    camera.lookAt(newTarget)
    camera.updateProjectionMatrix();
    controls.update();
};


参见示例:

var camera, scene, renderer, controls, cubeMesh;

document.getElementById('reset').onclick = function () {
    var newTarget = new THREE.Vector3(0, 0, 0);
    newTarget.copy(cubeMesh.position);
    controls.reset();
    camera.lookAt(newTarget)
    camera.updateProjectionMatrix();
    controls.update();
};

document.getElementById('target').onclick = function () {
    var newPosition = new THREE.Vector3(0, 0, 0);
    newPosition.applyMatrix4( camera.matrixWorld );
    var newTarget = new THREE.Vector3(0, 0, 0);
    newTarget.copy(cubeMesh.position);
    controls.reset();
    camera.position.copy(newPosition);
    camera.lookAt(newTarget)
    camera.updateProjectionMatrix();
    controls.update();
};


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();
button {
    position : absolute;
    top : 0;
    right : 0;
}

.button2  {
    position : absolute;
    top : 0;
    left : 0;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/TrackballControls.js"></script>

<button id="reset" class="button2">
    reset camera
</button>

<button id="target">
    look at target
</button>