我将项目中的 Three.js 从 143 升级到 161(主要是因为新版本中修复了一个错误)。模型在 143 中工作正常,没有错误,但现在在 161 中我收到以下错误:
Uncaught TypeError: Cannot read properties of undefined (reading 'matrixWorld')
at SkinnedMesh.applyBoneTransform (three.module.js:32558:60)
at SkinnedMesh.getVertexPosition (three.module.js:32459:8)
at SkinnedMesh.computeBoundingSphere (three.module.js:32396:9)
at Frustum.intersectsObject (three.module.js:13361:49)
at projectObject (three.module.js:29990:46)
at projectObject (three.module.js:30048:5)
at projectObject (three.module.js:30048:5)
at WebGLRenderer.render (three.module.js:29833:4)
at animate (modelViewer.js:303:14)
加载某些模型(但不是全部)时会出现错误。到目前为止,当模型有多个单独的对象时,似乎会发生错误。作为单个对象的模型似乎不会出错。有些模型对于单独的对象有多个骨架,有些模型只有一个骨架,尽管这似乎对错误是否发生没有影响。
这是我的代码:
let navbarWidth = 350;
let settingsBarWidth = 312;
let backgroundColor = 0xE0E0E0;
let scene, camera, controls, ambientLight, grid, renderer;
let gltfLoader;
let modelPath = '';
function loadModel() {
// Load the model
gltfLoader.load(modelPath + '.gltf', function (gltf) {
// Show the model
scene.add(gltf.scene);
}, undefined, function (error) {
console.log(error);
}
);
}
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
controls.update();
}
// Initialize the model viewer
if (!WebGL.isWebGLAvailable()) {
$('#divModelCanvas').append(WebGL.getWebGLErrorMessage());
}
let container = document.getElementById('divModelCanvas');
// Create a scene
scene = new THREE.Scene();
scene.background = new THREE.Color(backgroundColor);
// Add a camera
camera = new THREE.PerspectiveCamera(45, (window.innerWidth - navbarWidth - settingsBarWidth) / window.innerHeight, 1, 4000);
camera.position.set(100, 200, -300);
// Add orbit controls
controls = new OrbitControls(camera, container);
controls.screenSpacePanning = true;
controls.target.set(0, 100, 0);
// Add lighting
ambientLight = new THREE.AmbientLight(0xFFFFFF, 3.15); // In 143, 1.0 was okay, in 161 need a higher value or the scene is very dark
scene.add(ambientLight);
// Add ground and a grid
let ground = new THREE.Mesh(new THREE.PlaneGeometry(5000, 5000), new THREE.MeshPhongMaterial({ color: 0xFFFFFF, depthWrite: false }));
ground.rotation.x = Math.PI / 2;
ground.receiveShadow = true;
scene.add(ground);
grid = new THREE.GridHelper(5000, 50, 0x000000, 0x000000);
grid.material.opacity = 0.2;
grid.material.transparent = true;
scene.add(grid);
// Add a renderer
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth - navbarWidth - settingsBarWidth, window.innerHeight);
container.appendChild(renderer.domElement);
// Initialize the model loaders
gltfLoader = new GLTFLoader();
animate();
// Load a model
modelPath = 'path_to_model';
loadModel();
我尝试从控制台复制并粘贴示例场景对象,但我无法做到这一点(将其字符串化为 JSON 不起作用,因为它包含循环引用)。这是部分放大场景的屏幕截图,如果有帮助的话:
如果有人知道可能导致此错误的原因以及如何修复它,我将非常感激。
您的错误的调用堆栈指向:
SkinnedMesh.applyBoneTransform (three.module.js:32558:60)
这一行是:
// three.js r161
// Copyright 2010-2023 Three.js Authors
_matrix4.multiplyMatrices( skeleton.bones[ boneIndex ].matrixWorld, skeleton.boneInverses[ boneIndex ] );
具体来说,它正在尝试读取
skeleton.bones[ boneIndex ].matrixWorld
,这意味着skeleton.bones[ boneIndex ]
未定义。
听起来您走在正确的轨道上,这是一个数据错误,但真正放大谜题的这一部分并寻找不一致之处可能是值得的。换句话说,找到一个尽可能简单的有效文件,以及无效的文件。然后,检查文件本身,重点关注骨架/骨骼的定义方式。您可能会开始看到这里的微小(甚至重大)差异,这可能会带来很大的不同。