javascript - 设置 three.js 对象的 matrixWorld 属性

标签 javascript matrix 3d three.js transform

我有一个包含编码旋转和位置数据的 4x4 变换矩阵的数组(我已经确认该矩阵表示 Octave 中的有效变换)。我想使用该数组的内容设置三个.js 对象(Object3D)的 matrixWorld 属性,即根据变换矩阵设置对象的位置和旋转。

根据this page从 three.js 文档和这里提出的各种问题(例如 this onethis one ),似乎关键是设置 nameOfObject.matrixAutoUpdate为假。但是,考虑到这一点,我尝试了多种方法来设置 nameOfObject.matrixWorld并且它们都没有改变对象被渲染的位置:它保持在原点没有旋转,就像 matrixWorld 时的情况一样。是 4x4 单位矩阵。

这是我尝试过的(此代码在调用 render() 之前的更新方法中):

// Setting up a three.js matrix
var tempMatrix = new THREE.Matrix4();
tempMatrix.fromArray(arrayContainingTransformationMatrix);

// Values are set as expected
console.log(tempMatrix.elements);

// Note that the approaches below were tried one at a time

// First approach (doesn't work)
nameOfObject.matrixAutoUpdate = false;
nameOfObject.matrixWorld.copy(tempMatrix);

// Second approach (also doesn't work)
// Based on the second SO question linked above
nameOfObject.matrixAutoUpdate = false;
nameOfObject.matrix.copy(tempMatrix);
nameOfObject.updateMatrixWorld(true);

// Third approach (this doesn't work either, unfortunately)
nameOfObject.matrixAutoUpdate = false;
nameOfObject.matrixWorld.fromArray(arrayContainingTransformationMatrix);

// Appears to be set correctly regardless of which approach is used
console.log(sphere1.matrixWorld.elements);

几点注意事项:
  • 我希望实际上不需要设置 matrixAutoUpdate在每次迭代中都设置为 false,但现在我这样做只是为了安全起见。
  • 如果 nameOfObject.position根据变换矩阵第四列的值修改而不是改变matrixWorld ,对象的位置按预期更改,因此这似乎不是渲染问题。
  • 我在多个地方读过 updateMatrix()手动设置矩阵时不应调用它,因为它会根据 position 覆盖它和 rotation特性。我假设 updateMatrixWorld()受到类似的考虑,但我没有找到关于它的作用的太多讨论。

  • 任何建议,将不胜感激!最坏的情况,我会查看源代码,但是到目前为止,three.js 一直很容易使用,我怀疑我只是遗漏了一些东西。

    最佳答案

    目前,我可以通过设置对象的 matrix 来达到预期的效果。属性(相对于对象父级的局部变换)。由于对象的父对象是 scene ,这样的代码有效:

    scene.add(nameOfObject);
    
    // Using this transformation matrix (translation of two units along the x axis):
    // 1 0 0 2
    // 0 1 0 0
    // 0 0 1 0
    // 0 0 0 1
    
    // Column-major version of the transformation
    var tempArrayCM = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2, 0, 0, 1];
    // Per the docs, Matrix4.fromArray() uses column-major format
    
    // Row-major version of the transformation
    var matrixT = new THREE.Matrix4();
    matrixT.set(1, 0, 0, 2, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
    // Per the docs, Matrix4.set() uses row-major format
    
    nameOfObject.matrixAutoUpdate = false;
    
    nameOfObject.matrix.fromArray(tempArrayCM); // This works
    
    //nameOfObject.matrix.copy(matrixT); // This also works
    
    //nameOfObject.matrixWorld.fromArray(tempArrayCM); // No effect
    
    //nameOfObject.matrixWorld.copy(matrixT); // No effect
    

    似乎设置 matrixWorld只是行不通。我想当有问题的对象是 scene 的 child 时,这很好。 ,但我可以想象如果对象是 scene 的 child 的 child ,这会导致问题并且有必要独立于其父级设置其世界位置( 编辑: 似乎 SceneUtilsattachdetach 方法允许这样做,尽管是间接的)。

    我不会将此标记为答案,因为它实际上只是一种解决方法,仅当对象的父对象为 scene 时才适用。 .

    顺便说一句:我觉得 Matrix4.set() 有点奇怪。使用行优先顺序,但 Matrix4.fromArray()Matrix4.elements使用列优先顺序。

    关于javascript - 设置 three.js 对象的 matrixWorld 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37446330/

    相关文章:

    javascript - 单击图标时更改图标字体

    c - 如何应用矩阵 - 理解请求

    r - 使用来自强制矩阵的数据更新矩阵

    css - CSS3匹配3d形状(立方体顶部)

    ios - 开始 3D 游戏开发

    javascript - sideNav的函数onOpen()未运行

    JavaScript:无法从另一个函数获取变量的值

    javascript - 仅带有一个参数的Function.prototype.call和Function.prototype.apply

    c++ - Opencv,在编译时确定像素的类型

    r - 线条下方的3D填充