From 72c1115adbbda7456ed134b8a0898e7c5af306f7 Mon Sep 17 00:00:00 2001
From: PoseidonEnergy Aligning HTML Elements to 3D
// before checking
camera.updateMatrix();
-camera.updateMatrixWorld();
+camera.ensureMatrices();
camera.matrixWorldInverse.copy(camera.matrixWorld).invert();
...
// then for each mesh
someMesh.updateMatrix();
-someMesh.updateMatrixWorld();
+someMesh.ensureMatrices();
viewProjection.multiplyMatrices(
camera.projectionMatrix, camera.matrixWorldInverse);
diff --git a/manual/en/custom-buffergeometry.html b/manual/en/custom-buffergeometry.html
index 6d7350a71e05a5..7d0d7ed01cc0a8 100644
--- a/manual/en/custom-buffergeometry.html
+++ b/manual/en/custom-buffergeometry.html
@@ -344,7 +344,7 @@ Custom BufferGeometry
function getPoint(lat, long) {
latHelper.rotation.x = lat;
longHelper.rotation.y = long;
- longHelper.updateMatrixWorld(true);
+ longHelper.ensureMatrices(true);
return pointHelper.getWorldPosition(temp).toArray();
}
diff --git a/manual/en/lights.html b/manual/en/lights.html
index eeccf58600bd22..712ca616548058 100644
--- a/manual/en/lights.html
+++ b/manual/en/lights.html
@@ -259,7 +259,7 @@
+function updateLight() {
-+ light.target.updateMatrixWorld();
++ light.target.ensureMatrices();
+ helper.update();
+}
+updateLight();
@@ -303,7 +303,7 @@ onChange function can be simpler.
function updateLight() {
-- light.target.updateMatrixWorld();
+- light.target.ensureMatrices();
helper.update();
}
-updateLight();
diff --git a/manual/en/load-gltf.html b/manual/en/load-gltf.html
index 471f5d6d303e44..51c27afdd18ba2 100644
--- a/manual/en/load-gltf.html
+++ b/manual/en/load-gltf.html
@@ -272,7 +272,7 @@ Loading a .GLTF File
+ { prefix: 'Car_04', rot: [0, Math.PI, 0], },
+ ];
+
-+ root.updateMatrixWorld();
++ root.ensureMatrices();
+ for (const car of loadedCars.children.slice()) {
+ const fix = fixes.find(fix => car.name.startsWith(fix.prefix));
+ const obj = new THREE.Object3D();
@@ -592,7 +592,7 @@ Loading a .GLTF File
+ { prefix: 'Car_04', y: 40, rot: [0, Math.PI, 0], },
];
-root.updateMatrixWorld();
+root.ensureMatrices();
for (const car of loadedCars.children.slice()) {
const fix = fixes.find(fix => car.name.startsWith(fix.prefix));
const obj = new THREE.Object3D();
diff --git a/manual/en/load-obj.html b/manual/en/load-obj.html
index f2ae1202806b35..86ad94d1bf699d 100644
--- a/manual/en/load-obj.html
+++ b/manual/en/load-obj.html
@@ -517,7 +517,7 @@ Loading a .OBJ File
+ const objLoader = new OBJLoader();
+ objLoader.setMaterials(mtl);
objLoader.load('resources/models/windmill/windmill.obj', (root) => {
- root.updateMatrixWorld();
+ root.ensureMatrices();
scene.add(root);
// compute the box that contains all the stuff
// from root and below
diff --git a/manual/en/matrix-transformations.html b/manual/en/matrix-transformations.html
index a65c3e8c28016e..ee8a0a8b2fc0c4 100644
--- a/manual/en/matrix-transformations.html
+++ b/manual/en/matrix-transformations.html
@@ -70,7 +70,7 @@ Object and world matrices
An object's matrix stores the object's transformation relative to the object's parent; to get the object's transformation in world coordinates, you must access the object's world matrix.
- When either the parent or the child object's transformation changes, you can request that the child object's world matrix be updated by calling `object.updateMatrixWorld()`.
+ When either the parent or the child object's transformation changes, you can request that the child object's world matrix be updated by calling `object.ensureMatrices()`.
An object can be transformed via `applyMatrix4()`. Note: Under-the-hood, this method relies on `Matrix4.decompose()`, and not all matrices are decomposable in this way. For example, if an object has a non-uniformly scaled parent, then the object's world matrix may not be decomposable, and this method may not be appropriate.
diff --git a/manual/en/shadows.html b/manual/en/shadows.html
index f23f5cddf93592..b7e1bbd57c02c4 100644
--- a/manual/en/shadows.html
+++ b/manual/en/shadows.html
@@ -333,7 +333,7 @@
Shadows
light's shadow camera, and the helper showing the light's shadow camera.
function updateCamera() {
// update the light target's matrixWorld because it's needed by the helper
- light.target.updateMatrixWorld();
+ light.target.ensureMatrices();
helper.update();
// update the light's shadow camera's projection matrix
light.shadow.camera.updateProjectionMatrix();
diff --git a/manual/examples/custom-buffergeometry-dynamic.html b/manual/examples/custom-buffergeometry-dynamic.html
index b5f5c651c76c8c..ce9d248ef972e0 100644
--- a/manual/examples/custom-buffergeometry-dynamic.html
+++ b/manual/examples/custom-buffergeometry-dynamic.html
@@ -77,7 +77,7 @@
latHelper.rotation.x = lat;
longHelper.rotation.y = long;
- longHelper.updateMatrixWorld( true );
+ longHelper.ensureMatrices( true );
return pointHelper.getWorldPosition( temp ).toArray();
}
diff --git a/manual/examples/lights-directional-w-helper.html b/manual/examples/lights-directional-w-helper.html
index d5d3a73a942b75..3c734cbf05538f 100644
--- a/manual/examples/lights-directional-w-helper.html
+++ b/manual/examples/lights-directional-w-helper.html
@@ -147,7 +147,7 @@
function updateLight() {
- light.target.updateMatrixWorld();
+ light.target.ensureMatrices();
helper.update();
}
diff --git a/manual/examples/lights-spot-w-helper.html b/manual/examples/lights-spot-w-helper.html
index 52a9dda9e9840c..bce31023593fa8 100644
--- a/manual/examples/lights-spot-w-helper.html
+++ b/manual/examples/lights-spot-w-helper.html
@@ -168,7 +168,7 @@
function updateLight() {
- light.target.updateMatrixWorld();
+ light.target.ensureMatrices();
helper.update();
}
diff --git a/manual/examples/load-gltf-animated-cars.html b/manual/examples/load-gltf-animated-cars.html
index cb7b8f67a6cbde..32b0ec5e74b151 100644
--- a/manual/examples/load-gltf-animated-cars.html
+++ b/manual/examples/load-gltf-animated-cars.html
@@ -202,7 +202,7 @@
{ prefix: 'Car_04', y: 40, rot: [ 0, Math.PI, 0 ], },
];
- root.updateMatrixWorld();
+ root.ensureMatrices();
for ( const car of loadedCars.children.slice() ) {
const fix = fixes.find( fix => car.name.startsWith( fix.prefix ) );
diff --git a/manual/examples/load-gltf-car-path-fixed.html b/manual/examples/load-gltf-car-path-fixed.html
index 94d48cecd6d66e..5544b5ed678b96 100644
--- a/manual/examples/load-gltf-car-path-fixed.html
+++ b/manual/examples/load-gltf-car-path-fixed.html
@@ -202,7 +202,7 @@
{ prefix: 'Car_04', rot: [ 0, Math.PI, 0 ], },
];
- root.updateMatrixWorld();
+ root.ensureMatrices();
for ( const car of loadedCars.children.slice() ) {
const fix = fixes.find( fix => car.name.startsWith( fix.prefix ) );
diff --git a/manual/examples/load-gltf-car-path.html b/manual/examples/load-gltf-car-path.html
index 85fbd4d4472378..2487eb1c22d934 100644
--- a/manual/examples/load-gltf-car-path.html
+++ b/manual/examples/load-gltf-car-path.html
@@ -199,7 +199,7 @@
{ prefix: 'Car_04', rot: [ 0, Math.PI, 0 ], },
];
- root.updateMatrixWorld();
+ root.ensureMatrices();
for ( const car of loadedCars.children.slice() ) {
const fix = fixes.find( fix => car.name.startsWith( fix.prefix ) );
diff --git a/manual/examples/load-gltf-rotate-cars-fixed.html b/manual/examples/load-gltf-rotate-cars-fixed.html
index 24b4f9c85e3e1c..01f26a86fa5c7d 100644
--- a/manual/examples/load-gltf-rotate-cars-fixed.html
+++ b/manual/examples/load-gltf-rotate-cars-fixed.html
@@ -142,7 +142,7 @@
{ prefix: 'Car_04', rot: [ 0, Math.PI, 0 ], },
];
- root.updateMatrixWorld();
+ root.ensureMatrices();
for ( const car of loadedCars.children.slice() ) {
const fix = fixes.find( fix => car.name.startsWith( fix.prefix ) );
diff --git a/manual/examples/load-gltf-shadows.html b/manual/examples/load-gltf-shadows.html
index 45495a86ea09b1..ae3bfe5aef4578 100644
--- a/manual/examples/load-gltf-shadows.html
+++ b/manual/examples/load-gltf-shadows.html
@@ -132,8 +132,8 @@
function updateCamera() {
// update the light target's matrixWorld because it's needed by the helper
- light.updateMatrixWorld();
- light.target.updateMatrixWorld();
+ light.ensureMatrices();
+ light.target.ensureMatrices();
helper.update();
// update the light's shadow camera's projection matrix
light.shadow.camera.updateProjectionMatrix();
@@ -365,7 +365,7 @@
{ prefix: 'Car_04', y: 40, rot: [ 0, Math.PI, 0 ], },
];
- root.updateMatrixWorld();
+ root.ensureMatrices();
for ( const car of loadedCars.children.slice() ) {
const fix = fixes.find( fix => car.name.startsWith( fix.prefix ) );
diff --git a/manual/examples/load-obj-auto-camera-xz.html b/manual/examples/load-obj-auto-camera-xz.html
index bc4ff9650c04e3..9d4aa44b3e1b91 100644
--- a/manual/examples/load-obj-auto-camera-xz.html
+++ b/manual/examples/load-obj-auto-camera-xz.html
@@ -131,7 +131,7 @@
const objLoader = new OBJLoader();
objLoader.load( 'resources/models/windmill_2/windmill.obj', ( root ) => {
- root.updateMatrixWorld();
+ root.ensureMatrices();
scene.add( root );
// compute the box that contains all the stuff
// from root and below
diff --git a/manual/examples/shadows-directional-light-shadow-acne.html b/manual/examples/shadows-directional-light-shadow-acne.html
index ae0b2240ddbd8a..bcfc0395febe74 100644
--- a/manual/examples/shadows-directional-light-shadow-acne.html
+++ b/manual/examples/shadows-directional-light-shadow-acne.html
@@ -193,7 +193,7 @@
function updateCamera() {
// update the light target's matrixWorld because it's needed by the helper
- light.target.updateMatrixWorld();
+ light.target.ensureMatrices();
helper.update();
// update the light's shadow camera's projection matrix
light.shadow.camera.updateProjectionMatrix();
diff --git a/manual/examples/shadows-directional-light-with-camera-gui.html b/manual/examples/shadows-directional-light-with-camera-gui.html
index 0ff237497d6692..0426c177092541 100644
--- a/manual/examples/shadows-directional-light-with-camera-gui.html
+++ b/manual/examples/shadows-directional-light-with-camera-gui.html
@@ -158,7 +158,7 @@
function updateCamera() {
// update the light target's matrixWorld because it's needed by the helper
- light.target.updateMatrixWorld();
+ light.target.ensureMatrices();
helper.update();
// update the light's shadow camera's projection matrix
light.shadow.camera.updateProjectionMatrix();
diff --git a/manual/examples/shadows-directional-light-with-camera-helper.html b/manual/examples/shadows-directional-light-with-camera-helper.html
index 42fd78e70f6ace..fd3cca0f20eb8d 100644
--- a/manual/examples/shadows-directional-light-with-camera-helper.html
+++ b/manual/examples/shadows-directional-light-with-camera-helper.html
@@ -157,7 +157,7 @@
const onChange = () => {
- light.target.updateMatrixWorld();
+ light.target.ensureMatrices();
helper.update();
};
diff --git a/manual/examples/shadows-directional-light.html b/manual/examples/shadows-directional-light.html
index 255d92d386cbc0..d6ba5d68799f27 100644
--- a/manual/examples/shadows-directional-light.html
+++ b/manual/examples/shadows-directional-light.html
@@ -154,7 +154,7 @@
const onChange = () => {
- light.target.updateMatrixWorld();
+ light.target.ensureMatrices();
helper.update();
};
diff --git a/manual/examples/shadows-spot-light-with-camera-gui.html b/manual/examples/shadows-spot-light-with-camera-gui.html
index f1b1646052d62c..665a961a41fa42 100644
--- a/manual/examples/shadows-spot-light-with-camera-gui.html
+++ b/manual/examples/shadows-spot-light-with-camera-gui.html
@@ -155,7 +155,7 @@
function updateCamera() {
// update the light target's matrixWorld because it's needed by the helper
- light.target.updateMatrixWorld();
+ light.target.ensureMatrices();
// update the light's shadow camera's projection matrix
light.shadow.camera.updateProjectionMatrix();
// and now update the camera helper we're using to show the light's shadow camera
diff --git a/manual/examples/shadows-spot-light-with-shadow-radius.html b/manual/examples/shadows-spot-light-with-shadow-radius.html
index ea71f79a7a1cb2..6caec8557ab346 100644
--- a/manual/examples/shadows-spot-light-with-shadow-radius.html
+++ b/manual/examples/shadows-spot-light-with-shadow-radius.html
@@ -156,7 +156,7 @@
function updateCamera() {
// update the light target's matrixWorld because it's needed by the helper
- light.target.updateMatrixWorld();
+ light.target.ensureMatrices();
// update the light's shadow camera's projection matrix
light.shadow.camera.updateProjectionMatrix();
// and now update the camera helper we're using to show the light's shadow camera
diff --git a/manual/fr/align-html-elements-to-3d.html b/manual/fr/align-html-elements-to-3d.html
index 9b451fbf6449b4..c5b263c83d9b0e 100644
--- a/manual/fr/align-html-elements-to-3d.html
+++ b/manual/fr/align-html-elements-to-3d.html
@@ -271,14 +271,14 @@ Aligner les éléments HTML en 3D
// avant de vérifier
camera.updateMatrix();
-camera.updateMatrixWorld();
+camera.ensureMatrices();
camera.matrixWorldInverse.copy(camera.matrixWorld).invert();
...
// puis pour chaque maillage
someMesh.updateMatrix();
-someMesh.updateMatrixWorld();
+someMesh.ensureMatrices();
viewProjection.multiplyMatrices(
camera.projectionMatrix, camera.matrixWorldInverse);
diff --git a/manual/fr/custom-buffergeometry.html b/manual/fr/custom-buffergeometry.html
index 30438ec64dd9e8..34f13c5dffe4d5 100644
--- a/manual/fr/custom-buffergeometry.html
+++ b/manual/fr/custom-buffergeometry.html
@@ -341,7 +341,7 @@ BufferGeometry Personnalisée
function getPoint(lat, long) {
latHelper.rotation.x = lat;
longHelper.rotation.y = long;
- longHelper.updateMatrixWorld(true);
+ longHelper.ensureMatrices(true);
return pointHelper.getWorldPosition(temp).toArray();
}
diff --git a/manual/fr/lights.html b/manual/fr/lights.html
index 3f4ae5ff60894d..29369909c779b3 100644
--- a/manual/fr/lights.html
+++ b/manual/fr/lights.html
@@ -259,7 +259,7 @@ Ensuite, nous pouvons l'utiliser à la fois pour la position de la lumière
et pour la position de la cible, comme ceci
+function updateLight() {
-+ light.target.updateMatrixWorld();
++ light.target.ensureMatrices();
+ helper.update();
+}
+updateLight();
@@ -303,7 +303,7 @@ onChange peut être plus simple.
function updateLight() {
-- light.target.updateMatrixWorld();
+- light.target.ensureMatrices();
helper.update();
}
-updateLight();
diff --git a/manual/fr/load-gltf.html b/manual/fr/load-gltf.html
index fc6661e871e17e..d7488364f172bd 100644
--- a/manual/fr/load-gltf.html
+++ b/manual/fr/load-gltf.html
@@ -226,7 +226,7 @@ Chargement d'un fichier .GLTF
+ { prefix: 'Car_04', rot: [0, Math.PI, 0], },
+ ];
+
-+ root.updateMatrixWorld();
++ root.ensureMatrices();
+ for (const car of loadedCars.children.slice()) {
+ const fix = fixes.find(fix => car.name.startsWith(fix.prefix));
+ const obj = new THREE.Object3D();
@@ -493,7 +493,7 @@ Chargement d'un fichier .GLTF
+ { prefix: 'Car_04', y: 40, rot: [0, Math.PI, 0], },
];
-root.updateMatrixWorld();
+root.ensureMatrices();
for (const car of loadedCars.children.slice()) {
const fix = fixes.find(fix => car.name.startsWith(fix.prefix));
const obj = new THREE.Object3D();
diff --git a/manual/fr/load-obj.html b/manual/fr/load-obj.html
index f068e25dd2aaa7..678616cca7bd75 100644
--- a/manual/fr/load-obj.html
+++ b/manual/fr/load-obj.html
@@ -517,7 +517,7 @@ Charger un fichier .OBJ
+ const objLoader = new OBJLoader();
+ objLoader.setMaterials(mtl);
objLoader.load('resources/models/windmill/windmill.obj', (root) => {
- root.updateMatrixWorld();
+ root.ensureMatrices();
scene.add(root);
// calcule la boîte qui contient tout ce qui se trouve
// à partir de la racine et en dessous
diff --git a/manual/fr/matrix-transformations.html b/manual/fr/matrix-transformations.html
index 5b79d1773b8dc1..72d4f853a1bd6f 100644
--- a/manual/fr/matrix-transformations.html
+++ b/manual/fr/matrix-transformations.html
@@ -69,7 +69,7 @@ Matrices de l'objet et du monde
La matrice d'un objet stocke la transformation de l'objet par rapport à son parent ; pour obtenir la transformation de l'objet en coordonnées du monde, vous devez accéder à la matrice du monde de l'objet.
- Lorsque la transformation du parent ou de l'enfant change, vous pouvez demander la mise à jour de la matrice du monde de l'objet enfant en appelant `object.updateMatrixWorld()`.
+ Lorsque la transformation du parent ou de l'enfant change, vous pouvez demander la mise à jour de la matrice du monde de l'objet enfant en appelant `object.ensureMatrices()`.
Un objet peut être transformé via `applyMatrix4()`. Note : En coulisses, cette méthode repose sur `Matrix4.decompose()`, et toutes les matrices ne sont pas décomposables de cette manière. Par exemple, si un objet a un parent avec une mise à l'échelle non uniforme, la matrice du monde de l'objet peut ne pas être décomposable, et cette méthode pourrait ne pas être appropriée.
diff --git a/manual/fr/shadows.html b/manual/fr/shadows.html
index a1d75a9e98d8d2..bca3b806517d6c 100644
--- a/manual/fr/shadows.html
+++ b/manual/fr/shadows.html
@@ -331,7 +331,7 @@
Ombres
caméra d'ombre de la lumière et l'helper affichant la caméra d'ombre de la lumière.
function updateCamera() {
// mettre à jour le matrixWorld de la cible de la lumière car il est nécessaire pour l'helper
- light.target.updateMatrixWorld();
+ light.target.ensureMatrices();
helper.update();
// mettre à jour la matrice de projection de la caméra d'ombre de la lumière
light.shadow.camera.updateProjectionMatrix();
diff --git a/manual/ja/align-html-elements-to-3d.html b/manual/ja/align-html-elements-to-3d.html
index f918af1c8f22ae..a0e2c63a62daa7 100644
--- a/manual/ja/align-html-elements-to-3d.html
+++ b/manual/ja/align-html-elements-to-3d.html
@@ -1,4 +1,4 @@
-
+
でHTML要素を3Dに揃える
@@ -264,14 +264,14 @@ でHTML要素を3Dに揃える
// before checking
camera.updateMatrix();
-camera.updateMatrixWorld();
+camera.ensureMatrices();
camera.matrixWorldInverse.copy(camera.matrixWorld).invert();
...
// then for each mesh
someMesh.updateMatrix();
-someMesh.updateMatrixWorld();
+someMesh.ensureMatrices();
viewProjection.multiplyMatrices(
camera.projectionMatrix, camera.matrixWorldInverse);
diff --git a/manual/ja/custom-buffergeometry.html b/manual/ja/custom-buffergeometry.html
index f2e79cc218f657..90b7b133545c7b 100644
--- a/manual/ja/custom-buffergeometry.html
+++ b/manual/ja/custom-buffergeometry.html
@@ -1,4 +1,4 @@
-
+
のカスタムバッファジオメトリ
@@ -290,7 +290,7 @@ のカスタムバッファジオメトリ
function getPoint(lat, long) {
latHelper.rotation.x = lat;
longHelper.rotation.y = long;
- longHelper.updateMatrixWorld(true);
+ longHelper.ensureMatrices(true);
return pointHelper.getWorldPosition(temp).toArray();
}
diff --git a/manual/ja/lights.html b/manual/ja/lights.html
index fb3f9c086aa691..8dd67d4f8da5a4 100644
--- a/manual/ja/lights.html
+++ b/manual/ja/lights.html
@@ -231,7 +231,7 @@ Directional
そのため、lil-guiが値を更新時に onChangeFn 関数を渡しています。
makeXYZGUI関数はlight.positionとlight.target.positionの両方に使えます。
+function updateLight() {
-+ light.target.updateMatrixWorld();
++ light.target.ensureMatrices();
+ helper.update();
+}
+updateLight();
@@ -273,7 +273,7 @@ PointLight(点
light.targetがないので onChange 関数はもっとシンプルになります。
function updateLight() {
-- light.target.updateMatrixWorld();
+- light.target.ensureMatrices();
helper.update();
}
-updateLight();
diff --git a/manual/ja/load-gltf.html b/manual/ja/load-gltf.html
index 7dd15962a0d1ac..f85a26fefc7ab4 100644
--- a/manual/ja/load-gltf.html
+++ b/manual/ja/load-gltf.html
@@ -1,4 +1,4 @@
-
+
でGLFTファイルを読み込む
@@ -250,7 +250,7 @@ でGLFTファイルを読み込む
+ { prefix: 'Car_04', rot: [0, Math.PI, 0], },
+ ];
+
-+ root.updateMatrixWorld();
++ root.ensureMatrices();
+ for (const car of loadedCars.children.slice()) {
+ const fix = fixes.find(fix => car.name.startsWith(fix.prefix));
+ const obj = new THREE.Object3D();
@@ -540,7 +540,7 @@ でGLFTファイルを読み込む
+ { prefix: 'Car_04', y: 40, rot: [0, Math.PI, 0], },
];
-root.updateMatrixWorld();
+root.ensureMatrices();
for (const car of loadedCars.children.slice()) {
const fix = fixes.find(fix => car.name.startsWith(fix.prefix));
const obj = new THREE.Object3D();
diff --git a/manual/ja/load-obj.html b/manual/ja/load-obj.html
index 7a14e6455a244d..85e223d7f1e5a0 100644
--- a/manual/ja/load-obj.html
+++ b/manual/ja/load-obj.html
@@ -1,4 +1,4 @@
-
+
でOBJファイルを読み込む
@@ -472,7 +472,7 @@ でOBJファイルを読み込む
+ mtl.preload();
+ objLoader.setMaterials(mtl);
objLoader.load('resources/models/windmill/windmill.obj', (root) => {
- root.updateMatrixWorld();
+ root.ensureMatrices();
scene.add(root);
// compute the box that contains all the stuff
// from root and below
diff --git a/manual/ja/shadows.html b/manual/ja/shadows.html
index f07959802763bb..d878471c08ec08 100644
--- a/manual/ja/shadows.html
+++ b/manual/ja/shadows.html
@@ -306,7 +306,7 @@ のシャドウ
ライトやヘルパー、ライトのシャドウカメラやカメラのヘルパーを更新するupdateCamera関数を書いてみましょう。
function updateCamera() {
// update the light target's matrixWorld because it's needed by the helper
- light.target.updateMatrixWorld();
+ light.target.ensureMatrices();
helper.update();
// update the light's shadow camera's projection matrix
light.shadow.camera.updateProjectionMatrix();
diff --git a/manual/ko/align-html-elements-to-3d.html b/manual/ko/align-html-elements-to-3d.html
index d67dc8342abe25..0616e2da7a6e84 100644
--- a/manual/ko/align-html-elements-to-3d.html
+++ b/manual/ko/align-html-elements-to-3d.html
@@ -1,4 +1,4 @@
-
+
HTML 요소를 3D로 정렬하기
@@ -245,14 +245,14 @@ HTML 요소를 3D로 정렬하기
// 좌표 확인 전
camera.updateMatrix();
-camera.updateMatrixWorld();
+camera.ensureMatrices();
camera.matrixWorldInverse.copy(camera.matrixWorld).invert();
...
// 각 mesh마다 좌표를 업데이트합니다.
someMesh.updateMatrix();
-someMesh.updateMatrixWorld();
+someMesh.ensureMatrices();
viewProjection.multiplyMatrices(
camera.projectionMatrix, camera.matrixWorldInverse);
diff --git a/manual/ko/custom-buffergeometry.html b/manual/ko/custom-buffergeometry.html
index 843a18640b1092..815040c3efac08 100644
--- a/manual/ko/custom-buffergeometry.html
+++ b/manual/ko/custom-buffergeometry.html
@@ -1,4 +1,4 @@
-
+
사용자 지정 BufferGeometry
@@ -329,7 +329,7 @@ 사용자 지정 BufferGeometry
function getPoint(lat, long) {
latHelper.rotation.x = lat;
longHelper.rotation.y = long;
- longHelper.updateMatrixWorld(true);
+ longHelper.ensureMatrices(true);
return pointHelper.getWorldPosition(temp).toArray();
}
diff --git a/manual/ko/lights.html b/manual/ko/lights.html
index 716ee4c1e08267..64af102b613d4f 100644
--- a/manual/ko/lights.html
+++ b/manual/ko/lights.html
@@ -239,7 +239,7 @@
그리고 조명의 위치, 목표의 위치 객체에 방금 만든 함수를 각각 적용합니다.
+function updateLight() {
-+ light.target.updateMatrixWorld();
++ light.target.ensureMatrices();
+ helper.update();
+}
+updateLight();
@@ -283,7 +283,7 @@ PointLight에는 목표가 없으므로 onChange 함수도 훨씬 간단하게
짤 수 있습니다.
function updateLight() {
-- light.target.updateMatrixWorld();
+- light.target.ensureMatrices();
helper.update();
}
-updateLight();
diff --git a/manual/ko/load-gltf.html b/manual/ko/load-gltf.html
index 6516509639b0b1..967d4153c0ad30 100644
--- a/manual/ko/load-gltf.html
+++ b/manual/ko/load-gltf.html
@@ -1,4 +1,4 @@
-
+
에서 .GLTF 파일 불러오기
@@ -263,7 +263,7 @@ 에서 .GLTF 파일 불러오기
+ { prefix: 'Car_04', rot: [0, Math.PI, 0], },
+ ];
+
-+ root.updateMatrixWorld();
++ root.ensureMatrices();
+ for (const car of loadedCars.children.slice()) {
+ const fix = fixes.find(fix => car.name.startsWith(fix.prefix));
+ const obj = new THREE.Object3D();
@@ -566,7 +566,7 @@ 에서 .GLTF 파일 불러오기
+ { prefix: 'Car_04', y: 40, rot: [0, Math.PI, 0], },
];
-root.updateMatrixWorld();
+root.ensureMatrices();
for (const car of loadedCars.children.slice()) {
const fix = fixes.find(fix => car.name.startsWith(fix.prefix));
const obj = new THREE.Object3D();
diff --git a/manual/ko/load-obj.html b/manual/ko/load-obj.html
index 030af4757784d2..84a3f36586af42 100644
--- a/manual/ko/load-obj.html
+++ b/manual/ko/load-obj.html
@@ -1,4 +1,4 @@
-
+
에서 .OBJ 파일 불러오기
@@ -492,7 +492,7 @@ 에서 .OBJ 파일 불러오기
+ const objLoader = new OBJLoader();
+ objLoader.setMaterials(mtl);
objLoader.load('resources/models/windmill/windmill.obj', (root) => {
- root.updateMatrixWorld();
+ root.ensureMatrices();
scene.add(root);
// 모든 요소를 포함하는 육면체를 계산합니다
const box = new THREE.Box3().setFromObject(root);
diff --git a/manual/ko/shadows.html b/manual/ko/shadows.html
index 2c6cbb7a7ca5c0..339b46bf5517cc 100644
--- a/manual/ko/shadows.html
+++ b/manual/ko/shadows.html
@@ -1,4 +1,4 @@
-
+
그림자<(Shadows)
@@ -326,7 +326,7 @@ 그림자(Shadows)
조명, 조명 헬퍼, 조명의 그림자용 카메라, 그림자용 카메라의 헬퍼를 업데이트할 거예요.
function updateCamera() {
// 헬퍼가 가이드라인을 그릴 때 필요한 조명 목표(target)의 matrixWorld를 업데이트 합니다
- light.target.updateMatrixWorld();
+ light.target.ensureMatrices();
helper.update();
// 그림자용 카메라의 투영 행렬(projection matrix)를 업데이트합니다
light.shadow.camera.updateProjectionMatrix();
diff --git a/manual/ru/custom-buffergeometry.html b/manual/ru/custom-buffergeometry.html
index 863df54850638b..2f20276e669a39 100644
--- a/manual/ru/custom-buffergeometry.html
+++ b/manual/ru/custom-buffergeometry.html
@@ -1,4 +1,4 @@
-
+
Пользовательская BufferGeometry
@@ -325,7 +325,7 @@ Пользовательская BufferGeometry
function getPoint(lat, long) {
latHelper.rotation.x = lat;
longHelper.rotation.y = long;
- longHelper.updateMatrixWorld(true);
+ longHelper.ensureMatrices(true);
return pointHelper.getWorldPosition(temp).toArray();
}
diff --git a/manual/ru/lights.html b/manual/ru/lights.html
index 7393a9c4ef5fe6..07f3e29ffe6844 100644
--- a/manual/ru/lights.html
+++ b/manual/ru/lights.html
@@ -1,4 +1,4 @@
-
+
- Освещение
@@ -258,7 +258,7 @@ Затем мы можем использовать это как для положения источника света,
так и для цели, как тут
+function updateLight() {
-+ light.target.updateMatrixWorld();
++ light.target.ensureMatrices();
+ helper.update();
+}
+updateLight();
@@ -301,7 +301,7 @@ onChange функция может быть проще.
function updateLight() {
-- light.target.updateMatrixWorld();
+- light.target.ensureMatrices();
helper.update();
}
-updateLight();
diff --git a/manual/ru/shadows.html b/manual/ru/shadows.html
index 0a86e380906e73..0ec592c64fe7d1 100644
--- a/manual/ru/shadows.html
+++ b/manual/ru/shadows.html
@@ -300,7 +300,7 @@ Тени
камеры тени источника света и помощника, отображающего камеру тени источника света.
function updateCamera() {
// update the light target's matrixWorld because it's needed by the helper
- light.target.updateMatrixWorld();
+ light.target.ensureMatrices();
helper.update();
// update the light's shadow camera's projection matrix
light.shadow.camera.updateProjectionMatrix();
diff --git a/manual/zh/align-html-elements-to-3d.html b/manual/zh/align-html-elements-to-3d.html
index d20d23a4728b3c..368965502c748b 100644
--- a/manual/zh/align-html-elements-to-3d.html
+++ b/manual/zh/align-html-elements-to-3d.html
@@ -1,4 +1,4 @@
-
+
@@ -263,14 +263,14 @@ 对齐HTML元素到3D对象
// 在检查前
camera.updateMatrix();
-camera.updateMatrixWorld();
+camera.ensureMatrices();
camera.matrixWorldInverse.copy(camera.matrixWorld).invert();
...
// 然后,对每一个Mesh
someMesh.updateMatrix();
-someMesh.updateMatrixWorld();
+someMesh.ensureMatrices();
viewProjection.multiplyMatrices(
camera.projectionMatrix, camera.matrixWorldInverse);
diff --git a/manual/zh/custom-buffergeometry.html b/manual/zh/custom-buffergeometry.html
index 795fdf956ecbbe..0867fad1577732 100644
--- a/manual/zh/custom-buffergeometry.html
+++ b/manual/zh/custom-buffergeometry.html
@@ -1,4 +1,4 @@
-
+
自定义缓冲几何体
@@ -289,7 +289,7 @@ 自定义缓冲几何体
function getPoint(lat, long) {
latHelper.rotation.x = lat;
longHelper.rotation.y = long;
- longHelper.updateMatrixWorld(true);
+ longHelper.ensureMatrices(true);
return pointHelper.getWorldPosition(temp).toArray();
}
diff --git a/manual/zh/lights.html b/manual/zh/lights.html
index 6f6fcfe16a1010..13783c083b04e3 100644
--- a/manual/zh/lights.html
+++ b/manual/zh/lights.html
@@ -206,7 +206,7 @@ 方向光(update
方法来更新辅助对象本身的状态。因此我们传入一个 onChangeFn 函数,每当 lil-gui 改变了某个值的时候,就会被调用。
应用到光照位置与目标点位置的控制,就如下所示:
+function updateLight() {
-+ light.target.updateMatrixWorld();
++ light.target.ensureMatrices();
+ helper.update();
+}
+updateLight();
@@ -245,7 +245,7 @@ 点光源(
因为点光源没有 target 属性,所以 onChange 函数可以简化。
function updateLight() {
-- light.target.updateMatrixWorld();
+- light.target.ensureMatrices();
helper.update();
}
-updateLight();
diff --git a/manual/zh/load-gltf.html b/manual/zh/load-gltf.html
index ea0dd47d4b74bd..b113c2d592b4be 100644
--- a/manual/zh/load-gltf.html
+++ b/manual/zh/load-gltf.html
@@ -263,7 +263,7 @@ 加载 .gltf 文件
+ { prefix: 'Car_04', rot: [0, Math.PI, 0], },
+ ];
+
-+ root.updateMatrixWorld();
++ root.ensureMatrices();
+ for (const car of loadedCars.children.slice()) {
+ const fix = fixes.find(fix => car.name.startsWith(fix.prefix));
+ const obj = new THREE.Object3D();
@@ -565,7 +565,7 @@ 加载 .gltf 文件
+ { prefix: 'Car_04', y: 40, rot: [0, Math.PI, 0], },
];
-root.updateMatrixWorld();
+root.ensureMatrices();
for (const car of loadedCars.children.slice()) {
const fix = fixes.find(fix => car.name.startsWith(fix.prefix));
const obj = new THREE.Object3D();
diff --git a/manual/zh/load-obj.html b/manual/zh/load-obj.html
index ab51172963ad25..7fc626ee064e31 100644
--- a/manual/zh/load-obj.html
+++ b/manual/zh/load-obj.html
@@ -412,7 +412,7 @@ 加载 .OBJ 文件
+ const objLoader = new OBJLoader();
+ objLoader.setMaterials(mtl);
objLoader.load('resources/models/windmill/windmill.obj', (root) => {
- root.updateMatrixWorld();
+ root.ensureMatrices();
scene.add(root);
// compute the box that contains all the stuff
// from root and below
diff --git a/manual/zh/shadows.html b/manual/zh/shadows.html
index 9ba2ed8fd438b7..3acea7889c83d9 100644
--- a/manual/zh/shadows.html
+++ b/manual/zh/shadows.html
@@ -286,7 +286,7 @@ 阴影
这个方法将更新光源,光源的帮助类以及光源的阴影相机和像是光的阴影相机的帮助类。
function updateCamera() {
// update the light target's matrixWorld because it's needed by the helper
- light.target.updateMatrixWorld();
+ light.target.ensureMatrices();
helper.update();
// update the light's shadow camera's projection matrix
light.shadow.camera.updateProjectionMatrix();
diff --git a/src/audio/AudioListener.js b/src/audio/AudioListener.js
index f9478d06ccc864..040a6e88cbc5db 100644
--- a/src/audio/AudioListener.js
+++ b/src/audio/AudioListener.js
@@ -172,9 +172,9 @@ class AudioListener extends Object3D {
}
- updateMatrixWorld( force ) {
+ updateMatrixWorld() {
- super.updateMatrixWorld( force );
+ super.updateMatrixWorld();
const listener = this.context.listener;
diff --git a/src/audio/PositionalAudio.js b/src/audio/PositionalAudio.js
index 366f7443fa23f1..fe1f80af464b53 100644
--- a/src/audio/PositionalAudio.js
+++ b/src/audio/PositionalAudio.js
@@ -214,9 +214,9 @@ class PositionalAudio extends Audio {
}
- updateMatrixWorld( force ) {
+ updateMatrixWorld() {
- super.updateMatrixWorld( force );
+ super.updateMatrixWorld();
if ( this.hasPlaybackControl === true && this.isPlaying === false ) return;
diff --git a/src/cameras/Camera.js b/src/cameras/Camera.js
index 2c2569639c4476..d1b1a0e141768a 100644
--- a/src/cameras/Camera.js
+++ b/src/cameras/Camera.js
@@ -109,29 +109,9 @@ class Camera extends Object3D {
}
- updateMatrixWorld( force ) {
+ updateMatrixWorld() {
- super.updateMatrixWorld( force );
-
- // exclude scale from view matrix to be glTF conform
-
- this.matrixWorld.decompose( _position, _quaternion, _scale );
-
- if ( _scale.x === 1 && _scale.y === 1 && _scale.z === 1 ) {
-
- this.matrixWorldInverse.copy( this.matrixWorld ).invert();
-
- } else {
-
- this.matrixWorldInverse.compose( _position, _quaternion, _scale.set( 1, 1, 1 ) ).invert();
-
- }
-
- }
-
- updateWorldMatrix( updateParents, updateChildren ) {
-
- super.updateWorldMatrix( updateParents, updateChildren );
+ super.updateMatrixWorld();
// exclude scale from view matrix to be glTF conform
diff --git a/src/cameras/CubeCamera.js b/src/cameras/CubeCamera.js
index afaae16a8069a0..bdd261499543d4 100644
--- a/src/cameras/CubeCamera.js
+++ b/src/cameras/CubeCamera.js
@@ -162,7 +162,7 @@ class CubeCamera extends Object3D {
this.add( camera );
- camera.updateMatrixWorld();
+ camera.ensureMatrices();
}
@@ -177,7 +177,7 @@ class CubeCamera extends Object3D {
*/
update( renderer, scene ) {
- if ( this.parent === null ) this.updateMatrixWorld();
+ if ( this.parent === null ) this.ensureMatrices();
const { renderTarget, activeMipmapLevel } = this;
diff --git a/src/core/Object3D.js b/src/core/Object3D.js
index a50a5f767e4cc5..55864830cb6e76 100644
--- a/src/core/Object3D.js
+++ b/src/core/Object3D.js
@@ -1152,92 +1152,73 @@ class Object3D extends EventDispatcher {
}
/**
- * Updates the transformation matrix in world space of this 3D objects and its descendants.
- *
- * To ensure correct results, this method also recomputes the 3D object's transformation matrix in
- * local space. The computation of the local and world matrix can be controlled with the
- * {@link Object3D#matrixAutoUpdate} and {@link Object3D#matrixWorldAutoUpdate} flags which are both
- * `true` by default. Set these flags to `false` if you need more control over the update matrix process.
- *
- * @param {boolean} [force=false] - When set to `true`, a recomputation of world matrices is forced even
- * when {@link Object3D#matrixWorldNeedsUpdate} is `false`.
+ * Updates the transformation matrix in world space.
*/
- updateMatrixWorld( force ) {
-
- if ( this.matrixAutoUpdate ) this.updateMatrix();
-
- if ( this.matrixWorldNeedsUpdate || force ) {
-
- if ( this.matrixWorldAutoUpdate === true ) {
-
- if ( this.parent === null ) {
-
- this.matrixWorld.copy( this.matrix );
-
- } else {
-
- this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );
-
- }
-
- }
-
- this.matrixWorldNeedsUpdate = false;
-
- force = true;
-
- }
+ updateMatrixWorld() {
- // make sure descendants are updated if required
+ if ( this.parent === null ) {
- const children = this.children;
+ this.matrixWorld.copy( this.matrix );
- for ( let i = 0, l = children.length; i < l; i ++ ) {
-
- const child = children[ i ];
+ } else {
- child.updateMatrixWorld( force );
+ this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );
}
}
/**
- * An alternative version of {@link Object3D#updateMatrixWorld} with more control over the
- * update of ancestor and descendant nodes.
- *
- * @param {boolean} [updateParents=false] Whether ancestor nodes should be updated or not.
- * @param {boolean} [updateChildren=false] Whether descendant nodes should be updated or not.
+ * @desc Ensures that the local and world matrices of the current object and all of
+ * its descendants are updated. A variety of arguments are provided for more
+ * control over the update process.
+ * @param {boolean?} force - (optional) Forces an update of this object's world matrix, even if
+ * {@link Object3D#matrixWorldNeedsUpdate} is `false`.
+ * @param {boolean?} [updateParents=false] - (optional) Whether ancestor nodes should be updated.
+ * @param {boolean?} [updateChildren=true] - (optional) Whether descendant nodes should be updated.
+ * @param {boolean?} updateLocal - (optional) Whether local matrices should be updated.
+ * @param {boolean?} updateWorld - (optional) Whether world matrices should be updated.
+ * @param {boolean?} respectAutoUpdateFlags - (optional) Whether {@link Object3D#matrixAutoUpdate}
+ * and {@link Object3D#matrixWorldAutoUpdate} should be respected.
*/
- updateWorldMatrix( updateParents, updateChildren ) {
+ ensureMatrices(
+ force = false,
+ updateParents = false,
+ updateChildren = true,
+ updateLocal = true,
+ updateWorld = true,
+ respectAutoUpdateFlags = true
+ ) {
const parent = this.parent;
- if ( updateParents === true && parent !== null ) {
+ if ( updateParents && parent !== null ) {
- parent.updateWorldMatrix( true, false );
+ parent.ensureMatrices( force, true, false, updateLocal, updateWorld, respectAutoUpdateFlags );
}
- if ( this.matrixAutoUpdate ) this.updateMatrix();
+ if ( updateLocal && ( ! respectAutoUpdateFlags || this.matrixAutoUpdate ) ) {
- if ( this.matrixWorldAutoUpdate === true ) {
+ this.updateMatrix();
- if ( this.parent === null ) {
+ }
- this.matrixWorld.copy( this.matrix );
+ if ( updateWorld && ( ! respectAutoUpdateFlags || this.matrixWorldAutoUpdate ) ) {
- } else {
+ if ( force || this.matrixWorldNeedsUpdate ) {
- this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );
+ this.updateMatrixWorld();
+
+ this.matrixWorldNeedsUpdate = false;
+
+ force = true;
}
}
- // make sure descendants are updated
-
- if ( updateChildren === true ) {
+ if ( updateChildren ) {
const children = this.children;
@@ -1245,7 +1226,7 @@ class Object3D extends EventDispatcher {
const child = children[ i ];
- child.updateWorldMatrix( false, true );
+ child.ensureMatrices( force, false, true, updateLocal, updateWorld, respectAutoUpdateFlags );
}
@@ -1253,6 +1234,30 @@ class Object3D extends EventDispatcher {
}
+ /**
+ * An alternative version of {@link Object3D#ensureMatrices} that always
+ * ignores the {@link Object3D#matrixWorldNeedsUpdate} flag, and does
+ * not update children by default.
+ *
+ * @param {boolean?} [updateParents=false] - (optional) Whether ancestor nodes should be updated.
+ * @param {boolean?} [updateChildren=false] - (optional) Whether descendant nodes should be updated.
+ * @param {boolean?} updateLocal - (optional) Whether local matrices should be updated.
+ * @param {boolean?} updateWorld - (optional) Whether world matrices should be updated.
+ * @param {boolean?} respectAutoUpdateFlags - (optional) Whether {@link Object3D#matrixAutoUpdate}
+ * and {@link Object3D#matrixWorldAutoUpdate} should be respected.
+ */
+ updateWorldMatrix(
+ updateParents = false,
+ updateChildren = false,
+ updateLocal = true,
+ updateWorld = true,
+ respectAutoUpdateFlags = true
+ ) {
+
+ this.ensureMatrices( true, updateParents, updateChildren, updateLocal, updateWorld, respectAutoUpdateFlags );
+
+ }
+
/**
* Serializes the 3D object into JSON.
*
diff --git a/src/helpers/Box3Helper.js b/src/helpers/Box3Helper.js
index af0ceee8449349..4827a8a7e1218a 100644
--- a/src/helpers/Box3Helper.js
+++ b/src/helpers/Box3Helper.js
@@ -51,7 +51,7 @@ class Box3Helper extends LineSegments {
}
- updateMatrixWorld( force ) {
+ updateMatrixWorld() {
const box = this.box;
@@ -63,7 +63,7 @@ class Box3Helper extends LineSegments {
this.scale.multiplyScalar( 0.5 );
- super.updateMatrixWorld( force );
+ super.updateMatrixWorld();
}
diff --git a/src/helpers/PlaneHelper.js b/src/helpers/PlaneHelper.js
index f1f36324c0c938..770242393ed36b 100644
--- a/src/helpers/PlaneHelper.js
+++ b/src/helpers/PlaneHelper.js
@@ -64,7 +64,7 @@ class PlaneHelper extends Line {
}
- updateMatrixWorld( force ) {
+ updateMatrixWorld() {
this.position.set( 0, 0, 0 );
@@ -74,7 +74,7 @@ class PlaneHelper extends Line {
this.translateZ( - this.plane.constant );
- super.updateMatrixWorld( force );
+ super.updateMatrixWorld();
}
diff --git a/src/helpers/SkeletonHelper.js b/src/helpers/SkeletonHelper.js
index 4ea9cbf191b818..e23b4253da8a3e 100644
--- a/src/helpers/SkeletonHelper.js
+++ b/src/helpers/SkeletonHelper.js
@@ -96,7 +96,7 @@ class SkeletonHelper extends LineSegments {
}
- updateMatrixWorld( force ) {
+ updateMatrixWorld() {
const bones = this.bones;
@@ -127,7 +127,7 @@ class SkeletonHelper extends LineSegments {
geometry.getAttribute( 'position' ).needsUpdate = true;
- super.updateMatrixWorld( force );
+ super.updateMatrixWorld();
}
diff --git a/src/lights/LightShadow.js b/src/lights/LightShadow.js
index a0ab21ef45ae7e..4f136a9553da56 100644
--- a/src/lights/LightShadow.js
+++ b/src/lights/LightShadow.js
@@ -208,7 +208,7 @@ class LightShadow {
_lookTarget.setFromMatrixPosition( light.target.matrixWorld );
shadowCamera.lookAt( _lookTarget );
- shadowCamera.updateMatrixWorld();
+ shadowCamera.ensureMatrices();
_projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );
this._frustum.setFromProjectionMatrix( _projScreenMatrix, shadowCamera.coordinateSystem, shadowCamera.reversedDepth );
diff --git a/src/nodes/lighting/PointShadowNode.js b/src/nodes/lighting/PointShadowNode.js
index 1d3ec51802d03d..21d9384b84a81a 100644
--- a/src/nodes/lighting/PointShadowNode.js
+++ b/src/nodes/lighting/PointShadowNode.js
@@ -272,7 +272,7 @@ class PointShadowNode extends ShadowNode {
_lookTarget.add( cubeDirections[ face ] );
camera.up.copy( cubeUps[ face ] );
camera.lookAt( _lookTarget );
- camera.updateMatrixWorld();
+ camera.ensureMatrices();
shadowMatrix.makeTranslation( - _lightPositionWorld.x, - _lightPositionWorld.y, - _lightPositionWorld.z );
diff --git a/src/nodes/utils/ReflectorNode.js b/src/nodes/utils/ReflectorNode.js
index f7635142dbc0f0..40b573366d808f 100644
--- a/src/nodes/utils/ReflectorNode.js
+++ b/src/nodes/utils/ReflectorNode.js
@@ -504,7 +504,7 @@ class ReflectorBaseNode extends Node {
virtualCamera.near = camera.near;
virtualCamera.far = camera.far;
- virtualCamera.updateMatrixWorld();
+ virtualCamera.ensureMatrices();
virtualCamera.projectionMatrix.copy( camera.projectionMatrix );
// Now update projection matrix with new clip plane, implementing code from: http://www.terathon.com/code/oblique.html
diff --git a/src/objects/SkinnedMesh.js b/src/objects/SkinnedMesh.js
index 4a492b8feac447..2823558befc86b 100644
--- a/src/objects/SkinnedMesh.js
+++ b/src/objects/SkinnedMesh.js
@@ -233,7 +233,7 @@ class SkinnedMesh extends Mesh {
if ( bindMatrix === undefined ) {
- this.updateMatrixWorld( true );
+ this.ensureMatrices( true );
this.skeleton.calculateInverses();
@@ -287,9 +287,9 @@ class SkinnedMesh extends Mesh {
}
- updateMatrixWorld( force ) {
+ updateMatrixWorld() {
- super.updateMatrixWorld( force );
+ super.updateMatrixWorld();
if ( this.bindMode === AttachedBindMode ) {
diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js
index 3b70003d882e61..aa347f4b717582 100644
--- a/src/renderers/WebGLRenderer.js
+++ b/src/renderers/WebGLRenderer.js
@@ -1607,11 +1607,11 @@ class WebGLRenderer {
// update scene graph
- if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld();
+ if ( scene.matrixWorldAutoUpdate === true ) scene.ensureMatrices();
// update camera matrices and frustum
- if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld();
+ if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.ensureMatrices();
if ( xr.enabled === true && xr.isPresenting === true && ( output === null || output.isCompositing() === false ) ) {
diff --git a/src/renderers/common/Renderer.js b/src/renderers/common/Renderer.js
index bc5e48639a3c4f..450c19313889da 100644
--- a/src/renderers/common/Renderer.js
+++ b/src/renderers/common/Renderer.js
@@ -1445,9 +1445,9 @@ class Renderer {
//
- if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld();
+ if ( scene.matrixWorldAutoUpdate === true ) scene.ensureMatrices();
- if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld();
+ if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.ensureMatrices();
if ( xr.enabled === true && xr.isPresenting === true ) {
diff --git a/src/renderers/common/XRManager.js b/src/renderers/common/XRManager.js
index a31d2f70f9d922..24008dcfe5bdb4 100644
--- a/src/renderers/common/XRManager.js
+++ b/src/renderers/common/XRManager.js
@@ -1310,7 +1310,7 @@ function updateUserCamera( camera, cameraXR, parent ) {
}
camera.matrix.decompose( camera.position, camera.quaternion, camera.scale );
- camera.updateMatrixWorld( true );
+ camera.ensureMatrices( true );
camera.projectionMatrix.copy( cameraXR.projectionMatrix );
camera.projectionMatrixInverse.copy( cameraXR.projectionMatrixInverse );
diff --git a/src/renderers/webgl/WebGLShadowMap.js b/src/renderers/webgl/WebGLShadowMap.js
index caaf9dd211ad8b..0764cf02fa9b1e 100644
--- a/src/renderers/webgl/WebGLShadowMap.js
+++ b/src/renderers/webgl/WebGLShadowMap.js
@@ -333,7 +333,7 @@ function WebGLShadowMap( renderer, objects, capabilities ) {
_lookTarget.add( _cubeDirections[ face ] );
camera.up.copy( _cubeUps[ face ] );
camera.lookAt( _lookTarget );
- camera.updateMatrixWorld();
+ camera.ensureMatrices();
shadowMatrix.makeTranslation( - _lightPositionWorld.x, - _lightPositionWorld.y, - _lightPositionWorld.z );
diff --git a/src/renderers/webxr/WebXRManager.js b/src/renderers/webxr/WebXRManager.js
index 03ed5ab7e7426b..2370ca91d077b3 100644
--- a/src/renderers/webxr/WebXRManager.js
+++ b/src/renderers/webxr/WebXRManager.js
@@ -798,7 +798,7 @@ class WebXRManager extends EventDispatcher {
}
camera.matrix.decompose( camera.position, camera.quaternion, camera.scale );
- camera.updateMatrixWorld( true );
+ camera.ensureMatrices( true );
camera.projectionMatrix.copy( cameraXR.projectionMatrix );
camera.projectionMatrixInverse.copy( cameraXR.projectionMatrixInverse );
diff --git a/test/unit/addons/exporters/USDZExporter.tests.js b/test/unit/addons/exporters/USDZExporter.tests.js
index 2f516ae674112e..54abe43b16742d 100644
--- a/test/unit/addons/exporters/USDZExporter.tests.js
+++ b/test/unit/addons/exporters/USDZExporter.tests.js
@@ -198,7 +198,7 @@ export default QUnit.module( 'Addons', () => {
const meshes = [ box, sphere ];
- originalScene.updateMatrixWorld( true );
+ originalScene.ensureMatrices( true );
const exportResult = await exporter.parseAsync( originalScene );
diff --git a/test/unit/src/core/Object3D.tests.js b/test/unit/src/core/Object3D.tests.js
index 2e941d7035c088..2af1ef4bf2be5c 100644
--- a/test/unit/src/core/Object3D.tests.js
+++ b/test/unit/src/core/Object3D.tests.js
@@ -354,7 +354,7 @@ export default QUnit.module( 'Core', () => {
child.scale.set( 1, 2, 1 );
parent.add( child );
- parent.updateMatrixWorld();
+ parent.ensureMatrices();
child.localToWorld( v.set( 2, 2, 2 ) );
@@ -384,7 +384,7 @@ export default QUnit.module( 'Core', () => {
child.scale.set( 1, 2, 1 );
parent.add( child );
- parent.updateMatrixWorld();
+ parent.ensureMatrices();
child.worldToLocal( v.set( 2, 2, 2 ) );
@@ -469,8 +469,8 @@ export default QUnit.module( 'Core', () => {
newParent.rotation.set( Math.PI / 5, Math.PI / 6, Math.PI / 7 );
newParent.scale.set( 5, 5, 5 );
- object.updateMatrixWorld();
- newParent.updateMatrixWorld();
+ object.ensureMatrices();
+ newParent.ensureMatrices();
expectedMatrixWorld.copy( object.matrixWorld );
newParent.attach( object );
@@ -494,8 +494,8 @@ export default QUnit.module( 'Core', () => {
newParent.scale.set( 6, 6, 6 );
oldParent.add( object );
- oldParent.updateMatrixWorld();
- newParent.updateMatrixWorld();
+ oldParent.ensureMatrices();
+ newParent.ensureMatrices();
expectedMatrixWorld.copy( object.matrixWorld );
newParent.attach( object );
@@ -720,7 +720,7 @@ export default QUnit.module( 'Core', () => {
child.position.set( 4, 5, 6 );
parent.add( child );
- parent.updateMatrixWorld();
+ parent.ensureMatrices();
assert.deepEqual( parent.matrix.elements, [
1, 0, 0, 0,
@@ -768,12 +768,12 @@ export default QUnit.module( 'Core', () => {
// Resetting local and world matrices to the origin
child.position.set( 0, 0, 0 );
- parent.updateMatrixWorld();
+ parent.ensureMatrices();
parent.position.set( 1, 2, 3 );
parent.matrixAutoUpdate = false;
child.matrixAutoUpdate = false;
- parent.updateMatrixWorld();
+ parent.ensureMatrices();
assert.deepEqual( parent.matrix.elements, [
1, 0, 0, 0,
@@ -805,7 +805,7 @@ export default QUnit.module( 'Core', () => {
child.matrixAutoUpdate = true;
parent.matrixWorldNeedsUpdate = true;
child.matrixWorldAutoUpdate = false;
- parent.updateMatrixWorld();
+ parent.ensureMatrices();
assert.deepEqual( child.matrixWorld.elements, [
1, 0, 0, 0,
@@ -819,7 +819,7 @@ export default QUnit.module( 'Core', () => {
child.position.set( 0, 0, 0 );
parent.position.set( 1, 2, 3 );
child.matrixWorldAutoUpdate = true;
- parent.updateMatrixWorld();
+ parent.ensureMatrices();
assert.deepEqual( child.matrixWorld.elements, [
1, 0, 0, 0,
@@ -833,14 +833,14 @@ export default QUnit.module( 'Core', () => {
// Resetting the local and world matrices to the origin
child.position.set( 0, 0, 0 );
child.matrixAutoUpdate = true;
- parent.updateMatrixWorld();
+ parent.ensureMatrices();
parent.position.set( 1, 2, 3 );
parent.updateMatrix();
parent.matrixAutoUpdate = false;
parent.matrixWorldNeedsUpdate = false;
- parent.updateMatrixWorld( true );
+ parent.ensureMatrices( true );
assert.deepEqual( parent.matrixWorld.elements, [
1, 0, 0, 0,
@@ -856,12 +856,12 @@ export default QUnit.module( 'Core', () => {
child.position.set( 0, 0, 0 );
parent.matrixAutoUpdate = true;
child.matrixAutoUpdate = true;
- parent.updateMatrixWorld();
+ parent.ensureMatrices();
parent.position.set( 1, 2, 3 );
child.position.set( 4, 5, 6 );
- child.updateMatrixWorld();
+ child.ensureMatrices();
assert.deepEqual( parent.matrix.elements, [
1, 0, 0, 0,
diff --git a/test/unit/src/core/Raycaster.tests.js b/test/unit/src/core/Raycaster.tests.js
index 072073462434e4..56d56c11416b8e 100644
--- a/test/unit/src/core/Raycaster.tests.js
+++ b/test/unit/src/core/Raycaster.tests.js
@@ -52,7 +52,7 @@ function getObjectsToCheck() {
for ( let i = 0; i < objects.length; i ++ ) {
- objects[ i ].updateMatrixWorld();
+ objects[ i ].ensureMatrices();
}
diff --git a/test/unit/src/math/Frustum.tests.js b/test/unit/src/math/Frustum.tests.js
index 34ff43bf5e6724..603d95414bc682 100644
--- a/test/unit/src/math/Frustum.tests.js
+++ b/test/unit/src/math/Frustum.tests.js
@@ -199,13 +199,13 @@ export default QUnit.module( 'Maths', () => {
assert.notOk( intersects, 'No intersection' );
object.position.set( - 1, - 1, - 1 );
- object.updateMatrixWorld();
+ object.ensureMatrices();
intersects = a.intersectsObject( object );
assert.ok( intersects, 'Successful intersection' );
object.position.set( 1, 1, 1 );
- object.updateMatrixWorld();
+ object.ensureMatrices();
intersects = a.intersectsObject( object );
assert.notOk( intersects, 'No intersection' );
@@ -223,7 +223,7 @@ export default QUnit.module( 'Maths', () => {
assert.notOk( intersects, 'No intersection' );
sprite.position.set( - 1, - 1, - 1 );
- sprite.updateMatrixWorld();
+ sprite.ensureMatrices();
intersects = a.intersectsSprite( sprite );
assert.ok( intersects, 'Successful intersection' );
diff --git a/test/unit/src/objects/Mesh.tests.js b/test/unit/src/objects/Mesh.tests.js
index 1893812c7846d8..adfd152b723d7c 100644
--- a/test/unit/src/objects/Mesh.tests.js
+++ b/test/unit/src/objects/Mesh.tests.js
@@ -112,21 +112,21 @@ export default QUnit.module( 'Objects', () => {
mesh.matrixWorld.identity();
mesh.position.setX( 150 );
- mesh.updateMatrixWorld( true );
+ mesh.ensureMatrices( true );
intersections.length = 0;
mesh.raycast( raycaster, intersections );
assert.ok( intersections.length > 0, 'bounding sphere between near and far' );
mesh.matrixWorld.identity();
mesh.position.setX( raycaster.near );
- mesh.updateMatrixWorld( true );
+ mesh.ensureMatrices( true );
intersections.length = 0;
mesh.raycast( raycaster, intersections );
assert.ok( intersections.length > 0, 'bounding sphere across near' );
mesh.matrixWorld.identity();
mesh.position.setX( raycaster.far );
- mesh.updateMatrixWorld( true );
+ mesh.ensureMatrices( true );
intersections.length = 0;
mesh.raycast( raycaster, intersections );
assert.ok( intersections.length > 0, 'bounding sphere across far' );
@@ -134,21 +134,21 @@ export default QUnit.module( 'Objects', () => {
mesh.matrixWorld.identity();
mesh.position.setX( 150 );
mesh.scale.setY( 9999 );
- mesh.updateMatrixWorld( true );
+ mesh.ensureMatrices( true );
intersections.length = 0;
mesh.raycast( raycaster, intersections );
assert.ok( intersections.length > 0, 'bounding sphere across near and far' );
mesh.matrixWorld.identity();
mesh.position.setX( - 9999 );
- mesh.updateMatrixWorld( true );
+ mesh.ensureMatrices( true );
intersections.length = 0;
mesh.raycast( raycaster, intersections );
assert.ok( intersections.length === 0, 'bounding sphere behind near' );
mesh.matrixWorld.identity();
mesh.position.setX( 9999 );
- mesh.updateMatrixWorld( true );
+ mesh.ensureMatrices( true );
intersections.length = 0;
mesh.raycast( raycaster, intersections );
assert.ok( intersections.length === 0, 'bounding sphere beyond far' );
From ff80343ea094de99a0e7314d6dcd358450be59ae Mon Sep 17 00:00:00 2001
From: PoseidonEnergy
Date: Wed, 4 Feb 2026 20:12:08 -0600
Subject: [PATCH 2/5] added missing bracket
---
examples/jsm/misc/Gyroscope.js | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/examples/jsm/misc/Gyroscope.js b/examples/jsm/misc/Gyroscope.js
index dc3e2e2a8f106c..5c2d706c7c833a 100644
--- a/examples/jsm/misc/Gyroscope.js
+++ b/examples/jsm/misc/Gyroscope.js
@@ -32,23 +32,25 @@ class Gyroscope extends Object3D {
}
- updateMatrixWorld( force ) {
+ updateMatrixWorld() {
- if ( this.parent !== null ) {
+ if ( this.parent !== null ) {
- this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );
+ this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );
- this.matrixWorld.decompose( _translationWorld, _quaternionWorld, _scaleWorld );
- this.matrix.decompose( _translationObject, _quaternionObject, _scaleObject );
+ this.matrixWorld.decompose( _translationWorld, _quaternionWorld, _scaleWorld );
+ this.matrix.decompose( _translationObject, _quaternionObject, _scaleObject );
- this.matrixWorld.compose( _translationWorld, _quaternionObject, _scaleWorld );
+ this.matrixWorld.compose( _translationWorld, _quaternionObject, _scaleWorld );
- } else {
+ } else {
- this.matrixWorld.copy( this.matrix );
+ this.matrixWorld.copy( this.matrix );
- }
+ }
+
+ }
}
From 4564c2a59bef35331cc2527ba70b360630b38747 Mon Sep 17 00:00:00 2001
From: PoseidonEnergy
Date: Wed, 4 Feb 2026 21:14:03 -0600
Subject: [PATCH 3/5] fixed recursion issue
---
src/helpers/PlaneHelper.js | 21 +++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/src/helpers/PlaneHelper.js b/src/helpers/PlaneHelper.js
index 770242393ed36b..2ee012557d9fa6 100644
--- a/src/helpers/PlaneHelper.js
+++ b/src/helpers/PlaneHelper.js
@@ -62,17 +62,30 @@ class PlaneHelper extends Line {
this.add( new Mesh( geometry2, new MeshBasicMaterial( { color: color, opacity: 0.2, transparent: true, depthWrite: false, toneMapped: false } ) ) );
+ this._calculatingMatrixWorld = false;
+
}
updateMatrixWorld() {
- this.position.set( 0, 0, 0 );
+ if ( ! this._calculatingMatrixWorld ) {
+
+ // this.lookAt() internally calls this.updateMatrixWorld(), so put this
+ // code in an if-statement to avoid a 'too much recursion' error.
+
+ this._calculatingMatrixWorld = true;
+
+ this.position.set( 0, 0, 0 );
+
+ this.scale.set( 0.5 * this.size, 0.5 * this.size, 1 );
+
+ this.lookAt( this.plane.normal );
- this.scale.set( 0.5 * this.size, 0.5 * this.size, 1 );
+ this.translateZ( - this.plane.constant );
- this.lookAt( this.plane.normal );
+ this._calculatingMatrixWorld = false;
- this.translateZ( - this.plane.constant );
+ }
super.updateMatrixWorld();
From 746aafba6dfcc43ded4bbfd180a533496870c794 Mon Sep 17 00:00:00 2001
From: PoseidonEnergy
Date: Wed, 4 Feb 2026 22:37:57 -0600
Subject: [PATCH 4/5] fix stereo examples
---
src/cameras/Camera.js | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/src/cameras/Camera.js b/src/cameras/Camera.js
index d1b1a0e141768a..a170939c583c1d 100644
--- a/src/cameras/Camera.js
+++ b/src/cameras/Camera.js
@@ -129,6 +129,33 @@ class Camera extends Object3D {
}
+ ensureMatrices(
+ force,
+ updateParents,
+ updateChildren,
+ updateLocal,
+ updateWorld,
+ respectAutoUpdateFlags
+ ) {
+
+ super.ensureMatrices( force, updateParents, updateChildren, updateLocal, updateWorld, respectAutoUpdateFlags );
+
+ // exclude scale from view matrix to be glTF conform
+
+ this.matrixWorld.decompose( _position, _quaternion, _scale );
+
+ if ( _scale.x === 1 && _scale.y === 1 && _scale.z === 1 ) {
+
+ this.matrixWorldInverse.copy( this.matrixWorld ).invert();
+
+ } else {
+
+ this.matrixWorldInverse.compose( _position, _quaternion, _scale.set( 1, 1, 1 ) ).invert();
+
+ }
+
+ }
+
clone() {
return new this.constructor().copy( this );
From 3654c9ad69f897ee38903d3c5ac02437c6aa1d35 Mon Sep 17 00:00:00 2001
From: PoseidonEnergy
Date: Thu, 5 Feb 2026 19:15:04 -0600
Subject: [PATCH 5/5] Modifying if-criteria for maximal short-circuiting.
---
src/core/Object3D.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/core/Object3D.js b/src/core/Object3D.js
index 55864830cb6e76..6fad494d61f2e6 100644
--- a/src/core/Object3D.js
+++ b/src/core/Object3D.js
@@ -1198,15 +1198,15 @@ class Object3D extends EventDispatcher {
}
- if ( updateLocal && ( ! respectAutoUpdateFlags || this.matrixAutoUpdate ) ) {
+ if ( updateLocal && ( this.matrixAutoUpdate || ! respectAutoUpdateFlags ) ) {
this.updateMatrix();
}
- if ( updateWorld && ( ! respectAutoUpdateFlags || this.matrixWorldAutoUpdate ) ) {
+ if ( updateWorld && ( this.matrixWorldAutoUpdate || ! respectAutoUpdateFlags ) ) {
- if ( force || this.matrixWorldNeedsUpdate ) {
+ if ( this.matrixWorldNeedsUpdate || force ) {
this.updateMatrixWorld();