summaryrefslogtreecommitdiff
path: root/world/src
diff options
context:
space:
mode:
Diffstat (limited to 'world/src')
-rw-r--r--world/src/main.rs106
1 files changed, 65 insertions, 41 deletions
diff --git a/world/src/main.rs b/world/src/main.rs
index 0decba6..efdd16b 100644
--- a/world/src/main.rs
+++ b/world/src/main.rs
@@ -22,13 +22,16 @@ use anyhow::Result;
use clap::Parser;
use gltf::{Gltf, image::Source, import_buffers};
use image::{ImageReader, codecs::webp::WebPEncoder};
-use log::info;
+use log::{debug, info};
use mesh::import_mesh;
use physics::import_physics;
use rand::random;
+use rayon::iter::{ParallelBridge, ParallelIterator};
use std::{
+ borrow::Cow,
fs::File,
io::{Cursor, Read, Write},
+ marker::PhantomData,
net::{SocketAddr, TcpStream},
path::{Path, PathBuf},
thread::{self, sleep},
@@ -73,23 +76,61 @@ pub struct Args {
scale: Option<f32>,
#[arg(short, long)]
z_up: bool,
+ #[arg(short, long)]
+ dry_run: bool,
}
fn main() -> Result<()> {
env_logger::init_from_env("LOG");
let args = Args::parse();
- let mut sock = TcpStream::connect(args.address)?;
let store = ResourceStore::new_memory();
- Packet::Connect(random()).write(&mut sock)?;
-
let path_base = args.scene.parent().unwrap();
let mut gltf = Gltf::from_reader_without_validation(File::open(&args.scene)?)?;
let blob = gltf.blob.take();
let buffers = import_buffers(&gltf, Some(path_base), blob)?;
- let mut prefab = Prefab::default();
+ let mut prefab = gltf
+ .nodes()
+ .par_bridge()
+ .map(|node| {
+ let mut prefab = Prefab::default();
+ if let Some(mesh) = node.mesh() {
+ info!("--- MESH ---");
+ import_mesh(mesh, &buffers, &store, path_base, &node, &mut prefab, &args)?;
+ }
+ let (position, _, _) = node.transform().decomposed();
+ if let Some(light) = node.light() {
+ info!("--- LIGHT ---");
+ let emission = Some(Vec3A::from_array(light.color()) * light.intensity());
+ if let Some(e) = emission {
+ info!("emission is {e}");
+ }
+ prefab.light.push((
+ Vec3A::from_array(position),
+ store.set(&LightPart {
+ emission,
+ ..Default::default()
+ })?,
+ ));
+ }
+ import_physics(&gltf, &node, &mut prefab, &store, &buffers, &args)?;
+ Ok::<_, anyhow::Error>(prefab)
+ })
+ .reduce(
+ || Ok(Prefab::default()),
+ |a, b| {
+ let mut a = a?;
+ let b = b?;
+ a.collision.extend(b.collision);
+ a.mesh.extend(b.mesh);
+ a.light.extend(b.light);
+ a.environment = a.environment.or(b.environment);
+ a.name = a.name.or(b.name);
+ Ok(a)
+ },
+ )?;
prefab.name = args.name.clone().or(gltf
.default_scene()
@@ -97,40 +138,23 @@ fn main() -> Result<()> {
.flatten()
.map(|n| n.to_owned()));
- for node in gltf.nodes() {
- if let Some(mesh) = node.mesh() {
- info!("--- MESH ---");
- import_mesh(mesh, &buffers, &store, path_base, &node, &mut prefab, &args)?;
- }
- let (position, _, _) = node.transform().decomposed();
- if let Some(light) = node.light() {
- info!("--- LIGHT ---");
- let emission = Some(Vec3A::from_array(light.color()) * light.intensity());
- if let Some(e) = emission {
- info!("emission is {e}");
- }
- prefab.light.push((
- Vec3A::from_array(position),
- store.set(&LightPart {
- emission,
- ..Default::default()
- })?,
- ));
- }
- import_physics(&gltf, &node, &mut prefab, &store, &buffers, &args)?;
- }
-
if let Some(skybox) = args.skybox {
let mut buf = Vec::new();
File::open(skybox)?.read_to_end(&mut buf)?;
prefab.environment = Some(store.set(&EnvironmentPart {
- skybox: Some(store.set(&Image(buf))?),
+ skybox: Some(store.set(&Image(Cow::Owned(buf)))?),
..Default::default()
})?);
}
let pres = store.set(&prefab)?;
+ if args.dry_run {
+ return Ok(());
+ }
+
+ let mut sock = TcpStream::connect(args.address)?;
+ Packet::Connect(random()).write(&mut sock)?;
Packet::AnnouncePrefab(pres.clone()).write(&mut sock)?;
sock.flush()?;
@@ -199,46 +223,46 @@ fn load_texture(
buffers: &[gltf::buffer::Data],
source: &Source,
webp: bool,
-) -> Result<Resource<Image>> {
+) -> Result<Resource<Image<'static>>> {
let mut image = match source {
gltf::image::Source::View { view, mime_type } => {
- info!("{name} texture is embedded and of type {mime_type:?}");
+ debug!("{name} texture is embedded and of type {mime_type:?}");
let buf =
&buffers[view.buffer().index()].0[view.offset()..view.offset() + view.length()];
- Image(buf.to_vec())
+ Image(Cow::Borrowed(buf))
}
gltf::image::Source::Uri {
uri,
mime_type: Some(mime_type),
} => {
- info!("{name} texture is {uri:?} and of type {mime_type:?}");
+ debug!("{name} texture is {uri:?} and of type {mime_type:?}");
let path = path.join(uri);
let mut buf = Vec::new();
File::open(path)?.read_to_end(&mut buf)?;
- Image(buf)
+ Image(buf.into())
}
gltf::image::Source::Uri {
uri,
mime_type: None,
} => {
- info!("{name} texture is {uri:?} and has no type");
+ debug!("{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)
+ Image(buf.into())
}
};
if webp {
- let mut image_out = Image(Vec::new());
+ let mut image_out = Vec::new();
let len = image.0.len();
ImageReader::new(Cursor::new(image.0))
.with_guessed_format()?
.decode()?
- .write_with_encoder(WebPEncoder::new_lossless(&mut image_out.0))?;
- info!("webp encode: {len} -> {}", image_out.0.len());
- image = image_out;
+ .write_with_encoder(WebPEncoder::new_lossless(&mut image_out))?;
+ debug!("webp encode: {len} -> {}", image_out.len());
+ image = Image(Cow::Owned(image_out));
}
- Ok(store.set(&image)?)
+ Ok(Resource(store.set(&image)?.0, PhantomData))
}