Three.js 轨迹球缩放工作旋转不

Three.js Trackball zoom works rotation does not

标题几乎说明了一切。我希望 trackerballcontrols 表现得像 this example 但由于某种原因我不能旋转相机只能放大和缩小。显然我希望能够旋转相机。这是代码。

        <!DOCTYPE html>
        <html>
        <head>
        <title>Page Title</title>
        </head>
        <body>
        
        <h1>FooBarBaz</h1>
        <p>LaDeDa</p>
        <script src="http://threejs.org/build/three.min.js"></script>
        <script src="https://threejs.org/examples/js/controls/TrackballControls.js"></script>
        <script>
        var scene = new THREE.Scene();
        var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
        
        var renderer = new THREE.WebGLRenderer();
        renderer.setSize( window.innerWidth, window.innerHeight );
        
        var objects = [
            {
                name : "earth",
                mesh : new THREE.Mesh(new THREE.SphereGeometry(1, 32, 32), new THREE.MeshPhongMaterial()),
                init : function(scene){
                this.mesh.position.set(0,0,0);
                //this.material.map = THREE.ImageUtils.loadTexture('../earth.jpg');
                scene.add(this.mesh);
                },
                animate : function(t){return}
            },
            {
                name : "satellite",
                mesh : new THREE.Mesh(new THREE.SphereGeometry(0.1, 32, 32), new THREE.MeshPhongMaterial()),
                init : function(scene){
                this.mesh.position.set(1.5,0,0);
                //this.material.map = THREE.ImageUtils.loadTexture('../earth.jpg');
                scene.add(this.mesh);
                },
                animate : function(t){this.mesh.position.set(Math.sin(t)*1.5,Math.cos(t)*1.5,0);}
            }];
        objects.forEach(object => object.init(scene));
        
        var light = new THREE.HemisphereLight(0xf6e86d, 0x404040, 0.5);
        scene.add(light);
        
        camera.position.x = 0;
        camera.position.y = -5;
        camera.position.z = 0;
        camera.lookAt(new THREE.Vector3( 0, 0, 0));
        var timeStep = 0.01;
        var time = 0;
        var controls = new THREE.TrackballControls( camera, renderer.domElement );
        controls.target.set( 0, 0, 0 );
        var render = function () {
            time += timeStep;
            requestAnimationFrame( render );
            objects.forEach(object => object.animate(time));
            controls.update();
            renderer.render(scene, camera);
        }            
        document.body.appendChild( renderer.domElement );
        render();</script>
        </body>
        </html>
        

您的代码有两点需要调整。

  1. 您需要在初始化控件之前将 renderer.domElement 附加到主体:

    document.body.appendChild(renderer.domElement);

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

  2. 由于您在 y-axis 上设置了 camera.position,并且在 TrackballControls 中 camera.up 默认设置为 y-axis,这使得您的控件无法工作正常。所以你需要做的是改变默认的 camera.up 行为:

    camera.up = new THREE.Vector3(1, 1, 1);//你可以自由更改值,只是不要使其平行于 y-axis

    对不起,我不是ThreeJS专家,你可以参考这个了解更多信息:https://github.com/mrdoob/three.js/issues/10161

所以下面的代码可以正常工作:

<!DOCTYPE html>
<html>

<head>
<title>Page Title</title>
</head>

<body>
<h1>FooBarBaz</h1>
<p>LaDeDa</p>
<script src="http://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/TrackballControls.js"></script>
<script>
    var scene = new THREE.Scene();
    var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

    var renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);


    var objects = [
        {
            name: "earth",
            mesh: new THREE.Mesh(new THREE.SphereGeometry(1, 32, 32), new THREE.MeshPhongMaterial()),
            init: function (scene) {
                this.mesh.position.set(0, 0, 0);
                //this.material.map = THREE.ImageUtils.loadTexture('../earth.jpg');
                scene.add(this.mesh);
            },
            animate: function (t) { return }
        },
        {
            name: "satellite",
            mesh: new THREE.Mesh(new THREE.SphereGeometry(0.1, 32, 32), new THREE.MeshPhongMaterial()),
            init: function (scene) {
                this.mesh.position.set(1.5, 0, 0);
                //this.material.map = THREE.ImageUtils.loadTexture('../earth.jpg');
                scene.add(this.mesh);
            },
            animate: function (t) { this.mesh.position.set(Math.sin(t) * 1.5, Math.cos(t) * 1.5, 0); }
        }];
    objects.forEach(object => object.init(scene));

    var light = new THREE.HemisphereLight(0xf6e86d, 0x404040, 0.5);
    scene.add(light);

    camera.position.x = 0;
    camera.position.y = -5;
    camera.position.z = 0;
    camera.up = new THREE.Vector3(1, 1, 1);

    camera.lookAt(new THREE.Vector3(0, 0, 0));
    var timeStep = 0.01;
    var time = 0;

    document.body.appendChild(renderer.domElement);
    var controls = new THREE.TrackballControls(camera, renderer.domElement);
    controls.target.set(0, 0, 0);
    var render = function () {
        time += timeStep;
        requestAnimationFrame(render);
        objects.forEach(object => object.animate(time));
        controls.update();
        renderer.render(scene, camera);
    }

    render();</script>
</body>

</html>