Skip to content

Commit

Permalink
Fixing smear aspect issue and creating BrushContext to allow brushing…
Browse files Browse the repository at this point in the history
… from code.
  • Loading branch information
b-guild committed Jul 7, 2024
1 parent aa395d5 commit 0d50bab
Show file tree
Hide file tree
Showing 4 changed files with 377 additions and 137 deletions.
64 changes: 24 additions & 40 deletions editor/src/interaction/terrain.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
use fyrox::fxhash::FxHashMap;
use fyrox::resource::texture::TextureResource;
use fyrox::scene::terrain::brushstroke::{
BrushSender, BrushThreadMessage, TerrainTextureData, TerrainTextureKind, UndoData,
};
use fyrox::scene::terrain::brushstroke::{BrushSender, BrushThreadMessage, UndoData};

use crate::fyrox::core::uuid::{uuid, Uuid};
use crate::fyrox::core::TypeUuidProvider;
Expand Down Expand Up @@ -157,37 +153,19 @@ impl TerrainInteractionMode {
return;
}
}
// Holding shift as start of stroke causes the stroke to reverse lowering and raising.
if let BrushMode::Raise { amount } = &mut brush.mode {
if shift {
*amount *= -1.0;
// Reverse the behavior of a brush when shift is held.
if shift {
match &mut brush.mode {
BrushMode::Raise { amount } => {
*amount *= -1.0;
}
BrushMode::Assign { value } => {
*value = 1.0 - *value;
}
_ => (),
}
}
let chunk_size = match brush.target {
BrushTarget::HeightMap => terrain.height_map_size(),
BrushTarget::LayerMask { .. } => terrain.mask_size(),
};
let kind = match brush.target {
BrushTarget::HeightMap => TerrainTextureKind::Height,
BrushTarget::LayerMask { .. } => TerrainTextureKind::Mask,
};
let resources: FxHashMap<Vector2<i32>, TextureResource> = match brush.target {
BrushTarget::HeightMap => terrain
.chunks_ref()
.iter()
.map(|c| (c.grid_position(), c.heightmap().clone()))
.collect(),
BrushTarget::LayerMask { layer } => terrain
.chunks_ref()
.iter()
.map(|c| (c.grid_position(), c.layer_masks[layer].clone()))
.collect(),
};
let data = TerrainTextureData {
chunk_size,
kind,
resources,
};
let data = terrain.texture_data(brush.target);
if let Some(sender) = &self.brush_sender {
sender.start_stroke(brush, handle, data);
} else {
Expand All @@ -208,10 +186,13 @@ impl TerrainInteractionMode {
};
if let Some(sender) = &self.brush_sender {
if let Some(start) = self.prev_brush_position.take() {
self.brush
.smear(start, position, scale, self.brush_value, sender);
self.brush.smear(start, position, scale, |p, a| {
sender.draw_pixel(p, a, self.brush_value)
});
} else {
self.brush.stamp(position, scale, self.brush_value, sender);
self.brush.stamp(position, scale, |p, a| {
sender.draw_pixel(p, a, self.brush_value)
});
}
self.prev_brush_position = Some(position);
}
Expand Down Expand Up @@ -298,9 +279,12 @@ impl InteractionMode for TerrainInteractionMode {
{
self.brush_value = closest.height;
} else if let Some(closest) = first {
let p = closest.position;
self.brush_value = terrain
.interpolate_value(Vector2::new(p.x, p.z), self.brush.target);
let p = terrain.project(closest.position);
self.brush_value = if let Some(position) = p {
terrain.interpolate_value(position, self.brush.target)
} else {
0.0
};
} else {
self.brush_value = 0.0;
}
Expand Down
31 changes: 22 additions & 9 deletions fyrox-impl/src/scene/terrain/brushstroke/brushraster.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,10 +218,11 @@ where
#[derive(Debug, Clone)]
pub struct SmearPixels<R> {
brush_raster: R,
start: Vector2<f32>,
end: Vector2<f32>,
segment: LineSegment2<f32>,
aspect_segment: LineSegment2<f32>,
hardness: f32,
inv_transform: Matrix2<f32>,
aspect_transform: Matrix2<f32>,
bounds_iter: RectIter,
}

Expand All @@ -248,12 +249,22 @@ impl<R> SmearPixels<R> {
.unwrap_or((Matrix2::identity(), Matrix2::identity()));
bounds.extend_to_contain(brush_raster.transformed_bounds(start, &transform));
bounds.extend_to_contain(brush_raster.transformed_bounds(end, &transform));
let segment = LineSegment2::new(&start, &end);
let aspect_bounds = brush_raster.bounds();
let aspect_transform =
Matrix2::new(1.0 / aspect_bounds.w(), 0.0, 0.0, 1.0 / aspect_bounds.h());
let aspect_transform = aspect_transform * inv_transform;
let aspect_segment = LineSegment2 {
start: aspect_transform * segment.start,
end: aspect_transform * segment.end,
};
Self {
brush_raster,
start,
end,
segment,
aspect_segment,
hardness,
inv_transform,
aspect_transform,
bounds_iter: RectIter::new(bounds.unwrap()),
}
}
Expand All @@ -269,12 +280,14 @@ where
let position = self.bounds_iter.next()?;
let fx = position.x as f32;
let fy = position.y as f32;
let segment = LineSegment2::new(&self.start, &self.end);
let center = segment.nearest_point(&Vector2::new(fx, fy));
let p = Vector2::new(fx, fy) - center;
let p = Vector2::new(fx, fy);
let aspect_p = self.aspect_transform * p;
let t = self.aspect_segment.nearest_t(&aspect_p);
let center = self.segment.interpolate_clamped(t);
let p = p - center;
let p = self.inv_transform * p;
let strength = self.brush_raster.strength_at(p);
let strength = apply_hardness(self.hardness, strength);
let s = self.brush_raster.strength_at(p);
let strength = apply_hardness(self.hardness, s);
Some(BrushPixel { position, strength })
}
}
Expand Down
Loading

0 comments on commit 0d50bab

Please sign in to comment.