local mesh rotation without geometry translate and pivot (THREEJS)

北城余情 提交于 2020-01-17 06:15:30

问题


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:

  1. 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


回答1:


To rotate about a point that isn't the object origin, this general order of operations applies:

  1. Subtract the point from the object position.
  2. Rotate.
  3. 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



来源:https://stackoverflow.com/questions/44563652/local-mesh-rotation-without-geometry-translate-and-pivot-threejs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!