This repository has been archived by the owner on Sep 26, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 13
/
NGP.bt
208 lines (179 loc) · 4.73 KB
/
NGP.bt
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
//------------------------------------------------
//--- 010 Editor v9.0.2 Binary Template
//
// File: NGP.bt
// Authors: TKGP
// Version:
// Purpose: DS2, something to do with navmeshes
// Category: Katana
// File Mask: *.ngp
// ID Bytes: 4E 56 47 32
// History:
//------------------------------------------------
#include "Util.bt"
LittleEndian();
if (ReadShort(4) == 0x100)
BigEndian();
local int VARINT_LONG = ReadShort(4) == 2;
//------------------------------------------------
typedef struct {
char magic[4]; Assert(magic == "NVG2");
short version; Assert(version == 1 || version == 2);
short unk06; Assert(unk06 == 0);
int meshCount;
int count0C;
int count10;
int count14;
int count18;
int unk1C; // Low 3 bytes always FF
Varint offset20 <format=hex>;
Varint offset28 <format=hex>;
Varint offset30 <format=hex>;
Varint offset38 <format=hex>;
Varint meshOffsets[meshCount] <optimize=true>;
} Header <bgcolor=cLtRed>;
typedef struct {
Vector3 unk00;
float unk0C;
int unk10;
short unk14;
short unk16;
short unk18;
short unk1A;
short unk1C;
short unk1E;
short unk20;
short unk22;
} StructA <bgcolor=cLtGreen>;
typedef struct {
int unk00;
int unk04;
int unk08;
} StructB <bgcolor=cAqua>;
typedef struct {
short unk00;
short unk02;
} StructC <bgcolor=cLtBlue>;
typedef struct {
short unk00;
} StructD <bgcolor=cYellow>;
typedef struct {
short v1;
short v2;
short v3;
short unk06; // Index of E4, but sometimes short.MinValue + n
short unk08;
short unk0A;
} Face;
typedef struct {
short unk00;
short unk02;
short unk04;
short unk06;
short unk08;
short unk0A;
short unk0C;
short unk0E;
} StructE4;
struct StructE5;
typedef struct (quad rootOffset, quad dataOffset) {
float unk00;
short leftIndex;
short rightIndex;
short dataCount;
short dataIndex;
local quad pos <hidden=true> = FTell();
if (leftIndex != -1) {
FSeek(rootOffset + leftIndex * 0xC);
StructE5 left(rootOffset, dataOffset);
}
if (rightIndex != -1) {
FSeek(rootOffset + rightIndex * 0xC);
StructE5 right(rootOffset, dataOffset);
}
if (dataCount > 0) {
FSeek(dataOffset + dataIndex * 2);
ushort data[dataCount];
}
FSeek(pos);
} StructE5 <read=ReadStructE5>;
string ReadStructE5(StructE5& e5) {
string str;
SPrintf(str, "%7.3f %3i %3i %3i %3i",
e5.unk00, e5.leftIndex, e5.rightIndex, e5.dataCount, e5.dataIndex);
return str;
}
typedef struct {
int unk00; // Low 2 bytes always FF
int thisLength <format=hex>;
int unk08;
if (header.version == 2) {
int unk0C <hidden=true>; Assert(unk0C == 0);
}
Vector3 boundingBoxMin;
Vector3 boundingBoxMax;
int vertexCount;
short faceCount;
short count30;
short unk30;
short unk32;
byte unk34; Assert(unk34 == 1);
byte unk35; Assert(unk35 == 0);
byte unk36; Assert(unk36 == 0);
byte unk37; Assert(unk37 == 0);
if (header.version == 2) {
int unk38 <hidden=true>; Assert(unk38 == 0);
int unk3C <hidden=true>; Assert(unk3C == 0);
}
Varint verticesOffset <format=hex>;
Varint offset48 <format=hex>;
Varint facesOffset <format=hex>;
Varint offset58 <format=hex>;
Varint offset60 <format=hex>;
Varint offset68 <format=hex>;
FSeek(verticesOffset.val);
Vector3 vertices[vertexCount] <bgcolor=cBlack>;
// Pad to 8
FSeek(offset48.val);
int unkSection2[faceCount] <bgcolor=cWhite>; // Always just 7s?
// Pad to 8
FSeek(facesOffset.val);
Face faces[faceCount] <bgcolor=cBlack>;
// Pad to 8
FSeek(offset58.val);
StructE4 unkSection4[count30] <bgcolor=cWhite>;
// Pad to 8
FSeek(offset60.val);
StructE5 rootStructE5(offset60.val, offset68.val) <bgcolor=cBlack>;
// Pad to 8
// FSeek(offset68.val);
// Data for E5
// Pad to 8
} Mesh <bgcolor=cLtPurple>;
//------------------------------------------------
Header header;
if (header.count0C > 0) {
FSeek(header.offset20.val);
StructA structAs[header.count0C];
}
if (header.count10 > 0) {
FSeek(header.offset28.val);
StructB structBs[header.count10];
}
if (header.count14 > 0) {
FSeek(header.offset30.val);
StructC structCs[header.count14];
}
if (header.count18 > 0) {
FSeek(header.offset38.val);
StructD structDs[header.count18];
}
// Just so 010 doesn't complain about struct ending before it started on DX9 files
FSeek(header.meshOffsets[0].val);
struct {
local int i <hidden=true>;
for (i = 0; i < header.meshCount; i++) {
FSeek(header.meshOffsets[i].val);
Mesh meshes;
}
} meshes;