-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathPL00R03.test.ts
110 lines (92 loc) · 3.5 KB
/
PL00R03.test.ts
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
/**
Miku-Legends-2
Copyright (C) 2024, DashGL Project
By Kion (kion@dashgl.com)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**/
import { test, expect } from "bun:test";
import { readFileSync, writeFileSync } from "fs";
import ByteReader from "../src/ByteReader";
import { readVertexList, readFace } from "../src/MeshReader";
type MeshHeader = {
triCount: number;
quadCount: number;
vertCount: number;
triOfs: number;
quadOfs: number;
vertOfs: number;
vertexColorOfs: number;
vertexColorBkOfs: number;
};
// Looks like this is actually the blade arm?
test("it should export an obj of the Buster Cannon", () => {
const filename = "PL00R03";
const file = readFileSync(`./bin/wpn_${filename}.BIN`).subarray(0x2000);
const type = file.readUInt32LE(0x00);
const length = file.readUInt32LE(0x04);
const something = file.readUInt32LE(0x08);
const memory = file.readUInt32LE(0x0c);
expect(type).toEqual(1);
expect(length).toEqual(0x6a8);
expect(something).toEqual(1);
expect(memory).toEqual(0x80113340);
const header = file.subarray(0x30);
const strips: MeshHeader[] = [];
let ofs = 0;
const localPointerDiff = 0x2b40;
for (let i = 0; i < 3; i++) {
const triCount = header.readUInt8(ofs + 0);
const quadCount = header.readUInt8(ofs + 1);
const vertCount = header.readUInt8(ofs + 2);
const triOfs = header.readUInt32LE(ofs + 0x04) - localPointerDiff;
const quadOfs = header.readUInt32LE(ofs + 0x08) - localPointerDiff;
const vertOfs = header.readUInt32LE(ofs + 0x0c) - localPointerDiff;
const vertexColorOfs = header.readUInt32LE(ofs + 0x10) - localPointerDiff;
const vertexColorBkOfs = header.readUInt32LE(ofs + 0x14) - localPointerDiff;
ofs += 0x18;
strips.push({
triCount,
quadCount,
vertCount,
triOfs,
quadOfs,
vertOfs,
vertexColorOfs,
vertexColorBkOfs,
});
}
const { buffer } = Buffer.from(header);
const reader = new ByteReader(buffer as ArrayBuffer);
strips.forEach((strip, index) => {
const { vertCount, vertOfs } = strip;
const vertexList = readVertexList(reader, vertOfs, vertCount);
const { triCount, triOfs } = strip;
const triList = readFace(reader, triOfs, triCount, false);
const { quadOfs, quadCount } = strip;
const quadList = readFace(reader, quadOfs, quadCount, true);
const obj: string[] = [];
vertexList.forEach(({ x, y, z }) => {
obj.push(`v ${x.toFixed(3)} ${y.toFixed(3)} ${z.toFixed(3)}`);
});
triList.forEach((face) => {
const [a, b, c] = face;
obj.push(`f ${a.index + 1} ${b.index + 1} ${c.index + 1}`);
});
quadList.forEach((face) => {
const [a, b, c, d] = face;
obj.push(`f ${a.index + 1} ${b.index + 1} ${d.index + 1} ${c.index + 1}`);
});
const name = index.toString().padStart(3, "0");
writeFileSync(`./fixtures/${filename}/${name}.OBJ`, obj.join("\n"));
});
console.log("Offset: 0x%s", ofs.toString(16));
});