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

标签 javascript matrix 3d three.js transform

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

根据 this page从 three.js 文档和此处提出的各种问题(例如 this onethis one )看来,关键是将 nameOfObject.matrixAutoUpdate 设置为 false。然而,考虑到这一点,我尝试了多种方法来设置 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 覆盖它旋转属性。我假设 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 的子对象时这很好,但我可以想象如果对象是 scene 的子对象的子对象并且它是有必要设置其独立于其父级的世界位置(编辑: SceneUtilsattachdetach 方法似乎允许这样做,尽管是间接的)。

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

旁白:我发现 Matrix4.set() 使用行优先顺序但 Matrix4.fromArray()Matrix4.elements 有点奇怪 使用列优先顺序。

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

相关文章:

c# - 推荐XNA教程开始学习3D(第一次)

Javascript 会自动设置元素的字体大小以使文本不会溢出? (自动调整)

javascript - HTML5视频搜索

matrix - 我可以计算给定一组点的变换矩阵吗?

c++ - 如何使用 C++ 和 L-Systems 在空间中的任何给定点和方向生成 3d 树?

math - 如何建立透视投影矩阵(无API)

javascript - 数据绑定(bind) AngularJS 时如何打印 <p> 标签内的超链接

javascript - jQuery DataTables 在每列中添加国家图标

r - 计算矩阵的特征值多少钱?

python - OpenCV 密集光流矩阵