Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add a new TilemapRenderSettings to control chunks RenderOrder #544

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion examples/3d_iso.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ fn startup(mut commands: Commands, asset_server: Res<AssetServer>) {
// Map size is 12x12 so we'll have render chunks that are:
// 12 tiles wide and 1 tile tall.
render_chunk_size: UVec2::new(3, 1),
y_sort: true,
y_sort: true, // equivalent to render_order: RenderOrder::YReverseThenX
..Default::default()
},
..Default::default()
});
Expand Down
72 changes: 71 additions & 1 deletion src/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,80 @@ use bevy::ecs::reflect::ReflectMapEntities;
use bevy::prelude::{ReflectComponent, Res, ResMut};
use bevy::render::render_resource::TextureUsages;
use bevy::{
math::{UVec2, Vec2},
math::{UVec2, Vec2, Vec3},
prelude::{Component, Deref, DerefMut, Entity, Handle, Image, Reflect},
};

/// The default chunk_size (in tiles) used per mesh.
pub const CHUNK_SIZE_2D: UVec2 = UVec2::from_array([64, 64]);

/// The order in which we want to perform the render
#[derive(Clone, Debug, Copy, Default)]
pub enum RenderOrder {
#[default]
None,
XThenY,
XReverseThenY,
XThenYReverse,
XReverseThenYReverse,
YThenX,
YReverseThenX,
YThenXReverse,
YReverseThenXReverse,
}

impl RenderOrder {
/// Compute a new Z translation value based upon the selected render order
/// Returned Z value will have an offset between 0 and 11
pub fn compute_z_translation(
&self,
translation: &Vec3,
tilemap_size: TilemapSize,
tile_size: TilemapTileSize,
) -> f32 {
let scaling_factor = 10.;
let map_size_x = tilemap_size.x as f32 * tile_size.x;
let map_size_y = tilemap_size.y as f32 * tile_size.y;
let mut z_value = translation.z;
match self {
Self::XThenY => {
z_value += scaling_factor * (translation.x / map_size_x);
z_value += translation.y / map_size_y;
}
Self::XReverseThenY => {
z_value += scaling_factor * (1. - (translation.x / map_size_x));
z_value += translation.y / map_size_y;
}
Self::XThenYReverse => {
z_value += scaling_factor * (translation.x / map_size_x);
z_value += 1. - (translation.y / map_size_y);
}
Self::XReverseThenYReverse => {
z_value += scaling_factor * (1. - (translation.x / map_size_x));
z_value += 1. - (translation.y / map_size_y);
}
Self::YThenX => {
z_value += translation.x / map_size_x;
z_value += scaling_factor * (translation.y / map_size_y);
}
Self::YReverseThenX => {
z_value += translation.x / map_size_x;
z_value += scaling_factor * (1. - (translation.y / map_size_y));
}
Self::YThenXReverse => {
z_value += 1. - (translation.x / map_size_x);
z_value += scaling_factor * (translation.y / map_size_y);
}
Self::YReverseThenXReverse => {
z_value += 1. - (translation.x / map_size_x);
z_value += scaling_factor * (1. - (translation.y / map_size_y));
}
_ => {}
};
z_value
}
}

/// Custom parameters for the render pipeline.
///
/// It must be added as a component to the tilemap entity.
Expand All @@ -30,13 +97,16 @@ pub struct TilemapRenderSettings {
///
/// `render_chunk_size`'s `z` value should be `1` when using this for 3d isometric tilemaps.
pub y_sort: bool,
/// The order in which we will render each chunk relative to each other
pub render_chunk_order: RenderOrder,
}

impl Default for TilemapRenderSettings {
fn default() -> Self {
Self {
render_chunk_size: CHUNK_SIZE_2D,
y_sort: false,
render_chunk_order: RenderOrder::None,
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/render/chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use bevy::{
render::mesh::MeshVertexBufferLayouts,
};

use crate::map::RenderOrder;
use crate::prelude::helpers::transform::{chunk_aabb, chunk_index_to_world_space};
use crate::render::extract::ExtractedFrustum;
use crate::{
Expand Down Expand Up @@ -59,6 +60,7 @@ impl RenderChunk2dStorage {
frustum_culling: &FrustumCulling,
render_size: RenderChunkSize,
y_sort: bool,
render_order: RenderOrder,
) -> &mut RenderChunk2d {
let pos = position.xyz();

Expand Down Expand Up @@ -96,6 +98,7 @@ impl RenderChunk2dStorage {
**frustum_culling,
render_size,
y_sort,
render_order,
);
self.entity_to_chunk.insert(chunk_entity, pos);
chunk_storage.insert(pos, chunk);
Expand Down Expand Up @@ -220,6 +223,7 @@ pub struct RenderChunk2d {
pub frustum_culling: bool,
pub render_size: RenderChunkSize,
pub y_sort: bool,
pub render_chunk_order: RenderOrder,
}

impl RenderChunk2d {
Expand All @@ -241,6 +245,7 @@ impl RenderChunk2d {
frustum_culling: bool,
render_size: RenderChunkSize,
y_sort: bool,
render_chunk_order: RenderOrder,
) -> Self {
let position = chunk_index_to_world_space(index.xy(), size_in_tiles, &grid_size, &map_type);
let local_transform = Transform::from_translation(position.extend(0.0));
Expand Down Expand Up @@ -277,6 +282,7 @@ impl RenderChunk2d {
frustum_culling,
render_size,
y_sort,
render_chunk_order,
}
}

Expand Down
6 changes: 5 additions & 1 deletion src/render/material.rs
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,11 @@ pub fn queue_material_tilemap_meshes<M: MaterialTilemap>(
- (transform.translation.y
/ (chunk.map_size.y as f32 * chunk.tile_size.y)))
} else {
transform.translation.z
chunk.render_chunk_order.compute_z_translation(
&transform.translation,
chunk.map_size,
chunk.tile_size,
)
};
transparent_phase.add(Transparent2d {
entity,
Expand Down
1 change: 1 addition & 0 deletions src/render/prepare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ pub(crate) fn prepare(
frustum_culling,
chunk_size,
tilemap_render_settings.y_sort,
tilemap_render_settings.render_chunk_order,
);
chunk.set(
&in_chunk_tile_index.into(),
Expand Down