-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathPL00P010.test.ts
128 lines (109 loc) · 3.3 KB
/
PL00P010.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/**
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 {
type MeshHeader,
readStrips,
readVertexList,
readFace,
} from "../src/MeshReader";
import ByteReader from "../src/ByteReader";
test("It should encode an obj with hair and normal shoes", () => {
const filename = "PL00P010";
const file = readFileSync(`./bin/${filename}.BIN`);
const dat = file.subarray(0x30, 0x30 + 0x2b40);
const { buffer } = Buffer.from(dat);
const reader = new ByteReader(buffer as ArrayBuffer);
const LIMBS = [
// Body
{
offset: 0x80,
names: [
"00_BODY",
"01_HIP",
"02_LEG_RIGHT_TOP",
"03_LEG_RIGHT_BOTTOM",
"04_LEG_LEFT_TOP",
"05_LEG_LEFT_BOTTOM",
],
},
// Head
{
offset: 0xb60,
names: ["10_HELMET", "11_FACE", "12_MOUTH"],
},
// Feet
{
offset: 0x1800,
names: ["20_NORM_RIGHT_FOOT", "21_NORM_LEFT_FOOT"],
},
// Left Arm
{
offset: 0x1dd0,
names: ["30_LEFT_SHOULDER", "31_LEFT_ARM", "32_LEFT_HAND"],
},
// Buster
{
offset: 0x2220,
names: ["40_LEFT_SHOULDER", "41_BUSTER", "42_BULLET_MAYBE"],
},
// Right Arm
{
offset: 0x26f0,
names: ["50_RIGHT_SHOULDER", "51_RIGHT_ARM", "52_RIGHT_HAND"],
},
// End Limbs
];
const strips: MeshHeader[] = [];
// Goto each limb offset
LIMBS.forEach(({ offset, names }) => {
readStrips(reader, offset, names).forEach((s) => {
strips.push(s);
});
});
strips.forEach(
({ name, triCount, quadCount, vertCount, triOfs, quadOfs, vertOfs }) => {
const vertices = readVertexList(reader, vertOfs, vertCount);
const tris = readFace(reader, triOfs, triCount, false);
const quads = readFace(reader, quadOfs, quadCount, true);
const obj: string[] = [];
vertices.forEach(({ x, y, z }) => {
obj.push(`v ${x.toFixed(3)} ${y.toFixed(3)} ${z.toFixed(3)}`);
});
tris.forEach((face) => {
const [a, b, c] = face;
obj.push(`f ${a.index + 1} ${b.index + 1} ${c.index + 1}`);
});
quads.forEach((face) => {
const [a, b, c, d] = face;
obj.push(
`f ${a.index + 1} ${b.index + 1} ${d.index + 1} ${c.index + 1}`,
);
});
writeFileSync(`./fixtures/${filename}/${name}.OBJ`, obj.join("\n"));
},
);
const shoulderA = readFileSync(
`./fixtures/${filename}/30_LEFT_SHOULDER.OBJ`,
"utf8",
);
const shoulderB = readFileSync(
`./fixtures/${filename}/40_LEFT_SHOULDER.OBJ`,
"utf8",
);
expect(shoulderA).toEqual(shoulderB);
});