VoxelEngine
 
Loading...
Searching...
No Matches
VariantBlock.h
1#pragma once
2
3#include <block/Block.h>
4#include <block/Geometry.h>
5
6#include <initializer_list>
7#include <vector>
8
9namespace engine {
10
16 class VariantBlock : public Block {
17 public:
20 static constexpr bool isValidRotationMode(RotationMode mode) {
21 return mode != RotationMode::AxisY && mode != RotationMode::AxisXYZ;
22 }
23
31 struct Condition {
32 Side direction;
33 std::vector<BlockID> blockIDs; // unordered_set is more correct, but vector is faster
34 std::vector<glm::vec3> requiredFacings; // Optional: if empty, any rotation is valid
35
36 bool operator==(const Condition& other) const {
37 return direction == other.direction && blockIDs == other.blockIDs &&
38 requiredFacings == other.requiredFacings;
39 }
40 };
41
46 struct Variant {
47 Geometry geometry;
48 std::vector<Condition> conditions;
49
50 bool operator==(const Variant& other) const {
51 return geometry.getID() == other.geometry.getID() && conditions == other.conditions;
52 }
53 };
54
55 struct Neighbours {
56 BlockID north;
57 BlockID south;
58 BlockID east;
59 BlockID west;
60 BlockID up;
61 BlockID down;
62
63 glm::vec3 northFacing;
64 glm::vec3 southFacing;
65 glm::vec3 eastFacing;
66 glm::vec3 westFacing;
67 glm::vec3 upFacing;
68 glm::vec3 downFacing;
69
70 BlockID operator[](Side direction) const;
71 glm::vec3 getFacing(Side direction) const;
72 void rotate(Side from, Side to);
73 };
74
76 BlockID id,
77 Layer layer,
78 const Geometry* baseGeo,
79 RotationMode rotationMode,
80 int variantCount
81 );
82 ~VariantBlock() override = default;
83
84
85 VariantBlock& allowMultiple(bool allowMultiple);
86 bool allowMultiple() const { return m_allowMultiple; }
87
88 VariantBlock& alwaysUseBaseGeometry(bool alwaysUseBaseGeometry);
89 bool alwaysUseBaseGeometry() const { return m_alwaysUseBaseGeometry; }
90
91 VariantBlock& addVariant(
92 const Geometry& geometry, std::initializer_list<Condition> conditions
93 );
94
95 VariantBlock& addVariant(Variant&& variant);
96
101 const Variant* getVariant(const Neighbours& neighbours) const;
102
107 std::vector<const Variant*> getVariants(const Neighbours& neighbours) const;
108
112 std::vector<const Geometry*> getGeometries(const Neighbours& neighbours) const;
113
114 private:
115 // variant count is small, vector is faster than unordered_set
116 std::vector<Variant> m_variants;
117 bool m_allowMultiple = false;
118 bool m_alwaysUseBaseGeometry = false;
119
120 bool checkConditions(
121 const std::vector<Condition>& conditions, const Neighbours& neighbours
122 ) const;
123 };
124} // namespace engine
Definition Block.h:31
Definition Geometry.h:13
A variant block is a block that can have multiple geometries based on the surrounding blocks.
Definition VariantBlock.h:16
const Variant * getVariant(const Neighbours &neighbours) const
Get a variant that matches the neighbours.
Definition VariantBlock.cpp:130
std::vector< const Geometry * > getGeometries(const Neighbours &neighbours) const
Get all geometries that match the neighbours and the base geometry if alwaysUseBaseGeometry is true.
Definition VariantBlock.cpp:160
static constexpr bool isValidRotationMode(RotationMode mode)
Check if a rotation mode is valid for VariantBlock.
Definition VariantBlock.h:20
std::vector< const Variant * > getVariants(const Neighbours &neighbours) const
Get all variants that match the neighbours.
Definition VariantBlock.cpp:147
Definition VariantBlock.h:31
Definition VariantBlock.h:55
Definition VariantBlock.h:46