我正在尝试旋转耳机的一部分。它可以在我的模型(在Maya中)中做到这一点。但是我似乎无法在threejs中弄清楚。
我知道我可以通过执行以下操作来旋转对象X Y和Z:
object.rotateX(THREE.Math.degToRad(degreeX));
object.rotateY(THREE.Math.degToRad(degreeY));
object.rotateZ(THREE.Math.degToRad(degreeZ));
但是,当其余部分旋转/移动时,如何使枢轴点保持静止?因此,在我的示例中,我希望听筒能够根据您在图片中看到的黑色螺丝在左右移动。
答案 0 :(得分:1)
您可以将耳机网格嵌套在另一个THREE.Group
内,将耳机重新放置在该组中,以使轴心位于所需位置,然后旋转父对象。
// You take your headphones and nest them inside a Group
var headphones = new THREE.Mesh(geom, material);
var parent = new THREE.Group();
parent.add(headphones);
// Then you move your headphones to the desired pivot position
headphones.position.set(-5, 0.1, 0);
// Parent is going to rotate around it origin
parent.rotateX(THREE.Math.degToRad(degreeX));
请注意,如果您希望将轴心放在(5, -0.1, 0)
上,则应沿相反方向移动耳机:(-5, 0.1, 0)
。
答案 1 :(得分:1)
将您的模型与另一个THREE.Object3D
关联,但是为了方便使用SceneUtils.attach
函数。
示例:
单击然后拖动,每次单击时,枢轴对象都会移动到该位置,然后通过调用THREE.SceneUtils.attach(model, scene, pivot)
将模型(多维数据集)附加到枢轴。放开鼠标时,将使用THREE.SceneUtils.detach(model, pivot, scene)
分离模型。
'use strict';
/* global THREE */
function main() {
const canvas = document.querySelector('#c');
const renderer = new THREE.WebGLRenderer({canvas: canvas});
const fov = 45;
const aspect = 2; // the canvas default
const near = 0.1;
const far = 100;
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
// make the camera look down
camera.position.set(0, 10, 0);
camera.up.set(0, 0, -1);
camera.lookAt(0, 0, 0);
const scene = new THREE.Scene();
scene.background = new THREE.Color('black');
scene.add(new THREE.GridHelper(40, 40));
let model;
{
const cubeSize = 3;
const cubeGeo = new THREE.BoxBufferGeometry(cubeSize, cubeSize, cubeSize);
const cubeMat = new THREE.MeshBasicMaterial({color: 'red'});
model = new THREE.Mesh(cubeGeo, cubeMat);
model.position.set(.5, .5, .5);
scene.add(model);
}
function resizeRendererToDisplaySize(renderer) {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
const needResize = canvas.width !== width || canvas.height !== height;
if (needResize) {
renderer.setSize(width, height, false);
}
return needResize;
}
function render() {
if (resizeRendererToDisplaySize(renderer)) {
const canvas = renderer.domElement;
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
}
renderer.render(scene, camera);
}
render();
let rotate = false;
const startPos = {x:0, y:0};
const raycaster = new THREE.Raycaster();
const pivot = new THREE.Object3D();
scene.add(pivot);
pivot.add(new THREE.AxesHelper(.5));
function setPivotPoint(e) {
startPos.x = e.clientX;
startPos.y = e.clientY;
const normalizedPosition = {
x: e.clientX / canvas.clientWidth * 2 - 1,
y: e.clientY / canvas.clientHeight * -2 + 1,
};
// this part is NOT important to the answer. The question
// is how to rotate from some point. This code is picking
// a point. Which point to pick was not part of the question
// but to demo the solution it's important to pick a point
// put the pivot where the mouse was clicked
raycaster.setFromCamera(normalizedPosition, camera);
const intersection = raycaster.intersectObjects(scene.children)[0];
if (intersection) {
if (rotate) {
removeFromPivot();
}
pivot.position.copy(intersection.point);
pivot.rotation.set(0,0,0);
pivot.updateMatrixWorld();
rotate = true;
// this the important part. We're making the cube
// a child of 'pivot' without it moving in world space
THREE.SceneUtils.attach(model, scene, pivot);
render();
}
}
function rotatePivot(e) {
e.preventDefault();
if (rotate) {
const dx = e.clientX - startPos.x;
const dy = e.clientY - startPos.y;
const maxDelta = Math.abs(dx) > Math.abs(dy) ? dx : dy;
pivot.rotation.y = maxDelta * 0.01;
render();
}
}
function removeFromPivot() {
if (rotate) {
rotate = false;
THREE.SceneUtils.detach(model, pivot, scene);
window.removeEventListener('mousemove', rotatePivot);
window.removeEventListener('mouseup', removeFromPivot);
}
}
canvas.addEventListener('mousedown', (e) => {
e.preventDefault();
setPivotPoint(e);
if (rotate) {
window.addEventListener('mousemove', rotatePivot);
window.addEventListener('mouseup', removeFromPivot);
}
});
}
main();
html, body {
margin: 0;
height: 100%;
}
#c {
width: 100%;
height: 100%;
display: block;
}
<canvas id="c"></canvas>
<script src="https://threejsfundamentals.org/threejs/resources/threejs/r98/three.min.js"></script>
<script src="https://threejsfundamentals.org/threejs/resources/threejs/r98/js/utils/SceneUtils.js"></script>