Skip to content

Commit

Permalink
Merge pull request #717 from b-guild/tile-anim
Browse files Browse the repository at this point in the history
Animation for tile map tiles
  • Loading branch information
mrDIMAS authored Jan 11, 2025
2 parents ef992eb + c969ed0 commit 46bae6c
Show file tree
Hide file tree
Showing 21 changed files with 549 additions and 18 deletions.
5 changes: 3 additions & 2 deletions editor/src/asset/preview/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ pub trait AssetPreviewGenerator: Send + Sync + 'static {

/// Generates a preview image for an asset. For example, in case of prefabs, it will be the
/// entire prefab content rendered to an image. In case of sounds it will be its waveform, and
/// so on.
/// so on.
fn generate_preview(
&mut self,
resource: &UntypedResource,
Expand Down Expand Up @@ -294,6 +294,7 @@ fn render_scene_to_texture(
scene: &mut Scene,
rt_size: Vector2<f32>,
) -> Option<AssetPreviewTexture> {
let elapsed_time = engine.elapsed_time();
let GraphicsContext::Initialized(ref mut graphics_context) = engine.graphics_context else {
Log::warn("Cannot render an asset preview when the renderer is not initialized!");
return None;
Expand Down Expand Up @@ -334,7 +335,7 @@ fn render_scene_to_texture(
let temp_handle = Handle::new(u32::MAX, u32::MAX);
if let Some(ldr_texture) = graphics_context
.renderer
.render_scene(temp_handle, scene, 0.0)
.render_scene(temp_handle, scene, elapsed_time, 0.0)
.ok()
.and_then(|data| {
data.ldr_scene_framebuffer
Expand Down
1 change: 1 addition & 0 deletions editor/src/highlight.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ impl SceneRenderPass for HighlightRenderPass {

let frustum = ctx.camera.frustum();
let mut render_context = RenderContext {
elapsed_time: ctx.elapsed_time,
observer_info: &observer_info,
frustum: Some(&frustum),
storage: &mut render_bundle_storage,
Expand Down
38 changes: 38 additions & 0 deletions editor/src/plugins/tilemap/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -581,6 +581,7 @@ impl SetTileSetPageCommand {
let mut tile_set = self.tile_set.data_ref();
swap_hash_map_entry(tile_set.pages.entry(self.position), &mut self.page);
tile_set.rebuild_transform_sets();
tile_set.rebuild_animations();
tile_set.change_count.set();
}
}
Expand Down Expand Up @@ -634,6 +635,7 @@ impl MoveTileSetPageCommand {
}
std::mem::swap(&mut self.start_offset, &mut self.end_offset);
tile_set.rebuild_transform_sets();
tile_set.rebuild_animations();
tile_set.change_count.set();
}
}
Expand Down Expand Up @@ -740,6 +742,7 @@ impl MoveTileSetTileCommand {
}
std::mem::swap(&mut self.start_offset, &mut self.end_offset);
tile_set.rebuild_transform_sets();
tile_set.rebuild_animations();
tile_set.change_count.set();
}
}
Expand Down Expand Up @@ -1006,6 +1009,41 @@ impl CommandTrait for SetMapTilesCommand {
}
}

#[derive(Debug)]
pub struct ModifyAnimationSpeedCommand {
pub tile_set: TileSetResource,
pub page: Vector2<i32>,
pub frame_rate: f32,
}

impl ModifyAnimationSpeedCommand {
fn swap(&mut self) {
let mut tile_set = self.tile_set.data_ref();
let Some(TileSetPageSource::Animation(anim)) =
&mut tile_set.pages.get_mut(&self.page).map(|p| &mut p.source)
else {
Log::err("Modify animation speed on non-animation tile page.");
return;
};
std::mem::swap(&mut self.frame_rate, &mut anim.frame_rate);
tile_set.change_count.set();
}
}

impl CommandTrait for ModifyAnimationSpeedCommand {
fn name(&mut self, _context: &dyn CommandContext) -> String {
"Modify Tile Animation Speed".into()
}

fn execute(&mut self, _context: &mut dyn CommandContext) {
self.swap()
}

fn revert(&mut self, _context: &mut dyn CommandContext) {
self.swap()
}
}

#[derive(Debug)]
pub struct ModifyPageTileSizeCommand {
pub tile_set: TileSetResource,
Expand Down
3 changes: 3 additions & 0 deletions editor/src/plugins/tilemap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -591,8 +591,10 @@ impl TileMapEditorPlugin {
interaction_mode.on_tile_map_selected(tile_map);
// Prepare the tile map interaction mode.
let Some(entry) = editor.scenes.current_scene_entry_mut() else {
// We have somehow lost the scene entry, so remove the effects from the tile map.
if let Some(tile_map) = self.get_tile_map_mut(editor) {
tile_map.before_effects.clear();
tile_map.after_effects.clear();
}
return;
};
Expand Down Expand Up @@ -781,6 +783,7 @@ impl EditorPlugin for TileMapEditorPlugin {
.and_then(|n| n.component_mut::<TileMap>())
{
tile_map.before_effects.clear();
tile_map.after_effects.clear();
}

if let Some(handle) = selection
Expand Down
46 changes: 46 additions & 0 deletions editor/src/plugins/tilemap/palette.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ pub const CURSOR_HIGHLIGHT_COLOR: Color = Color::from_rgba(255, 255, 255, 50);

const MOUSE_CLICK_DELAY_FRAMES: usize = 1;
const NO_PAGE_COLOR: Color = Color::from_rgba(20, 5, 5, 255);
const ANIMATION_BOOKEND_COLOR: Color = Color::DARK_CYAN;

#[derive(Debug, PartialEq, Clone)]
pub enum PaletteMessage {
Expand Down Expand Up @@ -1149,6 +1150,48 @@ impl PaletteWidget {
None,
);
}
fn draw_animation_bookends(&self, ctx: &mut DrawingContext) {
let TileBook::TileSet(tile_set) = &self.content else {
return;
};
let Some(page) = self.page else {
return;
};
let mut tile_set = tile_set.state();
let Some(page) = tile_set.data().and_then(|t| t.pages.get(&page)) else {
return;
};
let TileSetPageSource::Animation(tiles) = &page.source else {
return;
};
for pos in tiles.keys() {
let left = Vector2::new(pos.x - 1, pos.y);
let right = Vector2::new(pos.x + 1, pos.y);
if !tiles.contains_key(&left) {
self.push_left_bookend(left, ctx);
}
if !tiles.contains_key(&right) {
self.push_right_bookend(right, ctx);
}
}
self.commit_color(ANIMATION_BOOKEND_COLOR, ctx);
}
fn push_left_bookend(&self, position: Vector2<i32>, ctx: &mut DrawingContext) {
let t = self.tile_size;
let p = position.cast::<f32>();
let offset = Vector2::new(p.x * t.x, p.y * t.y);
let vertices = [(0.6, 0.5), (0.9, 0.0), (0.9, 1.0)]
.map(|(x, y)| Vector2::new(x * t.x, y * t.y) + offset);
ctx.push_triangle_filled(vertices);
}
fn push_right_bookend(&self, position: Vector2<i32>, ctx: &mut DrawingContext) {
let t = self.tile_size;
let p = position.cast::<f32>();
let offset = Vector2::new(p.x * t.x, p.y * t.y);
let vertices = [(0.4, 0.5), (0.1, 0.0), (0.1, 1.0)]
.map(|(x, y)| Vector2::new(x * t.x, y * t.y) + offset);
ctx.push_triangle_filled(vertices);
}
fn draw_material_background(&self, ctx: &mut DrawingContext) {
if self.kind != TilePaletteStage::Tiles || !self.editable {
return;
Expand Down Expand Up @@ -1353,6 +1396,9 @@ impl Control for PaletteWidget {
ctx.push_grid(self.zoom, area_size, bounds);
self.commit_color(Color::ORANGE, ctx);
}
if stage == TilePaletteStage::Tiles && self.content.is_animation_page(page) {
self.draw_animation_bookends(ctx);
}

let line_thickness = 1.0 / self.zoom;
let left = bounds.left_bottom_corner().x;
Expand Down
9 changes: 7 additions & 2 deletions editor/src/plugins/tilemap/panel_preview.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,9 +194,14 @@ impl Control for PanelPreview {
ctx.transform_stack
.push(self.visual_transform() * self.transform);

for (pos, handle) in stamp.iter() {
let time = ctx.elapsed_time;

for (pos, &handle) in stamp.iter() {
let handle = tile_set
.get_animated_version(time, handle)
.unwrap_or(handle);
let data = tile_set
.get_transformed_render_data(stamp.transformation(), *handle)
.get_transformed_render_data(stamp.transformation(), handle)
.unwrap_or_else(TileRenderData::missing_data);
let t = self.tile_size;
let position = Vector2::new(pos.x as f32 * t.x, pos.y as f32 * t.y);
Expand Down
Loading

0 comments on commit 46bae6c

Please sign in to comment.