Three.js 使用两个(切换)相机进行轨道控制

Three.js Orbit Controls with Two (Toggled) Cameras

我在一个场景中有两个摄像机,一个视口和一个渲染器。我在相机之间切换(使用 html 按钮)。

问题

问题 1

对于camera1,移动鼠标没有反应。当我切换到 camera2 时,轨道控制工作正常。切换回camera1移动鼠标还是没有反应

jsfiddle v1 原版(camera1 无响应) jsfiddle.net/steveow/xu0k1z75/

更新:问题 1,由 Stallion 修复 - 避免将相机位置设置为 (0,0,0)。

问题2

对于 camera1,仍然存在一个问题,即 Pan 和 Dolly 非常慢,至少在最初是这样。它们可能稍后会加速(在使用 camera2 进行平移和移动后),但之后速度非常快。

jsfiddle:v2 camera1 Pan & Dolly 非常慢,至少在开始时是这样,以后可能会过快。 http://jsfiddle.net/steveow/uk94hxrp/

更新:Pan & Dolly "slowness" 是因为相机非常靠近 OrbitControls.target 位置(默认为 (0,0,0))。因此,如果我选择不同的 .target 位置,则可以避免 "slowness"。

注意事项

我目前正在创建一个新的 THREE.OrbitControls 对象,每当我切换相机时。但之前我曾尝试在初始化期间创建两个持久性 THREE.OrbitControls 对象,然后将一个名为 "controls" 的通用变量分配给应该处于活动状态的任何一个。我尝试将 orbitControls 设置为 html div "container" 而不是 renderer.domElement。我试过在动画循环中包含 controls.update()。

前段时间我确实使用过这两款相机,但现在回不去了。

我查看了 OrbitControls 代码,但我 none 更聪明。

CODE(关于原始问题,问题 1,但稍作修改。)。

这里是相机初始化代码:-

//... camera1

    camera1Fov = 75;
    camera1Far = 1200;
    camera1 = new THREE.PerspectiveCamera( camera1Fov, window.innerWidth / window.innerHeight, 1, camera1Far );
    //camera1.position.z = camera1Far;
    camera1.position.set(0,0,0);


    scene.add(camera1);
    camera1.name = "Camera_1";

    var sGeo        = new THREE.SphereGeometry( 40,8,8);
    var sMaterial   = new THREE.MeshPhongMaterial( { color: 0xff00ff } );
    Cam1Target      = new THREE.Mesh(sGeo, sMaterial);
    Cam1Target.position.set(0,0,-200);
    scene.add(Cam1Target);

    controls1 = new THREE.OrbitControls(camera1, renderer.domElement);
    controls = controls1;//... initially.
    camera1.lookAt( Cam1Target );
    RenderCamera = camera1;

    camera1_Helper = new THREE.CameraHelper( camera1 );
    camera1_Helper.update();
    scene.add (camera1_Helper);

// camera2
    camera2 = new THREE.PerspectiveCamera( cameraFOV, window.innerWidth / window.innerHeight, 1, 20000 );
    c2PosX =  5500;
    c2PosY =  3500;
    c2PosZ = -10000;

    camera2.position.set( c2PosX, c2PosY, c2PosZ );
    scene.add(camera2);
    camera2.name = "Camera_2";    
    //controls2 = new THREE.OrbitControls(camera2, renderer.domElement);
    //camera2.lookAt(camera1);

这是动画和相机切换和相机重置代码:-

//----------------------------------------------------------------
function F_frame()
{
   //... Render
   af = requestAnimationFrame(F_frame);

   controls.update(); 

   renderer.render(scene, RenderCamera);


   tick+=0.001;

}//... EOF Frame().

//-------------------------------------------------------------
function F_Switch_Camera() 
{
    var SelectedCameraString = document.getElementById('myTextField').value;
    //...toggle
    if (SelectedCameraString == "camera1") 
    {
        SelectedCameraString = "camera2";
        RenderCamera = camera2;
        controls = new THREE.OrbitControls(camera2, container);//renderer.domElement);
        //controls.object = camera2;
        //controls.update();
        //controls = controls2;
    } else {
        SelectedCameraString = "camera1";
        RenderCamera = camera1;
        controls = new THREE.OrbitControls(camera1, container);//renderer.domElement);
        //controls.object = camera1;
        //controls.update();
        //controls = controls1;     
    }
    document.getElementById('myTextField').value = SelectedCameraString;
}       
//----------------------------------------------------------------------
function F_Reset_Camera1()
{
    camera1.position.set(0,0,0);
    camera1.lookAt ( Cam1Target );
}
//----------------------------------------------------------------------
function F_Reset_Camera2()
{
    camera2.position.set( c2PosX, c2PosY, c2PosZ );
    camera2.lookAt ( camera1 );
}

更新

非常感谢用户 Stallion 的简单修复 - 不要将相机世界位置设置为 (0,0,0),而是使用 (0,0,1)。

有快速修复:

将 camera1 位置设置为

camera1.position.set(0,0,1);

勾选 fiddle http://jsfiddle.net/Stallion33/sgcfu4tt/