Add TextureEntry.realize() to ease indexing into specific faces

This commit is contained in:
Salad Dais
2022-07-14 03:10:11 +00:00
parent 58db8f66de
commit 4b963f96d2
2 changed files with 34 additions and 2 deletions

View File

@@ -1065,12 +1065,38 @@ class TextureEntry:
default_factory=lambda: MediaFlags(WebPage=False, TexGen=TexGen.DEFAULT, _Unused=0),
)
Glow: Dict[_TE_FIELD_KEY, int] = _te_field(se.U8, default=0)
Materials: Dict[_TE_FIELD_KEY, UUID] = _te_field(se.UUID, optional=True, default=UUID())
Materials: Dict[_TE_FIELD_KEY, UUID] = _te_field(se.UUID, optional=True, default=UUID.ZERO)
def unwrap(self):
"""Return `self` regardless of whether this is lazy wrapped object or not"""
return self
def realize(self, num_faces: int):
"""
Turn the "default" vs "exception cases" wire format TE representation to per-face lookups
Makes it easier to just index into a list of offsets with a face number.
Returns something like:
{
"OffsetsS": [0.5, 0.2, ...],
...
}
"""
as_dict = {}
for key, vals in dataclasses.asdict(self).items():
# Fill all of the faces in this key with the default value stored in the TE
key_arr = as_dict[key] = [vals[None]] * num_faces
# Walk over the exception cases and replace the default value
for face_nums, val in vals.items():
# Default case already handled
if face_nums is None:
continue
for face_num in face_nums:
if face_num >= num_faces:
raise ValueError(f"Bad value for num_faces? {face_num} >= {num_faces}")
key_arr[face_num] = val
return as_dict
TE_SERIALIZER = se.Dataclass(TextureEntry)

View File

@@ -12,12 +12,18 @@ EXAMPLE_TE = b'\x89UgG$\xcbC\xed\x92\x0bG\xca\xed\x15F_\x08\xca*\x98:\x18\x02,\r
class TemplateTests(unittest.TestCase):
def test_te_round_trips(self):
deserialized = TextureEntrySubfieldSerializer.deserialize(None, EXAMPLE_TE)
serialized = TextureEntrySubfieldSerializer.serialize(None, deserialized)
self.assertEqual(EXAMPLE_TE, serialized)
def test_realize_te(self):
deserialized: TextureEntry = TextureEntrySubfieldSerializer.deserialize(None, EXAMPLE_TE)
realized = deserialized.realize(num_faces=4)
self.assertEqual(UUID('ca2a983a-1802-2c0d-f41e-c6f591015d83'), realized["Textures"][3])
with self.assertRaises(ValueError):
deserialized.realize(3)
def test_face_bitfield_round_trips(self):
test_val = b"\x81\x03"
reader = se.BufferReader("!", test_val)