Skip to content

Commit

Permalink
Getting uniforms in per batch
Browse files Browse the repository at this point in the history
  • Loading branch information
jamescarterbell committed Jan 5, 2024
1 parent e9c4953 commit df38c85
Show file tree
Hide file tree
Showing 22 changed files with 566 additions and 206 deletions.
18 changes: 16 additions & 2 deletions crates/bevy_tiles/src/chunks.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use std::ops::Deref;

use aery::prelude::{CleanupPolicy, Relation};
use bevy::ecs::{component::Component, entity::Entity};
use bevy::{
ecs::{component::Component, entity::Entity},
math::Vec2,
};

mod chunk_query;

Expand All @@ -17,7 +20,7 @@ pub struct InMap;
/// Right now, changes to this coordinate don't automatically update any information.
/// If you wish to move a chunk, add, or remove a chunk, please do so via commands.
/// Use this if you wish to track changes or other information.
#[derive(Component, Debug, PartialEq, Eq, Hash)]
#[derive(Component, Debug, PartialEq, Eq, Hash, Clone, Copy)]
pub struct ChunkCoord<const N: usize = 2>([isize; N]);

impl<const N: usize> From<[isize; N]> for ChunkCoord<N> {
Expand All @@ -34,6 +37,12 @@ impl<const N: usize> Deref for ChunkCoord<N> {
}
}

impl From<&ChunkCoord<2>> for Vec2 {
fn from(value: &ChunkCoord<2>) -> Self {
Vec2::new(value.0[0] as f32, value.0[1] as f32)
}
}

/// Holds handles to all the tiles in a chunk.
/// # Note
/// Manually updating this value, adding it, or removing it from an entity may
Expand All @@ -54,4 +63,9 @@ impl Chunk {
pub fn total_size(&self) -> usize {
self.tiles.len()
}

/// Gets a readonly reference to the underlying chunk data.
pub fn get_tiles(&self) -> &Vec<Option<Entity>> {
&self.tiles
}
}
4 changes: 2 additions & 2 deletions crates/bevy_tiles/src/chunks/chunk_query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use bevy::{

use crate::{
chunks::ChunkCoord,
maps::{MapLabel, TileMapLabel, Tilemap},
maps::{MapLabel, TileMap, TileMapLabel},
prelude::{calculate_chunk_coordinate, Chunk, CoordIterator, InMap},
};

Expand All @@ -27,7 +27,7 @@ where
F: ReadOnlyWorldQuery + 'static,
{
chunk_q: Query<'w, 's, Q, (F, Relations<InMap>, With<Chunk>, With<MapLabel<L>>)>,
map_q: Query<'w, 's, &'static Tilemap<N>, With<MapLabel<L>>>,
map_q: Query<'w, 's, &'static TileMap<N>, With<MapLabel<L>>>,
}

impl<'w, 's, L, Q, F, const N: usize> Deref for ChunkQuery<'w, 's, L, Q, F, N>
Expand Down
49 changes: 40 additions & 9 deletions crates/bevy_tiles/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use std::{
use crate::{
maps::MapLabel,
prelude::{
calculate_chunk_coordinate, calculate_tile_index, Chunk, ChunkCoord, InMap, TileMapLabel,
Tilemap,
calculate_chunk_coordinate, calculate_tile_index, Chunk, ChunkCoord, InMap, TileMap,
TileMapLabel,
},
tiles::{InChunk, TileCoord, TileIndex},
};
Expand Down Expand Up @@ -228,6 +228,19 @@ where
});
}

/// Spawn a new map, overwriting any old maps found.
pub fn spawn_map<T>(&mut self, bundle: T) -> EntityCommands<'w, 's, '_>
where
T: Bundle + 'static,
{
let map_id = self.spawn(bundle).id();
self.add(SpawnMap::<L, N> {
map_id,
label: PhantomData,
});
self.entity(map_id)
}

/// Recursively despawns a map and all it's chunks and tiles.
pub fn despawn_map(&mut self) -> &mut Self {
self.add(DespawnMap::<L, N> { label: PhantomData });
Expand All @@ -240,7 +253,7 @@ where
#[inline]
fn spawn_or_remove_chunk<L, const N: usize>(
world: &mut World,
map: &mut Tilemap<N>,
map: &mut TileMap<N>,
map_id: Entity,
chunk_c: [isize; N],
) -> (Entity, Chunk)
Expand All @@ -261,7 +274,7 @@ where
#[inline]
fn remove_chunk<const N: usize>(
world: &mut World,
map: &mut Tilemap<N>,
map: &mut TileMap<N>,
chunk_c: [isize; N],
) -> Option<(Entity, Chunk)> {
map.chunks
Expand All @@ -273,7 +286,7 @@ fn remove_chunk<const N: usize>(

/// Takes the map out of the world or spawns a new one and returns the entity id to return the map to.
#[inline]
fn spawn_or_remove_map<L, const N: usize>(world: &mut World) -> (Entity, Tilemap<N>)
fn spawn_or_remove_map<L, const N: usize>(world: &mut World) -> (Entity, TileMap<N>)
where
L: TileMapLabel + Send + 'static,
{
Expand All @@ -283,19 +296,19 @@ where
} else {
(
world.spawn(MapLabel::<L>::default()).id(),
Tilemap::<N>::default(),
TileMap::<N>::with_chunk_size(L::CHUNK_SIZE),
)
}
}

/// Takes the map out of the world if it exists.
#[inline]
fn remove_map<L, const N: usize>(world: &mut World) -> Option<(Entity, Tilemap<N>)>
fn remove_map<L, const N: usize>(world: &mut World) -> Option<(Entity, TileMap<N>)>
where
L: TileMapLabel + Send + 'static,
{
world
.query_filtered::<Entity, (With<Tilemap<N>>, With<MapLabel<L>>)>()
.query_filtered::<Entity, (With<TileMap<N>>, With<MapLabel<L>>)>()
.get_single_mut(world)
.ok()
.map(|map_id| {
Expand All @@ -304,7 +317,7 @@ where
world
.get_entity_mut(map_id)
.unwrap()
.take::<Tilemap<N>>()
.take::<TileMap<N>>()
.unwrap(),
)
})
Expand Down Expand Up @@ -685,6 +698,24 @@ where
chunk_ids
}

/// Insert the given entity and have it be treated as the given map.
/// # Note
/// This will despawn any existing map with this label.
pub fn insert_map<L, const N: usize>(world: &mut World, map_id: Entity)
where
L: TileMapLabel + Send + 'static,
{
let map_info = remove_map::<L, N>(world);
if let Some(map_info) = map_info {
CheckedDespawn(map_info.0).apply(world);
} else {
world.entity_mut(map_id).insert((
MapLabel::<L>::default(),
TileMap::<N>::with_chunk_size(L::CHUNK_SIZE),
));
}
}

trait GroupBy: Iterator {
fn group_by<F, K>(
self,
Expand Down
20 changes: 18 additions & 2 deletions crates/bevy_tiles/src/commands/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,26 @@ use aery::edges::CheckedDespawn;
use bevy::ecs::{entity::Entity, query::With, system::Command, world::World};

use crate::{
maps::{MapLabel, Tilemap},
maps::{MapLabel, TileMap},
prelude::TileMapLabel,
};

use super::insert_map;

pub struct SpawnMap<L, const N: usize = 2> {
pub map_id: Entity,
pub label: std::marker::PhantomData<L>,
}

impl<L, const N: usize> Command for SpawnMap<L, N>
where
L: TileMapLabel + 'static,
{
fn apply(self, world: &mut World) {
insert_map::<L, N>(world, self.map_id)
}
}

pub struct DespawnMap<L, const N: usize = 2> {
pub label: std::marker::PhantomData<L>,
}
Expand All @@ -16,7 +32,7 @@ where
{
fn apply(self, world: &mut World) {
if let Ok(map_id) = world
.query_filtered::<Entity, (With<MapLabel<L>>, With<Tilemap<N>>)>()
.query_filtered::<Entity, (With<MapLabel<L>>, With<TileMap<N>>)>()
.get_single(world)
{
CheckedDespawn(map_id).apply(world);
Expand Down
9 changes: 6 additions & 3 deletions crates/bevy_tiles/src/maps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,17 @@ impl<L> Default for MapLabel<L> {
/// Manually updating this value, adding it, or removing it from an entity may
/// cause issues, please only mutate map information via commands.
#[derive(Component)]
pub struct Tilemap<const N: usize = 2> {
pub struct TileMap<const N: usize = 2> {
pub(crate) chunks: HashMap<ChunkCoord<N>, Entity>,
/// The size of a chunk in one direction.
pub chunk_size: usize,
}

impl<const N: usize> Default for Tilemap<N> {
fn default() -> Self {
impl<const N: usize> TileMap<N> {
pub(crate) fn with_chunk_size(chunk_size: usize) -> Self {
Self {
chunks: Default::default(),
chunk_size,
}
}
}
4 changes: 2 additions & 2 deletions crates/bevy_tiles/src/tiles/tile_query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use bevy::{

use crate::{
chunks::{Chunk, ChunkCoord, InMap},
maps::{MapLabel, TileMapLabel, Tilemap},
maps::{MapLabel, TileMap, TileMapLabel},
prelude::{
calculate_chunk_coordinate, calculate_tile_coordinate, calculate_tile_index,
max_tile_index, CoordIterator,
Expand All @@ -32,7 +32,7 @@ where
{
tile_q: Query<'w, 's, Q, (F, Relations<InChunk>, With<MapLabel<L>>)>,
chunk_q: Query<'w, 's, &'static Chunk, (Relations<InMap>, With<MapLabel<L>>)>,
map_q: Query<'w, 's, &'static Tilemap<N>, With<MapLabel<L>>>,
map_q: Query<'w, 's, &'static TileMap<N>, With<MapLabel<L>>>,
}

impl<'w, 's, L, Q, F, const N: usize> Deref for TileQuery<'w, 's, L, Q, F, N>
Expand Down
33 changes: 20 additions & 13 deletions crates/bevy_tiles_render/examples/hello_tile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ use bevy::{
transform::{components::Transform, TransformBundle},
DefaultPlugins,
};
use bevy_tiles::TilesPlugin;
use bevy_tiles_render::{settings::ChunkRenderSettings, tiles::TriThing, TilesRenderPlugin};
use bevy_tiles::{commands::TileCommandExt, maps::TileMapLabel, TilesPlugin};
use bevy_tiles_render::{
maps::{TileMapRenderer, TileMapRenderingBundle},
TilesRenderPlugin,
};

fn main() {
App::new()
Expand All @@ -17,19 +20,23 @@ fn main() {
.run();
}

struct GameLayer;

impl TileMapLabel for GameLayer {
const CHUNK_SIZE: usize = 16;
}

fn spawn(mut commands: Commands) {
for i in -5..5 {
commands.spawn((
TransformBundle {
local: Transform {
translation: Vec3::new(0.0, 64.0 * i as f32, 0.0),
..Default::default()
},
..Default::default()
},
TriThing,
));
let mut tile_commands = commands.tiles::<GameLayer, 2>();
tile_commands.spawn_map(TileMapRenderingBundle::default());

for i in -10..10 {
tile_commands.spawn_tile([0, 10 * i], ());
}
for i in -10..10 {
tile_commands.spawn_tile([10 * i, 0], ());
}

commands.spawn(Camera2dBundle {
..Default::default()
});
Expand Down
Loading

0 comments on commit df38c85

Please sign in to comment.