javascript - Three.js - 与父级分开旋转相机
问题描述
我有一个场景,其中对象围绕CatmullRomCurve3
路径移动,按或箭头键时向左移动,按或left
箭头down
键时向右移动。right
up
我最初有一个问题,我希望对象与路径成 90 度而不是沿着路径面对。你可以在那里找到我的这个场景的代码。这个问题已经用这个答案解决了。
基本上,我所要做的就是实现以下代码来旋转对象:
object.lookAt((p2).sub(p1).applyAxisAngle(axis, -Math.PI * 0.5).add(p1));
虽然对象现在可以正确旋转,但我现在遇到的问题是它camera
没有面向与对象相同的方向或与对象一起移动(我想要对象的肩上型透视),但有人建议我解决这个问题将相机添加为对象的子对象,这很有效!
新问题
我现在希望对象的默认位置与路径成 90 度角(原样),但是当您按下left
或down
箭头时,我希望对象面朝左(沿着原来的路径返回),并面向当按right
和up
箭头时,反之。
我设法通过if
在循环中设置一些语句来使其工作,这些语句根据按下的键render
将值更改-Math.PI * 0.5
为任一-Math.PI * 2
或-Math.PI * 0.5
左右。
但是,这也会导致相机采用该新lookAt
值,因为它是对象的子对象,但我希望相机始终保持在同一位置(即与路径成 90 度角,就像对象在静止时所做的那样)。
那么,当对象发生变化时,如何阻止相机旋转/移动/更改它lookAt
(我不确定它是哪一个)?
似乎我对相机所做的一切都不会影响它,它总是锁定到对象的相同方向。
提前致谢。
解决方案
我希望我已经正确理解了你的问题:
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>
推荐阅读
- android - 如何使用 Spotify API 将音乐流式传输到我们的 Android 应用程序?
- performance - BST算法中给定范围内节点计数的运行时间
- c++ - 为什么相同的语句不适用于 C++ 中的类成员?
- swift - XMLMapper 未在 UITableView 中显示结果
- docker - 如何配置我的 docker-compose 以将在 docker 容器中运行的“应用程序”连接到在物理机中运行的“数据库”
- python - 从python中的列表中删除多余的括号
- flutter - 如何将折叠动画添加到小部件?
- spring - 如何在 application.properties 文件中指定环境变量,以便我的应用程序可以在 Spring 中使用 Docker 容器 MySQL 而不是本地 MySQL?
- php - Ajax 调用:在附加到视图之前处理数据
- json - 从另一个 json BASH 更改 json 字典中的值