@threlte/gltf 3.0.6 → 3.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/package.json +1 -1
- package/src/utils/parser.js +23 -4
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
package/src/utils/parser.js
CHANGED
|
@@ -21,6 +21,9 @@ export function parse(fileName, gltf, options = {}) {
|
|
|
21
21
|
const objects = []
|
|
22
22
|
gltf.scene.traverse((child) => objects.push(child))
|
|
23
23
|
|
|
24
|
+
// Detect skinned meshes — these need per-instance cloning
|
|
25
|
+
const hasSkinnedMeshes = objects.some((o) => o.isSkinnedMesh)
|
|
26
|
+
|
|
24
27
|
// Browse for duplicates
|
|
25
28
|
const duplicates = {
|
|
26
29
|
names: {},
|
|
@@ -184,14 +187,15 @@ export function parse(fileName, gltf, options = {}) {
|
|
|
184
187
|
else result += `material={gltf.${node}.material} `
|
|
185
188
|
}
|
|
186
189
|
|
|
187
|
-
if (obj.skeleton)
|
|
190
|
+
if (obj.skeleton)
|
|
191
|
+
result += `skeleton={${hasSkinnedMeshes ? `clonedNodes${sanitizeName(obj.name)}` : `gltf.${node}`}.skeleton} `
|
|
188
192
|
if (obj.visible === false) result += `visible={false} `
|
|
189
193
|
if (obj.castShadow === true) result += `castShadow `
|
|
190
194
|
if (obj.receiveShadow === true) result += `receiveShadow `
|
|
191
195
|
if (obj.morphTargetDictionary)
|
|
192
|
-
result += `morphTargetDictionary={gltf.${node}.morphTargetDictionary} `
|
|
196
|
+
result += `morphTargetDictionary={${hasSkinnedMeshes ? `clonedNodes${sanitizeName(obj.name)}` : `gltf.${node}`}.morphTargetDictionary} `
|
|
193
197
|
if (obj.morphTargetInfluences)
|
|
194
|
-
result += `morphTargetInfluences={gltf.${node}.morphTargetInfluences} `
|
|
198
|
+
result += `morphTargetInfluences={${hasSkinnedMeshes ? `clonedNodes${sanitizeName(obj.name)}` : `gltf.${node}`}.morphTargetInfluences} `
|
|
195
199
|
if (obj.intensity && rNbr(obj.intensity)) result += `intensity={${rNbr(obj.intensity)}} `
|
|
196
200
|
//if (obj.power && obj.power !== 4 * Math.PI) result += `power={${rNbr(obj.power)}} `
|
|
197
201
|
if (obj.angle && obj.angle !== Math.PI / 3) result += `angle={${rDeg(obj.angle)}} `
|
|
@@ -402,7 +406,7 @@ export function parse(fileName, gltf, options = {}) {
|
|
|
402
406
|
|
|
403
407
|
// Bail out on lights and bones
|
|
404
408
|
if (type === 'bone') {
|
|
405
|
-
return `<T is={gltf.${node}} />\n`
|
|
409
|
+
return `<T is={${hasSkinnedMeshes ? `clonedNodes${sanitizeName(obj.name)}` : `gltf.${node}`}} />\n`
|
|
406
410
|
}
|
|
407
411
|
|
|
408
412
|
// Collect children
|
|
@@ -495,6 +499,7 @@ export function parse(fileName, gltf, options = {}) {
|
|
|
495
499
|
const imports = `
|
|
496
500
|
${options.types ? `\nimport type * as THREE from 'three'` : ''}
|
|
497
501
|
${hasAnimations ? `import { Group } from 'three'` : ''}
|
|
502
|
+
${hasSkinnedMeshes ? `import { clone as cloneSkeleton } from 'three/examples/jsm/utils/SkeletonUtils.js'` : ''}
|
|
498
503
|
${options.types ? `import type { Snippet } from 'svelte'` : ''}
|
|
499
504
|
import { ${['T', options.types && !options.isolated ? 'type Props' : '']
|
|
500
505
|
.filter(Boolean)
|
|
@@ -575,6 +580,19 @@ ${
|
|
|
575
580
|
|
|
576
581
|
${!options.preload ? `const gltf = ${useGltf}` : 'const gltf = load()'}
|
|
577
582
|
|
|
583
|
+
${
|
|
584
|
+
hasSkinnedMeshes
|
|
585
|
+
? `function cloneScene(scene${options.types ? ': THREE.Group' : ''}) {
|
|
586
|
+
const clone = cloneSkeleton(scene)
|
|
587
|
+
const nodes${options.types ? ': Record<string, THREE.Object3D>' : ''} = {}
|
|
588
|
+
clone.traverse((child) => {
|
|
589
|
+
if (child.name) nodes[child.name] = child
|
|
590
|
+
})
|
|
591
|
+
return nodes${options.types ? ' as unknown as GLTFResult["nodes"]' : ''}
|
|
592
|
+
}`
|
|
593
|
+
: ''
|
|
594
|
+
}
|
|
595
|
+
|
|
578
596
|
${
|
|
579
597
|
hasAnimations
|
|
580
598
|
? `export const { actions, mixer } = useGltfAnimations${
|
|
@@ -588,6 +606,7 @@ ${
|
|
|
588
606
|
{#await gltf}
|
|
589
607
|
{@render fallback?.()}
|
|
590
608
|
{:then gltf}
|
|
609
|
+
${hasSkinnedMeshes ? '{@const clonedNodes = cloneScene(gltf.scene)}' : ''}
|
|
591
610
|
${scene}
|
|
592
611
|
{:catch err}
|
|
593
612
|
{@render error?.({ error: err })}
|