【问题标题】:How to rotate a 3D object on axis three.js?如何在轴 three.js 上旋转 3D 对象?
【发布时间】:2012-06-19 02:49:11
【问题描述】:

我对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 [1...@shape.length]
    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)

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

我找到了页面How to rotate a Three.js Vector3 around an axis?,但它只是让一个Vector3点围绕世界轴旋转?

我已经尝试使用 ma​​trixRotationWorld 作为

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

但它不起作用,我不知道是我用错了还是有其他方法..

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

【问题讨论】:

  • @ 表示法是什么?
  • '@' 在 CoffeeScript 中的意思是 'this'。在 JavaScript 中。这是一个简写。

标签: javascript coffeescript three.js


【解决方案1】:

自 r59 版本以来,three.js 提供了这三个 functions 来围绕对象轴旋转对象。

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

【讨论】:

  • 谢谢。这应该是最佳答案,大多数其他答案要么已弃用,要么效率低下。干得好!
  • 这不应该用于动画!取自Three.js documentationThis is typically done as a one time operation, and not during a loop Use Object3D.rotation for typical real-time mesh rotation.
  • @MatthewCliatt 你是对的。您能否为动画提供更好或更有效的解决方案?
  • @Hetong 我自己还在寻找正确的解决方案。
【解决方案2】:

我是这样解决的:

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

包含库:

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

用法:

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

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

这里是回购:https://github.com/albertopiras/threeJS-object-controls

【讨论】:

  • 链接死的快得惊人,这将使这个答案变得不那么有用。您能否将解决方案的相关部分提炼成答案正文中的文本或代码?
【解决方案3】:

这是我使用的两个函数。它们基于矩阵旋转。并且可以绕任意轴旋转。要使用世界坐标轴旋转,您需要使用第二个函数 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 回调)中调用这些函数,从而在 x 轴上旋转 90 度:

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

【讨论】:

  • 我认为为每次调用都创建一个新的 THREE.Matrix4 成本很高,如果它用于每一帧动画,你会不会重复使用它?
  • 我得到了有人在github上发布的这两个函数。我不得不编辑它们以使用新的函数名称,例如最新版本的threejs 开发版本。我自己也想知道这一点。垃圾收集器会不时地清除对象。我在 Chrome 中查看了内存使用图,它在创建和销毁对象的位置上下波动,但动画对于我迄今为止使用的所有内容都很好。
  • 当我尝试更改函数以重用相同的矩阵时,我的任何演示都无法运行。如果有人设法在不创建这样的新矩阵的情况下实现这一点,请发帖。
  • 如何使用它来围绕其边缘旋转平面?
  • 谨慎使用这种方法!在 Three.js 中,应该对 Object3D 进行直接矩阵操作(使用 object.matrixAutoUpdate = false)或对旋转、位置等属性进行操作。three.js docs 此外,rotateAroundWorldAxis 不适用于应用于对象。您必须从object.matrix 中提取旋转,乘以rotWorldMatrix 并从结果中设置object.rotation 的组件。
【解决方案4】:

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

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

【讨论】:

    【解决方案5】:

    在 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
    

    【讨论】:

      【解决方案6】:

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

      3js 变化如此之快 :D

      【讨论】:

        【解决方案7】:

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

        rotationMatrix.multiply(object.matrix);

        【讨论】:

          【解决方案8】:

          以防万一...在 r52 中,该方法被称为 setEulerFromRotationMatrix 而不是 getRotationFromMatrix

          【讨论】:

            【解决方案9】:

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2012-06-22
              • 2014-04-28
              • 2013-08-06
              • 2018-05-09
              • 2015-01-06
              • 1970-01-01
              • 2015-02-06
              • 1970-01-01
              相关资源
              最近更新 更多