gpt4 book ai didi

javascript - 带有两个(切换)相机的 Three.js 轨道控制

转载 作者:行者123 更新时间:2023-12-03 07:20:12 27 4
gpt4 key购买 nike

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

问题

问题1

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

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

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

问题2

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

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

更新:平移和移动“缓慢”是因为相机非常接近 OrbitControls.target 位置(默认为 (0,0,0))。因此,如果我选择不同的 .target 位置,则可以避免“缓慢”。

注释

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

不久前我确实使用过任一相机,但我无法回到那个状态。

我查看了 OrbitControls 代码,但一无所知。

代码(与原始问题相同,问题 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)。

最佳答案

有一个快速修复:

将相机1位置设置为

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

检查 fiddle http://jsfiddle.net/Stallion33/sgcfu4tt/

// Variables
var cameraDistance = 500;
var cameraFOV = 45;
var lightD = 20;
var sphereRadius = 20;

//var SelectedCameraString = "camera" ;
var camera1, camera2, RenderCamera;
var controls, controls1, controls2;

// Scene
var scene = new THREE.Scene();

// Renderer
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0x008888); //scene.fog.color );
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.sortObjects = false;

document.getElementById('container').appendChild(renderer.domElement);


scene.add(new THREE.AmbientLight(0xffffff));

///var light1 = new THREE.PointLight(0xffffff);
//light1.position.set(-5400, 1400, -1400);

//... 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);

/*
// Near & Far Plane dimensions
c1_hNear = 2 * Math.tan(camera1.fov * Math.PI / 180 / 2) * camera1.near; // CHANGED - deg to radians
c1_wNear = c1_hNear * camera1.aspect; // width

c1_hFar = 2 * Math.tan(camera1.fov * Math.PI / 180 / 2) * camera1.far; // CHANGED - deg to radians
c1_wFar = c1_hFar * camera1.aspect; // width

//... Frustrum Vertex Points
//... far
var camera1_farTopLeft = new THREE.Vector3(-c1_wFar / 2, c1_hFar / 2, -camera1.far); // CHANGED - sign flips
var camera1_farBottomRight = new THREE.Vector3( c1_wFar / 2, -c1_hFar / 2, -camera1.far);
var camera1_farTopRight = new THREE.Vector3( c1_wFar / 2, c1_hFar / 2, -camera1.far);
var camera1_farBottomLeft = new THREE.Vector3(-c1_wFar / 2, -c1_hFar / 2, -camera1.far);
//... near
var camera1_nearTopLeft = new THREE.Vector3(-c1_wNear / 2, c1_hNear / 2, -camera1.near); // CHANGED - sign flips
var camera1_nearBottomRight = new THREE.Vector3( c1_wNear / 2, -c1_hNear / 2, -camera1.near);
var camera1_nearTopRight = new THREE.Vector3( c1_wNear / 2, c1_hNear / 2, -camera1.near);
var camera1_nearBottomLeft = new THREE.Vector3(-c1_wNear / 2, -c1_hNear / 2, -camera1.near);

//... SW store vertices in array

Frustrum_Vertices = [];

Frustrum_Vertices.push (camera1_farTopLeft);
Frustrum_Vertices.push (camera1_farBottomRight);
Frustrum_Vertices.push (camera1_farTopRight);
Frustrum_Vertices.push (camera1_farBottomLeft);

Frustrum_Vertices.push (camera1_nearTopLeft);
Frustrum_Vertices.push (camera1_nearBottomRight);
Frustrum_Vertices.push (camera1_nearTopRight);
Frustrum_Vertices.push (camera1_nearBottomLeft);

//... Frustrum_Marker_Spheres

Frustrum_Marker_Spheres = [];

var FV = Frustrum_Vertices;
for (iii=0;iii<Frustrum_Vertices.length; iii++)
{
var sphereRadius = 60;
var FVsphereMaterial = new THREE.MeshPhongMaterial( { color: 0xffff00, side: THREE.DoubleSide } );

if(iii>3)
{
sphereRadius = 0.05;//90;
var FVsphereMaterial = new THREE.MeshPhongMaterial( { color: 0x0000ff, side: THREE.DoubleSide } );
}
var sphereGeo = new THREE.SphereGeometry( sphereRadius, 8, 8);
var sphereMesh = new THREE.Mesh( sphereGeo, FVsphereMaterial);
Frustrum_Marker_Spheres.push ( sphereMesh );
sphereMesh.position.set( FV[iii].x, FV[iii].y, FV[iii].z );

camera1.add( sphereMesh );
}
*/

scene.add(camera1);
camera1.position.set(0, 0, 1);
camera1.name = "Camera_1";
RenderCamera = camera1;

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

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);
var c2PosX = 5500;
var c2PosY = 3500;
var 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);

/*
// Material
var material = new THREE.MeshPhongMaterial({
color: 0xff0000,
opacity: 1,
visible: true,
side: THREE.DoubleSide
});

// Smaterial
var Smaterial = new THREE.MeshLambertMaterial({
color: 0xffff00,
opacity: 0.5,
visible: true,
transparent: true,
side: THREE.DoubleSide
});

//... Fbox
//approximation to frustrum geometry
var FboxGeo = new THREE.BoxGeometry( 200,100,500);
var FboxMesh = new THREE.Mesh(FboxGeo, Smaterial);
FboxMesh.position.set(0, 0, -125 );
//camera1.add(FboxMesh);


//====================================================

function srnd(rng){return (Math.random()*rng*2)-rng;}

//====================================================

//... make balls
var sphereRadius = 20;
for(var i=0;i<100;i++)
{
// Ball
var ballGeo = new THREE.SphereGeometry( sphereRadius, sphereRadius, sphereRadius);
var ballMaterial = new THREE.MeshLambertMaterial( { color: 0x00ff00 } );
var ballMesh = new THREE.Mesh(ballGeo, ballMaterial);
ballMesh.position.set(srnd(500),srnd(500), -camera1Far + srnd(500));
scene.add(ballMesh);
}
*/
//var tick=0;
var raf;

//var frustum = new THREE.Frustum();

F_frame();

//... END OF MAIN
//====================================================


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

controls.update(); //...BAD in jsfiddle

renderer.render(scene, RenderCamera);

//tick+=0.001;

} //... EOF Frame().

//-------------------------------------------------------------
function F_Switch_Camera() {
var SelectedCameraString = document.getElementById('myTextField').value;
//...toggle
//alert("Hello");
if (SelectedCameraString == "camera1") {
SelectedCameraString = "camera2";
RenderCamera = camera2;
//controls = new THREE.OrbitControls(camera2, container);//renderer.domElement);
controls = new THREE.OrbitControls(camera2, renderer.domElement);
//controls.object = camera2;
//controls.update();
//controls = controls2;
} else {
SelectedCameraString = "camera1";
RenderCamera = camera1;
//controls = new THREE.OrbitControls(camera1, container);//renderer.domElement);
controls = new THREE.OrbitControls(camera1, renderer.domElement);
//controls.object = camera1;
//controls = controls1;
//controls.update();
}
document.getElementById('myTextField').value = SelectedCameraString;
}

//----------------------------------------------------------------------
function F_Reset_Camera1() {
camera1.position.set(0, 0, 1);
camera1.lookAt(Cam1Target);
}
//----------------------------------------------------------------------
function F_Reset_Camera2() {
camera2.position.set(c2PosX, c2PosY, c2PosZ);
camera2.lookAt(camera1);
}
#container {
height: 100%;
width: 100%;
min-height: 100%;
min-width: 100%;
}
<script src="https://cdn.jsdelivr.net/npm/three@0.122.0/build/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.122.0/examples/js/controls/OrbitControls.min.js"></script>

<h1 id="title_A">Camera Frustrum Box</h1>
<input type="submit" id="byBtn1" value="Switch Camera" onclick="F_Switch_Camera()" />
<input type="text" id="myTextField" value="camera1" />
<input type="submit" id="byBtn2" value="Reset Camera1" onclick="F_Reset_Camera1()" />
<input type="submit" id="byBtn3" value="Reset Camera2" onclick="F_Reset_Camera2()" />
<div id="container"></div>

关于javascript - 带有两个(切换)相机的 Three.js 轨道控制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36239892/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com