我有一个带有相机设置的3D场景,看起来总是在那个场景的中心。
如何通过更新相机的x,y,z来更改相机的坐标以旋转和缩放该中心?
旋转至少应包括滚动/偏航/缩放
我正在使用webGL / THREE,但我相信这应该适用于任何语言/引擎
答案 0 :(得分:2)
我认为最简单的方法是使用矩阵层次结构。
在原点创建一个节点。在您想要相机的地方创建一个子节点。在原点处旋转节点。问孩子它在哪里,把相机放在那里。使用lookAt
定位相机
这几乎总是比计算一个圆圈容易。你可以通过创造性地将节点放在场景中,移动它们并使用它们设置摄像机的位置和目标来实现各种效果。
var canvas = document.querySelector("#c");
var camera = new THREE.PerspectiveCamera(70, 1, 1, 1000);
var scene = new THREE.Scene();
// make some cubes
var geometry = new THREE.BoxBufferGeometry(20, 20, 20);
var material = new THREE.MeshLambertMaterial({ color: 0xFFEECC });
for (var z = -1; z <= 1; ++z) {
for (var x = -1; x <= 1; ++x) {
var mesh = new THREE.Mesh(geometry, material);
mesh.position.x = x * 30;
mesh.position.z = z * 30;
scene.add(mesh);
}
}
// add some lights
var light = new THREE.DirectionalLight(0xE0E0FF, 1);
light.position.set(200, 500, 200);
scene.add(light);
var light = new THREE.DirectionalLight(0xFFE0E0, 0.95);
light.position.set(-200, -500, -200);
scene.add(light);
// now make nodes for camera
var cameraCenterNode = new THREE.Object3D();
var cameraPositionNode = new THREE.Object3D();
scene.add(cameraCenterNode);
cameraCenterNode.add(cameraPositionNode);
cameraPositionNode.position.x = 100;
cameraPositionNode.position.y = 40;
var renderer = new THREE.WebGLRenderer({canvas: canvas});
function resizeIfChanged() {
var width = canvas.clientWidth;
var height = canvas.clientHeight;
if (canvas.width != width || canvas.height != height) {
camera.aspect = width / height;
camera.updateProjectionMatrix();
renderer.setSize(width, height, false);
}
}
function render(time) {
time *= 0.001; // make it seconds
resizeIfChanged();
// Rotate camera center
cameraCenterNode.rotation.y = time;
// get cameraPositionNode's world position and put it in camera
cameraPositionNode.getWorldPosition(camera.position);
// point camera at center
camera.lookAt(cameraCenterNode.position);
renderer.render(scene, camera);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
body { margin: 0 }
canvas { width: 100vw; height: 100vh; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r78/three.min.js"></script>
<canvas id="c"></canvas>
至于缩放,它实际上取决于你想要达到的目标。
例如,您可以计算cameraCenterNode
和cameraPositionNode
之间的点。例如:
var out = cameraPositionNode.getWorldPosition();
var in = cameraCenternode.getWorldPosition();
in.lerp(out, zoomAmount); // where 0.0 = in and 1.0 = out
// now set the camera there
camera.position.copy(in);
或者可以随时沿着-zAxis
向前移动相机var worldMatrix = camera.getWorldMatrix();
var zoomVector = new THREE.Vector3(
wm.elememts[8], wm.elememts[9], wm.elememts[10]);
camera.position.sub(zoomVector.multiplyScalar(zoomAmount));
从您的问题中不清楚您真正希望相机如何工作。如果您希望它指向原点并始终围绕OR旋转,如果您希望它像典型的建模包一样更自由浮动。无论你必须选择一些旋转点。无论是固定点还是新点,取决于相机在哪里进行相同类型的计算都可以。
答案 1 :(得分:1)
如果我理解正确,你只需要&#34;旋转&#34;相机位置并将其设置为查看场景的原点:
camera.position.x = R * Math.cos(bearing) * Math.cos(pitch);
camera.position.y = R * Math.sin(bearing) * Math.cos(pitch);
camera.position.z = R * Math.sin(pitch);
camera.lookAt(new THREE.Vector3(0, 0, 0));
此处R
是从相机到原点的距离,bearing
是水平平面中的旋转pitch
- 在垂直平面中。
答案 2 :(得分:0)