没有几何平移和枢轴的局部网格旋转(THREEJS)

时间:2017-06-15 09:19:11

标签: three.js rotation geometry pivot

我尝试将“局部旋转”应用于THREEJS中的网格。

我希望旋转应用于几何中心,但它应用于几何体“origin”(0,0,0)。

假设:

  1. 我无法修改几何体。
  2. 我现在做的是什么:

    mesh3D.position.copy(worldPosition);
    mesh3D.rotation.setFromRotationMatrix(localRotation);
    mesh3D.updateMatrixWorld(true);
    

    唯一能以某种方式使用枢轴的解决方案吗?我也想避免这种情况,因为它改变了对象子层次结构......

    由于

1 个答案:

答案 0 :(得分:0)

要围绕一个不是对象原点的点旋转,这个一般操作顺序适用:

  1. 从对象位置减去该点。
  2. 旋转。
  3. 将原始点添加到对象位置。
  4. 在您的情况下,原始点是几何中心。

    以下示例是一个三角形,其中对象原点和一个角位于场景原点,但三角形围绕其几何中心旋转。更改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