summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/src/scene_prepare.rs104
-rw-r--r--client/src/scene_render.rs55
-rw-r--r--world/src/main.rs13
-rw-r--r--world/src/physics.rs19
4 files changed, 100 insertions, 91 deletions
diff --git a/client/src/scene_prepare.rs b/client/src/scene_prepare.rs
index ae7e599..b5ac2cf 100644
--- a/client/src/scene_prepare.rs
+++ b/client/src/scene_prepare.rs
@@ -22,12 +22,13 @@ use std::{
collections::{HashMap, HashSet},
hash::Hash,
io::Cursor,
+ marker::PhantomData,
sync::{Arc, RwLock},
};
use weareshared::{
Affine3A,
packets::Resource,
- resources::{AttributeArray, Image, IndexArray, MeshPart, Prefab},
+ resources::{Image, MeshPart, Prefab},
};
use wgpu::{
AddressMode, BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayout, BindingResource,
@@ -79,8 +80,8 @@ pub struct ScenePreparer {
textures: DemandMap<Resource<Image>, (Arc<Texture>, Arc<BindGroup>)>,
placeholder_textures: DemandMap<(), (Arc<Texture>, Arc<BindGroup>)>,
- index_buffers: DemandMap<Resource<IndexArray>, (Arc<Buffer>, u32)>,
- vertex_buffers: DemandMap<Resource<AttributeArray>, (Arc<Buffer>, u32)>,
+ index_buffers: DemandMap<Resource<Vec<[u16; 3]>>, (Arc<Buffer>, u32)>,
+ vertex_buffers: DemandMap<Resource<Vec<f32>>, (Arc<Buffer>, u32)>,
placeholder_vertex_buffers: DemandMap<(u32, bool), Arc<Buffer>>,
mesh_parts: DemandMap<Resource<MeshPart>, Arc<RMeshPart>>,
pub prefabs: DemandMap<Resource<Prefab>, Arc<RPrefab>>,
@@ -90,9 +91,9 @@ pub struct RPrefab(pub Vec<(Affine3A, Arc<RMeshPart>)>);
pub struct RMeshPart {
pub index_count: u32,
pub index: Arc<Buffer>,
- pub position: [Arc<Buffer>; 3],
- pub normal: [Arc<Buffer>; 3],
- pub texcoord: [Arc<Buffer>; 2],
+ pub position: Arc<Buffer>,
+ pub normal: Arc<Buffer>,
+ pub texcoord: Arc<Buffer>,
pub texture: Arc<BindGroup>,
}
@@ -129,7 +130,6 @@ impl ScenePreparer {
for pres in self.index_buffers.needed() {
if let Some(buf) = dls.try_get(pres.clone())? {
let buf = buf
- .0
.into_iter()
.flatten()
.flat_map(u16::to_le_bytes)
@@ -147,10 +147,8 @@ impl ScenePreparer {
for pres in self.vertex_buffers.needed() {
if let Some(buf) = dls.try_get(pres.clone())? {
let buf = buf
- .0
.into_iter()
- .map(f32::to_le_bytes)
- .flatten()
+ .flat_map(f32::to_le_bytes)
.collect::<Vec<_>>();
let buffer = self.device.create_buffer_init(&BufferInitDescriptor {
contents: &buf,
@@ -196,54 +194,32 @@ impl ScenePreparer {
for pres in self.mesh_parts.needed() {
if let Some(part) = dls.try_get(pres.clone())? {
if let (Some(indexres), Some(positionres)) = (part.index, part.va_position) {
- let Some((index, index_count)) = self.index_buffers.try_get(indexres.clone())
- else {
- continue;
- };
- let mut position = Vec::new();
- let mut vertex_count = 0;
- for vr in positionres {
- if let Some((vertex, n)) = self.vertex_buffers.try_get(vr) {
- vertex_count = n;
- position.push(vertex);
- }
- }
- let mut normal = Vec::new();
- if let Some(normalres) = part.va_normal {
- for vr in normalres {
- if let Some((vertex, _)) = self.vertex_buffers.try_get(vr) {
- normal.push(vertex);
- }
- }
+ let index = self.index_buffers.try_get(indexres);
+ 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)
} else {
- // TODO generate normals
- for _ in 0..3 {
- if let Some(buf) = self
- .placeholder_vertex_buffers
- .try_get((vertex_count, false))
- {
- normal.push(buf);
- }
- }
- }
- let mut texcoord = Vec::new();
- if let Some(texcoordres) = part.va_texcoord {
- for vr in texcoordres {
- if let Some((vertex, _)) = self.vertex_buffers.try_get(vr) {
- texcoord.push(vertex);
- }
- }
+ vertex_count
+ .map(|vc| self.placeholder_vertex_buffers.try_get((vc * 4, false)))
+ .flatten()
+ };
+
+ let texcoord = if let Some(res) = part.va_texcoord {
+ self.vertex_buffers
+ .try_get(Resource(res.0, PhantomData))
+ .map(|e| e.0)
} else {
- // TODO generate UVs
- for _ in 0..3 {
- if let Some(buf) = self
- .placeholder_vertex_buffers
- .try_get((vertex_count, false))
- {
- texcoord.push(buf);
- }
- }
- }
+ vertex_count
+ .map(|vc| self.placeholder_vertex_buffers.try_get((vc * 2, false)))
+ .flatten()
+ };
+
let mut texture = None;
if let Some(albedores) = part.tex_albedo {
if let Some((_tex, bg)) = self.textures.try_get(albedores) {
@@ -255,10 +231,12 @@ impl ScenePreparer {
}
}
- if texcoord.len() == 2
- && normal.len() == 3
- && position.len() == 3
- && texture.is_some()
+ if let (
+ Some(normal),
+ Some((index, index_count)),
+ Some(texcoord),
+ Some((position, _)),
+ ) = (normal, index, texcoord, position)
{
debug!("part created ({pres})");
self.mesh_parts.insert(
@@ -266,9 +244,9 @@ impl ScenePreparer {
Arc::new(RMeshPart {
index_count,
index,
- texcoord: texcoord.try_into().unwrap(),
- normal: normal.try_into().unwrap(),
- position: position.try_into().unwrap(),
+ texcoord,
+ normal,
+ position,
texture: texture.unwrap(),
}),
);
diff --git a/client/src/scene_render.rs b/client/src/scene_render.rs
index 047cee4..f6f7dbb 100644
--- a/client/src/scene_render.rs
+++ b/client/src/scene_render.rs
@@ -35,20 +35,6 @@ pub struct ScenePipeline {
pipeline: RenderPipeline,
}
-macro_rules! v_attr {
- ($($n:literal),*) => {
- [$(VertexBufferLayout {
- step_mode: VertexStepMode::Vertex,
- array_stride: 4,
- attributes: &[VertexAttribute {
- format: VertexFormat::Float32,
- offset: 0,
- shader_location: $n,
- }],
- }),*]
- };
-}
-
impl ScenePipeline {
pub fn new(device: &Device, format: TextureFormat) -> (Self, BindGroupLayout) {
let module = device.create_shader_module(include_wgsl!("shader.wgsl"));
@@ -98,7 +84,35 @@ impl ScenePipeline {
vertex: VertexState {
module: &module,
entry_point: Some("vs_main"),
- buffers: &v_attr!(0, 1, 2, 3, 4, 5, 6, 7),
+ buffers: &[
+ VertexBufferLayout {
+ step_mode: VertexStepMode::Vertex,
+ array_stride: 3 * size_of::<f32>() as u64,
+ attributes: &[VertexAttribute {
+ format: VertexFormat::Float32x3,
+ offset: 0,
+ shader_location: 0,
+ }],
+ },
+ VertexBufferLayout {
+ step_mode: VertexStepMode::Vertex,
+ array_stride: 3 * size_of::<f32>() as u64,
+ attributes: &[VertexAttribute {
+ format: VertexFormat::Float32x3,
+ offset: 0,
+ shader_location: 1,
+ }],
+ },
+ VertexBufferLayout {
+ step_mode: VertexStepMode::Vertex,
+ array_stride: 2 * size_of::<f32>() as u64,
+ attributes: &[VertexAttribute {
+ format: VertexFormat::Float32x2,
+ offset: 0,
+ shader_location: 2,
+ }],
+ },
+ ],
compilation_options: PipelineCompilationOptions::default(),
},
primitive: PrimitiveState {
@@ -177,14 +191,9 @@ impl ScenePipeline {
rpass.set_pipeline(&self.pipeline);
rpass.set_push_constants(ShaderStages::VERTEX, 0, projection.as_flattened());
rpass.set_index_buffer(part.index.slice(..), IndexFormat::Uint16);
- rpass.set_vertex_buffer(0, part.position[0].slice(..));
- rpass.set_vertex_buffer(1, part.position[1].slice(..));
- rpass.set_vertex_buffer(2, part.position[2].slice(..));
- rpass.set_vertex_buffer(3, part.normal[0].slice(..));
- rpass.set_vertex_buffer(4, part.normal[1].slice(..));
- rpass.set_vertex_buffer(5, part.normal[2].slice(..));
- rpass.set_vertex_buffer(6, part.texcoord[0].slice(..));
- rpass.set_vertex_buffer(7, part.texcoord[1].slice(..));
+ rpass.set_vertex_buffer(0, part.position.slice(..));
+ rpass.set_vertex_buffer(1, part.normal.slice(..));
+ rpass.set_vertex_buffer(2, part.texcoord.slice(..));
rpass.draw_indexed(0..part.index_count, 0, 0..1);
}
}
diff --git a/world/src/main.rs b/world/src/main.rs
index c90ff0c..72e7df2 100644
--- a/world/src/main.rs
+++ b/world/src/main.rs
@@ -18,7 +18,7 @@
pub mod mesh;
pub mod physics;
-use anyhow::{Result, bail};
+use anyhow::Result;
use clap::Parser;
use gltf::{Gltf, image::Source, import_buffers};
use image::{ImageReader, codecs::webp::WebPEncoder};
@@ -221,8 +221,15 @@ fn load_texture(
File::open(path)?.read_to_end(&mut buf)?;
Image(buf)
}
- _ => {
- bail!("texture is external and has no mime type")
+ gltf::image::Source::Uri {
+ uri,
+ mime_type: None,
+ } => {
+ info!("{name} texture is {uri:?} and has no type");
+ let path = path.join(uri);
+ let mut buf = Vec::new();
+ File::open(path)?.read_to_end(&mut buf)?;
+ Image(buf)
}
};
diff --git a/world/src/physics.rs b/world/src/physics.rs
index 82bb28f..bc39a11 100644
--- a/world/src/physics.rs
+++ b/world/src/physics.rs
@@ -1,3 +1,20 @@
+/*
+ wearechat - generic multiplayer game with voip
+ Copyright (C) 2025 metamuffin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, version 3 of the License only.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ 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::mesh::node_transform_to_affine;
use anyhow::{Result, anyhow};
use gltf::{Gltf, Node, buffer::Data, json::Value};
use log::info;
@@ -7,8 +24,6 @@ use weareshared::{
vec3a,
};
-use crate::mesh::node_transform_to_affine;
-
pub fn import_physics(
gltf: &Gltf,
node: &Node,