amulet-core 2.0.7a0__cp312-cp312-macosx_10_15_universal2.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.
- amulet/core/__init__.py +38 -0
- amulet/core/__init__.pyi +31 -0
- amulet/core/__pyinstaller/__init__.py +2 -0
- amulet/core/__pyinstaller/hook-amulet.core.py +4 -0
- amulet/core/_amulet_core.cpython-312-darwin.so +0 -0
- amulet/core/_amulet_core.pyi +7 -0
- amulet/core/_version.py +21 -0
- amulet/core/amulet_coreConfig.cmake +23 -0
- amulet/core/biome/__init__.pyi +75 -0
- amulet/core/biome/biome.hpp +53 -0
- amulet/core/block/__init__.pyi +273 -0
- amulet/core/block/block.hpp +156 -0
- amulet/core/block_entity/__init__.pyi +78 -0
- amulet/core/block_entity/block_entity.hpp +84 -0
- amulet/core/chunk/__init__.pyi +67 -0
- amulet/core/chunk/chunk.hpp +126 -0
- amulet/core/chunk/component/__init__.pyi +15 -0
- amulet/core/chunk/component/biome_3d_component.hpp +99 -0
- amulet/core/chunk/component/block_component.hpp +101 -0
- amulet/core/chunk/component/block_component.pyi +28 -0
- amulet/core/chunk/component/block_entity_component.hpp +119 -0
- amulet/core/chunk/component/section_array_map.hpp +178 -0
- amulet/core/chunk/component/section_array_map.pyi +112 -0
- amulet/core/dll.hpp +21 -0
- amulet/core/entity/__init__.pyi +105 -0
- amulet/core/entity/entity.hpp +100 -0
- amulet/core/libamulet_core.dylib +0 -0
- amulet/core/palette/__init__.pyi +8 -0
- amulet/core/palette/biome_palette.hpp +65 -0
- amulet/core/palette/biome_palette.pyi +48 -0
- amulet/core/palette/block_palette.hpp +71 -0
- amulet/core/palette/block_palette.pyi +52 -0
- amulet/core/py.typed +0 -0
- amulet/core/selection/__init__.pyi +25 -0
- amulet/core/selection/box.hpp +97 -0
- amulet/core/selection/box.pyi +239 -0
- amulet/core/selection/box_group.hpp +89 -0
- amulet/core/selection/box_group.pyi +222 -0
- amulet/core/selection/cuboid.hpp +41 -0
- amulet/core/selection/cuboid.pyi +49 -0
- amulet/core/selection/ellipsoid.hpp +42 -0
- amulet/core/selection/ellipsoid.pyi +47 -0
- amulet/core/selection/shape.hpp +73 -0
- amulet/core/selection/shape.pyi +56 -0
- amulet/core/selection/shape_group.hpp +73 -0
- amulet/core/selection/shape_group.pyi +118 -0
- amulet/core/version/__init__.pyi +138 -0
- amulet/core/version/version.hpp +206 -0
- amulet_core-2.0.7a0.dist-info/METADATA +112 -0
- amulet_core-2.0.7a0.dist-info/RECORD +53 -0
- amulet_core-2.0.7a0.dist-info/WHEEL +5 -0
- amulet_core-2.0.7a0.dist-info/entry_points.txt +2 -0
- amulet_core-2.0.7a0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <map>
|
|
4
|
+
#include <stdexcept>
|
|
5
|
+
|
|
6
|
+
#include <amulet/core/biome/biome.hpp>
|
|
7
|
+
#include <amulet/core/version/version.hpp>
|
|
8
|
+
|
|
9
|
+
namespace Amulet {
|
|
10
|
+
|
|
11
|
+
class BiomePalette : public VersionRangeContainer {
|
|
12
|
+
private:
|
|
13
|
+
std::vector<Biome> _index_to_biome;
|
|
14
|
+
std::map<Biome, size_t> _biome_to_index;
|
|
15
|
+
|
|
16
|
+
public:
|
|
17
|
+
const std::vector<Biome>& get_biomes() const { return _index_to_biome; }
|
|
18
|
+
|
|
19
|
+
template <typename VersionRangeT>
|
|
20
|
+
BiomePalette(VersionRangeT&& version_range)
|
|
21
|
+
: VersionRangeContainer(std::forward<VersionRangeT>(version_range))
|
|
22
|
+
, _index_to_biome()
|
|
23
|
+
, _biome_to_index()
|
|
24
|
+
{
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
AMULET_CORE_EXPORT void serialise(BinaryWriter&) const;
|
|
28
|
+
AMULET_CORE_EXPORT static BiomePalette deserialise(BinaryReader&);
|
|
29
|
+
|
|
30
|
+
bool operator==(const BiomePalette& other) const
|
|
31
|
+
{
|
|
32
|
+
return _index_to_biome == other._index_to_biome;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
size_t size() const { return _index_to_biome.size(); }
|
|
36
|
+
|
|
37
|
+
const Biome& index_to_biome(size_t index) const
|
|
38
|
+
{
|
|
39
|
+
return _index_to_biome.at(index);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
size_t biome_to_index(const Biome& biome)
|
|
43
|
+
{
|
|
44
|
+
auto it = _biome_to_index.find(biome);
|
|
45
|
+
if (it != _biome_to_index.end()) {
|
|
46
|
+
return it->second;
|
|
47
|
+
}
|
|
48
|
+
const auto& version_range = get_version_range();
|
|
49
|
+
if (!version_range.contains(biome.get_platform(), biome.get_version())) {
|
|
50
|
+
throw std::invalid_argument(
|
|
51
|
+
"Biome(\"" + biome.get_platform() + "\", " + biome.get_version().toString() + ") is incompatible with VersionRange(\"" + version_range.get_platform() + "\", " + version_range.get_min_version().toString() + ", " + version_range.get_max_version().toString() + ").");
|
|
52
|
+
}
|
|
53
|
+
size_t index = _index_to_biome.size();
|
|
54
|
+
_index_to_biome.push_back(biome);
|
|
55
|
+
_biome_to_index[biome] = index;
|
|
56
|
+
return index;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
bool contains_biome(const Biome& biome) const
|
|
60
|
+
{
|
|
61
|
+
return _biome_to_index.contains(biome);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import collections.abc
|
|
4
|
+
import typing
|
|
5
|
+
|
|
6
|
+
import amulet.core.biome
|
|
7
|
+
import amulet.core.version
|
|
8
|
+
|
|
9
|
+
__all__: list[str] = ["BiomePalette"]
|
|
10
|
+
|
|
11
|
+
class BiomePalette(amulet.core.version.VersionRangeContainer):
|
|
12
|
+
@typing.overload
|
|
13
|
+
def __contains__(self, arg0: typing.SupportsInt) -> bool: ...
|
|
14
|
+
@typing.overload
|
|
15
|
+
def __contains__(self, arg0: amulet.core.biome.Biome) -> bool: ...
|
|
16
|
+
@typing.overload
|
|
17
|
+
def __getitem__(self, arg0: typing.SupportsInt) -> amulet.core.biome.Biome: ...
|
|
18
|
+
@typing.overload
|
|
19
|
+
def __getitem__(self, item: slice) -> list[amulet.core.biome.Biome]: ...
|
|
20
|
+
def __init__(self, arg0: amulet.core.version.VersionRange) -> None: ...
|
|
21
|
+
def __iter__(self) -> collections.abc.Iterator[amulet.core.biome.Biome]: ...
|
|
22
|
+
def __len__(self) -> int: ...
|
|
23
|
+
def __repr__(self) -> str: ...
|
|
24
|
+
def __reversed__(self) -> collections.abc.Iterator[amulet.core.biome.Biome]: ...
|
|
25
|
+
def biome_to_index(self, arg0: amulet.core.biome.Biome) -> int:
|
|
26
|
+
"""
|
|
27
|
+
Get the index of the biome in the palette.
|
|
28
|
+
If it is not in the palette already it will be added first.
|
|
29
|
+
|
|
30
|
+
:param biome: The biome to get the index of.
|
|
31
|
+
:return: The index of the biome in the palette.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
def count(self, value: amulet.core.biome.Biome) -> int: ...
|
|
35
|
+
def index(
|
|
36
|
+
self,
|
|
37
|
+
value: amulet.core.biome.Biome,
|
|
38
|
+
start: typing.SupportsInt = 0,
|
|
39
|
+
stop: typing.SupportsInt = 9223372036854775807,
|
|
40
|
+
) -> int: ...
|
|
41
|
+
def index_to_biome(self, arg0: typing.SupportsInt) -> amulet.core.biome.Biome:
|
|
42
|
+
"""
|
|
43
|
+
Get the biome at the specified palette index.
|
|
44
|
+
|
|
45
|
+
:param index: The index to get
|
|
46
|
+
:return: The biome at that index
|
|
47
|
+
:raises IndexError if there is no biome at that index.
|
|
48
|
+
"""
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <map>
|
|
4
|
+
#include <stdexcept>
|
|
5
|
+
|
|
6
|
+
#include <amulet/io/binary_reader.hpp>
|
|
7
|
+
#include <amulet/io/binary_writer.hpp>
|
|
8
|
+
|
|
9
|
+
#include <amulet/core/block/block.hpp>
|
|
10
|
+
#include <amulet/core/dll.hpp>
|
|
11
|
+
#include <amulet/core/version/version.hpp>
|
|
12
|
+
|
|
13
|
+
namespace Amulet {
|
|
14
|
+
|
|
15
|
+
class BlockPalette : public VersionRangeContainer {
|
|
16
|
+
private:
|
|
17
|
+
std::vector<BlockStack> _index_to_block;
|
|
18
|
+
std::map<BlockStack, size_t> _block_to_index;
|
|
19
|
+
|
|
20
|
+
public:
|
|
21
|
+
const std::vector<BlockStack>& get_blocks() const { return _index_to_block; }
|
|
22
|
+
|
|
23
|
+
template <typename VersionRangeT>
|
|
24
|
+
BlockPalette(VersionRangeT&& version_range)
|
|
25
|
+
: VersionRangeContainer(std::forward<VersionRangeT>(version_range))
|
|
26
|
+
, _index_to_block()
|
|
27
|
+
, _block_to_index()
|
|
28
|
+
{
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
AMULET_CORE_EXPORT void serialise(BinaryWriter&) const;
|
|
32
|
+
AMULET_CORE_EXPORT static BlockPalette deserialise(BinaryReader&);
|
|
33
|
+
|
|
34
|
+
bool operator==(const BlockPalette& other) const
|
|
35
|
+
{
|
|
36
|
+
return _index_to_block == other._index_to_block;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
size_t size() const { return _index_to_block.size(); }
|
|
40
|
+
|
|
41
|
+
const BlockStack& index_to_block_stack(size_t index) const
|
|
42
|
+
{
|
|
43
|
+
return _index_to_block.at(index);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
size_t block_stack_to_index(const BlockStack& block_stack)
|
|
47
|
+
{
|
|
48
|
+
auto it = _block_to_index.find(block_stack);
|
|
49
|
+
if (it != _block_to_index.end()) {
|
|
50
|
+
return it->second;
|
|
51
|
+
}
|
|
52
|
+
auto version_range = get_version_range();
|
|
53
|
+
for (const auto& block : block_stack.get_blocks()) {
|
|
54
|
+
if (!version_range.contains(block.get_platform(), block.get_version())) {
|
|
55
|
+
throw std::invalid_argument(
|
|
56
|
+
"BlockStack(\"" + block.get_platform() + "\", " + block.get_version().toString() + ") is incompatible with VersionRange(\"" + version_range.get_platform() + "\", " + version_range.get_min_version().toString() + ", " + version_range.get_max_version().toString() + ").");
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
size_t index = _index_to_block.size();
|
|
60
|
+
_index_to_block.push_back(block_stack);
|
|
61
|
+
_block_to_index.emplace(block_stack, index);
|
|
62
|
+
return index;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
bool contains_block(const BlockStack& block) const
|
|
66
|
+
{
|
|
67
|
+
return _block_to_index.contains(block);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import collections.abc
|
|
4
|
+
import typing
|
|
5
|
+
|
|
6
|
+
import amulet.core.block
|
|
7
|
+
import amulet.core.version
|
|
8
|
+
|
|
9
|
+
__all__: list[str] = ["BlockPalette"]
|
|
10
|
+
|
|
11
|
+
class BlockPalette(amulet.core.version.VersionRangeContainer):
|
|
12
|
+
@typing.overload
|
|
13
|
+
def __contains__(self, arg0: typing.SupportsInt) -> bool: ...
|
|
14
|
+
@typing.overload
|
|
15
|
+
def __contains__(self, arg0: amulet.core.block.BlockStack) -> bool: ...
|
|
16
|
+
@typing.overload
|
|
17
|
+
def __getitem__(self, arg0: typing.SupportsInt) -> amulet.core.block.BlockStack: ...
|
|
18
|
+
@typing.overload
|
|
19
|
+
def __getitem__(self, item: slice) -> list[amulet.core.block.BlockStack]: ...
|
|
20
|
+
def __init__(self, arg0: amulet.core.version.VersionRange) -> None: ...
|
|
21
|
+
def __iter__(self) -> collections.abc.Iterator[amulet.core.block.BlockStack]: ...
|
|
22
|
+
def __len__(self) -> int: ...
|
|
23
|
+
def __repr__(self) -> str: ...
|
|
24
|
+
def __reversed__(
|
|
25
|
+
self,
|
|
26
|
+
) -> collections.abc.Iterator[amulet.core.block.BlockStack]: ...
|
|
27
|
+
def block_stack_to_index(self, arg0: amulet.core.block.BlockStack) -> int:
|
|
28
|
+
"""
|
|
29
|
+
Get the index of the block stack in the palette.
|
|
30
|
+
If it is not in the palette already it will be added first.
|
|
31
|
+
|
|
32
|
+
:param block_stack: The block stack to get the index of.
|
|
33
|
+
:return: The index of the block stack in the palette.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
def count(self, value: amulet.core.block.BlockStack) -> int: ...
|
|
37
|
+
def index(
|
|
38
|
+
self,
|
|
39
|
+
value: amulet.core.block.BlockStack,
|
|
40
|
+
start: typing.SupportsInt = 0,
|
|
41
|
+
stop: typing.SupportsInt = 9223372036854775807,
|
|
42
|
+
) -> int: ...
|
|
43
|
+
def index_to_block_stack(
|
|
44
|
+
self, arg0: typing.SupportsInt
|
|
45
|
+
) -> amulet.core.block.BlockStack:
|
|
46
|
+
"""
|
|
47
|
+
Get the block stack at the specified palette index.
|
|
48
|
+
|
|
49
|
+
:param index: The index to get
|
|
50
|
+
:return: The block stack at that index
|
|
51
|
+
:raises IndexError if there is no block stack at that index.
|
|
52
|
+
"""
|
amulet/core/py.typed
ADDED
|
File without changes
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from amulet.core.selection.box import SelectionBox
|
|
4
|
+
from amulet.core.selection.box_group import SelectionBoxGroup
|
|
5
|
+
from amulet.core.selection.cuboid import SelectionCuboid
|
|
6
|
+
from amulet.core.selection.ellipsoid import SelectionEllipsoid
|
|
7
|
+
from amulet.core.selection.shape import SelectionShape
|
|
8
|
+
from amulet.core.selection.shape_group import SelectionShapeGroup
|
|
9
|
+
|
|
10
|
+
from . import box, box_group, cuboid, ellipsoid, shape, shape_group
|
|
11
|
+
|
|
12
|
+
__all__: list[str] = [
|
|
13
|
+
"SelectionBox",
|
|
14
|
+
"SelectionBoxGroup",
|
|
15
|
+
"SelectionCuboid",
|
|
16
|
+
"SelectionEllipsoid",
|
|
17
|
+
"SelectionShape",
|
|
18
|
+
"SelectionShapeGroup",
|
|
19
|
+
"box",
|
|
20
|
+
"box_group",
|
|
21
|
+
"cuboid",
|
|
22
|
+
"ellipsoid",
|
|
23
|
+
"shape",
|
|
24
|
+
"shape_group",
|
|
25
|
+
]
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
#include <array>
|
|
3
|
+
#include <cstdint>
|
|
4
|
+
|
|
5
|
+
#include <amulet/core/dll.hpp>
|
|
6
|
+
|
|
7
|
+
namespace Amulet {
|
|
8
|
+
|
|
9
|
+
class Matrix4x4;
|
|
10
|
+
class SelectionBoxGroup;
|
|
11
|
+
|
|
12
|
+
// An axis aligned cuboid selection box.
|
|
13
|
+
class AMULET_CORE_EXPORT SelectionBox {
|
|
14
|
+
private:
|
|
15
|
+
std::int64_t _min_x;
|
|
16
|
+
std::int64_t _min_y;
|
|
17
|
+
std::int64_t _min_z;
|
|
18
|
+
std::uint64_t _size_x;
|
|
19
|
+
std::uint64_t _size_y;
|
|
20
|
+
std::uint64_t _size_z;
|
|
21
|
+
|
|
22
|
+
public:
|
|
23
|
+
SelectionBox(
|
|
24
|
+
std::int64_t min_x,
|
|
25
|
+
std::int64_t min_y,
|
|
26
|
+
std::int64_t min_z,
|
|
27
|
+
std::uint64_t size_x,
|
|
28
|
+
std::uint64_t size_y,
|
|
29
|
+
std::uint64_t size_z)
|
|
30
|
+
: _min_x(min_x)
|
|
31
|
+
, _min_y(min_y)
|
|
32
|
+
, _min_z(min_z)
|
|
33
|
+
, _size_x(size_x)
|
|
34
|
+
, _size_y(size_y)
|
|
35
|
+
, _size_z(size_z)
|
|
36
|
+
{
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
SelectionBox(
|
|
40
|
+
std::array<std::int64_t, 3> point_1,
|
|
41
|
+
std::array<std::int64_t, 3> point_2)
|
|
42
|
+
{
|
|
43
|
+
_min_x = std::min(point_1[0], point_2[0]);
|
|
44
|
+
_min_y = std::min(point_1[1], point_2[1]);
|
|
45
|
+
_min_z = std::min(point_1[2], point_2[2]);
|
|
46
|
+
_size_x = std::max(point_1[0], point_2[0]) - _min_x;
|
|
47
|
+
_size_y = std::max(point_1[1], point_2[1]) - _min_y;
|
|
48
|
+
_size_z = std::max(point_1[2], point_2[2]) - _min_z;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
SelectionBox(const SelectionBox& other)
|
|
52
|
+
: SelectionBox(
|
|
53
|
+
other.min_x(),
|
|
54
|
+
other.min_y(),
|
|
55
|
+
other.min_z(),
|
|
56
|
+
other.size_x(),
|
|
57
|
+
other.size_y(),
|
|
58
|
+
other.size_z())
|
|
59
|
+
{
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Accessors
|
|
63
|
+
std::int64_t min_x() const { return _min_x; }
|
|
64
|
+
std::int64_t min_y() const { return _min_y; }
|
|
65
|
+
std::int64_t min_z() const { return _min_z; }
|
|
66
|
+
std::int64_t max_x() const { return _min_x + _size_x; }
|
|
67
|
+
std::int64_t max_y() const { return _min_y + _size_y; }
|
|
68
|
+
std::int64_t max_z() const { return _min_z + _size_z; }
|
|
69
|
+
std::array<std::int64_t, 3> min() const { return { _min_x, _min_y, _min_z }; }
|
|
70
|
+
std::array<std::int64_t, 3> max() const { return { max_x(), max_y(), max_z() }; }
|
|
71
|
+
|
|
72
|
+
// Shape and volume
|
|
73
|
+
std::uint64_t size_x() const { return _size_x; }
|
|
74
|
+
std::uint64_t size_y() const { return _size_y; }
|
|
75
|
+
std::uint64_t size_z() const { return _size_z; }
|
|
76
|
+
std::array<std::uint64_t, 3> shape() const { return { _size_x, _size_y, _size_z }; }
|
|
77
|
+
std::uint64_t volume() const { return _size_x * _size_y * _size_z; }
|
|
78
|
+
|
|
79
|
+
// Contains and intersects
|
|
80
|
+
bool contains_block(std::int64_t x, std::int64_t y, std::int64_t z) const;
|
|
81
|
+
bool contains_point(double x, double y, double z) const;
|
|
82
|
+
bool contains_box(const SelectionBox& other) const;
|
|
83
|
+
bool intersects(const SelectionBox& other) const;
|
|
84
|
+
bool intersects(const SelectionBoxGroup& other) const;
|
|
85
|
+
bool touches_or_intersects(const SelectionBox& other) const;
|
|
86
|
+
bool touches(const SelectionBox& other) const;
|
|
87
|
+
|
|
88
|
+
// Transform
|
|
89
|
+
SelectionBox translate(std::int64_t dx, std::int64_t dy, std::int64_t dz) const;
|
|
90
|
+
SelectionBoxGroup transform(const Matrix4x4&) const;
|
|
91
|
+
|
|
92
|
+
// Operators
|
|
93
|
+
std::strong_ordering operator<=>(const SelectionBox&) const;
|
|
94
|
+
bool operator==(const SelectionBox&) const;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
} // namespace Amulet
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import types
|
|
4
|
+
import typing
|
|
5
|
+
|
|
6
|
+
import amulet.core.selection.box_group
|
|
7
|
+
import amulet.utils.matrix
|
|
8
|
+
|
|
9
|
+
__all__: list[str] = ["SelectionBox"]
|
|
10
|
+
|
|
11
|
+
class SelectionBox:
|
|
12
|
+
"""
|
|
13
|
+
The SelectionBox class represents a single cuboid selection.
|
|
14
|
+
|
|
15
|
+
When combined with :class:`~amulet.api.selection.SelectionBoxGroup` it can represent any arbitrary shape.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
@typing.overload
|
|
19
|
+
def __eq__(self, other: SelectionBox) -> bool: ...
|
|
20
|
+
@typing.overload
|
|
21
|
+
def __eq__(self, other: typing.Any) -> bool | types.NotImplementedType: ...
|
|
22
|
+
def __ge__(self, arg0: SelectionBox) -> bool: ...
|
|
23
|
+
def __gt__(self, arg0: SelectionBox) -> bool: ...
|
|
24
|
+
def __hash__(self) -> int: ...
|
|
25
|
+
@typing.overload
|
|
26
|
+
def __init__(
|
|
27
|
+
self,
|
|
28
|
+
min_x: typing.SupportsInt,
|
|
29
|
+
min_y: typing.SupportsInt,
|
|
30
|
+
min_z: typing.SupportsInt,
|
|
31
|
+
size_x: typing.SupportsInt,
|
|
32
|
+
size_y: typing.SupportsInt,
|
|
33
|
+
size_z: typing.SupportsInt,
|
|
34
|
+
) -> None:
|
|
35
|
+
"""
|
|
36
|
+
Construct a new SelectionBox instance.
|
|
37
|
+
|
|
38
|
+
>>> # a selection box that selects one block.
|
|
39
|
+
>>> box = SelectionBox(0, 0, 0, 1, 1, 1)
|
|
40
|
+
|
|
41
|
+
:param min_x: The minimum x coordinate of the box.
|
|
42
|
+
:param min_y: The minimum y coordinate of the box.
|
|
43
|
+
:param min_z: The minimum z coordinate of the box.
|
|
44
|
+
:param size_x: The size of the box in the x axis.
|
|
45
|
+
:param size_y: The size of the box in the y axis.
|
|
46
|
+
:param size_z: The size of the box in the z axis.
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
@typing.overload
|
|
50
|
+
def __init__(
|
|
51
|
+
self,
|
|
52
|
+
point_1: tuple[typing.SupportsInt, typing.SupportsInt, typing.SupportsInt],
|
|
53
|
+
point_2: tuple[typing.SupportsInt, typing.SupportsInt, typing.SupportsInt],
|
|
54
|
+
) -> None:
|
|
55
|
+
"""
|
|
56
|
+
Construct a new SelectionBox instance.
|
|
57
|
+
|
|
58
|
+
>>> # a selection box that selects one block.
|
|
59
|
+
>>> box = SelectionBox((0, 0, 0), (1, 1, 1))
|
|
60
|
+
|
|
61
|
+
:param point_1: The first coordinate of the box.
|
|
62
|
+
:param point_2: The second coordinate of the box.
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
def __le__(self, arg0: SelectionBox) -> bool: ...
|
|
66
|
+
def __lt__(self, arg0: SelectionBox) -> bool: ...
|
|
67
|
+
def __repr__(self) -> str: ...
|
|
68
|
+
def __str__(self) -> str: ...
|
|
69
|
+
def contains_block(
|
|
70
|
+
self, x: typing.SupportsInt, y: typing.SupportsInt, z: typing.SupportsInt
|
|
71
|
+
) -> bool:
|
|
72
|
+
"""
|
|
73
|
+
Is the block contained within the selection.
|
|
74
|
+
|
|
75
|
+
>>> selection1: AbstractBaseSelection
|
|
76
|
+
>>> (1, 2, 3) in selection1
|
|
77
|
+
True
|
|
78
|
+
|
|
79
|
+
:param x: The x coordinate of the block. Defined by the most negative corner.
|
|
80
|
+
:param y: The y coordinate of the block. Defined by the most negative corner.
|
|
81
|
+
:param z: The z coordinate of the block. Defined by the most negative corner.
|
|
82
|
+
:return: True if the block is in the selection.
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
def contains_box(self, other: SelectionBox) -> bool:
|
|
86
|
+
"""
|
|
87
|
+
Does the other SelectionBox other fit entirely within this SelectionBox.
|
|
88
|
+
|
|
89
|
+
:param other: The SelectionBox to test.
|
|
90
|
+
:return: True if other fits in self, False otherwise.
|
|
91
|
+
"""
|
|
92
|
+
|
|
93
|
+
def contains_point(
|
|
94
|
+
self, x: typing.SupportsFloat, y: typing.SupportsFloat, z: typing.SupportsFloat
|
|
95
|
+
) -> bool:
|
|
96
|
+
"""
|
|
97
|
+
Is the point contained within the selection.
|
|
98
|
+
|
|
99
|
+
>>> selection1: AbstractBaseSelection
|
|
100
|
+
>>> (1.5, 2.5, 3.5) in selection1
|
|
101
|
+
True
|
|
102
|
+
|
|
103
|
+
:param x: The x coordinate of the point.
|
|
104
|
+
:param y: The y coordinate of the point.
|
|
105
|
+
:param z: The z coordinate of the point.
|
|
106
|
+
:return: True if the point is in the selection.
|
|
107
|
+
"""
|
|
108
|
+
|
|
109
|
+
@typing.overload
|
|
110
|
+
def intersects(self, other: SelectionBox) -> bool:
|
|
111
|
+
"""
|
|
112
|
+
Does this selection intersect ``other``.
|
|
113
|
+
|
|
114
|
+
:param other: The other selection.
|
|
115
|
+
:return: True if the selections intersect, False otherwise.
|
|
116
|
+
"""
|
|
117
|
+
|
|
118
|
+
@typing.overload
|
|
119
|
+
def intersects(
|
|
120
|
+
self, other: amulet.core.selection.box_group.SelectionBoxGroup
|
|
121
|
+
) -> bool: ...
|
|
122
|
+
def touches(self, other: SelectionBox) -> bool:
|
|
123
|
+
"""
|
|
124
|
+
Method to check if this instance of :class:`SelectionBox` touches but does not intersect another SelectionBox.
|
|
125
|
+
|
|
126
|
+
:param other: The other SelectionBox
|
|
127
|
+
:return: True if the two :class:`SelectionBox` instances touch, False otherwise
|
|
128
|
+
"""
|
|
129
|
+
|
|
130
|
+
def touches_or_intersects(self, other: SelectionBox) -> bool:
|
|
131
|
+
"""
|
|
132
|
+
Does this SelectionBox touch or intersect the other SelectionBox.
|
|
133
|
+
|
|
134
|
+
:param other: The other SelectionBox.
|
|
135
|
+
:return: True if the two :class:`SelectionBox` instances touch or intersect, False otherwise.
|
|
136
|
+
"""
|
|
137
|
+
|
|
138
|
+
def transform(
|
|
139
|
+
self, matrix: amulet.utils.matrix.Matrix4x4
|
|
140
|
+
) -> amulet.core.selection.box_group.SelectionBoxGroup:
|
|
141
|
+
"""
|
|
142
|
+
Transform this box by the given transformation matrix.
|
|
143
|
+
"""
|
|
144
|
+
|
|
145
|
+
def translate(
|
|
146
|
+
self, dx: typing.SupportsInt, dy: typing.SupportsInt, dz: typing.SupportsInt
|
|
147
|
+
) -> SelectionBox:
|
|
148
|
+
"""
|
|
149
|
+
Create a new :class:`SelectionBox` based on this one with the coordinates moved by the given offset.
|
|
150
|
+
|
|
151
|
+
:param dx: The x offset.
|
|
152
|
+
:param dy: The y offset.
|
|
153
|
+
:param dz: The z offset.
|
|
154
|
+
:return: The new selection with the given offset.
|
|
155
|
+
"""
|
|
156
|
+
|
|
157
|
+
@property
|
|
158
|
+
def max(self) -> tuple[int, int, int]:
|
|
159
|
+
"""
|
|
160
|
+
The maximum coordinate of the box.
|
|
161
|
+
"""
|
|
162
|
+
|
|
163
|
+
@property
|
|
164
|
+
def max_x(self) -> int:
|
|
165
|
+
"""
|
|
166
|
+
The maximum x coordinate of the box.
|
|
167
|
+
"""
|
|
168
|
+
|
|
169
|
+
@property
|
|
170
|
+
def max_y(self) -> int:
|
|
171
|
+
"""
|
|
172
|
+
The maximum y coordinate of the box.
|
|
173
|
+
"""
|
|
174
|
+
|
|
175
|
+
@property
|
|
176
|
+
def max_z(self) -> int:
|
|
177
|
+
"""
|
|
178
|
+
The maximum z coordinate of the box.
|
|
179
|
+
"""
|
|
180
|
+
|
|
181
|
+
@property
|
|
182
|
+
def min(self) -> tuple[int, int, int]:
|
|
183
|
+
"""
|
|
184
|
+
The minimum coordinate of the box.
|
|
185
|
+
"""
|
|
186
|
+
|
|
187
|
+
@property
|
|
188
|
+
def min_x(self) -> int:
|
|
189
|
+
"""
|
|
190
|
+
The minimum x coordinate of the box.
|
|
191
|
+
"""
|
|
192
|
+
|
|
193
|
+
@property
|
|
194
|
+
def min_y(self) -> int:
|
|
195
|
+
"""
|
|
196
|
+
The minimum y coordinate of the box.
|
|
197
|
+
"""
|
|
198
|
+
|
|
199
|
+
@property
|
|
200
|
+
def min_z(self) -> int:
|
|
201
|
+
"""
|
|
202
|
+
The minimum z coordinate of the box.
|
|
203
|
+
"""
|
|
204
|
+
|
|
205
|
+
@property
|
|
206
|
+
def shape(self) -> tuple[int, int, int]:
|
|
207
|
+
"""
|
|
208
|
+
The length of the box in the x, y and z axis.
|
|
209
|
+
|
|
210
|
+
>>> SelectionBox(0, 0, 0, 1, 1, 1).shape
|
|
211
|
+
(1, 1, 1)
|
|
212
|
+
"""
|
|
213
|
+
|
|
214
|
+
@property
|
|
215
|
+
def size_x(self) -> int:
|
|
216
|
+
"""
|
|
217
|
+
The length of the box in the x axis.
|
|
218
|
+
"""
|
|
219
|
+
|
|
220
|
+
@property
|
|
221
|
+
def size_y(self) -> int:
|
|
222
|
+
"""
|
|
223
|
+
The length of the box in the y axis.
|
|
224
|
+
"""
|
|
225
|
+
|
|
226
|
+
@property
|
|
227
|
+
def size_z(self) -> int:
|
|
228
|
+
"""
|
|
229
|
+
The length of the box in the z axis.
|
|
230
|
+
"""
|
|
231
|
+
|
|
232
|
+
@property
|
|
233
|
+
def volume(self) -> int:
|
|
234
|
+
"""
|
|
235
|
+
The number of blocks in the box.
|
|
236
|
+
|
|
237
|
+
>>> SelectionBox(0, 0, 0, 1, 1, 1).volume
|
|
238
|
+
1
|
|
239
|
+
"""
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <array>
|
|
4
|
+
#include <concepts>
|
|
5
|
+
#include <ranges>
|
|
6
|
+
#include <set>
|
|
7
|
+
|
|
8
|
+
#include <amulet/core/dll.hpp>
|
|
9
|
+
|
|
10
|
+
#include "box.hpp"
|
|
11
|
+
|
|
12
|
+
namespace Amulet {
|
|
13
|
+
|
|
14
|
+
class AMULET_CORE_EXPORT SelectionBoxGroup {
|
|
15
|
+
private:
|
|
16
|
+
std::set<SelectionBox> _boxes;
|
|
17
|
+
|
|
18
|
+
public:
|
|
19
|
+
// Forwarding constructor
|
|
20
|
+
template <typename... Args>
|
|
21
|
+
SelectionBoxGroup(Args&&... args)
|
|
22
|
+
: _boxes(std::forward<Args>(args)...)
|
|
23
|
+
{
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
SelectionBoxGroup(std::initializer_list<SelectionBox> boxes)
|
|
27
|
+
: _boxes(boxes)
|
|
28
|
+
{
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Accessors
|
|
32
|
+
const std::set<SelectionBox>& get_boxes() const
|
|
33
|
+
{
|
|
34
|
+
return _boxes;
|
|
35
|
+
}
|
|
36
|
+
size_t count() const
|
|
37
|
+
{
|
|
38
|
+
return _boxes.size();
|
|
39
|
+
}
|
|
40
|
+
std::set<SelectionBox>::const_iterator begin() const
|
|
41
|
+
{
|
|
42
|
+
return _boxes.begin();
|
|
43
|
+
}
|
|
44
|
+
std::set<SelectionBox>::const_iterator end() const
|
|
45
|
+
{
|
|
46
|
+
return _boxes.end();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Bounds
|
|
50
|
+
std::int64_t min_x() const;
|
|
51
|
+
std::int64_t min_y() const;
|
|
52
|
+
std::int64_t min_z() const;
|
|
53
|
+
std::int64_t max_x() const;
|
|
54
|
+
std::int64_t max_y() const;
|
|
55
|
+
std::int64_t max_z() const;
|
|
56
|
+
std::array<std::int64_t, 3> min() const;
|
|
57
|
+
std::array<std::int64_t, 3> max() const;
|
|
58
|
+
std::pair<
|
|
59
|
+
std::array<std::int64_t, 3>,
|
|
60
|
+
std::array<std::int64_t, 3>>
|
|
61
|
+
bounds() const;
|
|
62
|
+
SelectionBox bounding_box() const;
|
|
63
|
+
|
|
64
|
+
// Contains and intersects
|
|
65
|
+
bool contains_block(std::int64_t x, std::int64_t y, std::int64_t z) const;
|
|
66
|
+
bool contains_point(double x, double y, double z) const;
|
|
67
|
+
bool intersects(const SelectionBox& other) const;
|
|
68
|
+
bool intersects(const SelectionBoxGroup& other) const;
|
|
69
|
+
|
|
70
|
+
// Transform
|
|
71
|
+
SelectionBoxGroup translate(std::int64_t dx, std::int64_t dy, std::int64_t dz) const;
|
|
72
|
+
SelectionBoxGroup transform(const Matrix4x4&) const;
|
|
73
|
+
|
|
74
|
+
// Operators
|
|
75
|
+
operator bool() const
|
|
76
|
+
{
|
|
77
|
+
return !_boxes.empty();
|
|
78
|
+
}
|
|
79
|
+
std::strong_ordering operator<=>(const SelectionBoxGroup& other) const = default;
|
|
80
|
+
bool operator==(const SelectionBoxGroup& rhs) const = default;
|
|
81
|
+
bool operator!=(const SelectionBoxGroup& rhs) const = default;
|
|
82
|
+
|
|
83
|
+
operator std::set<SelectionBox>() const
|
|
84
|
+
{
|
|
85
|
+
return _boxes;
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
}
|