summaryrefslogtreecommitdiff
path: root/client/src/scene_prepare.rs
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/scene_prepare.rs')
-rw-r--r--client/src/scene_prepare.rs191
1 files changed, 133 insertions, 58 deletions
diff --git a/client/src/scene_prepare.rs b/client/src/scene_prepare.rs
index 5c5102d..8941fa7 100644
--- a/client/src/scene_prepare.rs
+++ b/client/src/scene_prepare.rs
@@ -14,12 +14,13 @@
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-use crate::download::Downloader;
+use crate::{download::Downloader, meshops::generate_tangents};
use anyhow::Result;
use egui::{Grid, Widget};
+use glam::{Vec2, Vec3, Vec3A};
use humansize::DECIMAL;
use image::ImageReader;
-use log::debug;
+use log::{debug, trace};
use std::{
collections::{HashMap, HashSet},
hash::Hash,
@@ -85,10 +86,12 @@ pub struct ScenePreparer {
texture_bgl: BindGroupLayout,
textures: DemandMap<Resource<Image<'static>>, (Arc<Texture>, Arc<BindGroup>)>,
- placeholder_textures: DemandMap<bool, (Arc<Texture>, Arc<BindGroup>)>,
+ placeholder_textures: DemandMap<TextureIdentityKind, (Arc<Texture>, Arc<BindGroup>)>,
index_buffers: DemandMap<Resource<Vec<[u32; 3]>>, (Arc<Buffer>, u32)>,
- vertex_buffers: DemandMap<Resource<Vec<f32>>, (Arc<Buffer>, u32)>,
- placeholder_vertex_buffers: DemandMap<(u32, bool), Arc<Buffer>>,
+ vertex_buffers: DemandMap<Resource<Vec<f32>>, Arc<Buffer>>,
+ generated_tangent_buffers: DemandMap<TangentBufferSpec, Arc<Buffer>>,
+ generated_normal_buffers: DemandMap<NormalBufferSpec, Arc<Buffer>>,
+ generated_texcoord_buffers: DemandMap<TexcoordBufferSpec, Arc<Buffer>>,
mesh_parts: DemandMap<Resource<MeshPart>, Arc<RMeshPart>>,
pub prefabs: DemandMap<Resource<Prefab>, Arc<RPrefab>>,
}
@@ -99,12 +102,37 @@ pub struct RMeshPart {
pub index: Arc<Buffer>,
pub va_position: Arc<Buffer>,
pub va_normal: Arc<Buffer>,
+ pub va_tangent: Arc<Buffer>,
pub va_texcoord: Arc<Buffer>,
pub tex_albedo: Arc<BindGroup>,
pub tex_normal: Arc<BindGroup>,
pub double_sided: bool,
}
+#[derive(Debug, Clone, Hash, PartialEq, Eq)]
+struct TangentBufferSpec {
+ index: Resource<Vec<[u32; 3]>>,
+ position: Resource<Vec<Vec3>>,
+ texcoord: Resource<Vec<Vec2>>,
+}
+
+#[derive(Debug, Clone, Hash, PartialEq, Eq)]
+struct NormalBufferSpec {
+ index: Resource<Vec<[u32; 3]>>,
+ position: Resource<Vec<Vec3A>>,
+}
+#[derive(Debug, Clone, Hash, PartialEq, Eq)]
+struct TexcoordBufferSpec {
+ index: Resource<Vec<[u32; 3]>>,
+ position: Resource<Vec<Vec3A>>,
+}
+
+#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
+enum TextureIdentityKind {
+ Normal,
+ Multiply,
+}
+
impl ScenePreparer {
pub fn new(device: Arc<Device>, queue: Arc<Queue>, texture_bgl: BindGroupLayout) -> Self {
Self {
@@ -114,8 +142,10 @@ impl ScenePreparer {
mesh_parts: DemandMap::new(),
prefabs: DemandMap::new(),
textures: DemandMap::new(),
- placeholder_vertex_buffers: DemandMap::new(),
placeholder_textures: DemandMap::new(),
+ generated_tangent_buffers: DemandMap::new(),
+ generated_normal_buffers: DemandMap::new(),
+ generated_texcoord_buffers: DemandMap::new(),
device,
queue,
}
@@ -140,19 +170,14 @@ impl ScenePreparer {
for pres in self.index_buffers.needed() {
let start = Instant::now();
if let Some(buf) = dls.try_get(pres.clone())? {
- let buf = buf
- .into_iter()
- .flatten()
- .flat_map(u32::to_le_bytes)
- .collect::<Vec<_>>();
let buffer = self.device.create_buffer_init(&BufferInitDescriptor {
- contents: &buf,
+ contents: bytemuck::cast_slice(buf.as_slice()),
label: None,
usage: BufferUsages::INDEX | BufferUsages::COPY_DST,
});
self.index_buffers.insert(
pres.clone(),
- (Arc::new(buffer), (buf.len() / size_of::<u32>()) as u32),
+ (Arc::new(buffer), (buf.len() * 3) as u32),
buf.len(),
);
debug!(
@@ -166,20 +191,13 @@ impl ScenePreparer {
for pres in self.vertex_buffers.needed() {
let start = Instant::now();
if let Some(buf) = dls.try_get(pres.clone())? {
- let buf = buf
- .into_iter()
- .flat_map(f32::to_le_bytes)
- .collect::<Vec<_>>();
let buffer = self.device.create_buffer_init(&BufferInitDescriptor {
- contents: &buf,
+ contents: bytemuck::cast_slice(buf.as_slice()),
label: None,
usage: BufferUsages::VERTEX | BufferUsages::COPY_DST,
});
- self.vertex_buffers.insert(
- pres.clone(),
- (Arc::new(buffer), (buf.len() / size_of::<f32>()) as u32),
- buf.len(),
- );
+ self.vertex_buffers
+ .insert(pres.clone(), Arc::new(buffer), buf.len());
debug!(
"vertex attribute buffer created (len={}, took {:?}) {pres}",
buf.len() / size_of::<f32>(),
@@ -214,47 +232,62 @@ impl ScenePreparer {
num_done += 1;
}
}
- for variant in self.placeholder_textures.needed() {
- let v = if variant { 255 } else { 0 };
- let tex_bg = create_texture(
- &self.device,
- &self.queue,
- &self.texture_bgl,
- &[v, v, v, 255],
- 1,
- 1,
- );
- self.placeholder_textures.insert(variant, tex_bg, 4);
+ for kind in self.placeholder_textures.needed() {
+ let color = match kind {
+ TextureIdentityKind::Normal => [128, 128, 255, 255],
+ TextureIdentityKind::Multiply => [255, 255, 255, 255],
+ };
+ let tex_bg = create_texture(&self.device, &self.queue, &self.texture_bgl, &color, 1, 1);
+ self.placeholder_textures.insert(kind, tex_bg, 4);
num_done += 1;
}
+ for spec in self.generated_tangent_buffers.needed() {
+ if let (Some(index), Some(position), Some(texcoord)) = (
+ dls.try_get(spec.index.clone())?,
+ dls.try_get(spec.position.clone())?,
+ dls.try_get(spec.texcoord.clone())?,
+ ) {
+ let tangents = generate_tangents(&index, &position, &texcoord);
+ let buffer = self.device.create_buffer_init(&BufferInitDescriptor {
+ label: None,
+ usage: BufferUsages::COPY_DST | BufferUsages::VERTEX,
+ contents: bytemuck::cast_slice(tangents.as_slice()),
+ });
+ self.generated_tangent_buffers.insert(
+ spec,
+ Arc::new(buffer),
+ size_of::<f32>() * tangents.len() * 3,
+ );
+ }
+ }
for pres in self.mesh_parts.needed() {
let start = Instant::now();
if let Some(part) = dls.try_get(pres.clone())? {
if let (Some(indexres), Some(positionres)) = (part.index, part.va_position) {
- let index = self.index_buffers.try_get(indexres);
+ let index = self.index_buffers.try_get(indexres.clone());
let position = self
.vertex_buffers
.try_get(Resource(positionres.0, PhantomData));
- let vertex_count = position.as_ref().map(|(_, c)| *c / 3);
- let normal = if let Some(res) = part.va_normal {
- self.vertex_buffers
- .try_get(Resource(res.0, PhantomData))
- .map(|e| e.0)
+ let normal = if let Some(res) = part.va_normal.clone() {
+ self.vertex_buffers.try_get(Resource(res.0, PhantomData))
} else {
- vertex_count
- .map(|vc| self.placeholder_vertex_buffers.try_get((vc * 4, false)))
- .flatten()
+ todo!()
};
- let texcoord = if let Some(res) = part.va_texcoord {
- self.vertex_buffers
- .try_get(Resource(res.0, PhantomData))
- .map(|e| e.0)
+ let texcoord = if let Some(res) = part.va_texcoord.clone() {
+ self.vertex_buffers.try_get(Resource(res.0, PhantomData))
} else {
- vertex_count
- .map(|vc| self.placeholder_vertex_buffers.try_get((vc * 2, false)))
- .flatten()
+ todo!()
+ };
+ let tangent = if let Some(res) = part.va_tangent.clone() {
+ self.vertex_buffers.try_get(Resource(res.0, PhantomData))
+ } else {
+ self.generated_tangent_buffers.try_get(TangentBufferSpec {
+ index: indexres,
+ position: Resource(positionres.0, PhantomData),
+ texcoord: part.va_texcoord.expect("TODO"),
+ })
};
let mut tex_albedo = None;
@@ -263,7 +296,10 @@ impl ScenePreparer {
tex_albedo = Some(bg)
}
} else {
- if let Some((_tex, bg)) = self.placeholder_textures.try_get(true) {
+ if let Some((_tex, bg)) = self
+ .placeholder_textures
+ .try_get(TextureIdentityKind::Multiply)
+ {
tex_albedo = Some(bg)
}
}
@@ -273,20 +309,25 @@ impl ScenePreparer {
tex_normal = Some(bg)
}
} else {
- if let Some((_tex, bg)) = self.placeholder_textures.try_get(false) {
+ if let Some((_tex, bg)) = self
+ .placeholder_textures
+ .try_get(TextureIdentityKind::Normal)
+ {
tex_normal = Some(bg)
}
}
if let (
- Some(va_normal),
Some((index, index_count)),
+ Some(va_normal),
+ Some(va_tangent),
Some(va_texcoord),
- Some((va_position, _)),
+ Some(va_position),
Some(tex_normal),
Some(tex_albedo),
- ) = (normal, index, texcoord, position, tex_normal, tex_albedo)
- {
+ ) = (
+ index, normal, tangent, texcoord, position, tex_normal, tex_albedo,
+ ) {
debug!("part created (took {:?}) {pres}", start.elapsed());
self.mesh_parts.insert(
pres,
@@ -294,6 +335,7 @@ impl ScenePreparer {
index_count,
index,
va_normal,
+ va_tangent,
va_position,
va_texcoord,
tex_albedo,
@@ -307,6 +349,7 @@ impl ScenePreparer {
}
}
}
+ self.print_missing();
Ok(num_done)
}
}
@@ -373,6 +416,34 @@ impl<K, V> Widget for &DemandMap<K, V> {
ui.response()
}
}
+impl ScenePreparer {
+ pub fn print_missing(&self) {
+ fn visit<K, V>(name: &str, m: &DemandMap<K, V>)
+ where
+ K: Clone,
+ K: Hash,
+ K: std::cmp::Eq,
+ V: Clone,
+ {
+ let nl = m.needed().len();
+ if nl > 0 {
+ trace!("{name}: need {nl}")
+ }
+ }
+ visit("prefabs", &self.prefabs);
+ visit("mesh_parts", &self.mesh_parts);
+ visit("vertex_buffers", &self.vertex_buffers);
+ visit("index_buffers", &self.index_buffers);
+ visit("placeholder_textures", &self.placeholder_textures);
+ visit("generated_tangent_buffers", &self.generated_tangent_buffers);
+ visit("generated_normal_buffers", &self.generated_normal_buffers);
+ visit(
+ "generated_texcoord_buffers",
+ &self.generated_texcoord_buffers,
+ );
+ visit("textures", &self.textures);
+ }
+}
impl Widget for &ScenePreparer {
fn ui(self, ui: &mut egui::Ui) -> egui::Response {
@@ -389,8 +460,12 @@ impl Widget for &ScenePreparer {
self.index_buffers.ui(ui);
ui.label("placeholder_textures");
self.placeholder_textures.ui(ui);
- ui.label("placeholder_vertex_buffers");
- self.placeholder_vertex_buffers.ui(ui);
+ ui.label("generated_tangent_buffers");
+ self.generated_tangent_buffers.ui(ui);
+ ui.label("generated_normal_buffers");
+ self.generated_normal_buffers.ui(ui);
+ ui.label("generated_texcoord_buffers");
+ self.generated_texcoord_buffers.ui(ui);
ui.label("textures");
self.textures.ui(ui);
})