summaryrefslogtreecommitdiff
path: root/world
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-01-07 16:50:44 +0100
committermetamuffin <metamuffin@disroot.org>2025-01-07 16:50:44 +0100
commit0a0abfe7b093d91447fb7070820a0e6d56d6c22d (patch)
tree17cdfd63bce8d717cd35d4d88646b837fbffc594 /world
parentd0d8c07e1915b47610bf91176d908c9b46a5ab54 (diff)
downloadweareserver-0a0abfe7b093d91447fb7070820a0e6d56d6c22d.tar
weareserver-0a0abfe7b093d91447fb7070820a0e6d56d6c22d.tar.bz2
weareserver-0a0abfe7b093d91447fb7070820a0e6d56d6c22d.tar.zst
normal texture
Diffstat (limited to 'world')
-rw-r--r--world/src/main.rs174
1 files changed, 124 insertions, 50 deletions
diff --git a/world/src/main.rs b/world/src/main.rs
index b68b287..517f1e9 100644
--- a/world/src/main.rs
+++ b/world/src/main.rs
@@ -1,18 +1,20 @@
#![feature(iter_array_chunks)]
-use anyhow::Result;
+use anyhow::{Result, bail};
use clap::Parser;
-use log::info;
+use gltf::image::Source;
+use log::{info, warn};
use rand::random;
use std::{
- io::Write,
+ fs::File,
+ io::{Read, Write},
net::{SocketAddr, TcpStream},
- path::PathBuf,
+ path::{Path, PathBuf},
thread::{self, sleep},
time::Duration,
};
use weareshared::{
Affine3A, Vec3A,
- packets::{Data, Object, Packet, ReadWrite},
+ packets::{Data, Object, Packet, ReadWrite, Resource},
resources::{AttributeArray, IndexArray, Part, Prefab},
store::ResourceStore,
vec3a,
@@ -37,35 +39,71 @@ fn main() -> Result<()> {
Packet::Connect(random()).write(&mut sock)?;
- let (gltf, buffers, _) = gltf::import(args.scene)?;
+ let (gltf, buffers, _) = gltf::import(&args.scene)?;
+ let path_base = args.scene.parent().unwrap();
let mut prefab = Prefab::default();
for node in gltf.nodes() {
if let Some(mesh) = node.mesh() {
for p in mesh.primitives() {
let reader = p.reader(|buf| Some(&buffers[buf.index()]));
- let mut pos_x = vec![];
- let mut pos_y = vec![];
- let mut pos_z = vec![];
- let mut norm_x = vec![];
- let mut norm_y = vec![];
- let mut norm_z = vec![];
- let mut uv_x = vec![];
- let mut uv_y = vec![];
- for p in reader.read_positions().unwrap() {
- pos_x.push(p[0]);
- pos_y.push(p[1]);
- pos_z.push(p[2]);
- }
- for p in reader.read_normals().unwrap() {
- norm_x.push(p[0]);
- norm_y.push(p[1]);
- norm_z.push(p[2]);
- }
- for p in reader.read_tex_coords(0).unwrap().into_f32() {
- uv_x.push(p[0]);
- uv_y.push(p[1]);
- }
+
+ let va_position = reader
+ .read_positions()
+ .map(|iter| {
+ let mut pos_x = vec![];
+ let mut pos_y = vec![];
+ let mut pos_z = vec![];
+ for p in iter {
+ pos_x.push(p[0]);
+ pos_y.push(p[1]);
+ pos_z.push(p[2]);
+ }
+ info!("vertex positions");
+ Ok::<_, anyhow::Error>([
+ store.set(&AttributeArray(pos_x).write_alloc())?,
+ store.set(&AttributeArray(pos_y).write_alloc())?,
+ store.set(&AttributeArray(pos_z).write_alloc())?,
+ ])
+ })
+ .transpose()?;
+
+ let va_normal = reader
+ .read_normals()
+ .map(|iter| {
+ let mut normal_x = vec![];
+ let mut normal_y = vec![];
+ let mut normal_z = vec![];
+ for p in iter {
+ normal_x.push(p[0]);
+ normal_y.push(p[1]);
+ normal_z.push(p[2]);
+ }
+ info!("vertex normals");
+ Ok::<_, anyhow::Error>([
+ store.set(&AttributeArray(normal_x).write_alloc())?,
+ store.set(&AttributeArray(normal_y).write_alloc())?,
+ store.set(&AttributeArray(normal_z).write_alloc())?,
+ ])
+ })
+ .transpose()?;
+ let va_texcoord = reader
+ .read_tex_coords(0)
+ .map(|iter| {
+ let mut texcoord_u = vec![];
+ let mut texcoord_v = vec![];
+ for p in iter.into_f32() {
+ texcoord_u.push(p[0]);
+ texcoord_v.push(p[1]);
+ }
+ info!("vertex texture coordinates");
+ Ok::<_, anyhow::Error>([
+ store.set(&AttributeArray(texcoord_u).write_alloc())?,
+ store.set(&AttributeArray(texcoord_v).write_alloc())?,
+ ])
+ })
+ .transpose()?;
+
let index = reader
.read_indices()
.unwrap()
@@ -73,36 +111,42 @@ fn main() -> Result<()> {
.map(|e| e as u16)
.array_chunks::<3>()
.collect::<Vec<_>>();
+ let index = Some(store.set(&IndexArray(index).write_alloc())?);
let mut tex_albedo = None;
if let Some(tex) = p.material().pbr_metallic_roughness().base_color_texture() {
- let s = tex.texture().source().source();
- if let gltf::image::Source::View { view, mime_type } = s {
- info!("albedo texture is of type {mime_type:?}");
- let buf = &buffers[view.buffer().index()].0
- [view.offset()..view.offset() + view.length()];
- tex_albedo = Some(store.set(buf)?);
- }
+ tex_albedo = Some(load_texture(
+ "albedo",
+ &store,
+ path_base,
+ &buffers,
+ &tex.texture().source().source(),
+ )?);
+ }
+ let mut tex_normal = None;
+ if let Some(tex) = p.material().normal_texture() {
+ tex_normal = Some(load_texture(
+ "normal",
+ &store,
+ path_base,
+ &buffers,
+ &tex.texture().source().source(),
+ )?);
}
+ let g_metallic = Some(p.material().pbr_metallic_roughness().metallic_factor());
+ let g_roughness = Some(p.material().pbr_metallic_roughness().roughness_factor());
+
let part = store.set(
&Part {
- va_position: Some([
- store.set(&AttributeArray(pos_x).write_alloc())?,
- store.set(&AttributeArray(pos_y).write_alloc())?,
- store.set(&AttributeArray(pos_z).write_alloc())?,
- ]),
- va_normal: Some([
- store.set(&AttributeArray(norm_x).write_alloc())?,
- store.set(&AttributeArray(norm_y).write_alloc())?,
- store.set(&AttributeArray(norm_z).write_alloc())?,
- ]),
- va_texcoord: Some([
- store.set(&AttributeArray(uv_x).write_alloc())?,
- store.set(&AttributeArray(uv_y).write_alloc())?,
- ]),
+ g_metallic,
+ g_roughness,
+ va_position,
+ va_normal,
+ va_texcoord,
tex_albedo,
- index: Some(store.set(&IndexArray(index).write_alloc())?),
+ tex_normal,
+ index,
..Part::default()
}
.write_alloc(),
@@ -160,3 +204,33 @@ fn main() -> Result<()> {
}
Ok(())
}
+
+fn load_texture(
+ name: &str,
+ store: &ResourceStore,
+ path: &Path,
+ buffers: &[gltf::buffer::Data],
+ source: &Source,
+) -> Result<Resource> {
+ match source {
+ gltf::image::Source::View { view, mime_type } => {
+ info!("{name} texture is embedded and of type {mime_type:?}");
+ let buf =
+ &buffers[view.buffer().index()].0[view.offset()..view.offset() + view.length()];
+ return Ok(store.set(buf)?);
+ }
+ gltf::image::Source::Uri {
+ uri,
+ mime_type: Some(mime_type),
+ } => {
+ info!("{name} texture is at {uri:?} and of type {mime_type:?}");
+ let path = path.join(uri);
+ let mut buf = Vec::new();
+ File::open(path)?.read_to_end(&mut buf)?;
+ return Ok(store.set(&buf)?);
+ }
+ _ => {
+ bail!("texture is external and has no mime type")
+ }
+ }
+}