-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbinary_reader.py
More file actions
88 lines (64 loc) · 3.11 KB
/
Copy pathbinary_reader.py
File metadata and controls
88 lines (64 loc) · 3.11 KB
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
from io import BytesIO
import struct
from typing import Literal
from mathutils import Euler, Matrix
class BinaryReader(BytesIO):
def __init__(self, data: bytes, big_endian=False) -> None:
super().__init__(data)
self.endian_symbol: Literal["<", ">"]
self.byte_order: Literal["little", "big"]
if big_endian:
self.endian_symbol = ">"
self.byte_order = "big"
else:
self.endian_symbol = "<"
self.byte_order = "little"
def read_uint8(self) -> int:
return int.from_bytes(self.read(1), signed=False, byteorder=self.byte_order)
def read_int8(self) -> int:
return int.from_bytes(self.read(1), signed=True, byteorder=self.byte_order)
def read_uint16(self) -> int:
return int.from_bytes(self.read(2), signed=False, byteorder=self.byte_order)
def read_int16(self) -> int:
return int.from_bytes(self.read(2), signed=True, byteorder=self.byte_order)
def read_uint32(self) -> int:
return int.from_bytes(self.read(4), signed=False, byteorder=self.byte_order)
def read_int32(self) -> int:
return int.from_bytes(self.read(4), signed=True, byteorder=self.byte_order)
def read_vec4B(self) -> tuple[int, int, int, int]:
return struct.unpack(self.endian_symbol + "4B", self.read(4))
def read_vec3H(self) -> tuple[int, int, int]:
return struct.unpack(self.endian_symbol + "3H", self.read(6))
def read_vec3I(self) -> tuple[int, int, int]:
return struct.unpack(self.endian_symbol + "3I", self.read(12))
def read_float(self) -> float:
return struct.unpack(self.endian_symbol + "f", self.read(4))[0]
def read_vec2f(self) -> tuple[float, float]:
return struct.unpack(self.endian_symbol + "2f", self.read(8))
def read_vec3f(self) -> tuple[float, float, float]:
return struct.unpack(self.endian_symbol + "3f", self.read(12))
def read_vec4f(self) -> tuple[float, float, float, float]:
return struct.unpack(self.endian_symbol + "4f", self.read(16))
def read_rgba(self) -> tuple[float, float, float, float]:
r, g, b, a = self.read_vec4B()
return (r / 255, g / 255, b / 255, a / 255)
def read_bgra(self) -> tuple[float, float, float, float]:
b, g, r, a = self.read_vec4B()
return (r / 255, g / 255, b / 255, a / 255)
def read_loc_rot_scale(self) -> Matrix:
location = self.read_vec3f()
rotation = Euler(self.read_vec3f())
scale = self.read_vec3f()
return Matrix.LocRotScale(location, rotation, scale)
def read_matrix_3x4(self) -> Matrix:
rows = [self.read_vec3f() for _ in range(4)]
return Matrix(rows).to_4x4().transposed()
def read_matrix_4x3(self) -> Matrix:
rows = [self.read_vec4f() for _ in range(3)]
return Matrix(rows).to_4x4().transposed()
def read_matrix_4x4(self) -> Matrix:
rows = [self.read_vec4f() for _ in range(4)]
return Matrix(rows).transposed()
def read_string_block(self, length: int) -> str:
text = self.read(length).decode(errors="ignore")
return text.split("\x00")[0]