我尝试将“局部旋转”应用于THREEJS中的网格。
我希望旋转应用于几何中心,但它应用于几何体“origin”(0,0,0)。
假设:
我现在做的是什么:
mesh3D.position.copy(worldPosition);
mesh3D.rotation.setFromRotationMatrix(localRotation);
mesh3D.updateMatrixWorld(true);
唯一能以某种方式使用枢轴的解决方案吗?我也想避免这种情况,因为它改变了对象子层次结构......
由于
答案 0 :(得分:0)
要围绕一个不是对象原点的点旋转,这个一般操作顺序适用:
在您的情况下,原始点是几何中心。
以下示例是一个三角形,其中对象原点和一个角位于场景原点,但三角形围绕其几何中心旋转。更改matRot = new THREE.Matrix4().makeRotationX(0.01);
以使用makeRotationY
/ makeRotationZ
查看其在其他方向上工作。
请注意,这些转换应用于对象的局部矩阵,因此任何子对象也将在其父对象之后进行转换。
var renderer, scene, camera, controls, stats, tri;
var WIDTH = window.innerWidth,
HEIGHT = window.innerHeight,
FOV = 35,
NEAR = 1,
FAR = 1000;
function createTri(){
var geo = new THREE.BufferGeometry();
geo.addAttribute("position", new THREE.BufferAttribute(new Float32Array([
-10, 20, 0,
-20, 0, 0,
0, 0, 0
]), 3));
geo.addAttribute("normal", new THREE.BufferAttribute(new Float32Array([
0, 0, 1,
0, 0, 1,
0, 0, 1
]), 3));
geo.setIndex(new THREE.BufferAttribute(new Uint32Array([
0, 1, 2
]), 1));
geo.computeBoundingBox();
tri = new THREE.Mesh(geo, new THREE.MeshPhongMaterial({side: THREE.DoubleSide}));
scene.add(tri);
}
var matAdd = null, matSub = null, matRot = null;
function rotateTri(){
var geoCenter = tri.geometry.boundingBox.getCenter();
matAdd.makeTranslation(geoCenter.x, geoCenter.y, geoCenter.z);
matSub.getInverse(matAdd);
tri.applyMatrix(matSub);
tri.applyMatrix(matRot);
tri.applyMatrix(matAdd);
}
function init() {
matAdd = new THREE.Matrix4();
matSub = new THREE.Matrix4();
matRot = new THREE.Matrix4().makeRotationX(0.01);
document.body.style.backgroundColor = "slateGray";
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
document.body.appendChild(renderer.domElement);
document.body.style.overflow = "hidden";
document.body.style.margin = "0";
document.body.style.padding = "0";
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(FOV, WIDTH / HEIGHT, NEAR, FAR);
camera.position.z = 100;
scene.add(camera);
controls = new THREE.TrackballControls(camera, renderer.domElement);
controls.dynamicDampingFactor = 0.5;
controls.rotateSpeed = 3;
var light = new THREE.PointLight(0xffffff, 1, Infinity);
camera.add(light);
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0';
document.body.appendChild(stats.domElement);
resize();
window.onresize = resize;
createTri();
animate();
}
function resize() {
WIDTH = window.innerWidth;
HEIGHT = window.innerHeight;
if (renderer && camera && controls) {
renderer.setSize(WIDTH, HEIGHT);
camera.aspect = WIDTH / HEIGHT;
camera.updateProjectionMatrix();
controls.handleResize();
}
}
function render() {
renderer.render(scene, camera);
}
function animate() {
rotateTri(); // rotation method
requestAnimationFrame(animate);
render();
controls.update();
stats.update();
}
function threeReady() {
init();
}
(function () {
function addScript(url, callback) {
callback = callback || function () { };
var script = document.createElement("script");
script.addEventListener("load", callback);
script.setAttribute("src", url);
document.head.appendChild(script);
}
addScript("https://threejs.org/build/three.js", function () {
addScript("https://threejs.org/examples/js/controls/TrackballControls.js", function () {
addScript("https://threejs.org/examples/js/libs/stats.min.js", function () {
threeReady();
})
})
})
})();

three.js r85