@threlte/gltf 0.0.5 → 1.0.0-next.1
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 +12 -0
- package/cli.js +25 -8
- package/package.json +1 -1
- package/readme.md +11 -11
- package/src/index.js +2 -2
- package/src/utils/parser.js +50 -22
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @threlte/gltf
|
|
2
2
|
|
|
3
|
+
## 1.0.0-next.1
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 72c71414: Added option to add a preload method that makes preloading an asset easy. Also, added the option to make an isolated component (so no \$\$restProps usage)
|
|
8
|
+
|
|
9
|
+
## 1.0.0-next.0
|
|
10
|
+
|
|
11
|
+
### Major Changes
|
|
12
|
+
|
|
13
|
+
- 3a5376e2: Adapted gltf package to Threlte 6 T syntax
|
|
14
|
+
|
|
3
15
|
## 0.0.5
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/cli.js
CHANGED
|
@@ -12,19 +12,21 @@ const __dirname = dirname(__filename)
|
|
|
12
12
|
|
|
13
13
|
const cli = meow(
|
|
14
14
|
`
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
Usage
|
|
16
|
+
$ npx @threlte/gltf [Model.glb] [options]
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
Options
|
|
19
19
|
--output, -o Output file name/path
|
|
20
20
|
--types, -t Add Typescript definitions
|
|
21
21
|
--keepnames, -k Keep original names
|
|
22
22
|
--keepgroups, -K Keep (empty) groups, disable pruning
|
|
23
23
|
--meta, -m Include metadata (as userData)
|
|
24
|
-
--shadows, s
|
|
25
|
-
--printwidth, w
|
|
24
|
+
--shadows, -s Let meshes cast and receive shadows
|
|
25
|
+
--printwidth, -w Prettier printWidth (default: 120)
|
|
26
26
|
--precision, -p Number of fractional digits (default: 2)
|
|
27
27
|
--draco, -d Draco binary path
|
|
28
|
+
--preload -P Add preload method to module script
|
|
29
|
+
--isolated, -i Output as isolated module (No $$restProps usage)
|
|
28
30
|
--root, -r Sets directory from which .gltf file is served
|
|
29
31
|
--transform, -T Transform the asset for the web (draco, prune, resize)
|
|
30
32
|
--resolution, -R Transform resolution for texture resizing (default: 1024)
|
|
@@ -45,6 +47,8 @@ const cli = meow(
|
|
|
45
47
|
printwidth: { type: 'number', alias: 'p', default: 120 },
|
|
46
48
|
meta: { type: 'boolean', alias: 'm' },
|
|
47
49
|
precision: { type: 'number', alias: 'p', default: 2 },
|
|
50
|
+
isolated: { type: 'boolean', alias: 'i', default: false },
|
|
51
|
+
preload: { type: 'boolean', alias: 'P', default: false },
|
|
48
52
|
draco: { type: 'string', alias: 'd' },
|
|
49
53
|
root: { type: 'string', alias: 'r' },
|
|
50
54
|
transform: { type: 'boolean', alias: 'T' },
|
|
@@ -60,6 +64,15 @@ const cli = meow(
|
|
|
60
64
|
|
|
61
65
|
const { packageJson } = readPackageUpSync({ cwd: __dirname, normalize: false })
|
|
62
66
|
|
|
67
|
+
function toPascalCase(string) {
|
|
68
|
+
return `${string}`
|
|
69
|
+
.toLowerCase()
|
|
70
|
+
.replace(new RegExp(/[-_]+/, 'g'), ' ')
|
|
71
|
+
.replace(new RegExp(/[^\w\s]/, 'g'), '')
|
|
72
|
+
.replace(new RegExp(/\s+(.)(\w*)/, 'g'), ($1, $2, $3) => `${$2.toUpperCase() + $3}`)
|
|
73
|
+
.replace(new RegExp(/\w/), (s) => s.toUpperCase())
|
|
74
|
+
}
|
|
75
|
+
|
|
63
76
|
if (cli.input.length === 0) {
|
|
64
77
|
console.log(cli.help)
|
|
65
78
|
} else {
|
|
@@ -69,16 +82,20 @@ if (cli.input.length === 0) {
|
|
|
69
82
|
Command: npx @threlte/gltf@${packageJson.version} ${process.argv.slice(2).join(' ')}`
|
|
70
83
|
}
|
|
71
84
|
const file = cli.input[0]
|
|
72
|
-
const filePath = path.resolve(__dirname, file)
|
|
73
85
|
let nameExt = file.match(/[-_\w]+[.][\w]+$/i)[0]
|
|
74
86
|
let name = nameExt.split('.').slice(0, -1).join('.')
|
|
75
|
-
const baseName = name.charAt(0).toUpperCase() + name.slice(1)
|
|
87
|
+
const baseName = toPascalCase(name.charAt(0).toUpperCase() + name.slice(1))
|
|
76
88
|
const output = baseName + '.svelte'
|
|
77
89
|
const showLog = (log) => {
|
|
78
90
|
console.info('log:', log)
|
|
79
91
|
}
|
|
80
92
|
try {
|
|
81
|
-
const response = await gltf(file, output,
|
|
93
|
+
const response = await gltf(file, output, baseName, {
|
|
94
|
+
...config,
|
|
95
|
+
showLog,
|
|
96
|
+
timeout: 0,
|
|
97
|
+
delay: 1
|
|
98
|
+
})
|
|
82
99
|
} catch (e) {
|
|
83
100
|
console.error(e)
|
|
84
101
|
}
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -58,20 +58,20 @@ Command: npx gltfjsx@0.0.1 ./stacy.glb
|
|
|
58
58
|
-->
|
|
59
59
|
<script>
|
|
60
60
|
import { Group } from 'three'
|
|
61
|
-
import { T
|
|
61
|
+
import { T } from '@threlte/core'
|
|
62
62
|
import { useGltf, useGltfAnimations } from '@threlte/extras'
|
|
63
63
|
|
|
64
64
|
export const ref = new Group()
|
|
65
65
|
|
|
66
|
-
const
|
|
66
|
+
const gltf = useGltf('/stacy.glb')
|
|
67
67
|
export const { actions, mixer } = useGltfAnimations(gltf, ref)
|
|
68
68
|
</script>
|
|
69
69
|
|
|
70
70
|
{#if $gltf}
|
|
71
|
-
<
|
|
71
|
+
<T is={ref} {...$$restProps}>
|
|
72
72
|
<T.Group name="Scene">
|
|
73
73
|
<T.Group name="Stacy" rotation={[Math.PI / 2, 0, 0]} scale={0.01}>
|
|
74
|
-
<
|
|
74
|
+
<T is={$gltf.nodes.mixamorigHips} />
|
|
75
75
|
<T.SkinnedMesh
|
|
76
76
|
name="stacy"
|
|
77
77
|
geometry={$gltf.nodes.stacy.geometry}
|
|
@@ -84,7 +84,7 @@ Command: npx gltfjsx@0.0.1 ./stacy.glb
|
|
|
84
84
|
</T.Group>
|
|
85
85
|
|
|
86
86
|
<slot {ref} />
|
|
87
|
-
</
|
|
87
|
+
</T>
|
|
88
88
|
{/if}
|
|
89
89
|
```
|
|
90
90
|
|
|
@@ -161,7 +161,7 @@ Command: npx gltfjsx@0.0.1 ./stacy.glb -t
|
|
|
161
161
|
<script lang="ts">
|
|
162
162
|
import type * as THREE from 'three'
|
|
163
163
|
import { Group } from 'three'
|
|
164
|
-
import { T,
|
|
164
|
+
import { T, type Props, type Events, type Slots } from '@threlte/core'
|
|
165
165
|
import { useGltf, useGltfAnimations } from '@threlte/extras'
|
|
166
166
|
|
|
167
167
|
type $$Props = Props<THREE.Group>
|
|
@@ -179,15 +179,15 @@ Command: npx gltfjsx@0.0.1 ./stacy.glb -t
|
|
|
179
179
|
materials: {}
|
|
180
180
|
}
|
|
181
181
|
|
|
182
|
-
const
|
|
182
|
+
const gltf = useGltf<GLTFResult>('/stacy.glb')
|
|
183
183
|
export const { actions, mixer } = useGltfAnimations<ActionName>(gltf, ref)
|
|
184
184
|
</script>
|
|
185
185
|
|
|
186
186
|
{#if $gltf}
|
|
187
|
-
<
|
|
187
|
+
<T is={ref} {...$$restProps}>
|
|
188
188
|
<T.Group name="Scene">
|
|
189
189
|
<T.Group name="Stacy" rotation={[Math.PI / 2, 0, 0]} scale={0.01}>
|
|
190
|
-
<
|
|
190
|
+
<T is={$gltf.nodes.mixamorigHips} />
|
|
191
191
|
<T.SkinnedMesh
|
|
192
192
|
name="stacy"
|
|
193
193
|
geometry={$gltf.nodes.stacy.geometry}
|
|
@@ -200,7 +200,7 @@ Command: npx gltfjsx@0.0.1 ./stacy.glb -t
|
|
|
200
200
|
</T.Group>
|
|
201
201
|
|
|
202
202
|
<slot {ref} />
|
|
203
|
-
</
|
|
203
|
+
</T>
|
|
204
204
|
{/if}
|
|
205
205
|
```
|
|
206
206
|
|
|
@@ -209,7 +209,7 @@ Command: npx gltfjsx@0.0.1 ./stacy.glb -t
|
|
|
209
209
|
If your GLTF contains animations it will add [@threlte/extras's `useGltfAnimations`](https://threlte.xyz/extras/use-gltf-animations) hook, which extracts all clips and prepares them as actions:
|
|
210
210
|
|
|
211
211
|
```svelte
|
|
212
|
-
const
|
|
212
|
+
const gltf = useGltf('/stacy.glb')
|
|
213
213
|
export const { actions, mixer } = useGltfAnimations(gltf, ref)
|
|
214
214
|
```
|
|
215
215
|
|
package/src/index.js
CHANGED
|
@@ -22,7 +22,7 @@ function toArrayBuffer(buf) {
|
|
|
22
22
|
return ab
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
export default function (file, output, options) {
|
|
25
|
+
export default function (file, output, baseName, options) {
|
|
26
26
|
function getRelativeFilePath(file) {
|
|
27
27
|
const filePath = path.resolve(file)
|
|
28
28
|
const rootPath = options.root ? path.resolve(options.root) : path.dirname(file)
|
|
@@ -53,7 +53,7 @@ export default function (file, output, options) {
|
|
|
53
53
|
arrayBuffer,
|
|
54
54
|
'',
|
|
55
55
|
(gltf) => {
|
|
56
|
-
const raw = parse(filePath, gltf, options)
|
|
56
|
+
const raw = parse(filePath, baseName, gltf, options)
|
|
57
57
|
try {
|
|
58
58
|
const prettiered = prettier.format(raw, {
|
|
59
59
|
semi: false,
|
package/src/utils/parser.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import THREE from 'three'
|
|
2
2
|
import isVarName from './isVarName.js'
|
|
3
3
|
|
|
4
|
-
function parse(fileName, gltf, options = {}) {
|
|
4
|
+
function parse(fileName, baseName, gltf, options = {}) {
|
|
5
5
|
const url = (fileName.toLowerCase().startsWith('http') ? '' : '/') + fileName
|
|
6
6
|
const animations = gltf.animations
|
|
7
7
|
const hasAnimations = animations.length > 0
|
|
@@ -374,7 +374,7 @@ function parse(fileName, gltf, options = {}) {
|
|
|
374
374
|
|
|
375
375
|
// Bail out on lights and bones
|
|
376
376
|
if (type === 'bone') {
|
|
377
|
-
return `<
|
|
377
|
+
return `<T is={$gltf.${node}} />\n`
|
|
378
378
|
}
|
|
379
379
|
|
|
380
380
|
// Collect children
|
|
@@ -467,6 +467,22 @@ function parse(fileName, gltf, options = {}) {
|
|
|
467
467
|
}
|
|
468
468
|
: undefined
|
|
469
469
|
|
|
470
|
+
const imports = `
|
|
471
|
+
${options.types ? `\nimport type * as THREE from 'three'` : ''}
|
|
472
|
+
import { Group } from 'three'
|
|
473
|
+
import { ${[
|
|
474
|
+
'T',
|
|
475
|
+
options.types && !options.isolated ? 'type Props, type Events, type Slots' : ''
|
|
476
|
+
].join(', ')} } from '@threlte/core'
|
|
477
|
+
import { ${['useGltf', hasAnimations ? 'useGltfAnimations' : ''].join(
|
|
478
|
+
', '
|
|
479
|
+
)} } from '@threlte/extras'
|
|
480
|
+
`
|
|
481
|
+
|
|
482
|
+
const useGltf = `useGltf${options.types ? '<GLTFResult>' : ''}('${url}'${
|
|
483
|
+
useGltfOptions ? `, ${JSON.stringify(useGltfOptions)}` : ''
|
|
484
|
+
})`
|
|
485
|
+
|
|
470
486
|
// Output
|
|
471
487
|
return `
|
|
472
488
|
<!--
|
|
@@ -477,29 +493,41 @@ ${
|
|
|
477
493
|
}
|
|
478
494
|
${parseExtras(gltf.parser.json.asset && gltf.parser.json.asset.extras)}-->
|
|
479
495
|
|
|
480
|
-
|
|
496
|
+
${
|
|
497
|
+
options.preload
|
|
498
|
+
? `
|
|
481
499
|
|
|
500
|
+
<script context="module"${options.types ? ' lang="ts"' : ''}>
|
|
501
|
+
${imports}
|
|
482
502
|
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
503
|
+
${options.types ? printThrelteTypes(objects, animations) : ''}
|
|
504
|
+
|
|
505
|
+
const load = () => {
|
|
506
|
+
return ${useGltf}
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
export const preload${baseName} = () => {
|
|
510
|
+
load()
|
|
511
|
+
}
|
|
512
|
+
</script>
|
|
513
|
+
`
|
|
514
|
+
: ''
|
|
515
|
+
}
|
|
491
516
|
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
517
|
+
|
|
518
|
+
<script${options.types ? ' lang="ts"' : ''}>
|
|
519
|
+
|
|
520
|
+
${!options.preload ? imports : ''}
|
|
521
|
+
|
|
522
|
+
${options.types && !options.isolated ? 'type $$Props = Props<THREE.Group>' : ''}
|
|
523
|
+
${options.types && !options.isolated ? 'type $$Events = Events<THREE.Group>' : ''}
|
|
524
|
+
${options.types && !options.isolated ? 'type $$Slots = Slots<THREE.Group>' : ''}
|
|
495
525
|
|
|
496
526
|
export const ref = new Group()
|
|
497
527
|
|
|
498
|
-
${options.types ? printThrelteTypes(objects, animations) : ''}
|
|
528
|
+
${options.types && !options.preload ? printThrelteTypes(objects, animations) : ''}
|
|
499
529
|
|
|
500
|
-
const
|
|
501
|
-
useGltfOptions ? `, ${JSON.stringify(useGltfOptions)}` : ''
|
|
502
|
-
})
|
|
530
|
+
${!options.preload ? `const gltf = ${useGltf}` : 'const gltf = load()'}
|
|
503
531
|
${
|
|
504
532
|
hasAnimations
|
|
505
533
|
? `export const { actions, mixer } = useGltfAnimations${
|
|
@@ -511,13 +539,13 @@ ${parseExtras(gltf.parser.json.asset && gltf.parser.json.asset.extras)}-->
|
|
|
511
539
|
</script>
|
|
512
540
|
|
|
513
541
|
{#if $gltf}
|
|
514
|
-
|
|
542
|
+
<T is={ref} dispose={false} ${!options.isolated ? '{...$$restProps}' : ''}>
|
|
515
543
|
${scene}
|
|
516
544
|
|
|
517
545
|
<slot {ref} />
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
546
|
+
</T>
|
|
547
|
+
{/if}
|
|
548
|
+
`
|
|
521
549
|
}
|
|
522
550
|
|
|
523
551
|
export default parse
|