From 5bb81c4ede64e4ba99f0c6ad9f5393b83c602159 Mon Sep 17 00:00:00 2001 From: krapnikkk Date: Sat, 1 Aug 2026 23:13:05 +0800 Subject: [PATCH] Fix glTF interleaved attribute import --- plugins.json | 2 +- plugins/gltf_importer/gltf_importer.js | 30 ++++++++++--------- .../gltf_importer/src/plugin/import_gltf.ts | 29 ++++++++++-------- plugins/gltf_importer/src/plugin/plugin.ts | 2 +- 4 files changed, 34 insertions(+), 29 deletions(-) diff --git a/plugins.json b/plugins.json index 971cae2e..aceb68ad 100644 --- a/plugins.json +++ b/plugins.json @@ -1366,7 +1366,7 @@ "description": "Import .GLTF and .GLB models", "icon": "icon.png", "creation_date": "2025-09-25", - "version": "1.2.0", + "version": "1.2.1", "variant": "desktop", "min_version": "4.12.6", "has_changelog": false, diff --git a/plugins/gltf_importer/gltf_importer.js b/plugins/gltf_importer/gltf_importer.js index bfd1e9e0..c9d8c9a0 100644 --- a/plugins/gltf_importer/gltf_importer.js +++ b/plugins/gltf_importer/gltf_importer.js @@ -2763,10 +2763,11 @@ let primitiveToUniqueVertexIndices = []; for (let [primitive, primitiveIndex] of valuesAndIndices(primitives)) { primitiveToUniqueVertexIndices[primitiveIndex] = []; - for (let vertexIndex = 0; vertexIndex < primitive.geometry.attributes.position.count; vertexIndex++) { - let x = primitive.geometry.attributes.position.array[vertexIndex * 3]; - let y = primitive.geometry.attributes.position.array[vertexIndex * 3 + 1]; - let z = primitive.geometry.attributes.position.array[vertexIndex * 3 + 2]; + const position = primitive.geometry.attributes.position; + for (let vertexIndex = 0; vertexIndex < position.count; vertexIndex++) { + let x = position.getX(vertexIndex); + let y = position.getY(vertexIndex); + let z = position.getZ(vertexIndex); const vertexVec = new THREE.Vector3(x, y, z); vertexVec.multiply(node.scale); vertexVec.multiplyScalar(options.scale); @@ -2786,25 +2787,26 @@ mesh.vertices = Object.fromEntries(uniqueVertices.map((v, i) => [vertexKeys[i], v])); let faces = []; for (let [primitive, primitiveIndex] of valuesAndIndices(primitives)) { - if (primitive.geometry.index == void 0) + const index = primitive.geometry.index; + if (index == void 0) continue; - for (let faceIndex = 0; faceIndex < primitive.geometry.index.count / 3; faceIndex++) { + for (let faceIndex = 0; faceIndex < index.count / 3; faceIndex++) { let texture = primitiveTextures[primitiveIndex]; let uvWidth = texture?.uv_width ?? Project?.texture_width ?? 16; let uvHeight = texture?.uv_height ?? Project?.texture_height ?? 16; let v1Uv, v2Uv, v3Uv; - let v1Idx = primitive.geometry.index.array[faceIndex * 3]; - let v2Idx = primitive.geometry.index.array[faceIndex * 3 + 1]; - let v3Idx = primitive.geometry.index.array[faceIndex * 3 + 2]; + let v1Idx = index.getX(faceIndex * 3); + let v2Idx = index.getX(faceIndex * 3 + 1); + let v3Idx = index.getX(faceIndex * 3 + 2); let v1Key = vertexKeys[primitiveToUniqueVertexIndices[primitiveIndex][v1Idx]]; let v2Key = vertexKeys[primitiveToUniqueVertexIndices[primitiveIndex][v2Idx]]; let v3Key = vertexKeys[primitiveToUniqueVertexIndices[primitiveIndex][v3Idx]]; let faceVertexKeys = [v1Key, v2Key, v3Key]; if (primitive.geometry.attributes.uv != void 0) { - let uvComponents = primitive.geometry.attributes.uv.array; - v1Uv = [uvComponents[v1Idx * 2], uvComponents[v1Idx * 2 + 1]]; - v2Uv = [uvComponents[v2Idx * 2], uvComponents[v2Idx * 2 + 1]]; - v3Uv = [uvComponents[v3Idx * 2], uvComponents[v3Idx * 2 + 1]]; + let uv2 = primitive.geometry.attributes.uv; + v1Uv = [uv2.getX(v1Idx), uv2.getY(v1Idx)]; + v2Uv = [uv2.getX(v2Idx), uv2.getY(v2Idx)]; + v3Uv = [uv2.getX(v3Idx), uv2.getY(v3Idx)]; } else { v1Uv = [0, 0]; v2Uv = [1, 0]; @@ -2907,7 +2909,7 @@ description: "Import .GLTF and .GLB models", icon: "icon.png", creation_date: "2025-09-25", - version: "1.2.0", + version: "1.2.1", variant: "desktop", min_version: "4.12.6", has_changelog: false, diff --git a/plugins/gltf_importer/src/plugin/import_gltf.ts b/plugins/gltf_importer/src/plugin/import_gltf.ts index e5dc52d5..383558c1 100644 --- a/plugins/gltf_importer/src/plugin/import_gltf.ts +++ b/plugins/gltf_importer/src/plugin/import_gltf.ts @@ -271,10 +271,12 @@ function importMeshPrimitives(node: THREE.Object3D, primitives: THREE.Mesh[], op for (let [primitive, primitiveIndex] of valuesAndIndices(primitives)) { primitiveToUniqueVertexIndices[primitiveIndex] = []; - for (let vertexIndex = 0; vertexIndex < primitive.geometry.attributes.position.count; vertexIndex++ ) { - let x = primitive.geometry.attributes.position.array[vertexIndex*3]; - let y = primitive.geometry.attributes.position.array[vertexIndex*3 + 1]; - let z = primitive.geometry.attributes.position.array[vertexIndex*3 + 2]; + const position = primitive.geometry.attributes.position; + + for (let vertexIndex = 0; vertexIndex < position.count; vertexIndex++ ) { + let x = position.getX(vertexIndex); + let y = position.getY(vertexIndex); + let z = position.getZ(vertexIndex); // Apply node local scale to vertices const vertexVec = new THREE.Vector3(x, y, z); @@ -306,19 +308,20 @@ function importMeshPrimitives(node: THREE.Object3D, primitives: THREE.Mesh[], op // Construct faces by using the primitive's original vertex index to look up UV and unique vertex key for (let [primitive, primitiveIndex] of valuesAndIndices(primitives)) { - if (primitive.geometry.index == undefined) + const index = primitive.geometry.index; + if (index == undefined) continue; // I guess indices are optional? seems weird - for (let faceIndex = 0; faceIndex < primitive.geometry.index.count/3; faceIndex++ ) { + for (let faceIndex = 0; faceIndex < index.count/3; faceIndex++ ) { let texture = primitiveTextures[primitiveIndex]; let uvWidth = texture?.uv_width ?? Project?.texture_width ?? 16; let uvHeight = texture?.uv_height ?? Project?.texture_height ?? 16; let v1Uv: ArrayVector2, v2Uv: ArrayVector2, v3Uv: ArrayVector2; // Original vertex index - let v1Idx = primitive.geometry.index.array[faceIndex*3]; - let v2Idx = primitive.geometry.index.array[faceIndex*3 + 1]; - let v3Idx = primitive.geometry.index.array[faceIndex*3 + 2]; + let v1Idx = index.getX(faceIndex*3); + let v2Idx = index.getX(faceIndex*3 + 1); + let v3Idx = index.getX(faceIndex*3 + 2); // Unique vertex keys let v1Key = vertexKeys[primitiveToUniqueVertexIndices[primitiveIndex][v1Idx]]; let v2Key = vertexKeys[primitiveToUniqueVertexIndices[primitiveIndex][v2Idx]]; @@ -327,10 +330,10 @@ function importMeshPrimitives(node: THREE.Object3D, primitives: THREE.Mesh[], op // UV (optional apparently) if (primitive.geometry.attributes.uv != undefined) { - let uvComponents = primitive.geometry.attributes.uv.array; - v1Uv = [ uvComponents[v1Idx*2] , uvComponents[v1Idx*2 + 1] ]; - v2Uv = [ uvComponents[v2Idx*2] , uvComponents[v2Idx*2 + 1] ]; - v3Uv = [ uvComponents[v3Idx*2] , uvComponents[v3Idx*2 + 1] ]; + let uv = primitive.geometry.attributes.uv; + v1Uv = [ uv.getX(v1Idx), uv.getY(v1Idx) ]; + v2Uv = [ uv.getX(v2Idx), uv.getY(v2Idx) ]; + v3Uv = [ uv.getX(v3Idx), uv.getY(v3Idx) ]; } else { // TODO: this currently doesn't allow for merging into quad // maybe fill missing uvs after creating primitive diff --git a/plugins/gltf_importer/src/plugin/plugin.ts b/plugins/gltf_importer/src/plugin/plugin.ts index bbe4cbf7..65d526cf 100644 --- a/plugins/gltf_importer/src/plugin/plugin.ts +++ b/plugins/gltf_importer/src/plugin/plugin.ts @@ -10,7 +10,7 @@ BBPlugin.register('gltf_importer', { description: 'Import .GLTF and .GLB models', icon: 'icon.png', creation_date: '2025-09-25', - version: '1.2.0', + version: '1.2.1', variant: 'desktop', min_version: '4.12.6', has_changelog: false,