首页 > 解决方案 > 如何在轴上旋转 3D 对象

问题描述

在这里,我希望仅使用相机旋转对象,而不是围绕对象旋转整个相机。首先,对象的中心原点在正常工作的地方保持不变,但是一旦我平移对象,原点的中心就会不同,并围绕对象旋转相机。 https://jsfiddle.net/1ax8hf07/

  var scene, renderer, camera;
    var cube;
    var controls;
    var containerWidth = window.innerWidth,
        containerHeight = window.innerHeight;
    var isDragging = false;
    var previousMousePosition = {
        x: 0,
        y: 0
    };

    init();

    animate();

    function init() {
        configureRenderer();
        scene = new THREE.Scene();
        configureCube();
        configureCamera();
        configureLight();
        configureControls();
    }

    function configureRenderer() {
        renderer = new THREE.WebGLRenderer({
            antialias: true,
            alpha: true
        });
        renderer.setSize(innerWidth, innerHeight);
        document.body.appendChild(renderer.domElement);
        window.onresize = function () {
            renderer.setSize(window.innerWidth, window.innerHeight);
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            if (controls)
                controls.handleResize();
        }
    }

    function configureCube() {
        var cubeGeometry = new THREE.BoxGeometry(20, 20, 20);
        var cubeMaterial = new THREE.MeshLambertMaterial({
            color: 0xff0000
        });
        cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
        cube.position.set(50, 0, 0);
        scene.add(cube);
        cubeGeometry.center();
    }

    function configureCamera() {
        camera = new THREE.PerspectiveCamera(45, containerWidth / containerHeight, 1, 1000);
        camera.position.set(0, 160, 400);
        camera.lookAt(scene);
    }

    function configureLight() {
        pointLight = new THREE.PointLight(0xffffff, 1.0, 100000);
        pointLight.position.set(0, 300, 200);
        scene.add(pointLight);
    }

    function configureControls() {
        controls = new THREE.TrackballControls(camera, renderer.domElement);
        // controls.enabled = false;
        controls.update();
        controls.object.up.set(0, 0, 1);
    }

    function animate() {
        controls.update();
        requestAnimationFrame(animate);
        renderer.render(scene, camera);
    }

标签: three.js

解决方案


我不知道是否有更简单的方法,但就个人而言,当我需要移动或旋转某些东西时,我会自己做。在您的情况下,我建议跟踪鼠标移动并将旋转添加到转换矩阵。这就是你的代码的样子

var scene, renderer, camera;
var cube;
var controls;
var containerWidth = window.innerWidth,
  containerHeight = window.innerHeight;
var isDragging = false;
var previousMousePosition = {
  x: 0,
  y: 0
};

init();

animate();

function init() {
  configureRenderer();
  scene = new THREE.Scene();
  configureCube();
  configureCamera();
  configureLight();
  configureControls();
}

function configureRenderer() {
  renderer = new THREE.WebGLRenderer({
    antialias: true,
    alpha: true
  });
  renderer.setSize(innerWidth, innerHeight);
  document.body.appendChild(renderer.domElement);
  window.onresize = function() {
    renderer.setSize(window.innerWidth, window.innerHeight);
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    if (controls) controls.handleResize();
  };
}

function configureCube() {
  var cubeGeometry = new THREE.BoxGeometry(20, 20, 20);
  var cubeMaterial = new THREE.MeshLambertMaterial({
    color: 0xff0000
  });
  cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
  cube.position.set(50, 0, 0);
  scene.add(cube);
  cubeGeometry.center();
}

function configureCamera() {
  camera = new THREE.PerspectiveCamera(
    45,
    containerWidth / containerHeight,
    1,
    1000
  );
  camera.position.set(0, 160, 400);
  camera.lookAt(scene);
}

function configureLight() {
  pointLight = new THREE.PointLight(0xffffff, 1.0, 100000);
  pointLight.position.set(0, 300, 200);
  scene.add(pointLight);
}

function configureControls() {
  controls = new THREE.TrackballControls(camera, renderer.domElement);
  controls.enabled = false;
  controls.update();

  document.addEventListener("mousedown", onMouseDown, false);
  document.addEventListener("mouseup", onMouseUp, false);
}
function onMouseDown() {
  previousMousePosition.x = event.clientX;
  previousMousePosition.y = event.clientY;
  document.addEventListener("mousemove", onMouseMove, false);
}
function onMouseMove(event) {
  var rotationX = event.clientX - previousMousePosition.x;
  var rotationY = event.clientY - previousMousePosition.y;

  previousMousePosition.x = event.clientX;
  previousMousePosition.y = event.clientY;

  if (rotationX || rotationY) {
    rotateAroundWorldAxis(cube, new THREE.Vector3(0, 1, 0), rotationX * 0.01);
    rotateAroundWorldAxis(cube, new THREE.Vector3(1, 0, 0), rotationY * 0.01);
  }
}
function onMouseUp() {
  document.removeEventListener("mousemove", onMouseMove, false);
}
function rotateAroundWorldAxis(object, axis, radians) {
  var rotationMatrix = new THREE.Matrix4();
  rotationMatrix.makeRotationAxis(axis.normalize(), radians);
  rotationMatrix.multiply(object.matrix);
  object.matrix = rotationMatrix;
  object.rotation.setFromRotationMatrix(object.matrix);
}
function animate() {
  controls.update();
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
}

推荐阅读