Skip to content

Commit c5fa7fd

Browse files
committed
feat: support declarative bones
1 parent a01fca4 commit c5fa7fd

File tree

2 files changed

+28
-20
lines changed

2 files changed

+28
-20
lines changed

cli.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const cli = meow(
2020
--types, -t Add Typescript definitions
2121
--keepnames, -k Keep original names
2222
--keepgroups, -K Keep (empty) groups, disable pruning
23+
--bones, -b Lay out bones declaratively (default: false)
2324
--meta, -m Include metadata (as userData)
2425
--shadows, s Let meshes cast and receive shadows
2526
--printwidth, w Prettier printWidth (default: 120)
@@ -47,6 +48,7 @@ const cli = meow(
4748
types: { type: 'boolean', shortFlag: 't' },
4849
keepnames: { type: 'boolean', shortFlag: 'k' },
4950
keepgroups: { type: 'boolean', shortFlag: 'K' },
51+
bones: { type: 'boolean', shortFlag: 'b', default: false },
5052
shadows: { type: 'boolean', shortFlag: 's' },
5153
printwidth: { type: 'number', shortFlag: 'p', default: 1000 },
5254
meta: { type: 'boolean', shortFlag: 'm' },
@@ -61,7 +63,7 @@ const cli = meow(
6163
degraderesolution: { type: 'number', shortFlag: 'Q', default: 512 },
6264
simplify: { type: 'boolean', shortFlag: 'S', default: false },
6365
keepmeshes: { type: 'boolean', shortFlag: 'j', default: false },
64-
keepmaterials: { type: 'boolean', shortFlag: 'M', default: false },
66+
keepmaterials: { type: 'boolean', shortFlag: 'M', default: false },
6567
format: { type: 'string', shortFlag: 'f', default: 'webp' },
6668
exportdefault: { type: 'boolean', shortFlag: 'E' },
6769
weld: { type: 'number', default: 0.0001 },

src/utils/parser.js

+25-19
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ function parse(gltf, { fileName = 'model', ...options } = {}) {
109109
const types = [...new Set([...meshes, ...bones].map((o) => getType(o)))]
110110
const contextType = `type ContextType = Record<string, React.ForwardRefExoticComponent<
111111
${types.map((type) => `JSX.IntrinsicElements['${type}']`).join(' | ')}
112-
>>`;
112+
>>`
113113

114114
return `\ntype GLTFResult = GLTF & {
115115
nodes: {
@@ -339,7 +339,7 @@ function parse(gltf, { fileName = 'model', ...options } = {}) {
339339
}
340340

341341
// Bail out on lights and bones
342-
if (type === 'bone') {
342+
if (!options.bones && type === 'bone') {
343343
return `<primitive object={${node}} />`
344344
}
345345

@@ -356,7 +356,8 @@ function parse(gltf, { fileName = 'model', ...options } = {}) {
356356
result = `<instancedMesh args={[${geo}, ${mat}, ${!obj.count ? `${node}.count` : obj.count}]} `
357357
} else {
358358
// Form the object in JSX syntax
359-
result = `<${type} `
359+
if (type === 'bone') result = `<primitive object={${node}} `
360+
else result = `<${type} `
360361
}
361362
}
362363

@@ -374,7 +375,10 @@ function parse(gltf, { fileName = 'model', ...options } = {}) {
374375
result += `${children.length ? '>' : '/>'}\n`
375376

376377
// Add children and return
377-
if (children.length) result += children + `</${type}>`
378+
if (children.length) {
379+
if (type === 'bone') result += children + `</primitive>`
380+
else result += children + `</${type}>`
381+
}
378382
return result
379383
}
380384

@@ -445,8 +449,8 @@ ${parseExtras(gltf.parser.json.asset && gltf.parser.json.asset.extras)}*/`
445449
const result = `${options.types ? `\nimport * as THREE from 'three'` : ''}
446450
import React, { useRef ${hasInstances ? ', useMemo, useContext, createContext' : ''} } from 'react'
447451
import { useGLTF, ${hasInstances ? 'Merged, ' : ''} ${
448-
scene.includes('PerspectiveCamera') ? 'PerspectiveCamera,' : ''
449-
}
452+
scene.includes('PerspectiveCamera') ? 'PerspectiveCamera,' : ''
453+
}
450454
${scene.includes('OrthographicCamera') ? 'OrthographicCamera,' : ''}
451455
${hasAnimations ? 'useAnimations' : ''} } from '@react-three/drei'
452456
${options.types ? 'import { GLTF } from "three-stdlib"' : ''}
@@ -458,16 +462,18 @@ ${parseExtras(gltf.parser.json.asset && gltf.parser.json.asset.extras)}*/`
458462
const context = createContext(${options.types ? '{} as ContextType' : ''})
459463
export function Instances({ children, ...props }${options.types ? ': JSX.IntrinsicElements["group"]' : ''}) {
460464
const { nodes } = useGLTF('${url}'${options.draco ? `, ${JSON.stringify(options.draco)}` : ''})${
461-
options.types ? ' as GLTFResult' : ''
462-
}
465+
options.types ? ' as GLTFResult' : ''
466+
}
463467
const instances = useMemo(() => ({
464468
${Object.values(duplicates.geometries)
465469
.map((v) => `${v.name}: ${v.node}`)
466470
.join(', ')}
467471
}), [nodes])
468472
return (
469473
<Merged meshes={instances} {...props}>
470-
{(instances${options.types ? ': ContextType' : ''}) => <context.Provider value={instances} children={children} />}
474+
{(instances${
475+
options.types ? ': ContextType' : ''
476+
}) => <context.Provider value={instances} children={children} />}
471477
</Merged>
472478
)
473479
}
@@ -476,17 +482,17 @@ ${parseExtras(gltf.parser.json.asset && gltf.parser.json.asset.extras)}*/`
476482
}
477483
478484
export ${options.exportdefault ? 'default' : ''} function Model(props${
479-
options.types ? ": JSX.IntrinsicElements['group']" : ''
480-
}) {
485+
options.types ? ": JSX.IntrinsicElements['group']" : ''
486+
}) {
481487
${hasInstances ? 'const instances = useContext(context);' : ''} ${
482-
hasAnimations ? `const group = ${options.types ? 'useRef<THREE.Group>()' : 'useRef()'};` : ''
483-
} ${
484-
!options.instanceall
485-
? `const { nodes, materials${hasAnimations ? ', animations' : ''} } = useGLTF('${url}'${
486-
options.draco ? `, ${JSON.stringify(options.draco)}` : ''
487-
})${options.types ? ' as GLTFResult' : ''}`
488-
: ''
489-
} ${printAnimations(animations)}
488+
hasAnimations ? `const group = ${options.types ? 'useRef<THREE.Group>()' : 'useRef()'};` : ''
489+
} ${
490+
!options.instanceall
491+
? `const { nodes, materials${hasAnimations ? ', animations' : ''} } = useGLTF('${url}'${
492+
options.draco ? `, ${JSON.stringify(options.draco)}` : ''
493+
})${options.types ? ' as GLTFResult' : ''}`
494+
: ''
495+
} ${printAnimations(animations)}
490496
return (
491497
<group ${hasAnimations ? `ref={group}` : ''} {...props} dispose={null}>
492498
${scene}

0 commit comments

Comments
 (0)