Toast Engine
Loading...
Searching...
No Matches
procedural_voxel.hpp
Go to the documentation of this file.
1
13
14#pragma once
15#include "voxel_bucket.hpp"
16#include "voxel_group.hpp"
17#include "voxel_node.hpp"
18#include "voxel_piece.hpp"
19#include "voxel_volume.hpp"
20
21#include <cstdint>
22#include <future>
23#include <memory>
24#include <optional>
25#include <span>
26#include <toast/voxel/stamp.hpp>
28#include <unordered_map>
29#include <vector>
30
31namespace event {
33}
34
35namespace toast {
36
41class [[ToastNode, Color("Magenta")]] TOAST_API ProceduralVoxel : public VoxelNode {
42public:
43 struct PieceLayout {
44 Box<Node> node;
48 glm::vec4 average_color {0.0f};
49 };
50
52 [[nodiscard]]
53 auto layout() const noexcept -> const std::vector<PieceLayout>& {
54 return m_layout;
55 }
56
58 [[Reflect, Button("Rebuild")]]
59 void rebuild();
60
62 [[Reflect, Button("Bake"), EditorAction("voxel_editor.bake")]]
63 void bakeVoxel() { }
64
66 void sendLayout();
67
73 [[nodiscard, Reflect]]
74 auto getPieceAt(glm::vec3 pos) -> Box<Node>;
75
77 [[nodiscard, Reflect]]
78 auto getPieceCount() const noexcept -> int {
79 return static_cast<int>(m_layout.size());
80 }
81
86 [[nodiscard]]
87 auto pickPiece(glm::vec3 origin, glm::vec3 direction) -> VoxelPiece*;
88
90 [[nodiscard]]
91 auto pieceAt(glm::ivec3 voxel) -> VoxelPiece*;
92
97 void keepGrids(bool keep) noexcept { m_keep_grids = keep; }
98
99 struct Composed {
100 voxel::Volume volume;
101 glm::ivec3 origin {0};
102 };
103
108 [[nodiscard]]
109 auto composePieces(std::span<VoxelPiece* const> only) -> std::optional<Composed>;
110
111protected:
112 void buildShape() override;
113 auto shapeKey() -> uint64_t override;
114 auto buildsAsync() -> bool override;
115 void tickAsyncBuild() override;
116
118 void drawDebug() override;
119
120 void end();
121 void destroy();
122
123private:
124 struct Collected {
125 VoxelPiece* piece = nullptr;
126 glm::mat4 to_root {1.0f};
127 };
128
130 struct Landing {
131 VoxelPiece* piece = nullptr;
132 VoxelPiece::GridRef grid;
133 voxel::LatticePlacement placement;
135 PieceKind kind = PieceKind::fill;
136 voxel::WriteMode mode = voxel::WriteMode::replace;
137 uint8_t match_id = 0;
138 };
139
140 struct ComposeInput;
141 struct ComposeOutput;
142
143 void collect(Node& node, const glm::mat4& to_root, std::vector<Collected>& out);
144
145 struct BucketFill {
146 VoxelBucket* bucket = nullptr;
147 glm::ivec3 seed {0};
148 };
149
151 void collectBuckets(Node& node, const glm::mat4& to_root, std::vector<BucketFill>& out);
152
157 [[nodiscard]]
158 auto land(const std::vector<Collected>& pieces, bool wait) -> std::vector<Landing>;
159
161 static auto apply(voxel::Volume& target, const Landing& landing, glm::ivec3 origin) -> voxel::EditResult;
162
164 [[nodiscard]]
165 static auto compose(const ComposeInput& input) -> std::shared_ptr<ComposeOutput>;
166
167 [[nodiscard]]
168 auto keyOf(const std::vector<Collected>& pieces) -> uint64_t;
169
171 [[nodiscard]]
172 auto layoutOf(const std::vector<Landing>& landings) -> std::vector<PieceLayout>;
173
175 void launchCompose(const std::vector<Collected>& pieces);
176
178 void applyComposed(ComposeOutput& output);
179
180 [[nodiscard]]
181 auto averageColor(const Landing& landing) -> glm::vec3;
182
183 [[nodiscard]]
184 auto remapFor(const VoxelPiece& piece) -> voxel::PaletteRemapTable;
185
186 [[nodiscard]]
187 auto toolPiece() -> VoxelPiece*;
188
189 std::unique_ptr<voxel::Volume> m_highlight;
190 UID m_highlight_for;
191
192 std::vector<PieceLayout> m_layout;
193 std::vector<PieceLayout> m_pending_layout;
194 bool m_keep_grids = false;
195
196 std::future<std::shared_ptr<ComposeOutput>> m_compose_job;
197 std::shared_ptr<ComposeOutput> m_last_compose;
198 bool m_compose_wanted = false;
199 bool m_pending_projections = false;
200
201 struct CachedRemap {
203 uint64_t target_uid = 0;
204 uint32_t source_revision = 0;
205 uint32_t target_revision = 0;
206 };
207
208 std::unordered_map<uint64_t, CachedRemap> m_remaps;
209};
210
212[[nodiscard]]
213TOAST_API auto insideProceduralVoxel(Node& node) -> bool;
214
216[[nodiscard]]
217TOAST_API auto owningProceduralVoxel(Node& node) -> ProceduralVoxel*;
218
219// Placing pieces, everything in shape voxels
220
222[[nodiscard]]
223TOAST_API auto parentToShape(Node& node) -> glm::mat4;
224
226[[nodiscard]]
227TOAST_API auto piecePlacement(VoxelPiece& piece) -> voxel::LatticePlacement;
228
230[[nodiscard]]
231TOAST_API auto pieceBounds(VoxelPiece& piece) -> voxel::EditBounds;
232
237TOAST_API void placePiece(VoxelPiece& piece, const voxel::LatticeOrientation& orientation, glm::ivec3 min, glm::ivec3 max);
238
240[[nodiscard]]
241TOAST_API auto planeToShape(glm::vec4 plane, const voxel::LatticePlacement& placement) noexcept -> glm::vec4;
242
244[[nodiscard]]
245TOAST_API auto planeToPiece(glm::vec4 plane, const voxel::LatticePlacement& placement) noexcept -> glm::vec4;
246
247}
Intrusive reference-counted handle to a Node.
Definition box.hpp:35
Definition node.hpp:81
Definition procedural_voxel.hpp:41
auto layout() const noexcept -> const std::vector< PieceLayout > &
Definition procedural_voxel.hpp:53
void bakeVoxel()
Definition procedural_voxel.hpp:63
auto getPieceCount() const noexcept -> int
Definition procedural_voxel.hpp:78
void keepGrids(bool keep) noexcept
Definition procedural_voxel.hpp:97
Definition reflect.hpp:244
VoxelNode()=default
Definition voxel_piece.hpp:41
Definition voxel_volume.hpp:21
A box of voxels inside a ProceduralVoxel.
std::array< uint8_t, k_palette_size > PaletteRemapTable
Index 0 always maps to 0.
Definition stamp.hpp:138
Definition workspace_events.hpp:210
Definition procedural_voxel.hpp:99
glm::ivec3 origin
Shape voxel of the volume's first voxel.
Definition procedural_voxel.hpp:101
Definition procedural_voxel.hpp:43
voxel::EditBounds bounds
Where the grid lands, in shape voxels.
Definition procedural_voxel.hpp:47
Definition voxel_edit.hpp:49
Definition stamp.hpp:72
A flood fill inside a ProceduralVoxel.
Functions that allow the editing of Voxel Volumes.
WriteMode
Which voxels we should override.
Definition voxel_edit.hpp:26
Keeps pieces of a ProceduralVoxel together.
Frontend for a Voxel node.
Base of everything a ProceduralVoxel builds itself from.
PieceKind
Definition voxel_piece.hpp:26
@ fill
Adds its voxels with its write mode.
Definition voxel_piece.hpp:27