amulet-core 2.0a6__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 +6 -0
- amulet/__init__.pyi +2 -2
- amulet/_init.py +0 -2
- amulet/_version.py +3 -3
- amulet/biome.pyi +0 -2
- amulet/block.pyi +0 -2
- amulet/block_entity.pyi +0 -2
- amulet/chunk.hpp +2 -1
- amulet/chunk.pyi +0 -2
- amulet/chunk_components.pyi +20 -18
- amulet/collections/eq.py.hpp +1 -1
- amulet/collections/mapping.py.hpp +18 -11
- amulet/collections/mutable_mapping.py.hpp +17 -6
- amulet/collections/sequence.py.hpp +5 -6
- amulet/collections.pyi +8 -5
- amulet/entity.py +22 -20
- amulet/game/translate/_functions/_code_functions/_text.py +2 -2
- amulet/game/translate/_functions/abc.py +10 -3
- amulet/img/__init__.py +10 -0
- amulet/img/missing_no.png +0 -0
- amulet/img/missing_pack.png +0 -0
- amulet/level/__init__.pyi +2 -6
- amulet/level/abc/_chunk_handle.py +45 -22
- amulet/level/abc/_level/_creatable_level.py +1 -2
- amulet/level/abc/_level/_level.py +1 -5
- amulet/level/java/__init__.pyi +0 -5
- amulet/level/java/_raw/__init__.pyi +0 -4
- amulet/level/java/_raw/java_chunk_decode.cpp +2 -4
- amulet/level/java/long_array.pyi +2 -1
- amulet/mesh/block/__init__.pyi +301 -0
- amulet/mesh/block/_cube.py +198 -0
- amulet/mesh/block/_missing_block.py +20 -0
- amulet/mesh/block/block_mesh.cpp +107 -0
- amulet/mesh/block/block_mesh.hpp +207 -0
- amulet/mesh/util.py +17 -0
- amulet/player.py +4 -6
- amulet/pybind11/collections.hpp +80 -38
- amulet/pybind11/numpy.hpp +26 -0
- amulet/pybind11/py_module.hpp +16 -51
- amulet/pybind11/type_hints.hpp +51 -0
- amulet/pybind11/types.hpp +14 -6
- amulet/pybind11/typing.hpp +7 -0
- amulet/resource_pack/__init__.py +63 -0
- amulet/resource_pack/abc/__init__.py +2 -0
- amulet/resource_pack/abc/resource_pack.py +38 -0
- amulet/resource_pack/abc/resource_pack_manager.py +85 -0
- amulet/resource_pack/java/__init__.py +2 -0
- amulet/resource_pack/java/download_resources.py +212 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_black.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_blue.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_brown.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_cyan.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_gray.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_green.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_light_blue.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_light_gray.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_lime.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_magenta.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_orange.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_pink.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_purple.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_red.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_white.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_yellow.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/barrier.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/end_portal.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/grass.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/lava.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/structure_void.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/water.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/pack.png +0 -0
- amulet/resource_pack/java/resource_pack.py +44 -0
- amulet/resource_pack/java/resource_pack_manager.py +563 -0
- amulet/resource_pack/unknown_resource_pack.py +10 -0
- amulet/utils/__init__.pyi +0 -5
- amulet/utils/call_spec/_call_spec.py +2 -7
- amulet/utils/cast.py +10 -0
- amulet/utils/comment_json.py +188 -0
- amulet/utils/matrix.py +3 -3
- amulet/utils/numpy_helpers.py +2 -2
- amulet/utils/shareable_lock.py +2 -2
- amulet/utils/world_utils.py +2 -2
- amulet/version.pyi +0 -8
- {amulet_core-2.0a6.dist-info → amulet_core-2.0a8.dist-info}/METADATA +2 -2
- {amulet_core-2.0a6.dist-info → amulet_core-2.0a8.dist-info}/RECORD +91 -103
- {amulet_core-2.0a6.dist-info → amulet_core-2.0a8.dist-info}/WHEEL +1 -1
- amulet/chunk_/components/biome.py +0 -155
- amulet/chunk_/components/block_entity.py +0 -117
- amulet/chunk_/components/entity.py +0 -64
- amulet/chunk_/components/height_2d.py +0 -16
- amulet/level/bedrock/__init__.py +0 -2
- amulet/level/bedrock/_chunk_handle.py +0 -19
- amulet/level/bedrock/_dimension.py +0 -22
- amulet/level/bedrock/_level.py +0 -187
- amulet/level/bedrock/_raw/__init__.py +0 -5
- amulet/level/bedrock/_raw/_actor_counter.py +0 -53
- amulet/level/bedrock/_raw/_chunk.py +0 -54
- amulet/level/bedrock/_raw/_chunk_decode.py +0 -668
- amulet/level/bedrock/_raw/_chunk_encode.py +0 -602
- amulet/level/bedrock/_raw/_constant.py +0 -9
- amulet/level/bedrock/_raw/_dimension.py +0 -343
- amulet/level/bedrock/_raw/_level.py +0 -463
- amulet/level/bedrock/_raw/_level_dat.py +0 -90
- amulet/level/bedrock/_raw/_typing.py +0 -6
- amulet/level/bedrock/_raw/leveldb_chunk_versions.py +0 -83
- amulet/level/bedrock/chunk/__init__.py +0 -1
- amulet/level/bedrock/chunk/_chunk.py +0 -126
- amulet/level/bedrock/chunk/components/chunk_version.py +0 -12
- amulet/level/bedrock/chunk/components/finalised_state.py +0 -13
- amulet/level/bedrock/chunk/components/raw_chunk.py +0 -15
- amulet/level/construction/__init__.py +0 -0
- amulet/level/java/_chunk_handle.pyi +0 -15
- amulet/level/java/_dimension.pyi +0 -13
- amulet/level/java/_level.pyi +0 -120
- amulet/level/java/_raw/_chunk_decode.py +0 -561
- amulet/level/java/_raw/_chunk_encode.py +0 -463
- amulet/level/java/_raw/_constant.pyi +0 -20
- amulet/level/java/_raw/_data_pack/__init__.pyi +0 -8
- amulet/level/java/_raw/_data_pack/data_pack.pyi +0 -197
- amulet/level/java/_raw/_data_pack/data_pack_manager.pyi +0 -75
- amulet/level/java/_raw/_dimension.pyi +0 -72
- amulet/level/java/_raw/_level.pyi +0 -238
- amulet/level/java/_raw/_typing.pyi +0 -5
- amulet/level/java/anvil/__init__.pyi +0 -11
- amulet/level/java/anvil/_dimension.pyi +0 -109
- amulet/level/java/anvil/_region.pyi +0 -197
- amulet/level/java/anvil/_sector_manager.pyi +0 -142
- amulet/level/java_forge/__init__.py +0 -0
- amulet/level/mcstructure/__init__.py +0 -0
- amulet/level/nbt/__init__.py +0 -0
- amulet/level/schematic/__init__.py +0 -0
- amulet/level/sponge_schematic/__init__.py +0 -0
- amulet/pybind11/python.hpp +0 -14
- amulet/utils/call_spec/__init__.pyi +0 -53
- amulet/utils/call_spec/_call_spec.pyi +0 -272
- amulet/utils/matrix.pyi +0 -177
- amulet/utils/shareable_lock.pyi +0 -190
- amulet/utils/signal/__init__.pyi +0 -25
- amulet/utils/signal/_signal.pyi +0 -84
- amulet/utils/task_manager.pyi +0 -168
- amulet/utils/typing.py +0 -4
- amulet/utils/typing.pyi +0 -6
- amulet/utils/weakref.pyi +0 -50
- amulet/utils/world_utils.pyi +0 -109
- /amulet/img/{missing_world_icon.png → missing_world.png} +0 -0
- /amulet/{level/bedrock/chunk/components → mesh}/__init__.py +0 -0
- {amulet_core-2.0a6.dist-info → amulet_core-2.0a8.dist-info}/entry_points.txt +0 -0
- {amulet_core-2.0a6.dist-info → amulet_core-2.0a8.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
from typing import TypeAlias
|
|
2
|
+
import numpy
|
|
3
|
+
import itertools
|
|
4
|
+
|
|
5
|
+
from amulet.mesh.block import (
|
|
6
|
+
BlockMesh,
|
|
7
|
+
BlockMeshPart,
|
|
8
|
+
Triangle,
|
|
9
|
+
Vertex,
|
|
10
|
+
FloatVec3,
|
|
11
|
+
FloatVec2,
|
|
12
|
+
BlockMeshTransparency,
|
|
13
|
+
BlockMeshCullDirection,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
BoundsType: TypeAlias = tuple[
|
|
17
|
+
tuple[float, float], tuple[float, float], tuple[float, float]
|
|
18
|
+
]
|
|
19
|
+
TextureUVType: TypeAlias = tuple[
|
|
20
|
+
tuple[float, float, float, float],
|
|
21
|
+
tuple[float, float, float, float],
|
|
22
|
+
tuple[float, float, float, float],
|
|
23
|
+
tuple[float, float, float, float],
|
|
24
|
+
tuple[float, float, float, float],
|
|
25
|
+
tuple[float, float, float, float],
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
UNIT_BOX_COORDINATES = numpy.array(
|
|
29
|
+
list(itertools.product((0, 1), (0, 1), (0, 1)))
|
|
30
|
+
) # X, Y, Z
|
|
31
|
+
|
|
32
|
+
CULL_DIRECTION_NAMES = (
|
|
33
|
+
"down",
|
|
34
|
+
"up",
|
|
35
|
+
"north",
|
|
36
|
+
"east",
|
|
37
|
+
"south",
|
|
38
|
+
"west",
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
# This maps face direction to the vertices used (defined in UNIT_BOX_COORDINATES)
|
|
42
|
+
VERTEX_INDEXES = (
|
|
43
|
+
numpy.array([0, 4, 5, 1]),
|
|
44
|
+
numpy.array([3, 7, 6, 2]),
|
|
45
|
+
numpy.array([4, 0, 2, 6]),
|
|
46
|
+
numpy.array([5, 4, 6, 7]),
|
|
47
|
+
numpy.array([1, 5, 7, 3]),
|
|
48
|
+
numpy.array([0, 1, 3, 2]),
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
# This maps face direction to the vertices used (defined in UNIT_BOX_COORDINATES)
|
|
52
|
+
CUBE_FACE_LUT = dict(zip(CULL_DIRECTION_NAMES, VERTEX_INDEXES))
|
|
53
|
+
|
|
54
|
+
TRI_FACE = numpy.array([0, 1, 2, 0, 2, 3], numpy.uint32)
|
|
55
|
+
|
|
56
|
+
# cube_vert_lut = { # This maps from vertex index to index in [minx, miny, minz, maxx, maxy, maxz]
|
|
57
|
+
# 1: [0, 1, 5],
|
|
58
|
+
# 3: [0, 4, 5],
|
|
59
|
+
# 0: [0, 1, 2],
|
|
60
|
+
# 2: [0, 4, 2],
|
|
61
|
+
# 5: [3, 1, 5],
|
|
62
|
+
# 7: [3, 4, 5],
|
|
63
|
+
# 4: [3, 1, 2],
|
|
64
|
+
# 6: [3, 4, 2],
|
|
65
|
+
# }
|
|
66
|
+
#
|
|
67
|
+
# # combines the above two to map from face to index in [minx, miny, minz, maxx, maxy, maxz]. Used to index a numpy array
|
|
68
|
+
# # The above two have been kept separate because the merged result is unintuitive and difficult to edit.
|
|
69
|
+
# cube_lut = {
|
|
70
|
+
# face_dir_: [
|
|
71
|
+
# vert_coord_ for vert_ in vert_index_ for vert_coord_ in cube_vert_lut[vert_]
|
|
72
|
+
# ]
|
|
73
|
+
# for face_dir_, vert_index_ in CUBE_FACE_LUT.items()
|
|
74
|
+
# }
|
|
75
|
+
|
|
76
|
+
UV_ROTATION_LUT = [0, 3, 2, 3, 2, 1, 0, 1] # remap
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
# tvert_lut = { # TODO: implement this for the cases where the UV is not defined
|
|
80
|
+
# 'down': [],
|
|
81
|
+
# 'up': [],
|
|
82
|
+
# 'north': [],
|
|
83
|
+
# 'east': [],
|
|
84
|
+
# 'south': [],
|
|
85
|
+
# 'west': []
|
|
86
|
+
# }
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def get_cube(
|
|
90
|
+
down: str,
|
|
91
|
+
up: str,
|
|
92
|
+
north: str,
|
|
93
|
+
east: str,
|
|
94
|
+
south: str,
|
|
95
|
+
west: str,
|
|
96
|
+
transparency: BlockMeshTransparency = BlockMeshTransparency.FullOpaque,
|
|
97
|
+
tint: tuple[int, int, int] = (1, 1, 1),
|
|
98
|
+
bounds: BoundsType = ((0, 1), (0, 1), (0, 1)),
|
|
99
|
+
texture_uv: TextureUVType = ((0, 0, 1, 1),) * 6,
|
|
100
|
+
do_not_cull: tuple[bool, bool, bool, bool, bool, bool] = (
|
|
101
|
+
False,
|
|
102
|
+
False,
|
|
103
|
+
False,
|
|
104
|
+
False,
|
|
105
|
+
False,
|
|
106
|
+
False,
|
|
107
|
+
),
|
|
108
|
+
) -> BlockMesh:
|
|
109
|
+
texture_paths: dict[str, int] = {}
|
|
110
|
+
mesh_parts: list[tuple[list[Vertex], list[Triangle]] | None] = [
|
|
111
|
+
None,
|
|
112
|
+
None,
|
|
113
|
+
None,
|
|
114
|
+
None,
|
|
115
|
+
None,
|
|
116
|
+
None,
|
|
117
|
+
None,
|
|
118
|
+
]
|
|
119
|
+
box_coordinates = list(itertools.product(*bounds))
|
|
120
|
+
tint_vec = FloatVec3(*tint)
|
|
121
|
+
|
|
122
|
+
for (
|
|
123
|
+
cull_direction,
|
|
124
|
+
vertex_index,
|
|
125
|
+
do_not_cull_face,
|
|
126
|
+
texture_path,
|
|
127
|
+
texture_coords,
|
|
128
|
+
) in zip(
|
|
129
|
+
(
|
|
130
|
+
BlockMeshCullDirection.CullDown,
|
|
131
|
+
BlockMeshCullDirection.CullUp,
|
|
132
|
+
BlockMeshCullDirection.CullNorth,
|
|
133
|
+
BlockMeshCullDirection.CullEast,
|
|
134
|
+
BlockMeshCullDirection.CullSouth,
|
|
135
|
+
BlockMeshCullDirection.CullWest,
|
|
136
|
+
),
|
|
137
|
+
VERTEX_INDEXES,
|
|
138
|
+
do_not_cull,
|
|
139
|
+
(down, up, north, east, south, west),
|
|
140
|
+
texture_uv,
|
|
141
|
+
):
|
|
142
|
+
# Get the index of the texture path. Add if it is not contained.
|
|
143
|
+
texture_index = texture_paths.setdefault(texture_path, len(texture_paths))
|
|
144
|
+
if do_not_cull_face:
|
|
145
|
+
cull_direction = BlockMeshCullDirection.CullNone
|
|
146
|
+
part = mesh_parts[cull_direction]
|
|
147
|
+
if part is None:
|
|
148
|
+
mesh_parts[cull_direction] = part = ([], [])
|
|
149
|
+
verts, tris = part
|
|
150
|
+
vert_count = len(verts)
|
|
151
|
+
|
|
152
|
+
for i in range(4):
|
|
153
|
+
x, y, z = box_coordinates[vertex_index[i]]
|
|
154
|
+
uvx = texture_coords[UV_ROTATION_LUT[i * 2]]
|
|
155
|
+
uvy = texture_coords[UV_ROTATION_LUT[i * 2 + 1]]
|
|
156
|
+
verts.append(
|
|
157
|
+
Vertex(
|
|
158
|
+
FloatVec3(x, y, z),
|
|
159
|
+
FloatVec2(uvx, uvy),
|
|
160
|
+
tint_vec,
|
|
161
|
+
)
|
|
162
|
+
)
|
|
163
|
+
for a, b, c in TRI_FACE.reshape((2, 3)):
|
|
164
|
+
tris.append(
|
|
165
|
+
Triangle(a + vert_count, b + vert_count, c + vert_count, texture_index)
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
def create_part(
|
|
169
|
+
part: tuple[list[Vertex], list[Triangle]] | None
|
|
170
|
+
) -> BlockMeshPart | None:
|
|
171
|
+
return None if part is None else BlockMeshPart(*part)
|
|
172
|
+
|
|
173
|
+
return BlockMesh(
|
|
174
|
+
transparency,
|
|
175
|
+
list(texture_paths),
|
|
176
|
+
(
|
|
177
|
+
create_part(mesh_parts[0]),
|
|
178
|
+
create_part(mesh_parts[1]),
|
|
179
|
+
create_part(mesh_parts[2]),
|
|
180
|
+
create_part(mesh_parts[3]),
|
|
181
|
+
create_part(mesh_parts[4]),
|
|
182
|
+
create_part(mesh_parts[5]),
|
|
183
|
+
create_part(mesh_parts[6]),
|
|
184
|
+
),
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def get_unit_cube(
|
|
189
|
+
down: str,
|
|
190
|
+
up: str,
|
|
191
|
+
north: str,
|
|
192
|
+
east: str,
|
|
193
|
+
south: str,
|
|
194
|
+
west: str,
|
|
195
|
+
transparency: BlockMeshTransparency = BlockMeshTransparency.FullOpaque,
|
|
196
|
+
tint: tuple[int, int, int] = (1, 1, 1),
|
|
197
|
+
) -> BlockMesh:
|
|
198
|
+
return get_cube(down, up, north, east, south, west, transparency, tint)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import TYPE_CHECKING
|
|
3
|
+
|
|
4
|
+
from amulet.mesh.block import BlockMesh
|
|
5
|
+
from ._cube import get_unit_cube
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from amulet.resource_pack.abc import BaseResourcePackManager
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def get_missing_block(resource_pack: BaseResourcePackManager) -> BlockMesh:
|
|
12
|
+
texture_path = resource_pack.get_texture_path("minecraft", "missing_no")
|
|
13
|
+
return get_unit_cube(
|
|
14
|
+
texture_path,
|
|
15
|
+
texture_path,
|
|
16
|
+
texture_path,
|
|
17
|
+
texture_path,
|
|
18
|
+
texture_path,
|
|
19
|
+
texture_path,
|
|
20
|
+
)
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
#include <string>
|
|
2
|
+
#include <array>
|
|
3
|
+
#include <functional>
|
|
4
|
+
#include "block_mesh.hpp"
|
|
5
|
+
|
|
6
|
+
namespace Amulet {
|
|
7
|
+
|
|
8
|
+
const std::array<BlockMeshCullDirection, 4> roty_map = { BlockMeshCullNorth, BlockMeshCullEast, BlockMeshCullSouth, BlockMeshCullWest };
|
|
9
|
+
|
|
10
|
+
const RotationCullMapType RotationCullMap = []() {
|
|
11
|
+
RotationCullMapType cull_map;
|
|
12
|
+
for (std::int8_t roty = -3; roty < 4; roty++) {
|
|
13
|
+
// Create the rotated Y array
|
|
14
|
+
std::array<BlockMeshCullDirection, 4> roty_map_rotated;
|
|
15
|
+
auto split_y_point = 0 <= roty ? roty : roty + roty_map.size();
|
|
16
|
+
std::copy(roty_map.begin() + split_y_point, roty_map.end(), roty_map_rotated.begin());
|
|
17
|
+
std::copy(roty_map.begin(), roty_map.begin() + split_y_point, roty_map_rotated.end() - split_y_point);
|
|
18
|
+
// Create the X array
|
|
19
|
+
const std::array<BlockMeshCullDirection, 4> rotx_map = { roty_map_rotated[0], BlockMeshCullDown, roty_map_rotated[2], BlockMeshCullUp };
|
|
20
|
+
|
|
21
|
+
for (std::int8_t rotx = -3; rotx < 4; rotx++) {
|
|
22
|
+
// Create the rotated X array
|
|
23
|
+
std::array<BlockMeshCullDirection, 4> rotx_map_rotated;
|
|
24
|
+
auto split_x_point = 0 <= rotx ? rotx : rotx + rotx_map.size();
|
|
25
|
+
std::copy(rotx_map.begin() + split_x_point, rotx_map.end(), rotx_map_rotated.begin());
|
|
26
|
+
std::copy(rotx_map.begin(), rotx_map.begin() + split_x_point, rotx_map_rotated.end() - split_x_point);
|
|
27
|
+
|
|
28
|
+
cull_map[std::make_pair(roty, rotx)] = {
|
|
29
|
+
BlockMeshCullNone,
|
|
30
|
+
rotx_map_rotated[3],
|
|
31
|
+
rotx_map_rotated[1],
|
|
32
|
+
rotx_map_rotated[0],
|
|
33
|
+
roty_map_rotated[1],
|
|
34
|
+
rotx_map_rotated[2],
|
|
35
|
+
roty_map_rotated[3]
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return cull_map;
|
|
40
|
+
}();
|
|
41
|
+
|
|
42
|
+
BlockMesh merge_block_meshes(std::vector<std::reference_wrapper<const BlockMesh>> meshes) {
|
|
43
|
+
BlockMesh new_mesh;
|
|
44
|
+
new_mesh.transparency = BlockMeshTransparency::Partial;
|
|
45
|
+
std::map<std::string, size_t> texture_index_map;
|
|
46
|
+
for (const auto& wrapper : meshes) {
|
|
47
|
+
const auto& temp_mesh = wrapper.get();
|
|
48
|
+
// Get the minimum transparency of the two meshes.
|
|
49
|
+
new_mesh.transparency = std::min(new_mesh.transparency, temp_mesh.transparency);
|
|
50
|
+
|
|
51
|
+
// Copy over mesh parts
|
|
52
|
+
for (std::uint8_t cull_direction = 0; cull_direction < 7; cull_direction++) {
|
|
53
|
+
const auto& temp_mesh_part = temp_mesh.parts[cull_direction];
|
|
54
|
+
if (temp_mesh_part) {
|
|
55
|
+
auto& new_mesh_part = new_mesh.parts[cull_direction];
|
|
56
|
+
if (!new_mesh_part) {
|
|
57
|
+
// Initialise the mesh part if it is null.
|
|
58
|
+
new_mesh_part = BlockMeshPart();
|
|
59
|
+
}
|
|
60
|
+
// Get the number of triangles before copying
|
|
61
|
+
size_t vert_count = new_mesh_part->verts.size();
|
|
62
|
+
size_t triangle_count = new_mesh_part->triangles.size();
|
|
63
|
+
|
|
64
|
+
auto& new_verts = new_mesh_part->verts;
|
|
65
|
+
auto& temp_verts = temp_mesh_part->verts;
|
|
66
|
+
auto& new_triangles = new_mesh_part->triangles;
|
|
67
|
+
auto& temp_triangles = temp_mesh_part->triangles;
|
|
68
|
+
|
|
69
|
+
// Copy over vertices
|
|
70
|
+
new_verts.insert(
|
|
71
|
+
new_verts.end(),
|
|
72
|
+
temp_verts.begin(),
|
|
73
|
+
temp_verts.end());
|
|
74
|
+
// Copy over triangles
|
|
75
|
+
new_triangles.insert(
|
|
76
|
+
new_triangles.end(),
|
|
77
|
+
temp_triangles.begin(),
|
|
78
|
+
temp_triangles.end());
|
|
79
|
+
|
|
80
|
+
for (size_t i = triangle_count; i < new_mesh_part->triangles.size(); i++) {
|
|
81
|
+
// Update the triangle indexes
|
|
82
|
+
auto& triangle = new_mesh_part->triangles[i];
|
|
83
|
+
triangle.vert_index_a += vert_count;
|
|
84
|
+
triangle.vert_index_b += vert_count;
|
|
85
|
+
triangle.vert_index_c += vert_count;
|
|
86
|
+
if (temp_mesh.textures.size() <= triangle.texture_index) {
|
|
87
|
+
throw std::invalid_argument("Texture index is higher than the number of textures.");
|
|
88
|
+
}
|
|
89
|
+
const auto& texture_path = temp_mesh.textures[triangle.texture_index];
|
|
90
|
+
auto it = texture_index_map.find(texture_path);
|
|
91
|
+
if (it == texture_index_map.end()) {
|
|
92
|
+
// Texture has not been added yet.
|
|
93
|
+
size_t texture_index = new_mesh.textures.size();
|
|
94
|
+
new_mesh.textures.push_back(texture_path);
|
|
95
|
+
triangle.texture_index = texture_index;
|
|
96
|
+
texture_index_map[texture_path] = texture_index;
|
|
97
|
+
} else {
|
|
98
|
+
triangle.texture_index = it->second;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return new_mesh;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
#include <array>
|
|
3
|
+
#include <cmath>
|
|
4
|
+
#include <map>
|
|
5
|
+
#include <numbers>
|
|
6
|
+
#include <optional>
|
|
7
|
+
#include <stdexcept>
|
|
8
|
+
#include <string>
|
|
9
|
+
#include <vector>
|
|
10
|
+
#include <functional>
|
|
11
|
+
|
|
12
|
+
namespace Amulet {
|
|
13
|
+
|
|
14
|
+
class FloatVec2 {
|
|
15
|
+
public:
|
|
16
|
+
float x;
|
|
17
|
+
float y;
|
|
18
|
+
|
|
19
|
+
FloatVec2(float x, float y)
|
|
20
|
+
: x(x)
|
|
21
|
+
, y(y)
|
|
22
|
+
{
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
class FloatVec3 {
|
|
27
|
+
public:
|
|
28
|
+
float x;
|
|
29
|
+
float y;
|
|
30
|
+
float z;
|
|
31
|
+
|
|
32
|
+
FloatVec3(float x, float y, float z)
|
|
33
|
+
: x(x)
|
|
34
|
+
, y(y)
|
|
35
|
+
, z(z)
|
|
36
|
+
{
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
class Vertex {
|
|
41
|
+
public:
|
|
42
|
+
// The world coordinate
|
|
43
|
+
FloatVec3 coord;
|
|
44
|
+
// The texture coordinate
|
|
45
|
+
FloatVec2 texture_coord;
|
|
46
|
+
// The tint colour
|
|
47
|
+
FloatVec3 tint;
|
|
48
|
+
|
|
49
|
+
Vertex(
|
|
50
|
+
const FloatVec3& coord,
|
|
51
|
+
const FloatVec2& texture_coord,
|
|
52
|
+
const FloatVec3& tint)
|
|
53
|
+
: coord(coord)
|
|
54
|
+
, texture_coord(texture_coord)
|
|
55
|
+
, tint(tint)
|
|
56
|
+
{
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
class Triangle {
|
|
61
|
+
public:
|
|
62
|
+
// The indicies of the vertexes in BlockMeshPart::verts.
|
|
63
|
+
size_t vert_index_a;
|
|
64
|
+
size_t vert_index_b;
|
|
65
|
+
size_t vert_index_c;
|
|
66
|
+
// The index of the texture in BlockMesh::textures.
|
|
67
|
+
size_t texture_index;
|
|
68
|
+
|
|
69
|
+
Triangle(
|
|
70
|
+
size_t vert_index_a,
|
|
71
|
+
size_t vert_index_b,
|
|
72
|
+
size_t vert_index_c,
|
|
73
|
+
size_t texture_index)
|
|
74
|
+
: vert_index_a(vert_index_a)
|
|
75
|
+
, vert_index_b(vert_index_b)
|
|
76
|
+
, vert_index_c(vert_index_c)
|
|
77
|
+
, texture_index(texture_index)
|
|
78
|
+
{
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
class BlockMeshPart {
|
|
83
|
+
public:
|
|
84
|
+
// The vertices in this mesh part.
|
|
85
|
+
std::vector<Vertex> verts;
|
|
86
|
+
// The triangles in this mesh part.
|
|
87
|
+
std::vector<Triangle> triangles;
|
|
88
|
+
|
|
89
|
+
BlockMeshPart(): verts(), triangles() {}
|
|
90
|
+
BlockMeshPart(
|
|
91
|
+
const std::vector<Vertex>& verts,
|
|
92
|
+
const std::vector<Triangle>& triangles)
|
|
93
|
+
: verts(verts)
|
|
94
|
+
, triangles(triangles)
|
|
95
|
+
{
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
enum class BlockMeshTransparency : std::uint8_t {
|
|
100
|
+
// The block is a full block with opaque textures
|
|
101
|
+
FullOpaque,
|
|
102
|
+
// The block is a full block with transparent / translucent textures
|
|
103
|
+
FullTranslucent,
|
|
104
|
+
// The block is not a full block
|
|
105
|
+
Partial
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
enum BlockMeshCullDirection {
|
|
109
|
+
BlockMeshCullNone,
|
|
110
|
+
BlockMeshCullUp,
|
|
111
|
+
BlockMeshCullDown,
|
|
112
|
+
BlockMeshCullNorth,
|
|
113
|
+
BlockMeshCullEast,
|
|
114
|
+
BlockMeshCullSouth,
|
|
115
|
+
BlockMeshCullWest
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
typedef std::map<
|
|
119
|
+
std::pair<std::int8_t, std::int8_t>,
|
|
120
|
+
std::array<BlockMeshCullDirection, 7>>
|
|
121
|
+
RotationCullMapType;
|
|
122
|
+
|
|
123
|
+
// For every combination of 90 degree rotations in y and x axis
|
|
124
|
+
// gives the rotated cull direction.
|
|
125
|
+
extern const RotationCullMapType RotationCullMap;
|
|
126
|
+
|
|
127
|
+
class BlockMesh {
|
|
128
|
+
public:
|
|
129
|
+
BlockMeshTransparency transparency;
|
|
130
|
+
std::vector<std::string> textures;
|
|
131
|
+
// The mesh parts. Index matches BlockMeshCullDirection.
|
|
132
|
+
std::array<std::optional<BlockMeshPart>, 7> parts;
|
|
133
|
+
|
|
134
|
+
BlockMesh()
|
|
135
|
+
: transparency()
|
|
136
|
+
, textures()
|
|
137
|
+
, parts()
|
|
138
|
+
{
|
|
139
|
+
}
|
|
140
|
+
BlockMesh(
|
|
141
|
+
BlockMeshTransparency transparency,
|
|
142
|
+
const std::vector<std::string>& textures,
|
|
143
|
+
const std::array<std::optional<BlockMeshPart>, 7>& parts)
|
|
144
|
+
: transparency(transparency)
|
|
145
|
+
, textures(textures)
|
|
146
|
+
, parts(parts)
|
|
147
|
+
{
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
BlockMesh rotate(std::int8_t rotx, std::int8_t roty) const
|
|
151
|
+
{
|
|
152
|
+
if (rotx || roty) {
|
|
153
|
+
auto rotation_key = std::make_pair(rotx, roty);
|
|
154
|
+
auto it = RotationCullMap.find(rotation_key);
|
|
155
|
+
if (it != RotationCullMap.end()) {
|
|
156
|
+
const auto& cull_map = it->second;
|
|
157
|
+
BlockMesh mesh;
|
|
158
|
+
mesh.transparency = transparency;
|
|
159
|
+
mesh.textures = textures;
|
|
160
|
+
|
|
161
|
+
// Compuate rotation values
|
|
162
|
+
float theta_x = std::numbers::pi * rotx / 2.0;
|
|
163
|
+
float theta_y = std::numbers::pi * roty / 2.0;
|
|
164
|
+
float sin_x = std::sin(theta_x);
|
|
165
|
+
float cos_x = std::cos(theta_x);
|
|
166
|
+
float sin_y = std::sin(theta_y);
|
|
167
|
+
float cos_y = std::cos(theta_y);
|
|
168
|
+
|
|
169
|
+
for (std::uint8_t cull_direction = 0; cull_direction < 7; cull_direction++) {
|
|
170
|
+
// Copy the part to the new cull direction.
|
|
171
|
+
auto new_cull_direction = cull_map[cull_direction];
|
|
172
|
+
auto& part = mesh.parts[new_cull_direction] = parts[cull_direction];
|
|
173
|
+
|
|
174
|
+
if (part) {
|
|
175
|
+
// Rotate the vertex coords.
|
|
176
|
+
for (auto& vertex : part->verts) {
|
|
177
|
+
auto& coord = vertex.coord;
|
|
178
|
+
float x = coord.x - 0.5;
|
|
179
|
+
float y = coord.y - 0.5;
|
|
180
|
+
float z = coord.z - 0.5;
|
|
181
|
+
|
|
182
|
+
// Rotate in X axis
|
|
183
|
+
float y_ = y * cos_x - z * sin_x;
|
|
184
|
+
z = y * sin_x + z * cos_x;
|
|
185
|
+
y = y_;
|
|
186
|
+
|
|
187
|
+
// Rotate in Y axis
|
|
188
|
+
float x_ = x * cos_y + z * sin_y;
|
|
189
|
+
z = -x * sin_y + z * cos_y;
|
|
190
|
+
x = x_;
|
|
191
|
+
|
|
192
|
+
coord.x = x + 0.5;
|
|
193
|
+
coord.y = y + 0.5;
|
|
194
|
+
coord.z = z + 0.5;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return mesh;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return *this;
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
BlockMesh merge_block_meshes(std::vector<std::reference_wrapper<const BlockMesh>>);
|
|
206
|
+
|
|
207
|
+
}
|
amulet/mesh/util.py
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import numpy
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def rotate_3d(
|
|
5
|
+
verts: numpy.ndarray, x: float, y: float, z: float, dx: float, dy: float, dz: float
|
|
6
|
+
) -> numpy.ndarray:
|
|
7
|
+
sb, sh, sa = numpy.sin(numpy.radians([x, y, z]))
|
|
8
|
+
cb, ch, ca = numpy.cos(numpy.radians([x, y, z]))
|
|
9
|
+
trmtx = numpy.array(
|
|
10
|
+
[
|
|
11
|
+
[ch * ca, -ch * sa * cb + sh * sb, ch * sa * sb + sh * cb],
|
|
12
|
+
[sa, ca * cb, -ca * sb],
|
|
13
|
+
[-sh * ca, sh * sa * cb + ch * sb, -sh * sa * sb + ch * cb],
|
|
14
|
+
]
|
|
15
|
+
)
|
|
16
|
+
origin = numpy.array([dx, dy, dz])
|
|
17
|
+
return numpy.matmul(verts - origin, trmtx) + origin # type: ignore
|
amulet/player.py
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import Tuple
|
|
4
|
-
|
|
5
3
|
from amulet.data_types import DimensionId
|
|
6
4
|
|
|
7
5
|
LOCAL_PLAYER = "~local_player"
|
|
@@ -12,8 +10,8 @@ class Player:
|
|
|
12
10
|
self,
|
|
13
11
|
player_id: str,
|
|
14
12
|
dimension_id: DimensionId,
|
|
15
|
-
location:
|
|
16
|
-
rotation:
|
|
13
|
+
location: tuple[float, float, float],
|
|
14
|
+
rotation: tuple[float, float],
|
|
17
15
|
) -> None:
|
|
18
16
|
"""
|
|
19
17
|
Creates a new instance of :class:`Player` with the given UUID, location, and rotation
|
|
@@ -49,12 +47,12 @@ class Player:
|
|
|
49
47
|
return self._player_id
|
|
50
48
|
|
|
51
49
|
@property
|
|
52
|
-
def location(self) ->
|
|
50
|
+
def location(self) -> tuple[float, float, float]:
|
|
53
51
|
"""The current location of the player in the world"""
|
|
54
52
|
return self._location
|
|
55
53
|
|
|
56
54
|
@property
|
|
57
|
-
def rotation(self) ->
|
|
55
|
+
def rotation(self) -> tuple[float, float]:
|
|
58
56
|
"""The current rotation of the player in the world"""
|
|
59
57
|
return self._rotation
|
|
60
58
|
|