Подтвердить что ты не робот

Как повернуть 3D-объект на оси three.js?

У меня есть большая проблема вращения в three.js Я хочу повернуть свой 3D-куб в одну из моих игр.

//init
geometry = new THREE.CubeGeometry grid, grid, grid
material = new THREE.MeshLambertMaterial {color:0xFFFFFF * Math.random(), shading:THREE.FlatShading, overdraw:true, transparent: true, opacity:0.8}
for i in [[email protected]]
    othergeo = new THREE.Mesh new THREE.CubeGeometry(grid, grid, grid)
    othergeo.position.x = grid * @shape[i][0]
    othergeo.position.y = grid * @shape[i][1]
    THREE.GeometryUtils.merge geometry, othergeo
@mesh = new THREE.Mesh geometry, material

//rotate
@mesh.rotation.y += y * Math.PI / 180
@mesh.rotation.x += x * Math.PI / 180
@mesh.rotation.z += z * Math.PI / 180

и (x, y, z) могут быть (1, 0, 0)

то куб может вращаться, но проблема заключается в том, что куб вращается на собственной оси, поэтому после его вращения он не может вращаться, как ожидалось.

Я нахожу страницу Как вращать вектор Three.js Vector3 вокруг оси?, но он просто позволяет точке Vector3 вращаться вокруг мировой оси?

и я попытался использовать matrixRotationWorld как

@mesh.matrixRotationWorld.x += x * Math.PI / 180
@mesh.matrixRotationWorld.y += y * Math.PI / 180
@mesh.matrixRotationWorld.z += z * Math.PI / 180

но он не работает, я не использую его неправильно или есть другие способы.

так, как позволить 3D-кубу вращаться вокруг мировой оси???

4b9b3361

Ответ 1

Вот две функции, которые я использую. Они основаны на поворотах матрицы. и может вращаться вокруг произвольных осей. Чтобы вращаться с использованием мировых осей, вы хотели бы использовать вторую функцию rotateAroundWorldAxis().

// Rotate an object around an arbitrary axis in object space
var rotObjectMatrix;
function rotateAroundObjectAxis(object, axis, radians) {
    rotObjectMatrix = new THREE.Matrix4();
    rotObjectMatrix.makeRotationAxis(axis.normalize(), radians);

    // old code for Three.JS pre r54:
    // object.matrix.multiplySelf(rotObjectMatrix);      // post-multiply
    // new code for Three.JS r55+:
    object.matrix.multiply(rotObjectMatrix);

    // old code for Three.js pre r49:
    // object.rotation.getRotationFromMatrix(object.matrix, object.scale);
    // old code for Three.js r50-r58:
    // object.rotation.setEulerFromRotationMatrix(object.matrix);
    // new code for Three.js r59+:
    object.rotation.setFromRotationMatrix(object.matrix);
}

var rotWorldMatrix;
// Rotate an object around an arbitrary axis in world space       
function rotateAroundWorldAxis(object, axis, radians) {
    rotWorldMatrix = new THREE.Matrix4();
    rotWorldMatrix.makeRotationAxis(axis.normalize(), radians);

    // old code for Three.JS pre r54:
    //  rotWorldMatrix.multiply(object.matrix);
    // new code for Three.JS r55+:
    rotWorldMatrix.multiply(object.matrix);                // pre-multiply

    object.matrix = rotWorldMatrix;

    // old code for Three.js pre r49:
    // object.rotation.getRotationFromMatrix(object.matrix, object.scale);
    // old code for Three.js pre r59:
    // object.rotation.setEulerFromRotationMatrix(object.matrix);
    // code for r59+:
    object.rotation.setFromRotationMatrix(object.matrix);
}

Поэтому вы должны вызывать эти функции в вашей функции anim (обратный вызов requestAnimFrame), что приводит к повороту на 90 градусов по оси x:

var xAxis = new THREE.Vector3(1,0,0);
rotateAroundWorldAxis(mesh, xAxis, Math.PI / 180);

Ответ 2

Начиная с выпуска r59, three.js предоставляет эти три функции для поворота объекта вокруг оси объекта.

object.rotateX(angle);
object.rotateY(angle);
object.rotateZ(angle);

Ответ 3

Мне понадобилась функция rotateAroundWorldAxis, но приведенный выше код не работает с новейшей версией (r52). Похоже, что getRotationFromMatrix() был заменен на setEulerFromRotationMatrix()

function rotateAroundWorldAxis( object, axis, radians ) {

    var rotationMatrix = new THREE.Matrix4();

    rotationMatrix.makeRotationAxis( axis.normalize(), radians );
    rotationMatrix.multiplySelf( object.matrix );                       // pre-multiply
    object.matrix = rotationMatrix;
    object.rotation.setEulerFromRotationMatrix( object.matrix );
}

Ответ 4

с r55 вы должны изменить
  rotationMatrix.multiplySelf(object.matrix);
к
  rotationMatrix.multiply(object.matrix);

Ответ 5

На всякий случай... в r52 метод называется setEulerFromRotationMatrix вместо getRotationFromMatrix

Ответ 6

В Three.js R59, object.rotation.setEulerFromRotationMatrix(object.matrix); был изменен на object.rotation.setFromRotationMatrix(object.matrix);

3js меняется так быстро: D

Ответ 7

Где-то около r59 это становится проще (вращение вокруг x):

bb.GraphicsEngine.prototype.calcRotation = function ( obj, rotationX)
{
    var euler = new THREE.Euler( rotationX, 0, 0, 'XYZ' );
    obj.position.applyEuler(euler);
}

Ответ 8

В Three.js R66 это то, что я использую (версия CoffeeScript):

THREE.Object3D.prototype.rotateAroundWorldAxis = (axis, radians) ->
  rotWorldMatrix = new THREE.Matrix4()
  rotWorldMatrix.makeRotationAxis axis.normalize(), radians
  rotWorldMatrix.multiply this.matrix
  this.matrix = rotWorldMatrix
  this.rotation.setFromRotationMatrix this.matrix

Ответ 9

Я решил эту проблему следующим образом:

Я создал модуль "ObjectControls" для триJS, который позволяет вращать один объект OBJECT (или группу), а не SCENE.

Включить библиотеку:

<script src="ObjectControls.js"></script>

Использование:

var controls = new THREE.ObjectControls(camera, renderer.domElement, yourMesh);

Здесь вы можете найти живое демо: https://albertopiras.github.io/threeJS-object-controls/

Вот репо: https://github.com/albertopiras/threeJS-object-controls.