@that-sky-project/that-sky-level 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +504 -0
- package/README.md +34 -0
- package/dist/cli.js +22 -0
- package/docs/img/blender_edit_obj_model.png +0 -0
- package/docs/materials.md +37 -0
- package/level_example/HTNH_Test/HTNH_Test.Objects.level.json +258 -0
- package/level_example/HTNH_Test/HTNH_Test.obj +46 -0
- package/level_example/HTNH_Test/Makefile +11 -0
- package/main.js +218 -0
- package/package.json +23 -0
- package/src/formats/triangleMesh.js +82 -0
- package/src/formats/wavefront.js +148 -0
- package/src/level/adjacency.js +466 -0
- package/src/level/enums/kFieldType.js +8 -0
- package/src/level/enums/kMaterial.js +39 -0
- package/src/level/meshes/levelGeo.js +283 -0
- package/src/level/meshes/levelLod.js +15 -0
- package/src/level/meshes/levelMeshes.js +141 -0
- package/src/level/meshes/levelToc.js +69 -0
- package/src/level/objects/levelObjects.js +683 -0
- package/src/level/objects/levelObjectsJson.js +256 -0
- package/src/meshopt/LICENSE +21 -0
- package/src/meshopt/meshopt_decoder.js +199 -0
- package/src/meshopt/meshopt_encoder.js +221 -0
- package/src/utils/binaryStream.js +806 -0
- package/src/utils/helperClasses.js +110 -0
- package/src/utils/logger.js +14 -0
- package/src/utils/normVec.js +67 -0
- package/src/utils/vector.js +232 -0
- package/webpack.config.js +31 -0
|
@@ -0,0 +1,806 @@
|
|
|
1
|
+
const Long = require("long");
|
|
2
|
+
const { IBinarying } = require("./helperClasses");
|
|
3
|
+
const { Vec3, Vec4 } = require("./vector");
|
|
4
|
+
|
|
5
|
+
class WritableBinaryStream {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.buffer = Buffer.alloc(128);
|
|
8
|
+
this.bitOffset = 0;
|
|
9
|
+
this.cursor = 0;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Reallocate the buffer to meet the addition "advance" byte requirements.
|
|
14
|
+
* @param {number} advance
|
|
15
|
+
*/
|
|
16
|
+
realloc(advance) {
|
|
17
|
+
var newLength = this.buffer.byteLength
|
|
18
|
+
, newBuffer;
|
|
19
|
+
|
|
20
|
+
if (this.bitOffset)
|
|
21
|
+
// When calling this function, bitOffset must be 0; otherwise, the cursor
|
|
22
|
+
// needs to be moved forward.
|
|
23
|
+
this.cursor++;
|
|
24
|
+
|
|
25
|
+
// Reset bit offset.
|
|
26
|
+
this.bitOffset = 0;
|
|
27
|
+
|
|
28
|
+
if (this.cursor + advance <= this.buffer.byteLength)
|
|
29
|
+
return;
|
|
30
|
+
|
|
31
|
+
while (this.cursor + advance > newLength)
|
|
32
|
+
newLength <<= 1;
|
|
33
|
+
|
|
34
|
+
newBuffer = Buffer.alloc(newLength);
|
|
35
|
+
newBuffer.set(this.buffer);
|
|
36
|
+
this.buffer = newBuffer;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Get the total length of written data.
|
|
41
|
+
* @returns {number}
|
|
42
|
+
*/
|
|
43
|
+
getLength() {
|
|
44
|
+
return this.cursor;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Get a copy of written data.
|
|
49
|
+
* @returns {Buffer}
|
|
50
|
+
*/
|
|
51
|
+
data() {
|
|
52
|
+
var data = Buffer.alloc(this.cursor);
|
|
53
|
+
data.set(this.buffer.subarray(0, this.cursor));
|
|
54
|
+
return data;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Reset the buffer of the stream.
|
|
59
|
+
*/
|
|
60
|
+
clear() {
|
|
61
|
+
this.bitOffset = 0;
|
|
62
|
+
this.cursor = 0;
|
|
63
|
+
this.buffer = Buffer.alloc(128);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Write paddings.
|
|
68
|
+
* @param {number} count
|
|
69
|
+
* @param {number} [value]
|
|
70
|
+
*/
|
|
71
|
+
pad(count, value = 0) {
|
|
72
|
+
this.realloc(count);
|
|
73
|
+
this.buffer.fill(value, this.cursor, this.cursor + count);
|
|
74
|
+
this.cursor += count;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Write "value" as a number with "count" bits.
|
|
79
|
+
* @param {number} value
|
|
80
|
+
* @param {number} count
|
|
81
|
+
*/
|
|
82
|
+
writeBits(value, count) {
|
|
83
|
+
if (count < 1 || count > 32)
|
|
84
|
+
return;
|
|
85
|
+
|
|
86
|
+
// Convert to u32.
|
|
87
|
+
value = value >>> 0;
|
|
88
|
+
|
|
89
|
+
var written = 0
|
|
90
|
+
, byte, available, need, take, bits;
|
|
91
|
+
|
|
92
|
+
while (written < count) {
|
|
93
|
+
if (this.bitOffset == 0) {
|
|
94
|
+
// Expand buffer.
|
|
95
|
+
this.realloc(1);
|
|
96
|
+
// Initialize the new byte.
|
|
97
|
+
this.buffer[this.cursor] = 0;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
byte = this.buffer[this.cursor];
|
|
101
|
+
available = 8 - this.bitOffset;
|
|
102
|
+
need = count - written;
|
|
103
|
+
take = need < available ? need : available;
|
|
104
|
+
// Fetch the "take" bit to be written next. (starting from the low bit)
|
|
105
|
+
bits = (value >>> written) & ((1 << take) - 1);
|
|
106
|
+
// Merge to current byte.
|
|
107
|
+
byte |= (bits << this.bitOffset);
|
|
108
|
+
this.buffer[this.cursor] = byte;
|
|
109
|
+
written += take;
|
|
110
|
+
this.bitOffset += take;
|
|
111
|
+
|
|
112
|
+
if (this.bitOffset == 8) {
|
|
113
|
+
this.bitOffset = 0;
|
|
114
|
+
this.cursor++;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Write a Uint8Array-like object to the stream.
|
|
121
|
+
* @param {Uint8Array} buffer
|
|
122
|
+
*/
|
|
123
|
+
writeBytes(buffer) {
|
|
124
|
+
var length = buffer.byteLength;
|
|
125
|
+
|
|
126
|
+
this.realloc(length);
|
|
127
|
+
this.buffer.set(buffer, this.cursor);
|
|
128
|
+
this.cursor += length;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Writes a boolean to the stream.
|
|
133
|
+
* @param {boolean} value
|
|
134
|
+
*/
|
|
135
|
+
writeBool(value) {
|
|
136
|
+
this.writeBits(!!value, 1);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Writes a signed 8-bit integer to the stream.
|
|
141
|
+
* @param {number} value
|
|
142
|
+
*/
|
|
143
|
+
writeInt8(value) {
|
|
144
|
+
this.realloc(1);
|
|
145
|
+
this.buffer.writeInt8(value, this.cursor);
|
|
146
|
+
this.cursor += 1;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Writes an unsigned 8-bit integer to the stream.
|
|
151
|
+
* @param {number} value
|
|
152
|
+
*/
|
|
153
|
+
writeUint8(value) {
|
|
154
|
+
this.realloc(1);
|
|
155
|
+
this.buffer.writeUint8(value, this.cursor);
|
|
156
|
+
this.cursor += 1;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Writes a signed 16-bit integer to the stream.
|
|
161
|
+
* @param {number} value
|
|
162
|
+
*/
|
|
163
|
+
writeInt16(value) {
|
|
164
|
+
this.realloc(2);
|
|
165
|
+
this.buffer.writeInt16LE(value, this.cursor);
|
|
166
|
+
this.cursor += 2;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Writes an unsigned 16-bit integer to the stream.
|
|
171
|
+
* @param {number} value
|
|
172
|
+
*/
|
|
173
|
+
writeUint16(value) {
|
|
174
|
+
this.realloc(2);
|
|
175
|
+
this.buffer.writeUint16LE(value, this.cursor);
|
|
176
|
+
this.cursor += 2;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Writes a signed 32-bit integer to the stream.
|
|
181
|
+
* @param {number} value
|
|
182
|
+
*/
|
|
183
|
+
writeInt32(value) {
|
|
184
|
+
this.realloc(4);
|
|
185
|
+
this.buffer.writeInt32LE(value, this.cursor);
|
|
186
|
+
this.cursor += 4;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Writes an unsigned 32-bit integer to the stream.
|
|
191
|
+
* @param {number} value
|
|
192
|
+
*/
|
|
193
|
+
writeUint32(value) {
|
|
194
|
+
this.realloc(4);
|
|
195
|
+
this.buffer.writeUint32LE(value, this.cursor);
|
|
196
|
+
this.cursor += 4;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Writes a signed 64-bit integer to the stream.
|
|
201
|
+
* @param {Long} value
|
|
202
|
+
*/
|
|
203
|
+
writeInt64(value) {
|
|
204
|
+
this.realloc(8);
|
|
205
|
+
this.buffer.writeInt32LE(value.high, this.cursor);
|
|
206
|
+
this.cursor += 4;
|
|
207
|
+
this.buffer.writeInt32LE(value.low, this.cursor);
|
|
208
|
+
this.cursor += 4;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Writes an unsigned 64-bit integer to the stream.
|
|
213
|
+
* @param {Long} value
|
|
214
|
+
*/
|
|
215
|
+
writeUint64(value) {
|
|
216
|
+
this.realloc(8);
|
|
217
|
+
this.buffer.writeInt32LE(value.high, this.cursor);
|
|
218
|
+
this.cursor += 4;
|
|
219
|
+
this.buffer.writeInt32LE(value.low, this.cursor);
|
|
220
|
+
this.cursor += 4;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Writes a 32-bit, little-endian float to the stream.
|
|
225
|
+
* @param {number} value
|
|
226
|
+
*/
|
|
227
|
+
writeFloat(value) {
|
|
228
|
+
this.realloc(4);
|
|
229
|
+
this.buffer.writeFloatLE(value, this.cursor);
|
|
230
|
+
this.cursor += 4;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Writes a 64-bit, little-endian float to the stream.
|
|
235
|
+
* @param {number} value
|
|
236
|
+
*/
|
|
237
|
+
writeDouble(value) {
|
|
238
|
+
this.realloc(4);
|
|
239
|
+
this.buffer.writeDoubleLE(value, this.cursor);
|
|
240
|
+
this.cursor += 8;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Writes a compressed signed 8-bit integer to the stream.
|
|
245
|
+
* @param {number} value
|
|
246
|
+
* @param {number} min
|
|
247
|
+
* @param {number} max
|
|
248
|
+
*/
|
|
249
|
+
writeCompressedInt8(value, min, max) {
|
|
250
|
+
value = ((value) << 24) >> 24;
|
|
251
|
+
min = ((min | 0) << 24) >> 24;
|
|
252
|
+
max = ((max | 0) << 24) >> 24;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Writes a compressed unsigned 8-bit integer to the stream.
|
|
257
|
+
* @param {number} value
|
|
258
|
+
* @param {number} min
|
|
259
|
+
* @param {number} max
|
|
260
|
+
*/
|
|
261
|
+
writeCompressedUint8(value, min, max) {
|
|
262
|
+
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Writes a compressed signed 32-bit integer to the stream.
|
|
267
|
+
* @param {number} value
|
|
268
|
+
* @param {number} min
|
|
269
|
+
* @param {number} max
|
|
270
|
+
*/
|
|
271
|
+
writeCompressedInt32(value, min, max) {
|
|
272
|
+
value ^= 0x80000000;
|
|
273
|
+
min ^= 0x80000000;
|
|
274
|
+
max ^= 0x80000000;
|
|
275
|
+
this.writeCompressedUint32(value, min, max);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Writes a compressed unsigned 32-bit integer to the stream.
|
|
280
|
+
* @param {number} value
|
|
281
|
+
* @param {number} min
|
|
282
|
+
* @param {number} max
|
|
283
|
+
*/
|
|
284
|
+
writeCompressedUint32(value, min, max) {
|
|
285
|
+
value >>>= 0;
|
|
286
|
+
min >>>= 0;
|
|
287
|
+
max >>>= 0;
|
|
288
|
+
|
|
289
|
+
if (min > max)
|
|
290
|
+
throw new RangeError("min must be less than max.");
|
|
291
|
+
|
|
292
|
+
var width = 32 - Math.clz32(max - min);
|
|
293
|
+
|
|
294
|
+
this.writeBits(value - min, width);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Writes a compressed 32-bit, little-endian float to the stream.
|
|
299
|
+
* @param {number} value
|
|
300
|
+
* @param {number} min
|
|
301
|
+
* @param {number} max
|
|
302
|
+
* @param {number} pivot
|
|
303
|
+
* @param {number} bits
|
|
304
|
+
*/
|
|
305
|
+
writeCompressedFloat(value, min, max, pivot, bits) {
|
|
306
|
+
value = Math.fround(value);
|
|
307
|
+
min = Math.fround(min);
|
|
308
|
+
max = Math.fround(max);
|
|
309
|
+
pivot = Math.fround(pivot);
|
|
310
|
+
|
|
311
|
+
this.writeCompressedDouble(value, min, max, pivot, bits);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Writes a compressed 32-bit, little-endian float to the stream.
|
|
316
|
+
* @param {number} value
|
|
317
|
+
* @param {number} min
|
|
318
|
+
* @param {number} max
|
|
319
|
+
* @param {number} pivot
|
|
320
|
+
* @param {number} bits
|
|
321
|
+
*/
|
|
322
|
+
writeCompressedDouble(value, min, max, pivot, bits) {
|
|
323
|
+
if (min >= max)
|
|
324
|
+
throw new RangeError("min must be less than max");
|
|
325
|
+
if (pivot < min || pivot > max)
|
|
326
|
+
throw new RangeError("pivot must be within [min, max]");
|
|
327
|
+
if (bits < 1 || bits >= 32)
|
|
328
|
+
throw new RangeError("bits must be between 1 and 31");
|
|
329
|
+
|
|
330
|
+
var mask = ((1 << bits) - 1) >>> 0
|
|
331
|
+
, range = max - min
|
|
332
|
+
, pivotCode = Math.trunc(((pivot - min) / range) * mask)
|
|
333
|
+
, code, t;
|
|
334
|
+
|
|
335
|
+
if (value < pivot) {
|
|
336
|
+
// [min, pivot)
|
|
337
|
+
if (pivot - min == 0) {
|
|
338
|
+
// It won't happen.
|
|
339
|
+
code = 0;
|
|
340
|
+
} else {
|
|
341
|
+
t = Math.min(Math.max((value - min) / (pivot - min), 0), 1);
|
|
342
|
+
code = Math.trunc(t * pivotCode + 0.5);
|
|
343
|
+
}
|
|
344
|
+
} else {
|
|
345
|
+
// [pivot, max]
|
|
346
|
+
if (max - pivot == 0) {
|
|
347
|
+
// pivot == max
|
|
348
|
+
code = mask;
|
|
349
|
+
} else {
|
|
350
|
+
t = Math.min(Math.max((value - pivot) / (max - pivot), 0), 1);
|
|
351
|
+
code = Math.trunc(t * (mask - pivotCode) + 0.5) + pivotCode;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
this.writeBits(code, bits);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Writes three packed compressed 32-bit, little-endian float to the stream.
|
|
360
|
+
* @param {Vec3} value
|
|
361
|
+
* @param {Vec3} min
|
|
362
|
+
* @param {Vec3} max
|
|
363
|
+
* @param {Vec3} pivot
|
|
364
|
+
* @param {number} bits
|
|
365
|
+
*/
|
|
366
|
+
writeCompressedVec3(value, min, max, pivot, bits) {
|
|
367
|
+
this.writeCompressedFloat(value.x, min.x, max.x, pivot.x, bits);
|
|
368
|
+
this.writeCompressedFloat(value.y, min.y, max.y, pivot.y, bits);
|
|
369
|
+
this.writeCompressedFloat(value.z, min.z, max.z, pivot.z, bits);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Writes four packed compressed 32-bit, little-endian float from the stream.
|
|
374
|
+
* @param {Vec4} value
|
|
375
|
+
* @param {Vec4} min
|
|
376
|
+
* @param {Vec4} max
|
|
377
|
+
* @param {Vec4} pivot
|
|
378
|
+
* @param {number} bits
|
|
379
|
+
*/
|
|
380
|
+
writeCompressedVec4(value, min, max, pivot, bits) {
|
|
381
|
+
this.writeCompressedFloat(value.x, min.x, max.x, pivot.x, bits);
|
|
382
|
+
this.writeCompressedFloat(value.y, min.y, max.y, pivot.y, bits);
|
|
383
|
+
this.writeCompressedFloat(value.z, min.z, max.z, pivot.z, bits);
|
|
384
|
+
this.writeCompressedFloat(value.w, min.w, max.w, pivot.w, bits);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* Write an object.
|
|
389
|
+
* @param {IBinarying} t
|
|
390
|
+
*/
|
|
391
|
+
writeType(t) {
|
|
392
|
+
t.toStream(this);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
class ReadOnlyBinaryStream {
|
|
397
|
+
constructor(buffer) {
|
|
398
|
+
this.buffer = buffer || Buffer.alloc(0);
|
|
399
|
+
this.cursor = 0;
|
|
400
|
+
this.bitOffset = 0;
|
|
401
|
+
this.errorFlag = false;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* Returns true if the buffer has been read to its end.
|
|
406
|
+
* @returns {boolean}
|
|
407
|
+
*/
|
|
408
|
+
done() {
|
|
409
|
+
return this.cursor >= this.buffer.byteLength;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Return the error flag.
|
|
414
|
+
* @returns {boolean}
|
|
415
|
+
*/
|
|
416
|
+
error() {
|
|
417
|
+
return this.errorFlag;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* Get the total length of remaining data.
|
|
422
|
+
* @returns {number}
|
|
423
|
+
*/
|
|
424
|
+
getRemain() {
|
|
425
|
+
if (this.done())
|
|
426
|
+
return 0;
|
|
427
|
+
return this.buffer.byteLength - this.cursor;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* Move the cursor for given advance. Returns -1 if out of range.
|
|
432
|
+
* @param {number} advance
|
|
433
|
+
* @returns {number}
|
|
434
|
+
*/
|
|
435
|
+
move(advance = 0) {
|
|
436
|
+
if (this.done() || this.errorFlag)
|
|
437
|
+
return -1;
|
|
438
|
+
|
|
439
|
+
var cursor = this.cursor;
|
|
440
|
+
|
|
441
|
+
// Reset bit offset.
|
|
442
|
+
this.bitOffset = 0;
|
|
443
|
+
|
|
444
|
+
this.cursor += advance;
|
|
445
|
+
if (this.cursor > this.buffer.byteLength) {
|
|
446
|
+
this.errorFlag = 1;
|
|
447
|
+
return -1;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
return cursor;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* Skip "count" bytes.
|
|
455
|
+
* @param {number} [count]
|
|
456
|
+
*/
|
|
457
|
+
skip(count = 0) {
|
|
458
|
+
this.move(count);
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* Read "count" bits.
|
|
463
|
+
* @param {number} count
|
|
464
|
+
* @returns {number}
|
|
465
|
+
*/
|
|
466
|
+
readBits(count) {
|
|
467
|
+
if (count < 1 || count > 32) {
|
|
468
|
+
this.errorFlag = true;
|
|
469
|
+
return 0;
|
|
470
|
+
}
|
|
471
|
+
if (this.done()) {
|
|
472
|
+
this.errorFlag = true;
|
|
473
|
+
return 0;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
var result = 0
|
|
477
|
+
, bitsRead = 0
|
|
478
|
+
, byte, available, need, take, bits;
|
|
479
|
+
|
|
480
|
+
while (bitsRead < count) {
|
|
481
|
+
if (this.done()) {
|
|
482
|
+
this.errorFlag = true;
|
|
483
|
+
return 0;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
byte = this.buffer[this.cursor];
|
|
487
|
+
available = 8 - this.bitOffset;
|
|
488
|
+
need = count - bitsRead;
|
|
489
|
+
take = need < available ? need : available;
|
|
490
|
+
// Extract the "take" bits from "bitoffset".
|
|
491
|
+
bits = (byte >>> this.bitOffset) & ((1 << take) - 1);
|
|
492
|
+
// Convert to u32.
|
|
493
|
+
result |= (bits << bitsRead) >>> 0;
|
|
494
|
+
|
|
495
|
+
bitsRead += take;
|
|
496
|
+
this.bitOffset += take;
|
|
497
|
+
|
|
498
|
+
if (this.bitOffset == 8) {
|
|
499
|
+
this.bitOffset = 0;
|
|
500
|
+
this.cursor++;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
return result >>> 0;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* Read "count" bytes into a Buffer.
|
|
509
|
+
* @param {number} count
|
|
510
|
+
* @returns {Buffer}
|
|
511
|
+
*/
|
|
512
|
+
readBytes(count) {
|
|
513
|
+
var result = Buffer.alloc(count)
|
|
514
|
+
, cursor = this.move(count);
|
|
515
|
+
|
|
516
|
+
if (cursor < 0)
|
|
517
|
+
return result;
|
|
518
|
+
|
|
519
|
+
result.set(this.buffer.subarray(cursor, cursor + count));
|
|
520
|
+
|
|
521
|
+
return result;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* Writes a boolean to the stream.
|
|
526
|
+
* @returns {boolean}
|
|
527
|
+
*/
|
|
528
|
+
readBool() {
|
|
529
|
+
return !!this.readBits(1);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* Reads a signed 8-bit integer from the stream.
|
|
534
|
+
* @returns {number}
|
|
535
|
+
*/
|
|
536
|
+
readInt8() {
|
|
537
|
+
var cursor = this.move(1);
|
|
538
|
+
if (cursor < 0)
|
|
539
|
+
return 0;
|
|
540
|
+
return this.buffer.readInt8(cursor);
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
/**
|
|
544
|
+
* Reads an unsigned 8-bit integer from the stream.
|
|
545
|
+
* @returns {number}
|
|
546
|
+
*/
|
|
547
|
+
readUint8() {
|
|
548
|
+
var cursor = this.move(1);
|
|
549
|
+
if (cursor < 0)
|
|
550
|
+
return 0;
|
|
551
|
+
return this.buffer.readUint8(cursor);
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
/**
|
|
555
|
+
* Reads a signed, little-endian 16-bit integer from the stream.
|
|
556
|
+
* @returns {number}
|
|
557
|
+
*/
|
|
558
|
+
readInt16() {
|
|
559
|
+
var cursor = this.move(2);
|
|
560
|
+
if (cursor < 0)
|
|
561
|
+
return 0;
|
|
562
|
+
return this.buffer.readInt16LE(cursor);
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* Reads an unsigned, little-endian 16-bit integer from the stream.
|
|
567
|
+
* @returns {number}
|
|
568
|
+
*/
|
|
569
|
+
readUint16() {
|
|
570
|
+
var cursor = this.move(2);
|
|
571
|
+
if (cursor < 0)
|
|
572
|
+
return 0;
|
|
573
|
+
return this.buffer.readUint16LE(cursor);
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
/**
|
|
577
|
+
* Reads a signed, little-endian 32-bit integer from the stream.
|
|
578
|
+
* @returns {number}
|
|
579
|
+
*/
|
|
580
|
+
readInt32() {
|
|
581
|
+
var cursor = this.move(4);
|
|
582
|
+
if (cursor < 0)
|
|
583
|
+
return 0;
|
|
584
|
+
return this.buffer.readInt32LE(cursor);
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
/**
|
|
588
|
+
* Reads an unsigned, little-endian 32-bit integer from the stream.
|
|
589
|
+
* @returns {number}
|
|
590
|
+
*/
|
|
591
|
+
readUint32() {
|
|
592
|
+
var cursor = this.move(4);
|
|
593
|
+
if (cursor < 0)
|
|
594
|
+
return 0;
|
|
595
|
+
return this.buffer.readUint32LE(cursor);
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
/**
|
|
599
|
+
* Reads a signed, little-endian 64-bit integer from the stream.
|
|
600
|
+
* @returns {Long}
|
|
601
|
+
*/
|
|
602
|
+
readInt64() {
|
|
603
|
+
var cursorHi = this.move(4)
|
|
604
|
+
, cursorLo = this.move(4)
|
|
605
|
+
, hi, lo;
|
|
606
|
+
|
|
607
|
+
if (cursorLo < 0 || cursorHi < 0)
|
|
608
|
+
return Long.fromNumber(0);
|
|
609
|
+
|
|
610
|
+
hi = this.buffer.readUint32LE(cursorHi);
|
|
611
|
+
lo = this.buffer.readUint32LE(cursorLo);
|
|
612
|
+
|
|
613
|
+
return new Long(lo, hi);
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
/**
|
|
617
|
+
* Reads an unsigned, little-endian 32-bit integer from the stream.
|
|
618
|
+
* @returns {Long}
|
|
619
|
+
*/
|
|
620
|
+
readUint64() {
|
|
621
|
+
var cursorHi = this.move(4)
|
|
622
|
+
, cursorLo = this.move(4)
|
|
623
|
+
, hi, lo;
|
|
624
|
+
|
|
625
|
+
if (cursorLo < 0 || cursorHi < 0)
|
|
626
|
+
return Long.fromNumber(0);
|
|
627
|
+
|
|
628
|
+
hi = this.buffer.readUint32LE(cursorHi);
|
|
629
|
+
lo = this.buffer.readUint32LE(cursorLo);
|
|
630
|
+
|
|
631
|
+
return new Long(lo, hi, true);
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
/**
|
|
635
|
+
* Reads a 32-bit, little-endian float from the stream.
|
|
636
|
+
* @returns {number}
|
|
637
|
+
*/
|
|
638
|
+
readFloat() {
|
|
639
|
+
var cursor = this.move(4);
|
|
640
|
+
if (cursor < 0)
|
|
641
|
+
return 0;
|
|
642
|
+
return this.buffer.readFloatLE(cursor);
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
/**
|
|
646
|
+
* Reads a 64-bit, little-endian float from the stream.
|
|
647
|
+
* @returns {number}
|
|
648
|
+
*/
|
|
649
|
+
readDouble() {
|
|
650
|
+
var cursor = this.move(8);
|
|
651
|
+
if (cursor < 0)
|
|
652
|
+
return 0;
|
|
653
|
+
return this.buffer.readDoubleLE(cursor);
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
/**
|
|
657
|
+
* Writes a compressed signed 32-bit integer to the stream.
|
|
658
|
+
* @param {number} min
|
|
659
|
+
* @param {number} max
|
|
660
|
+
* @returns {number}
|
|
661
|
+
*/
|
|
662
|
+
readCompressedInt32(min, max) {
|
|
663
|
+
min ^= 0x80000000;
|
|
664
|
+
max ^= 0x80000000;
|
|
665
|
+
return this.readCompressedUint32(min, max);
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
/**
|
|
669
|
+
* Writes a compressed unsigned 32-bit integer to the stream.
|
|
670
|
+
* @param {number} min
|
|
671
|
+
* @param {number} max
|
|
672
|
+
* @returns {number}
|
|
673
|
+
*/
|
|
674
|
+
readCompressedUint32(min, max) {
|
|
675
|
+
min >>>= 0;
|
|
676
|
+
max >>>= 0;
|
|
677
|
+
|
|
678
|
+
if (min > max)
|
|
679
|
+
throw new RangeError("min must be less than max.");
|
|
680
|
+
|
|
681
|
+
var width = 32 - Math.clz32(max - min)
|
|
682
|
+
, result;
|
|
683
|
+
|
|
684
|
+
result = this.readBits(width) + min;
|
|
685
|
+
|
|
686
|
+
return result;
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
/**
|
|
690
|
+
* Reads a compressed 32-bit, little-endian float from the stream.
|
|
691
|
+
* @param {number} min
|
|
692
|
+
* @param {number} max
|
|
693
|
+
* @param {number} pivot
|
|
694
|
+
* @param {number} bits
|
|
695
|
+
* @returns {number}
|
|
696
|
+
*/
|
|
697
|
+
readCompressedFloat(min, max, pivot, bits) {
|
|
698
|
+
min = Math.fround(min);
|
|
699
|
+
max = Math.fround(max);
|
|
700
|
+
pivot = Math.fround(pivot);
|
|
701
|
+
|
|
702
|
+
return Math.fround(this.readCompressedDouble(min, max, pivot, bits));
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
/**
|
|
706
|
+
* Reads a compressed 64-bit, little-endian float from the stream.
|
|
707
|
+
* @param {number} min
|
|
708
|
+
* @param {number} max
|
|
709
|
+
* @param {number} pivot
|
|
710
|
+
* @param {number} bits
|
|
711
|
+
* @returns {number}
|
|
712
|
+
*/
|
|
713
|
+
readCompressedDouble(min, max, pivot, bits) {
|
|
714
|
+
if (min >= max)
|
|
715
|
+
throw new RangeError("min must be less than max");
|
|
716
|
+
if (pivot < min || pivot > max)
|
|
717
|
+
throw new RangeError("pivot must be within [min, max]");
|
|
718
|
+
if (bits < 1 || bits >= 32)
|
|
719
|
+
throw new RangeError("bits must be between 1 and 31");
|
|
720
|
+
|
|
721
|
+
var mask = ((1 << bits) - 1) >>> 0
|
|
722
|
+
, range = max - min
|
|
723
|
+
, pivotCode = Math.trunc(((pivot - min) / range) * mask)
|
|
724
|
+
, result, code, t;
|
|
725
|
+
|
|
726
|
+
code = this.readBits(bits);
|
|
727
|
+
if (this.errorFlag)
|
|
728
|
+
return 0;
|
|
729
|
+
|
|
730
|
+
if (code <= pivotCode) {
|
|
731
|
+
if (pivotCode === 0) {
|
|
732
|
+
result = min;
|
|
733
|
+
} else {
|
|
734
|
+
t = code / pivotCode;
|
|
735
|
+
result = min * (1 - t) + pivot * t;
|
|
736
|
+
}
|
|
737
|
+
} else {
|
|
738
|
+
if (mask === pivotCode) {
|
|
739
|
+
result = max;
|
|
740
|
+
} else {
|
|
741
|
+
t = (code - pivotCode) / (mask - pivotCode);
|
|
742
|
+
result = pivot * (1 - t) + max * t;
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
return result;
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
/**
|
|
750
|
+
* Reads three compressed 32-bit, little-endian float from the stream.
|
|
751
|
+
* @param {Vec3} min
|
|
752
|
+
* @param {Vec3} max
|
|
753
|
+
* @param {Vec3} pivot
|
|
754
|
+
* @param {number} bits
|
|
755
|
+
* @returns {Vec3}
|
|
756
|
+
*/
|
|
757
|
+
readCompressedVec3(min, max, pivot, bits) {
|
|
758
|
+
var result = new Vec3();
|
|
759
|
+
|
|
760
|
+
result.x = this.readCompressedFloat(min.x, max.x, pivot.x, bits);
|
|
761
|
+
result.y = this.readCompressedFloat(min.y, max.y, pivot.y, bits);
|
|
762
|
+
result.z = this.readCompressedFloat(min.z, max.z, pivot.z, bits);
|
|
763
|
+
|
|
764
|
+
return result;
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
/**
|
|
768
|
+
* Reads four compressed 32-bit, little-endian float from the stream.
|
|
769
|
+
* @param {Vec4} min
|
|
770
|
+
* @param {Vec4} max
|
|
771
|
+
* @param {Vec4} pivot
|
|
772
|
+
* @param {number} bits
|
|
773
|
+
* @returns {Vec4}
|
|
774
|
+
*/
|
|
775
|
+
readCompressedVec4(min, max, pivot, bits) {
|
|
776
|
+
var result = new Vec4();
|
|
777
|
+
|
|
778
|
+
result.x = this.readCompressedFloat(min.x, max.x, pivot.x, bits);
|
|
779
|
+
result.y = this.readCompressedFloat(min.y, max.y, pivot.y, bits);
|
|
780
|
+
result.z = this.readCompressedFloat(min.z, max.z, pivot.z, bits);
|
|
781
|
+
result.w = this.readCompressedFloat(min.w, max.w, pivot.w, bits);
|
|
782
|
+
|
|
783
|
+
return result;
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
/**
|
|
787
|
+
* @returns {boolean}
|
|
788
|
+
*/
|
|
789
|
+
readBool() {
|
|
790
|
+
return !!this.readUint8();
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
/**
|
|
794
|
+
* Read an IBinarying object from the stream.
|
|
795
|
+
* @param {Constructor<IBinarying>} T
|
|
796
|
+
* @returns {IBinarying}
|
|
797
|
+
*/
|
|
798
|
+
readType(T) {
|
|
799
|
+
return T.deserialize(this);
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
module.exports = {
|
|
804
|
+
ReadOnlyBinaryStream,
|
|
805
|
+
WritableBinaryStream
|
|
806
|
+
};
|