在我的webapp中,我在不同宽度/高度比的不同模态/弹出窗口/对话框中使用ThreeJS场景。
此外,我想在这些不同的场景中使用多个用户定义的相机设置(旋转,位置,外观等)。
因此,当用户点击捕捉相机设置按钮时,我会通过camera.toJSON()
保存相机对象。
(在我这样做之前,我只保存了对象camera
,但遗憾的是这些对象非常大并且在存储多个摄像机对象时性能变慢。但是,这种方法有效,因为我能够复制保存的相机对象和当前使用的相机之间的所有所需值[例如current_camera.position.x=saved_camera.position.x
等等)
在我现在想要使用保存属性的每个场景中,我尝试了以下内容:
let m = new THREE.Matrix4();
m.fromArray(saved_camera.object.matrix);
current_camera.applyMatrix(m)
current_camera.updateMatrix();
不幸的是,这不起作用。
答案 0 :(得分:1)
如果你习惯使用矩阵,那么你可以关闭渲染过程中three.js所做的矩阵自动更新,并自己保持世界矩阵的最新状态。 (这包括您每次更改相机的方向时,如果您正在使用某种形式的鼠标交互来控制相机角度,请记住这一点。)
首先,将autoUpdateMatrix
属性设置为false
,关闭相机的自动矩阵更新。您仍然可以使用便捷属性(position
,rotation
,scale
),但您必须通过调用camera.updateMatrixWorld(true);
手动更新世界矩阵。
最后,当您准备好恢复特定的相机方向时,只需使用matrixWorld
copy
方法复制矩阵值。
var origin = new THREE.Vector3();
var theCamera = new THREE.PerspectiveCamera(35, 1, 1, 1000);
theCamera.autoUpdateMatrix = false; // turn off auto-update
theCamera.position.set(10, 10, 10);
theCamera.lookAt(origin);
theCamera.updateMatrixWorld(true); // manually update the matrix!
console.log("Camera original matrix: ", theCamera.matrixWorld.elements.toString());
var saveMatrix = new THREE.Matrix4();
saveMatrix.copy(theCamera.matrixWorld);
// saveMatrix now contains the current value of theCamera.matrixWorld
theCamera.position.set(50, -50, 75);
theCamera.lookAt(origin);
theCamera.updateMatrixWorld(true); // manually update the matrix!
console.log("Camera moved matrix: ", theCamera.matrixWorld.elements.toString());
// theCamera.matrixWorld now holds a value that's different from saveMatrix.
theCamera.matrixWorld.copy(saveMatrix);
// Don't upate the matrix, because you just SET it.
console.log("Camera moved matrix: ", theCamera.matrixWorld.elements.toString());
// theCamera.matrixWorld once again contains the saved value.

<script src="https://threejs.org/build/three.js"></script>
&#13;
编辑以解决OrbitControls:
看起来OrbitControls
使用便利属性,而不是从矩阵中收集信息。因此,当您恢复摄像机位置时,您还需要恢复这些属性。通过在矩阵上使用decompose
并将结果值复制到适当的属性中,可以轻松完成此操作:
var d = new THREE.Vector3(),
q = new THREE.Quaternion(),
s = new THREE.Vector3();
camera.matrixWorld.decompose( d, q, s );
camera.position.copy( d );
camera.quaternion.copy( q );
camera.scale.copy( s );