Three.js - 将相机与其父级分开旋转

时间:2018-04-27 10:27:00

标签: javascript three.js

我有一个场景,其中一个物体围绕CatmullRomCurve3路径移动,当您按下leftdown箭头键时向左移动,当您按下{{1}时向右移动}或right箭头键。

我最初had a problem我希望对象面向路径90度而不是面向路径。你可以在那里找到我的代码。 this answer解决了这个问题。

基本上,我所要做的就是实现以下代码来旋转对象:

up

虽然对象现在正确旋转,但我现在遇到的问题是object.lookAt((p2).sub(p1).applyAxisAngle(axis, -Math.PI * 0.5).add(p1)); 没有面向与对象相同的方向或者与对象一起移动(我想要对象的肩部类型透视)但是有人建议我通过添加相机作为对象的孩子来解决这个问题,哪个有效!

新问题

我现在希望对象的默认位置与路径成90度(原样),但是当您按下cameraleft箭头时,我希望对象朝左(沿着原来的路径返回),并在按下downright箭头时面向另一个方向。

我设法通过在up循环中设置一些if语句,将render的值更改为-Math.PI * 0.5或{{1}左右,取决于按下哪个键。

然而,这也会导致相机拍摄新的-Math.PI * 2值,因为它是对象的孩子,但我希望相机始终保持在相同的位置(即与路径成90度,当它仍然是对象时。)

那么,当对象发生变化时,如何阻止相机旋转/移动/更改它-Math.PI * 0.5(我不确定它是哪一个)?

似乎我对相机没有任何影响,它始终锁定在对象的相同方向。

提前致谢。

1 个答案:

答案 0 :(得分:0)

我希望我能正确理解你的问题:

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 20, -20);
camera.lookAt(0, 0, 0);
var renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

var grid = new THREE.GridHelper(300, 30);
grid.position.setZ(100);
scene.add(grid);

var points = [
  new THREE.Vector3(-80, 5, 35),
  new THREE.Vector3(-80, 5, 192.5),
  new THREE.Vector3(80, 5, 192.5),
  new THREE.Vector3(80, 5, 35)
];

var curve = new THREE.CatmullRomCurve3(points);
curve.closed = true;

var curvePoints = curve.getPoints(200);
var geomCurvePath = new THREE.BufferGeometry().setFromPoints(curvePoints);
var matCurvePath = new THREE.LineBasicMaterial({
  color: 0xff0000
});
var CurvePath = new THREE.Line(geomCurvePath, matCurvePath);
scene.add(CurvePath);

var group = new THREE.Group();
scene.add(group);

group.add(camera);

var pointerGeom = new THREE.ConeGeometry(4, 20, 4);
pointerGeom.translate(0, 10, 0);
pointerGeom.rotateX(Math.PI * 0.5);
var pointer = new THREE.Mesh(pointerGeom, new THREE.MeshNormalMaterial());
group.add(pointer);

btnLeft.addEventListener("click", function() {
  turn(Math.PI * 0.5)
});
btnRight.addEventListener("click", function() {
  turn(-Math.PI * 0.5)
});

function turn(angle) {
  pointer.rotation.y += angle;
}

var p1 = new THREE.Vector3();
var p2 = new THREE.Vector3();
var lookAt = new THREE.Vector3();
var axis = new THREE.Vector3(0, 1, 0);
var percentage = 0;

render();

function render() {
  requestAnimationFrame(render);
  percentage += 0.0005;
  curve.getPointAt(percentage % 1, p1);
  curve.getPointAt((percentage + 0.001) % 1, p2);
  lookAt.copy(p2).sub(p1).applyAxisAngle(axis, -Math.PI * 0.5).add(p1); // look at the point 90 deg from the path
  group.position.copy(p1);
  group.lookAt(lookAt);
  renderer.render(scene, camera);
}
body {
  overflow: hidden;
  margin: 0;
}

#buttons {
  position: absolute;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/92/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<div id="buttons">
  <button id="btnLeft">left</button>
  <button id="btnRight">right</button>
</div>