mirror of
https://github.com/FyroxEngine/Fyrox.git
synced 2026-10-12 02:02:20 +00:00
Improvements to autotiling
This commit is contained in:
@@ -499,7 +499,12 @@ impl BrushMacro for AutoTileMacro {
|
||||
}
|
||||
}
|
||||
|
||||
fn begin_update(&mut self, context: &BrushMacroInstance, tile_map: &TileMapContext) {
|
||||
fn begin_update(
|
||||
&mut self,
|
||||
context: &BrushMacroInstance,
|
||||
stamp: &Stamp,
|
||||
tile_map: &TileMapContext,
|
||||
) {
|
||||
let Some(tile_set) = tile_map.tile_set() else {
|
||||
self.context.clear();
|
||||
return;
|
||||
@@ -515,6 +520,13 @@ impl BrushMacro for AutoTileMacro {
|
||||
return;
|
||||
};
|
||||
let frequency_property = instance.frequency_property;
|
||||
// Check that at least one cell in the stamp is part of this instance.
|
||||
if !stamp.values().any(|StampElement { brush_cell, .. }| {
|
||||
brush_cell.is_some_and(|handle| instance.cells.contains_key(&handle))
|
||||
}) {
|
||||
self.context.clear();
|
||||
return;
|
||||
}
|
||||
Log::verify(self.context.fill_pattern_map(
|
||||
&tile_set.data_ref(),
|
||||
pattern_property,
|
||||
@@ -528,6 +540,9 @@ impl BrushMacro for AutoTileMacro {
|
||||
update: &mut MacroTilesUpdate,
|
||||
tile_map: &TileMap,
|
||||
) {
|
||||
if self.context.is_empty() {
|
||||
return;
|
||||
}
|
||||
let Some(instance) = &context.settings() else {
|
||||
return;
|
||||
};
|
||||
|
||||
@@ -343,7 +343,12 @@ pub trait BrushMacro: 'static + Send + Sync {
|
||||
/// stored in the current brush when the user presses the mouse button down to begin a stroke
|
||||
/// and gives the macros a chance to prepare themselves for the series of [`amend_update`](BrushMacro::amend_update)
|
||||
/// calls that will follow.
|
||||
fn begin_update(&mut self, context: &BrushMacroInstance, tile_map: &TileMapContext);
|
||||
fn begin_update(
|
||||
&mut self,
|
||||
context: &BrushMacroInstance,
|
||||
stamp: &Stamp,
|
||||
tile_map: &TileMapContext,
|
||||
);
|
||||
/// This is called for every macro instance whenever the user uses a brush to update a tile map.
|
||||
/// - `context`: The macro instance.
|
||||
/// - `update`: The change that the user is attempting to make to the tile map. Modify this to
|
||||
|
||||
@@ -287,10 +287,13 @@ fn macro_begin(
|
||||
tile_map_context: &TileMapContext,
|
||||
update: &mut TransTilesUpdate,
|
||||
macro_update: &mut MacroTilesUpdate,
|
||||
brush: &TileMapBrushResource,
|
||||
stamp: &Stamp,
|
||||
macros: &mut BrushMacroList,
|
||||
macro_instances: &mut Vec<(Uuid, Option<UntypedResource>)>,
|
||||
) {
|
||||
let Some(brush) = stamp.brush() else {
|
||||
return;
|
||||
};
|
||||
let tile_map_handle = tile_map_context.node;
|
||||
let Some(tile_map) = tile_map_context.engine.scenes[tile_map_context.scene].graph
|
||||
[tile_map_handle]
|
||||
@@ -324,7 +327,7 @@ fn macro_begin(
|
||||
continue;
|
||||
};
|
||||
context.settings = settings;
|
||||
brush_macro.begin_update(&context, tile_map_context);
|
||||
brush_macro.begin_update(&context, stamp, tile_map_context);
|
||||
brush_macro.amend_update(&context, macro_update, tile_map);
|
||||
}
|
||||
macro_update.fill_trans_tiles_update(update);
|
||||
@@ -545,7 +548,7 @@ impl InteractionMode for TileMapInteractionMode {
|
||||
let update = &mut self.update_effect.lock().update;
|
||||
draw(update, tiles, mode, &state, grid_coord, grid_coord);
|
||||
drop(tiles_guard);
|
||||
if let Some(brush) = state.stamp.brush() {
|
||||
if state.stamp.brush().is_some() {
|
||||
let tile_map = TileMapContext {
|
||||
node: self.tile_map,
|
||||
scene: scene_handle,
|
||||
@@ -555,7 +558,7 @@ impl InteractionMode for TileMapInteractionMode {
|
||||
&tile_map,
|
||||
update,
|
||||
&mut self.macro_update,
|
||||
brush,
|
||||
&state.stamp,
|
||||
&mut self.brush_macro_list.lock(),
|
||||
&mut self.macro_instance_list,
|
||||
);
|
||||
|
||||
@@ -617,7 +617,13 @@ impl BrushMacro for WfcMacro {
|
||||
|
||||
fn sync_cell_editors(&mut self, _context: &MacroMessageContext, _ui: &mut UserInterface) {}
|
||||
|
||||
fn begin_update(&mut self, _context: &BrushMacroInstance, _tile_map: &TileMapContext) {}
|
||||
fn begin_update(
|
||||
&mut self,
|
||||
_context: &BrushMacroInstance,
|
||||
_stamp: &Stamp,
|
||||
_tile_map: &TileMapContext,
|
||||
) {
|
||||
}
|
||||
|
||||
fn amend_update(
|
||||
&mut self,
|
||||
|
||||
@@ -475,6 +475,10 @@ impl<Ter, Pat, Tile> Default for AutoTileContext<Ter, Pat, Tile> {
|
||||
}
|
||||
|
||||
impl<Ter: Eq + Hash, Pat: Eq + Hash + Clone, Tile> AutoTileContext<Ter, Pat, Tile> {
|
||||
/// True if this context contains no patterns.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.patterns.is_empty()
|
||||
}
|
||||
/// Make the context empty in preparation for building a new context.
|
||||
pub fn clear(&mut self) {
|
||||
for (_, mut list) in self.patterns.drain() {
|
||||
|
||||
@@ -105,6 +105,7 @@ pub trait WfcConstrain {
|
||||
/// The type of patterns that wave function collapse will choose.
|
||||
type Pattern: Eq + Hash + Clone;
|
||||
/// Iterator for all the patterns that wave function collapse is allowed to choose.
|
||||
/// Note that any pattern with a probability of 0.0 must not be included.
|
||||
fn all_patterns(&self) -> impl Iterator<Item = &Self::Pattern>;
|
||||
/// The probability of choosing a given pattern when there are no restrictions on patterns
|
||||
/// in any of the adjacent cells. This should be between 0.0 and 1.0.
|
||||
@@ -567,9 +568,24 @@ impl<Pos: WavePosition + Debug, Pat: Clone + Hash + Eq + Debug> WfcPropagator<Po
|
||||
Con: WfcConstrain<Pattern = Pat, Offset = Pos::Offset>,
|
||||
Pos: Debug,
|
||||
{
|
||||
for p in constraint.all_patterns() {
|
||||
if pattern != p {
|
||||
self.after_restrict(position, p, constraint)?;
|
||||
for offset in Pos::all_offsets() {
|
||||
let other_pos = position.clone() + offset.clone();
|
||||
let Some(other_cell) = self.wave.get_mut(&other_pos) else {
|
||||
continue;
|
||||
};
|
||||
other_cell
|
||||
.pattern_possibilities
|
||||
.retain(|other_pattern, _counter| {
|
||||
if !constraint.is_legal(pattern, &offset, other_pattern) {
|
||||
self.pending
|
||||
.push((other_pos.clone(), other_pattern.clone()));
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
});
|
||||
if other_cell.pattern_possibilities.is_empty() {
|
||||
return Err(WfcFailure);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
||||
Reference in New Issue
Block a user