Javascript 如何在轴three.js上旋转3D对象?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11060734/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 04:15:47  来源:igfitidea点击:

How to rotate a 3D object on axis three.js?

javascriptcoffeescriptthree.js

提问by Tony Han

I have a great problem about the rotation in three.js I want to rotate my 3D cube in one of my game.

我有一个关于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

and (x, y, z) may be (1, 0, 0)

并且 (x, y, z) 可以是 (1, 0, 0)

then the cube can rotate, but the problem is the cube rotate on its own axis,so after it has rotated, it can't rotate as expected.

然后立方体可以旋转,但问题是立方体在自己的轴上旋转,所以旋转后,它不能按预期旋转。

I find the page How to rotate a Three.js Vector3 around an axis?, but it just let a Vector3 point rotate around the world axis?

我找到页面如何围绕轴旋转 Three.js Vector3?,但它只是让 Vector3 点绕世界轴旋转?

and I have tried to use matrixRotationWorldas

我尝试使用matrixRotationWorld作为

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

but it doesn't work, I don't whether I used it in a wrong way or there are other ways..

但它不起作用,我不知道是我以错误的方式使用它还是有其他方式..

so, how to let the 3D cube rotate around the world's axis???

那么,如何让 3D 立方体绕世界轴旋转???

回答by Hetong

Since release r59, three.js provides those three functions to rotate a object around object axis.

从 r59 版本开始,three.js 提供了这三个函数来围绕对象轴旋转对象。

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

回答by Cory Gross

Here are the two functions I use. They are based on matrix rotations. and can rotate around arbitrary axes. To rotate using the world's axes you would want to use the second function rotateAroundWorldAxis().

这是我使用的两个函数。它们基于矩阵旋转。并且可以绕任意轴旋转。要使用世界坐标轴旋转,您需要使用第二个函数 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);
}

So you should call these functions within your animfunction (requestAnimFrame callback), resulting in a rotation of 90 degrees on the x-axis:

所以你应该在你的anim函数中调用这些函数(requestAnimFrame 回调),导致在 x 轴上旋转 90 度:

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

回答by guntrumm

I needed the rotateAroundWorldAxisfunction but the above code doesn't work with the newest release (r52). It looks like getRotationFromMatrix()was replaced by setEulerFromRotationMatrix()

我需要该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 );
}

回答by block23

with r55 you have to change
rotationMatrix.multiplySelf( object.matrix );
to
rotationMatrix.multiply( object.matrix );

使用 r55 你必须改变
rotationMatrix.multiplySelf( object.matrix );

rotationMatrix.multiply(object.matrix);

回答by mind1n

In Three.js R59, object.rotation.setEulerFromRotationMatrix(object.matrix);has been changed to object.rotation.setFromRotationMatrix(object.matrix);

在 Three.js R59 中,object.rotation.setEulerFromRotationMatrix(object.matrix);已改为object.rotation.setFromRotationMatrix(object.matrix);

3js is changing so rapidly :D

3js 变化如此之快 :D

回答by Leprosy

Just in case...in r52 the method is called setEulerFromRotationMatrixinstead of getRotationFromMatrix

以防万一……在 r52 中,该方法被调用setEulerFromRotationMatrix而不是getRotationFromMatrix

回答by acarlon

Somewhere around r59 this gets easier (rotate around x):

在 r59 附近的某个地方这变得更容易(围绕 x 旋转):

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

回答by aymericbeaumet

In Three.js R66, this is what I use (CoffeeScript version):

在 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

回答by Alberto Piras

I solved this problem this way:

我是这样解决这个问题的:

I created the 'ObjectControls' module for ThreeJS that allows you to rotate a single OBJECT (or a Group), and not the SCENE.

我为 ThreeJS 创建了“ObjectControls”模块,它允许您旋转单个 OBJECT(或一个组),而不是 SCENE。

Include the libary:

包括库:

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

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

Usage:

用法:

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

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

You can find here a live demo here: https://albertopiras.github.io/threeJS-object-controls/

你可以在这里找到现场演示:https: //albertopiras.github.io/threeJS-object-controls/

Here is the repo: https://github.com/albertopiras/threeJS-object-controls.

这是仓库:https: //github.com/albertopiras/threeJS-object-controls