-
-
Notifications
You must be signed in to change notification settings - Fork 312
/
gltfjsx.js
executable file
·89 lines (81 loc) · 2.89 KB
/
gltfjsx.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import 'jsdom-global'
import fs from 'fs'
import path from 'path'
import transform from './utils/transform.js'
import { GLTFLoader } from './bin/GLTFLoader.js'
import { DRACOLoader } from './bin/DRACOLoader.js'
DRACOLoader.getDecoderModule = () => {}
import parse from './utils/parser.js'
const gltfLoader = new GLTFLoader()
gltfLoader.setDRACOLoader(new DRACOLoader())
function toArrayBuffer(buf) {
var ab = new ArrayBuffer(buf.length)
var view = new Uint8Array(ab)
for (var i = 0; i < buf.length; ++i) view[i] = buf[i]
return ab
}
function roundOff(value) {
return Math.round(value * 100) / 100
}
function getFileSize(file) {
const stats = fs.statSync(file)
let fileSize = stats.size
let fileSizeKB = roundOff(fileSize * 0.001)
let fileSizeMB = roundOff(fileSizeKB * 0.001)
return {
size: fileSizeKB > 1000 ? `${fileSizeMB}MB` : `${fileSizeKB}KB`,
sizeKB: fileSizeKB,
}
}
export default function (file, output, options) {
function getRelativeFilePath(file) {
const filePath = path.resolve(file)
const rootPath = options.root ? path.resolve(options.root) : path.dirname(file)
const relativePath = path.relative(rootPath, filePath) || ''
if (process.platform === 'win32') return relativePath.replace(/\\/g, '/')
return relativePath
}
return new Promise((resolve, reject) => {
async function run(stream) {
let size = ''
// Process GLTF
if (output && path.parse(output).ext === '.tsx') options.types = true
if (options.transform || options.instance || options.instanceall) {
const { name } = path.parse(file)
const outputDir = path.parse(path.resolve(output ?? file)).dir
const transformOut = path.join(outputDir, name + '-transformed.glb')
await transform(file, transformOut, options)
const { size: sizeOriginal, sizeKB: sizeKBOriginal } = getFileSize(file)
const { size: sizeTransformed, sizeKB: sizeKBTransformed } = getFileSize(transformOut)
size = `${file} [${sizeOriginal}] > ${transformOut} [${sizeTransformed}] (${Math.round(
100 - (sizeKBTransformed / sizeKBOriginal) * 100
)}%)`
file = transformOut
}
const filePath = getRelativeFilePath(file)
const data = fs.readFileSync(file)
const arrayBuffer = toArrayBuffer(data)
gltfLoader.parse(
arrayBuffer,
'',
async (gltf) => {
const output = await parse(gltf, { fileName: filePath, size, ...options })
if (options.console) console.log(output)
else stream?.write(output)
stream?.end()
resolve()
},
(reason) => console.log(reason)
)
}
if (options.console) {
run()
} else {
const stream = fs.createWriteStream(path.resolve(output))
stream.once('open', async () => {
if (!fs.existsSync(file)) reject(file + ' does not exist.')
else run(stream)
})
}
})
}