0

我正在使用这两个函数来旋转我的 three.js 场景中的对象

    // Rotate an object around an arbitrary axis in object space
    function rotateAroundObjectAxis(object, axis, radians) {
        rotationMatrix = new THREE.Matrix4();
        rotationMatrix.makeRotationAxis(axis.normalize(), radians);
        object.matrix.multiplySelf(rotationMatrix);  // post-multiply
        object.rotation.getRotationFromMatrix(object.matrix, object.scale);
        delete rotationMatrix;
    }

    // Rotate an object around an arbitrary axis in world space      
    function rotateAroundWorldAxis(object, axis, radians) {
        rotationMatrix = new THREE.Matrix4();
        rotationMatrix.makeRotationAxis(axis.normalize(), radians);
        rotationMatrix.multiplySelf(object.matrix);        // pre-multiply
        object.matrix = rotationMatrix;
        object.rotation.getRotationFromMatrix(object.matrix, object.scale);
        delete rotationMatrix;
    }

其中rotationMatrix 是一个全局变量。我对 Javascript 和 Web 应用程序开发没有经验,但我与一个似乎向我传达的人交谈,因为有时我会在一个框架中调用这些函数一次,我应该担心它每次调用都会创建新对象这一事实。到目前为止,这还没有给我带来问题,但是我是否应该担心垃圾收集器最终无法跟上?我知道这里的 delete 关键字与 C++ 不同,只会删除引用。当我在每个函数的末尾调用它时,这有帮助吗?除了让这个功能更高效之外,我还能做些什么吗?这样它就可以被尽可能多地调用,而不会减慢速度或最终使浏览器占用太多内存。

4

1 回答 1

0

在进一步摆弄这个之后,我学到了很多关于如何使用 Chrome 开发者工具的知识。我还重写了这些函数,以使我觉得可能会更有效。我将不得不看看它是如何扩展的,但是分析工具似乎表明这些在内存和垃圾收集器上要好一些。

然而,在世界空间中旋转的功能需要一个副本才能不创建新矩阵。简而言之,如果我们不每次调用都创建一个新矩阵,我们就不能简单地复制引用,我们必须复制矩阵。基本上它归结为这个副本或垃圾收集器开销是否会更昂贵。

// Rotate an object around an arbitrary axis in object space
var rotObjectMatrix= new THREE.Matrix4();
function rotateAroundObjectAxis(object, axis, radians) {
    rotObjectMatrix.makeRotationAxis(axis.normalize(), radians);
    object.matrix.multiplySelf(rotObjectMatrix);      // post-multiply
    object.rotation.getRotationFromMatrix(object.matrix, object.scale);
}

var rotWorldMatrix = new THREE.Matrix4();
// Rotate an object around an arbitrary axis in world space       
function rotateAroundWorldAxis(object, axis, radians) {
    rotWorldMatrix.makeRotationAxis(axis.normalize(), radians);
    rotWorldMatrix.multiplySelf(object.matrix);        // pre-multiply
    object.matrix.copy(rotWorldMatrix);
    object.rotation.getRotationFromMatrix(object.matrix, object.scale);
}

我不确定这是否会更好。我拍了这些截图。这个是用原来的功能,这个是新的功能。似乎表明新的性能稍好一些。我不确定我是否能注意到差异。

编辑:一旦我意识到 updateMatrix 函数,我想出了一个不同的函数。这避免了复制整个矩阵的使用。这是新的世界旋转功能:

/** Adds a rotation of rad to the obj's rotation about world's axis */
var rotWorldMatrix = new THREE.Matrix4();
function rotateWorldAxis(obj, axis, rad) {
    rotWorldMatrix.makeRotationAxis(axis.normalize(), rad);
    obj.updateMatrix();
    rotWorldMatrix.multiplySelf(obj.matrix); // pre-multiply
    obj.rotation.getRotationFromMatrix(rotWorldMatrix, obj.scale);
}
于 2012-06-28T01:34:33.807 回答