mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 04:33:37 +00:00
support instancing multiple meshes
This commit is contained in:
parent
4d903df33c
commit
e1fb86ef8e
1 changed files with 50 additions and 33 deletions
|
@ -5,7 +5,7 @@ use crate::{
|
||||||
LocalToWorld,
|
LocalToWorld,
|
||||||
};
|
};
|
||||||
use legion::prelude::*;
|
use legion::prelude::*;
|
||||||
use std::mem;
|
use std::{collections::HashMap, mem};
|
||||||
use wgpu::{Device, SwapChainOutput};
|
use wgpu::{Device, SwapChainOutput};
|
||||||
use zerocopy::AsBytes;
|
use zerocopy::AsBytes;
|
||||||
|
|
||||||
|
@ -33,42 +33,62 @@ impl ForwardInstancedPipeline {
|
||||||
Read<Handle<Mesh>>,
|
Read<Handle<Mesh>>,
|
||||||
Read<Instanced>,
|
Read<Instanced>,
|
||||||
)>::query();
|
)>::query();
|
||||||
let entities_count = entities.iter(world).count();
|
if entities.iter(world).count() == 0 {
|
||||||
if entities_count == 0 {
|
|
||||||
return Vec::new();
|
return Vec::new();
|
||||||
}
|
}
|
||||||
|
|
||||||
let size = mem::size_of::<SimpleMaterialUniforms>();
|
let uniform_size = mem::size_of::<SimpleMaterialUniforms>();
|
||||||
|
|
||||||
let temp_buf_data = device.create_buffer_mapped(
|
let mut mesh_groups: HashMap<
|
||||||
entities_count * size,
|
usize,
|
||||||
wgpu::BufferUsage::COPY_SRC | wgpu::BufferUsage::VERTEX,
|
Vec<(
|
||||||
);
|
legion::borrow::Ref<Material>,
|
||||||
|
legion::borrow::Ref<LocalToWorld>,
|
||||||
// TODO: generate these buffers for multiple meshes
|
)>,
|
||||||
|
> = HashMap::new();
|
||||||
let mut last_mesh_id = None;
|
for (material, transform, mesh, _) in entities.iter(world) {
|
||||||
for ((material, transform, mesh, _), slot) in entities
|
match mesh_groups.get_mut(&mesh.id) {
|
||||||
.iter(world)
|
Some(entities) => {
|
||||||
.zip(temp_buf_data.data.chunks_exact_mut(size))
|
entities.push((material, transform));
|
||||||
{
|
|
||||||
last_mesh_id = Some(mesh.id);
|
|
||||||
let (_, _, translation) = transform.0.to_scale_rotation_translation();
|
|
||||||
slot.copy_from_slice(
|
|
||||||
SimpleMaterialUniforms {
|
|
||||||
position: translation.into(),
|
|
||||||
color: material.color.into(),
|
|
||||||
}
|
}
|
||||||
.as_bytes(),
|
None => {
|
||||||
);
|
let mut entities = Vec::new();
|
||||||
|
let id = mesh.id;
|
||||||
|
entities.push((material, transform));
|
||||||
|
mesh_groups.insert(id, entities);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut instance_buffer_infos = Vec::new();
|
let mut instance_buffer_infos = Vec::new();
|
||||||
instance_buffer_infos.push(InstanceBufferInfo {
|
for (mesh_id, mut same_mesh_entities) in mesh_groups {
|
||||||
mesh_id: last_mesh_id.unwrap(),
|
let temp_buf_data = device.create_buffer_mapped(
|
||||||
buffer: temp_buf_data.finish(),
|
same_mesh_entities.len() * uniform_size,
|
||||||
instance_count: entities_count,
|
wgpu::BufferUsage::COPY_SRC | wgpu::BufferUsage::VERTEX,
|
||||||
});
|
);
|
||||||
|
|
||||||
|
let entity_count = same_mesh_entities.len();
|
||||||
|
for ((material, transform), slot) in same_mesh_entities
|
||||||
|
.drain(..)
|
||||||
|
.zip(temp_buf_data.data.chunks_exact_mut(uniform_size))
|
||||||
|
{
|
||||||
|
let (_, _, translation) = transform.0.to_scale_rotation_translation();
|
||||||
|
slot.copy_from_slice(
|
||||||
|
SimpleMaterialUniforms {
|
||||||
|
position: translation.into(),
|
||||||
|
color: material.color.into(),
|
||||||
|
}
|
||||||
|
.as_bytes(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
instance_buffer_infos.push(InstanceBufferInfo {
|
||||||
|
mesh_id: mesh_id,
|
||||||
|
buffer: temp_buf_data.finish(),
|
||||||
|
instance_count: entity_count,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
instance_buffer_infos
|
instance_buffer_infos
|
||||||
}
|
}
|
||||||
|
@ -261,10 +281,7 @@ impl Pipeline for ForwardInstancedPipeline {
|
||||||
));
|
));
|
||||||
pass.set_bind_group(0, self.local_bind_group.as_ref().unwrap(), &[]);
|
pass.set_bind_group(0, self.local_bind_group.as_ref().unwrap(), &[]);
|
||||||
|
|
||||||
let mut mesh_storage = world
|
let mut mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap();
|
||||||
.resources
|
|
||||||
.get_mut::<AssetStorage<Mesh>>()
|
|
||||||
.unwrap();
|
|
||||||
for instance_buffer_info in self.instance_buffer_infos.as_ref().unwrap().iter() {
|
for instance_buffer_info in self.instance_buffer_infos.as_ref().unwrap().iter() {
|
||||||
if let Some(mesh_asset) = mesh_storage.get(instance_buffer_info.mesh_id) {
|
if let Some(mesh_asset) = mesh_storage.get(instance_buffer_info.mesh_id) {
|
||||||
mesh_asset.setup_buffers(&render_graph.device);
|
mesh_asset.setup_buffers(&render_graph.device);
|
||||||
|
|
Loading…
Reference in a new issue