问题描述
我想要在几何中心周围应用旋转,但它会应用在几何中心周围几何原点(0,0,0)。
假设:
- 我无法修改几何图形。
我现在要做的是:
mesh3D.position.copy(worldPosition);
mesh3D.rotation.setFromRotationMatrix(localRotation);
mesh3D.updateMatrixWorld(true);
唯一的解决方法是以某种方式使用数据透视表吗?我还想避免这种情况,因为它会更改对象的子级别...
谢谢
要围绕不是对象原点的点进行旋转,请使用以下一般操作顺序:
- 从对象位置减去点。
- 旋转。
- 将原始点添加到对象位置。
在你的情况下,原始点是几何中心。
下面的例子是一个三角形,物体原点和一个角落在场景原点处,但三角形围绕其几何中心旋转。更改 matRot = new THREE.Matrix4()。makeRotationX(0.01);
使用 makeRotationY
/ makeRotationZ
看到它在其他方向工作。
请注意,这些转换应用于对象的本地矩阵,因此任何子对象都将也可以在他们的父母之后进行转换。
var renderer,scene,camera,控制,统计,三; var WIDTH = window.innerWidth,HEIGHT = window.innerHeight,FOV = 35,NEAR = 1,FAR = 1000;函数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,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); }函数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();相机=新的THREE.PerspectiveCamera(FOV,WIDTH / HEIGHT,NEAR,FAR); camera.position.z = 100; scene.add(照相机); controls = new THREE.TrackballControls(camera,renderer.domElement); controls.dynamicDampingFactor = 0.5; controls.rotateSpeed = 3; var light = new THREE.PointLight(0xffffff,1,Infinity); camera.add(光); stats = new Stats(); stats.domElement.style.position ='绝对'; stats.domElement.style.top ='0'; document.body.appendChild(stats.domElement);调整大小(); window.onresize = resize; createTri(); animate();} function resize(){WIDTH = window.innerWidth; HEIGHT = window.innerHeight; if(renderer&& camera&& amp; amp; amp; amp; amp; amp; amp; amp; amp;& amp; amp; amp; amp; amp; amp; camera.aspect = WIDTH / HEIGHT; camera.updateProjectionMatrix(); controls.handleResize(); }} function render(){renderer.render(scene,camera);} function animate(){rotateTri(); //旋转方法requestAnimationFrame(animate);渲染(); controls.update(); stats.update();}函数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();})})})})();
p>
three.js r85
I try to apply a "local rotation" to a mesh in THREEJS.
I want to rotation to be applied around the geometry center but it is applied around the geometry "origin" (0, 0, 0).
Assumption:
- I can not modify the geometry.
What I do right now:
mesh3D.position.copy(worldPosition);
mesh3D.rotation.setFromRotationMatrix(localRotation);
mesh3D.updateMatrixWorld(true);
Is the only solution to use a pivot somehow? I'd also like to avoid that as it changes the object children hierarchy...
Thanks
To rotate about a point that isn't the object origin, this general order of operations applies:
- Subtract the point from the object position.
- Rotate.
- Add the original point to the object position.
In your case, the original point is the geometric center.
The example below is a triangle where the object origin and one corner is at the scene origin, but the triangle rotates about its geometric center. Change matRot = new THREE.Matrix4().makeRotationX(0.01);
to use makeRotationY
/makeRotationZ
to see it working in other directions.
Note that these transformations are applied to the object's local matrix, so any child objects will be transformed as well, following their parent.
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
这篇关于局部网格旋转,无几何平移和旋转(THREEJS)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!