Three.js中弯曲GLB模型报错:Cannot read property 'length' of undefined求助
Hey there, let's break down why you're hitting that TypeError: Cannot read property 'length' of undefined error and how to fix it.
The Root Cause
Your GLB model uses BufferGeometry—the modern default geometry type in Three.js—while the BendModifier from that tutorial was built for the old, deprecated Geometry type.
The old Geometry had a direct vertices array property, but BufferGeometry stores vertex data in attributes.position (a typed array), so the modifier's line for (var i = 0; i < geometry.vertices.length; i++) fails because geometry.vertices doesn't exist on your model's geometry.
Solutions to Get Your Bend Working
1. Update the Bend Modifier for BufferGeometry
You can modify the existing BendModifiers.js to work with BufferGeometry instead of the old Geometry. Here's how to adjust the critical part of the code:
// Replace the original for loop targeting geometry.vertices with this: const positions = geometry.attributes.position.array; // Iterate 3 at a time (each vertex has x, y, z values) for (let i = 0; i < positions.length; i += 3) { // Extract vertex coordinates const x = positions[i]; const y = positions[i + 1]; const z = positions[i + 2]; // Put your existing bend calculation logic here // (replace references to vertex.x/y/z with x/y/z) // Save the modified coordinates back to the array positions[i] = modifiedX; positions[i + 1] = modifiedY; positions[i + 2] = modifiedZ; } // Tell Three.js the vertex data has changed geometry.attributes.position.needsUpdate = true; // Recompute normals if your model needs correct lighting post-bend geometry.computeVertexNormals();
2. Use a Modern, BufferGeometry-Friendly Approach
If you don't want to rewrite the old modifier, consider these alternatives:
- Buffer Animation System (THREE.BAS): A library built specifically for animating
BufferGeometryobjects, with pre-built bend modifiers that play nicely with GLB models. - Shader-Based Bending: Implement the bend effect directly in a custom
ShaderMaterial. This is more performant for complex models, as it offloads the work to the GPU.
Quick Check for Your Code
Also, double-check a small detail in your loader callback: you named the loaded object geometry, but it's actually a GLTF scene container. You're already accessing the mesh correctly with staticObj = geometry.scene.children[0], but just make sure that staticObj is indeed a Mesh with a valid BufferGeometry attached.
Example Modified Code Snippet
Here's a simplified, self-contained function to bend your GLB model's BufferGeometry:
glbLoader.load('3d_models/ed-object.glb', function (gltf) { staticObj = gltf.scene.children[0]; // Ensure we're working with BufferGeometry if (!(staticObj.geometry instanceof THREE.BufferGeometry)) { staticObj.geometry = new THREE.BufferGeometry().fromGeometry(staticObj.geometry); } const direction = new THREE.Vector3(0, 0, -1); const axis = new THREE.Vector3(0, 1, 0); const angle = Math.PI / 6; applyBendToBufferGeometry(staticObj.geometry, direction, axis, angle); }); function applyBendToBufferGeometry(geometry, direction, axis, angle) { const positions = geometry.attributes.position.array; const quaternion = new THREE.Quaternion(); const center = new THREE.Vector3(); // Calculate the model's center to use as the bend origin geometry.computeBoundingBox(); geometry.boundingBox.getCenter(center); for (let i = 0; i < positions.length; i += 3) { // Translate vertex to origin relative to model center const vertex = new THREE.Vector3( positions[i] - center.x, positions[i+1] - center.y, positions[i+2] - center.z ); // Calculate bend amount based on vertex distance from the bend direction const distance = vertex.dot(direction); const bendAmount = angle * (distance / 100); // Adjust 100 to control bend intensity // Apply rotation for the bend quaternion.setFromAxisAngle(axis, bendAmount); vertex.applyQuaternion(quaternion); // Translate vertex back to original position positions[i] = vertex.x + center.x; positions[i+1] = vertex.y + center.y; positions[i+2] = vertex.z + center.z; } geometry.attributes.position.needsUpdate = true; geometry.computeVertexNormals(); }
内容的提问来源于stack exchange,提问作者KIM

