three.js - 如何在轴上旋转 3D 对象
问题描述
在这里,我希望仅使用相机旋转对象,而不是围绕对象旋转整个相机。首先,对象的中心原点在正常工作的地方保持不变,但是一旦我平移对象,原点的中心就会不同,并围绕对象旋转相机。 https://jsfiddle.net/1ax8hf07/
var scene, renderer, camera;
var cube;
var controls;
var containerWidth = window.innerWidth,
containerHeight = window.innerHeight;
var isDragging = false;
var previousMousePosition = {
x: 0,
y: 0
};
init();
animate();
function init() {
configureRenderer();
scene = new THREE.Scene();
configureCube();
configureCamera();
configureLight();
configureControls();
}
function configureRenderer() {
renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
window.onresize = function () {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
if (controls)
controls.handleResize();
}
}
function configureCube() {
var cubeGeometry = new THREE.BoxGeometry(20, 20, 20);
var cubeMaterial = new THREE.MeshLambertMaterial({
color: 0xff0000
});
cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.position.set(50, 0, 0);
scene.add(cube);
cubeGeometry.center();
}
function configureCamera() {
camera = new THREE.PerspectiveCamera(45, containerWidth / containerHeight, 1, 1000);
camera.position.set(0, 160, 400);
camera.lookAt(scene);
}
function configureLight() {
pointLight = new THREE.PointLight(0xffffff, 1.0, 100000);
pointLight.position.set(0, 300, 200);
scene.add(pointLight);
}
function configureControls() {
controls = new THREE.TrackballControls(camera, renderer.domElement);
// controls.enabled = false;
controls.update();
controls.object.up.set(0, 0, 1);
}
function animate() {
controls.update();
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
解决方案
我不知道是否有更简单的方法,但就个人而言,当我需要移动或旋转某些东西时,我会自己做。在您的情况下,我建议跟踪鼠标移动并将旋转添加到转换矩阵。这就是你的代码的样子
var scene, renderer, camera;
var cube;
var controls;
var containerWidth = window.innerWidth,
containerHeight = window.innerHeight;
var isDragging = false;
var previousMousePosition = {
x: 0,
y: 0
};
init();
animate();
function init() {
configureRenderer();
scene = new THREE.Scene();
configureCube();
configureCamera();
configureLight();
configureControls();
}
function configureRenderer() {
renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
window.onresize = function() {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
if (controls) controls.handleResize();
};
}
function configureCube() {
var cubeGeometry = new THREE.BoxGeometry(20, 20, 20);
var cubeMaterial = new THREE.MeshLambertMaterial({
color: 0xff0000
});
cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.position.set(50, 0, 0);
scene.add(cube);
cubeGeometry.center();
}
function configureCamera() {
camera = new THREE.PerspectiveCamera(
45,
containerWidth / containerHeight,
1,
1000
);
camera.position.set(0, 160, 400);
camera.lookAt(scene);
}
function configureLight() {
pointLight = new THREE.PointLight(0xffffff, 1.0, 100000);
pointLight.position.set(0, 300, 200);
scene.add(pointLight);
}
function configureControls() {
controls = new THREE.TrackballControls(camera, renderer.domElement);
controls.enabled = false;
controls.update();
document.addEventListener("mousedown", onMouseDown, false);
document.addEventListener("mouseup", onMouseUp, false);
}
function onMouseDown() {
previousMousePosition.x = event.clientX;
previousMousePosition.y = event.clientY;
document.addEventListener("mousemove", onMouseMove, false);
}
function onMouseMove(event) {
var rotationX = event.clientX - previousMousePosition.x;
var rotationY = event.clientY - previousMousePosition.y;
previousMousePosition.x = event.clientX;
previousMousePosition.y = event.clientY;
if (rotationX || rotationY) {
rotateAroundWorldAxis(cube, new THREE.Vector3(0, 1, 0), rotationX * 0.01);
rotateAroundWorldAxis(cube, new THREE.Vector3(1, 0, 0), rotationY * 0.01);
}
}
function onMouseUp() {
document.removeEventListener("mousemove", onMouseMove, false);
}
function rotateAroundWorldAxis(object, axis, radians) {
var rotationMatrix = new THREE.Matrix4();
rotationMatrix.makeRotationAxis(axis.normalize(), radians);
rotationMatrix.multiply(object.matrix);
object.matrix = rotationMatrix;
object.rotation.setFromRotationMatrix(object.matrix);
}
function animate() {
controls.update();
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
推荐阅读
- c# - "使用泛型类型 'Func
' 需要 1 个类型参数”在定义具有 4 个以上参数的委托函数类型时出现问题 - html - 为 PUG 中的引导表中的每条记录添加一个删除按钮
- c# - C# 从列表和输入框中选择并传递参数
- javascript - 如何在 OpenLayers 5 中删除绘图?
- sql - 按周的星期一查询数据库和分组
- reactjs - React:将整数转换为带点分隔符的数字
- android - 得到“测试APK不包含用户指定的测试运行器类或清单文件。” 使用 Firebase
- java - javax.xml.stream.XMLStreamException: ParseError at [row,col]:[X,X] - JavaFX
- javascript - 如何读取sharp返回的图像的Buffer数据?
- python - 使用 pyinstaller 打包 .txt 文件以在 python 可执行文件中使用