amulet-core 2.0a7__cp312-cp312-win_amd64.whl → 2.0a8__cp312-cp312-win_amd64.whl
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.
Potentially problematic release.
This version of amulet-core might be problematic. Click here for more details.
- amulet/__init__.cp312-win_amd64.pyd +0 -0
- amulet/__init__.py.cpp +2 -0
- amulet/__init__.pyi +2 -0
- amulet/_version.py +3 -3
- amulet/chunk.hpp +2 -1
- amulet/level/abc/_chunk_handle.py +45 -22
- amulet/mesh/block/__init__.pyi +301 -0
- amulet/mesh/block/_cube.py +198 -0
- amulet/mesh/block/{missing_block.py → _missing_block.py} +2 -2
- amulet/mesh/block/block_mesh.cpp +107 -0
- amulet/mesh/block/block_mesh.hpp +207 -0
- amulet/resource_pack/__init__.py +16 -15
- amulet/resource_pack/abc/resource_pack_manager.py +3 -5
- amulet/resource_pack/java/resource_pack_manager.py +185 -173
- amulet/utils/cast.py +10 -0
- amulet/utils/shareable_lock.py +2 -2
- {amulet_core-2.0a7.dist-info → amulet_core-2.0a8.dist-info}/METADATA +2 -2
- {amulet_core-2.0a7.dist-info → amulet_core-2.0a8.dist-info}/RECORD +21 -75
- {amulet_core-2.0a7.dist-info → amulet_core-2.0a8.dist-info}/WHEEL +1 -1
- amulet/mesh/block/__init__.py +0 -1
- amulet/mesh/block/block_mesh.py +0 -369
- amulet/mesh/block/cube.py +0 -149
- amulet/resource_pack/bedrock/__init__.py +0 -2
- amulet/resource_pack/bedrock/bedrock_vanilla_fix/pack_icon.png +0 -0
- amulet/resource_pack/bedrock/bedrock_vanilla_fix/textures/blocks/grass_carried.png +0 -0
- amulet/resource_pack/bedrock/bedrock_vanilla_fix/textures/blocks/grass_side_carried.png +0 -0
- amulet/resource_pack/bedrock/bedrock_vanilla_fix/textures/blocks/water.png +0 -0
- amulet/resource_pack/bedrock/blockshapes/__init__.py +0 -31
- amulet/resource_pack/bedrock/blockshapes/air.py +0 -35
- amulet/resource_pack/bedrock/blockshapes/base_blockshape.py +0 -29
- amulet/resource_pack/bedrock/blockshapes/bubble_column.py +0 -29
- amulet/resource_pack/bedrock/blockshapes/cake.py +0 -46
- amulet/resource_pack/bedrock/blockshapes/chest.py +0 -54
- amulet/resource_pack/bedrock/blockshapes/comparator.py +0 -51
- amulet/resource_pack/bedrock/blockshapes/cross_texture.py +0 -186
- amulet/resource_pack/bedrock/blockshapes/cross_texture0.py +0 -17
- amulet/resource_pack/bedrock/blockshapes/cross_texture_green.py +0 -16
- amulet/resource_pack/bedrock/blockshapes/cube.py +0 -38
- amulet/resource_pack/bedrock/blockshapes/default.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/door.py +0 -38
- amulet/resource_pack/bedrock/blockshapes/door1.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/door2.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/door3.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/door4.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/door5.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/door6.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/double_plant.py +0 -40
- amulet/resource_pack/bedrock/blockshapes/enchanting_table.py +0 -22
- amulet/resource_pack/bedrock/blockshapes/farmland.py +0 -22
- amulet/resource_pack/bedrock/blockshapes/fence.py +0 -22
- amulet/resource_pack/bedrock/blockshapes/flat.py +0 -55
- amulet/resource_pack/bedrock/blockshapes/flat_wall.py +0 -55
- amulet/resource_pack/bedrock/blockshapes/furnace.py +0 -44
- amulet/resource_pack/bedrock/blockshapes/furnace_lit.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/green_cube.py +0 -39
- amulet/resource_pack/bedrock/blockshapes/ladder.py +0 -36
- amulet/resource_pack/bedrock/blockshapes/lilypad.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/partial_block.py +0 -57
- amulet/resource_pack/bedrock/blockshapes/piston.py +0 -44
- amulet/resource_pack/bedrock/blockshapes/piston_arm.py +0 -72
- amulet/resource_pack/bedrock/blockshapes/portal_frame.py +0 -22
- amulet/resource_pack/bedrock/blockshapes/pressure_plate.py +0 -29
- amulet/resource_pack/bedrock/blockshapes/pumpkin.py +0 -36
- amulet/resource_pack/bedrock/blockshapes/pumpkin_carved.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/pumpkin_lit.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/red_dust.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/repeater.py +0 -53
- amulet/resource_pack/bedrock/blockshapes/slab.py +0 -33
- amulet/resource_pack/bedrock/blockshapes/slab_double.py +0 -15
- amulet/resource_pack/bedrock/blockshapes/tree.py +0 -41
- amulet/resource_pack/bedrock/blockshapes/turtle_egg.py +0 -15
- amulet/resource_pack/bedrock/blockshapes/vine.py +0 -52
- amulet/resource_pack/bedrock/blockshapes/wall.py +0 -22
- amulet/resource_pack/bedrock/blockshapes/water.py +0 -38
- amulet/resource_pack/bedrock/download_resources.py +0 -147
- amulet/resource_pack/bedrock/resource_pack.py +0 -40
- amulet/resource_pack/bedrock/resource_pack_manager.py +0 -361
- amulet/resource_pack/bedrock/sort_blockshapes.py +0 -15
- {amulet_core-2.0a7.dist-info → amulet_core-2.0a8.dist-info}/entry_points.txt +0 -0
- {amulet_core-2.0a7.dist-info → amulet_core-2.0a8.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import json
|
|
3
|
-
import copy
|
|
4
3
|
from typing import Union, Iterable, Iterator, Optional
|
|
5
4
|
from PIL import Image
|
|
6
5
|
import numpy
|
|
@@ -9,22 +8,28 @@ import itertools
|
|
|
9
8
|
import logging
|
|
10
9
|
import re
|
|
11
10
|
|
|
12
|
-
import
|
|
11
|
+
from amulet_nbt import StringTag
|
|
13
12
|
|
|
14
|
-
from amulet.
|
|
13
|
+
from amulet.utils.cast import dynamic_cast
|
|
14
|
+
from amulet.block import Block, PropertyValueType
|
|
15
15
|
from amulet.resource_pack import BaseResourcePackManager
|
|
16
16
|
from amulet.resource_pack.java import JavaResourcePack
|
|
17
|
-
from amulet.mesh.block
|
|
17
|
+
from amulet.mesh.block import (
|
|
18
18
|
BlockMesh,
|
|
19
|
+
BlockMeshPart,
|
|
20
|
+
Triangle,
|
|
21
|
+
Vertex,
|
|
22
|
+
FloatVec3,
|
|
23
|
+
FloatVec2,
|
|
24
|
+
BlockMeshTransparency,
|
|
25
|
+
BlockMeshCullDirection,
|
|
26
|
+
merge_block_meshes,
|
|
19
27
|
FACE_KEYS,
|
|
20
|
-
|
|
28
|
+
CUBE_FACE_LUT,
|
|
29
|
+
UV_ROTATION_LUT,
|
|
30
|
+
TRI_FACE,
|
|
21
31
|
)
|
|
22
32
|
from amulet.mesh.util import rotate_3d
|
|
23
|
-
from amulet.mesh.block.cube import (
|
|
24
|
-
cube_face_lut,
|
|
25
|
-
uv_rotation_lut,
|
|
26
|
-
tri_face,
|
|
27
|
-
)
|
|
28
33
|
|
|
29
34
|
log = logging.getLogger(__name__)
|
|
30
35
|
|
|
@@ -42,6 +47,23 @@ UselessImageGroups = {
|
|
|
42
47
|
|
|
43
48
|
_PropertiesPattern = re.compile(r"(?P<name>[a-zA-Z0-9_]+)=(?P<value>[a-zA-Z0-9_]+),?")
|
|
44
49
|
|
|
50
|
+
CULL_DIRECTIONS = {
|
|
51
|
+
None: BlockMeshCullDirection.CullNone,
|
|
52
|
+
"down": BlockMeshCullDirection.CullDown,
|
|
53
|
+
"up": BlockMeshCullDirection.CullUp,
|
|
54
|
+
"north": BlockMeshCullDirection.CullNorth,
|
|
55
|
+
"east": BlockMeshCullDirection.CullEast,
|
|
56
|
+
"south": BlockMeshCullDirection.CullSouth,
|
|
57
|
+
"west": BlockMeshCullDirection.CullWest,
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def get_py_data(obj: PropertyValueType) -> str | bytes | int:
|
|
62
|
+
if isinstance(obj, StringTag):
|
|
63
|
+
return obj.py_str_or_bytes
|
|
64
|
+
else:
|
|
65
|
+
return obj.py_int
|
|
66
|
+
|
|
45
67
|
|
|
46
68
|
class JavaResourcePackManager(BaseResourcePackManager[JavaResourcePack]):
|
|
47
69
|
"""A class to load and handle the data from the packs.
|
|
@@ -217,11 +239,9 @@ class JavaResourcePackManager(BaseResourcePackManager[JavaResourcePack]):
|
|
|
217
239
|
def parse_state_val(val: Union[str, bool]) -> list:
|
|
218
240
|
"""Convert the json block state format into a consistent format."""
|
|
219
241
|
if isinstance(val, str):
|
|
220
|
-
return [
|
|
242
|
+
return [StringTag(v) for v in val.split("|")]
|
|
221
243
|
elif isinstance(val, bool):
|
|
222
|
-
return [
|
|
223
|
-
amulet_nbt.TAG_String("true") if val else amulet_nbt.TAG_String("false")
|
|
224
|
-
]
|
|
244
|
+
return [StringTag("true") if val else StringTag("false")]
|
|
225
245
|
else:
|
|
226
246
|
raise Exception(f"Could not parse state val {val}")
|
|
227
247
|
|
|
@@ -239,16 +259,18 @@ class JavaResourcePackManager(BaseResourcePackManager[JavaResourcePack]):
|
|
|
239
259
|
blockstate["variants"][variant]
|
|
240
260
|
)
|
|
241
261
|
except Exception as e:
|
|
242
|
-
log.
|
|
262
|
+
log.exception(
|
|
243
263
|
f"Failed to load block model {blockstate['variants'][variant]}\n{e}"
|
|
244
264
|
)
|
|
245
265
|
else:
|
|
246
266
|
properties_match = _PropertiesPattern.finditer(f",{variant}")
|
|
247
267
|
if all(
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
268
|
+
get_py_data(
|
|
269
|
+
block.properties.get(
|
|
270
|
+
match.group("name"),
|
|
271
|
+
StringTag(match.group("value")),
|
|
272
|
+
)
|
|
273
|
+
)
|
|
252
274
|
== match.group("value")
|
|
253
275
|
for match in properties_match
|
|
254
276
|
):
|
|
@@ -257,7 +279,7 @@ class JavaResourcePackManager(BaseResourcePackManager[JavaResourcePack]):
|
|
|
257
279
|
blockstate["variants"][variant]
|
|
258
280
|
)
|
|
259
281
|
except Exception as e:
|
|
260
|
-
log.
|
|
282
|
+
log.exception(
|
|
261
283
|
f"Failed to load block model {blockstate['variants'][variant]}\n{e}"
|
|
262
284
|
)
|
|
263
285
|
|
|
@@ -301,13 +323,13 @@ class JavaResourcePackManager(BaseResourcePackManager[JavaResourcePack]):
|
|
|
301
323
|
)
|
|
302
324
|
|
|
303
325
|
except Exception as e:
|
|
304
|
-
log.
|
|
326
|
+
log.exception(
|
|
305
327
|
f"Failed to load block model {case['apply']}\n{e}"
|
|
306
328
|
)
|
|
307
329
|
except Exception as e:
|
|
308
|
-
log.
|
|
330
|
+
log.exception(f"Failed to parse block state for {block}\n{e}")
|
|
309
331
|
|
|
310
|
-
return
|
|
332
|
+
return merge_block_meshes(models)
|
|
311
333
|
|
|
312
334
|
return self.missing_block
|
|
313
335
|
|
|
@@ -324,7 +346,7 @@ class JavaResourcePackManager(BaseResourcePackManager[JavaResourcePack]):
|
|
|
324
346
|
roty = int(blockstate_value.get("y", 0) // 90)
|
|
325
347
|
uvlock = blockstate_value.get("uvlock", False)
|
|
326
348
|
|
|
327
|
-
model =
|
|
349
|
+
model = self._load_block_model(model_path)
|
|
328
350
|
|
|
329
351
|
# TODO: rotate model based on uv_lock
|
|
330
352
|
return model.rotate(rotx, roty)
|
|
@@ -334,39 +356,29 @@ class JavaResourcePackManager(BaseResourcePackManager[JavaResourcePack]):
|
|
|
334
356
|
# recursively load model files into one dictionary
|
|
335
357
|
java_model = self._recursive_load_block_model(model_path)
|
|
336
358
|
|
|
337
|
-
# set up some variables
|
|
338
|
-
texture_dict = {}
|
|
339
|
-
textures = []
|
|
340
|
-
texture_count = 0
|
|
341
|
-
vert_count = {side: 0 for side in FACE_KEYS}
|
|
342
|
-
verts_src: dict[Optional[str], list[numpy.ndarray]] = {
|
|
343
|
-
side: [] for side in FACE_KEYS
|
|
344
|
-
}
|
|
345
|
-
tverts_src: dict[Optional[str], list[numpy.ndarray]] = {
|
|
346
|
-
side: [] for side in FACE_KEYS
|
|
347
|
-
}
|
|
348
|
-
tint_verts_src: dict[Optional[str], list[float]] = {
|
|
349
|
-
side: [] for side in FACE_KEYS
|
|
350
|
-
}
|
|
351
|
-
faces_src: dict[Optional[str], list[numpy.ndarray]] = {
|
|
352
|
-
side: [] for side in FACE_KEYS
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
texture_indexes_src: dict[Optional[str], list[int]] = {
|
|
356
|
-
side: [] for side in FACE_KEYS
|
|
357
|
-
}
|
|
358
|
-
transparent = Transparency.Partial
|
|
359
|
-
|
|
360
359
|
if java_model.get("textures", {}) and not java_model.get("elements"):
|
|
361
360
|
return self.missing_block
|
|
362
361
|
|
|
363
|
-
|
|
362
|
+
# set up some variables
|
|
363
|
+
texture_paths: dict[str, int] = {}
|
|
364
|
+
mesh_parts: list[tuple[list[Vertex], list[Triangle]] | None] = [
|
|
365
|
+
None,
|
|
366
|
+
None,
|
|
367
|
+
None,
|
|
368
|
+
None,
|
|
369
|
+
None,
|
|
370
|
+
None,
|
|
371
|
+
None,
|
|
372
|
+
]
|
|
373
|
+
transparency = BlockMeshTransparency.Partial
|
|
374
|
+
|
|
375
|
+
for element in dynamic_cast(java_model.get("elements", []), list):
|
|
364
376
|
# iterate through elements (one cube per element)
|
|
365
|
-
element_faces = element.get("faces", {})
|
|
377
|
+
element_faces = dynamic_cast(element.get("faces", {}), dict)
|
|
366
378
|
|
|
367
379
|
opaque_face_count = 0
|
|
368
380
|
if (
|
|
369
|
-
|
|
381
|
+
transparency
|
|
370
382
|
and "rotation" not in element
|
|
371
383
|
and element.get("to", [16, 16, 16]) == [16, 16, 16]
|
|
372
384
|
and element.get("from", [0, 0, 0]) == [0, 0, 0]
|
|
@@ -375,153 +387,153 @@ class JavaResourcePackManager(BaseResourcePackManager[JavaResourcePack]):
|
|
|
375
387
|
# if the block is not yet defined as a solid block
|
|
376
388
|
# and this element is a full size element
|
|
377
389
|
# check if the texture is opaque
|
|
378
|
-
|
|
390
|
+
transparency = BlockMeshTransparency.FullTranslucent
|
|
379
391
|
check_faces = True
|
|
380
392
|
else:
|
|
381
393
|
check_faces = False
|
|
382
394
|
|
|
383
395
|
# lower and upper box coordinates
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
[element.get("to", [16, 16, 16]), element.get("from", [0, 0, 0])],
|
|
387
|
-
float,
|
|
388
|
-
)
|
|
389
|
-
/ 16,
|
|
390
|
-
0,
|
|
391
|
-
)
|
|
396
|
+
x1, y1, z1 = [v / 16.0 for v in element.get("from", [0, 0, 0])]
|
|
397
|
+
x2, y2, z2 = [v / 16.0 for v in element.get("to", [16, 16, 16])]
|
|
392
398
|
|
|
393
399
|
# vertex coordinates of the box
|
|
394
400
|
box_coordinates = numpy.array(
|
|
395
|
-
list(
|
|
401
|
+
list(
|
|
402
|
+
itertools.product(
|
|
403
|
+
(min(x1, x2), max(x1, x2)),
|
|
404
|
+
(min(y1, y2), max(y1, y2)),
|
|
405
|
+
(min(z1, z2), max(z1, x2)),
|
|
406
|
+
)
|
|
407
|
+
)
|
|
396
408
|
)
|
|
397
409
|
|
|
398
|
-
for face_dir in element_faces:
|
|
399
|
-
if face_dir in
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
if len(texture_path_list) == 2:
|
|
415
|
-
namespace, texture_relative_path = texture_path_list
|
|
416
|
-
else:
|
|
417
|
-
namespace = "minecraft"
|
|
418
|
-
|
|
419
|
-
texture_path = self.get_texture_path(
|
|
420
|
-
namespace, texture_relative_path
|
|
410
|
+
for face_dir, face_data in element_faces.items():
|
|
411
|
+
if face_dir not in CUBE_FACE_LUT:
|
|
412
|
+
continue
|
|
413
|
+
|
|
414
|
+
# get the cull direction. If there is an opaque block in this direction then cull this face
|
|
415
|
+
cull_dir = face_data.get("cullface", None)
|
|
416
|
+
if cull_dir not in FACE_KEYS:
|
|
417
|
+
cull_dir = None
|
|
418
|
+
|
|
419
|
+
# get the relative texture path for the texture used
|
|
420
|
+
texture_relative_path = face_data.get("texture", None)
|
|
421
|
+
while isinstance(
|
|
422
|
+
texture_relative_path, str
|
|
423
|
+
) and texture_relative_path.startswith("#"):
|
|
424
|
+
texture_relative_path = java_model["textures"].get(
|
|
425
|
+
texture_relative_path[1:], None
|
|
421
426
|
)
|
|
427
|
+
texture_path_list = texture_relative_path.split(":", 1)
|
|
428
|
+
if len(texture_path_list) == 2:
|
|
429
|
+
namespace, texture_relative_path = texture_path_list
|
|
430
|
+
else:
|
|
431
|
+
namespace = "minecraft"
|
|
422
432
|
|
|
423
|
-
|
|
424
|
-
if self._texture_is_transparent[texture_path][1]:
|
|
425
|
-
check_faces = False
|
|
426
|
-
else:
|
|
427
|
-
opaque_face_count += 1
|
|
433
|
+
texture_path = self.get_texture_path(namespace, texture_relative_path)
|
|
428
434
|
|
|
429
|
-
|
|
430
|
-
if
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
435
|
+
if check_faces:
|
|
436
|
+
if self._texture_is_transparent[texture_path][1]:
|
|
437
|
+
check_faces = False
|
|
438
|
+
else:
|
|
439
|
+
opaque_face_count += 1
|
|
434
440
|
|
|
435
|
-
|
|
436
|
-
|
|
441
|
+
# texture index for the face
|
|
442
|
+
texture_index = texture_paths.setdefault(
|
|
443
|
+
texture_path, len(texture_paths)
|
|
444
|
+
)
|
|
437
445
|
|
|
438
|
-
|
|
439
|
-
|
|
446
|
+
# get the uv values for each vertex
|
|
447
|
+
texture_uv: tuple[float, float, float, float]
|
|
448
|
+
if "uv" in face_data:
|
|
449
|
+
uv = face_data["uv"]
|
|
440
450
|
texture_uv = (
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
/ 16
|
|
446
|
-
)
|
|
447
|
-
texture_rotation = element_faces[face_dir].get("rotation", 0)
|
|
448
|
-
uv_slice = (
|
|
449
|
-
uv_rotation_lut[2 * int(texture_rotation / 90) :]
|
|
450
|
-
+ uv_rotation_lut[: 2 * int(texture_rotation / 90)]
|
|
451
|
+
uv[0] / 16.0,
|
|
452
|
+
uv[1] / 16.0,
|
|
453
|
+
uv[2] / 16.0,
|
|
454
|
+
uv[3] / 16.0,
|
|
451
455
|
)
|
|
456
|
+
else:
|
|
457
|
+
# TODO: get the uv based on box location if not defined
|
|
458
|
+
texture_uv = (0.0, 0.0, 1.0, 1.0)
|
|
452
459
|
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
angle = rotation.get("angle", 0)
|
|
459
|
-
axis = rotation.get("axis", "x")
|
|
460
|
-
angles = [0, 0, 0]
|
|
461
|
-
if axis == "x":
|
|
462
|
-
angles[0] = -angle
|
|
463
|
-
elif axis == "y":
|
|
464
|
-
angles[1] = -angle
|
|
465
|
-
elif axis == "z":
|
|
466
|
-
angles[2] = -angle
|
|
467
|
-
face_verts = rotate_3d(face_verts, *angles, *origin)
|
|
468
|
-
|
|
469
|
-
verts_src[cull_dir].append(
|
|
470
|
-
face_verts
|
|
471
|
-
) # vertex coordinates for this face
|
|
472
|
-
|
|
473
|
-
tverts_src[cull_dir].append(
|
|
474
|
-
texture_uv[uv_slice].reshape((-1, 2)) # texture vertices
|
|
475
|
-
)
|
|
476
|
-
if "tintindex" in element_faces[face_dir]:
|
|
477
|
-
tint_verts_src[cull_dir] += [
|
|
478
|
-
0,
|
|
479
|
-
1,
|
|
480
|
-
0,
|
|
481
|
-
] * 4 # TODO: set this up for each supported block
|
|
482
|
-
else:
|
|
483
|
-
tint_verts_src[cull_dir] += [1, 1, 1] * 4
|
|
484
|
-
|
|
485
|
-
# merge the face indexes and texture index
|
|
486
|
-
face_table = tri_face + vert_count[cull_dir]
|
|
487
|
-
texture_indexes_src[cull_dir] += [texture_index, texture_index]
|
|
460
|
+
texture_rotation = face_data.get("rotation", 0)
|
|
461
|
+
uv_slice = (
|
|
462
|
+
UV_ROTATION_LUT[2 * int(texture_rotation / 90) :]
|
|
463
|
+
+ UV_ROTATION_LUT[: 2 * int(texture_rotation / 90)]
|
|
464
|
+
)
|
|
488
465
|
|
|
489
|
-
|
|
490
|
-
|
|
466
|
+
# merge the vertex coordinates and texture coordinates
|
|
467
|
+
face_verts = box_coordinates[CUBE_FACE_LUT[face_dir]]
|
|
468
|
+
if "rotation" in element:
|
|
469
|
+
rotation = element["rotation"]
|
|
470
|
+
origin = [r / 16 for r in rotation.get("origin", [8, 8, 8])]
|
|
471
|
+
angle = rotation.get("angle", 0)
|
|
472
|
+
axis = rotation.get("axis", "x")
|
|
473
|
+
angles = [0, 0, 0]
|
|
474
|
+
if axis == "x":
|
|
475
|
+
angles[0] = -angle
|
|
476
|
+
elif axis == "y":
|
|
477
|
+
angles[1] = -angle
|
|
478
|
+
elif axis == "z":
|
|
479
|
+
angles[2] = -angle
|
|
480
|
+
face_verts = rotate_3d(face_verts, *angles, *origin)
|
|
481
|
+
|
|
482
|
+
cull_direction = CULL_DIRECTIONS[cull_dir]
|
|
483
|
+
part = mesh_parts[cull_direction]
|
|
484
|
+
if part is None:
|
|
485
|
+
mesh_parts[cull_direction] = part = ([], [])
|
|
486
|
+
verts, tris = part
|
|
487
|
+
vert_count = len(verts)
|
|
488
|
+
|
|
489
|
+
if "tintindex" in face_data:
|
|
490
|
+
# TODO: set this up for each supported block
|
|
491
|
+
tint_vec = FloatVec3(0, 1, 0)
|
|
492
|
+
else:
|
|
493
|
+
tint_vec = FloatVec3(1, 1, 1)
|
|
494
|
+
|
|
495
|
+
for i in range(4):
|
|
496
|
+
x, y, z = face_verts[i]
|
|
497
|
+
uvx = texture_uv[uv_slice[i * 2]]
|
|
498
|
+
uvy = texture_uv[uv_slice[i * 2 + 1]]
|
|
499
|
+
verts.append(
|
|
500
|
+
Vertex(
|
|
501
|
+
FloatVec3(x, y, z),
|
|
502
|
+
FloatVec2(uvx, uvy),
|
|
503
|
+
tint_vec,
|
|
504
|
+
)
|
|
505
|
+
)
|
|
491
506
|
|
|
492
|
-
|
|
507
|
+
for a, b, c in TRI_FACE.reshape((2, 3)):
|
|
508
|
+
tris.append(
|
|
509
|
+
Triangle(
|
|
510
|
+
a + vert_count,
|
|
511
|
+
b + vert_count,
|
|
512
|
+
c + vert_count,
|
|
513
|
+
texture_index,
|
|
514
|
+
)
|
|
515
|
+
)
|
|
493
516
|
|
|
494
517
|
if opaque_face_count == 6:
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
texture_indexes: dict[Optional[str], numpy.ndarray] = {}
|
|
502
|
-
|
|
503
|
-
for cull_dir in FACE_KEYS:
|
|
504
|
-
face_array = faces_src[cull_dir]
|
|
505
|
-
if len(face_array) > 0:
|
|
506
|
-
faces[cull_dir] = numpy.concatenate(face_array, axis=None)
|
|
507
|
-
tint_verts[cull_dir] = numpy.concatenate(
|
|
508
|
-
tint_verts_src[cull_dir], axis=None
|
|
509
|
-
)
|
|
510
|
-
verts[cull_dir] = numpy.concatenate(verts_src[cull_dir], axis=None)
|
|
511
|
-
tverts[cull_dir] = numpy.concatenate(tverts_src[cull_dir], axis=None)
|
|
512
|
-
texture_indexes[cull_dir] = numpy.array(
|
|
513
|
-
texture_indexes_src[cull_dir], dtype=numpy.uint32
|
|
514
|
-
)
|
|
518
|
+
transparency = BlockMeshTransparency.FullOpaque
|
|
519
|
+
|
|
520
|
+
def create_part(
|
|
521
|
+
part: tuple[list[Vertex], list[Triangle]] | None
|
|
522
|
+
) -> BlockMeshPart | None:
|
|
523
|
+
return None if part is None else BlockMeshPart(*part)
|
|
515
524
|
|
|
516
525
|
return BlockMesh(
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
526
|
+
transparency,
|
|
527
|
+
list(texture_paths),
|
|
528
|
+
(
|
|
529
|
+
create_part(mesh_parts[0]),
|
|
530
|
+
create_part(mesh_parts[1]),
|
|
531
|
+
create_part(mesh_parts[2]),
|
|
532
|
+
create_part(mesh_parts[3]),
|
|
533
|
+
create_part(mesh_parts[4]),
|
|
534
|
+
create_part(mesh_parts[5]),
|
|
535
|
+
create_part(mesh_parts[6]),
|
|
536
|
+
),
|
|
525
537
|
)
|
|
526
538
|
|
|
527
539
|
def _recursive_load_block_model(self, model_path: str) -> dict:
|
amulet/utils/cast.py
ADDED
amulet/utils/shareable_lock.py
CHANGED
|
@@ -289,7 +289,7 @@ class ShareableRLock:
|
|
|
289
289
|
:raises: LockNotAcquired if the lock could not be acquired.
|
|
290
290
|
"""
|
|
291
291
|
if not self.acquire_unique(blocking, timeout, task_manager):
|
|
292
|
-
raise LockNotAcquired
|
|
292
|
+
raise LockNotAcquired("Lock was not acquired.")
|
|
293
293
|
try:
|
|
294
294
|
yield
|
|
295
295
|
finally:
|
|
@@ -328,7 +328,7 @@ class ShareableRLock:
|
|
|
328
328
|
:raises: LockNotAcquired if the lock could not be acquired.
|
|
329
329
|
"""
|
|
330
330
|
if not self.acquire_shared(blocking, timeout, task_manager):
|
|
331
|
-
raise LockNotAcquired
|
|
331
|
+
raise LockNotAcquired("Lock was not acquired.")
|
|
332
332
|
try:
|
|
333
333
|
yield
|
|
334
334
|
finally:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: amulet-core
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.0a8
|
|
4
4
|
Summary: A Python library for reading/writing Minecraft's various save formats.
|
|
5
5
|
Home-page: https://www.amuletmc.com
|
|
6
6
|
Author: James Clare, Ben Gothard et al.
|
|
@@ -11,7 +11,7 @@ Classifier: Operating System :: OS Independent
|
|
|
11
11
|
Requires-Python: >=3.11
|
|
12
12
|
Description-Content-Type: text/markdown
|
|
13
13
|
Requires-Dist: numpy~=2.0
|
|
14
|
-
Requires-Dist: amulet-nbt~=4.
|
|
14
|
+
Requires-Dist: amulet-nbt~=4.0a6
|
|
15
15
|
Requires-Dist: portalocker~=2.4
|
|
16
16
|
Requires-Dist: amulet-leveldb~=1.0b0
|
|
17
17
|
Requires-Dist: platformdirs~=3.1
|