-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathipl2glr.js
executable file
·128 lines (108 loc) · 3.35 KB
/
ipl2glr.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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#!/usr/bin/env node
// https://gtamods.com/wiki/Item_Placement
const fs = require('fs')
const path = require('path')
const child_process = require('child_process')
/*
const Module = require('./dff2glr.js')
Module.onRuntimeInitialized = main
const GTA3 = process.env.GTA3.replace(/\\/g,'')
function readAsset(asset) {
let offset = 2048 * asset.offset
let size = 2048 * asset.size
let f = fs.openSync(GTA3 + '/models/gta3.img', 'r')
let buf = Buffer.alloc(size)
fs.readSync(f, buf, 0, size, offset)
fs.closeSync(f)
return buf
}
function dff2glr(dff, txd) {
let dir = fs.readFileSync(GTA3 + '/models/gta3.dir')
let assets = Module.loadDIR(Module.to_bytes(dir))
let assetDFF = readAsset(Module.findEntry(assets, dff + '.dff'))
let model = Module.loadDFF(Module.to_bytes(assetDFF))
let assetTXD = (txd === 'generic')
? fs.readFileSync(GTA3 + '/models/generic.txd')
: readAsset(Module.findEntry(assets, txd + '.txd'))
let textures = Module.loadTXD(Module.to_bytes(assetTXD))
return Module.printModel(model, textures)
}
*/
function dff2glr(dff, txd) {
return child_process.execFileSync('dff2glr', [dff, txd])
}
function read(fname, cb) {
const lines = fs.readFileSync(fname).toString().split('\n')
let section = null
for (const s of lines) {
const line = s.trim().toLowerCase()
if (line === '' || line[0] === '#') continue
if (section === null) {
section = line
} else if (line === 'end') {
section = null
} else {
cb(section, line)
}
}
}
let txd = {}
const fname = process.argv[2]
const name = path.basename(fname.toLowerCase(), '.ipl')
let ides = [fname.match(/.*\/maps\//) + 'gta3.IDE']
if (process.argv.length > 3) {
ides.push(process.argv[3])
}
for (const ide of ides) {
read(ide, (section, line) => {
if (section === 'objs' || section === 'tobj') {
const row = line.split(', ')
const id = row[0]
const model = row[1]
txd[model] = row[2]
const dist = (row.length > 5) ? row[4] : row[3]
const flags = (section === 'tobj') ? row[row.length-3] : row[row.length-1]
}
})
}
let glr = {}
let nodes = []
let named = {}
function parseItem(section, line) {
if (section === 'inst') {
const [id, model, posX, posY, posZ, scaleX, scaleY, scaleZ, rotX, rotY, rotZ, rotW] = line.split(', ')
if (model.startsWith('lod')) return
if (!glr[model]) {
console.log(model, txd[model])
glr[model] = dff2glr(model, txd[model])
}
let obj = JSON.parse(glr[model])
named = Object.assign(named, obj.named)
let node = obj.scene.nodes[0]
if (node.children && node.children.length > 1) {
for (const child of node.children) {
if (child.name.endsWith('_l0')) { // breakable objects
node = child
break
}
}
}
node.name = model + '.' + id,
node.translation = [Number(posX), Number(posY), Number(posZ)]
node.rotation = [Number(rotX), Number(rotY), Number(rotZ), -Number(rotW)]
node.scale = [Number(scaleX), Number(scaleY), Number(scaleZ)]
nodes.push(node)
}
}
function main() {
read(fname, parseItem)
let model = {
asset: { generator: 'dff2gltf', version: '2.0' },
scene: { nodes: [{
name: name, children: nodes, rotation: [0.5,0.5,0.5,-0.5]
}] },
named: named
}
fs.writeFileSync(name + '.glr', JSON.stringify(model, null, 2))
}
main()