summaryrefslogtreecommitdiff
path: root/world/src
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-01-10 20:06:01 +0100
committermetamuffin <metamuffin@disroot.org>2025-01-10 20:06:01 +0100
commit3ac853862b5965c1ebfb10b12fb35cf5c671232f (patch)
tree4aaa6684d21ec7eb4dbae00878111989131aedba /world/src
parent2746fce8d943325f34b188a67b7039453d8484d1 (diff)
downloadweareserver-3ac853862b5965c1ebfb10b12fb35cf5c671232f.tar
weareserver-3ac853862b5965c1ebfb10b12fb35cf5c671232f.tar.bz2
weareserver-3ac853862b5965c1ebfb10b12fb35cf5c671232f.tar.zst
physics extension and fixes
Diffstat (limited to 'world/src')
-rw-r--r--world/src/main.rs8
-rw-r--r--world/src/mesh.rs95
-rw-r--r--world/src/physics.rs73
3 files changed, 112 insertions, 64 deletions
diff --git a/world/src/main.rs b/world/src/main.rs
index 5dbfd06..c90ff0c 100644
--- a/world/src/main.rs
+++ b/world/src/main.rs
@@ -16,6 +16,7 @@
*/
#![feature(iter_array_chunks)]
pub mod mesh;
+pub mod physics;
use anyhow::{Result, bail};
use clap::Parser;
@@ -23,6 +24,7 @@ use gltf::{Gltf, image::Source, import_buffers};
use image::{ImageReader, codecs::webp::WebPEncoder};
use log::info;
use mesh::import_mesh;
+use physics::import_physics;
use rand::random;
use std::{
fs::File,
@@ -93,6 +95,7 @@ fn main() -> Result<()> {
for node in gltf.nodes() {
if let Some(mesh) = node.mesh() {
+ info!("--- MESH ---");
import_mesh(
mesh,
&buffers,
@@ -105,7 +108,11 @@ fn main() -> Result<()> {
}
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 {
@@ -114,6 +121,7 @@ fn main() -> Result<()> {
})?,
));
}
+ import_physics(&gltf, &node, &mut prefab, &store, &buffers)?;
}
if let Some(skybox) = args.skybox {
diff --git a/world/src/mesh.rs b/world/src/mesh.rs
index c621753..67f86ad 100644
--- a/world/src/mesh.rs
+++ b/world/src/mesh.rs
@@ -21,8 +21,9 @@ use log::{debug, info};
use std::path::Path;
use weareshared::{
Affine3A, Vec3A,
- resources::{AttributeArray, IndexArray, MeshPart, Prefab},
+ resources::{MeshPart, Prefab},
store::ResourceStore,
+ vec2, vec3a,
};
pub fn import_mesh(
@@ -40,77 +41,39 @@ pub fn import_mesh(
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", pos_x.len());
- Ok::<_, anyhow::Error>([
- store.set(&AttributeArray(pos_x))?,
- store.set(&AttributeArray(pos_y))?,
- store.set(&AttributeArray(pos_z))?,
- ])
+ let a = iter.map(|[x, y, z]| vec3a(x, y, z)).collect::<Vec<_>>();
+ info!("{} vertex positions", a.len());
+ Ok::<_, anyhow::Error>(store.set(&a)?)
})
.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", normal_x.len());
- Ok::<_, anyhow::Error>([
- store.set(&AttributeArray(normal_x))?,
- store.set(&AttributeArray(normal_y))?,
- store.set(&AttributeArray(normal_z))?,
- ])
+ let a = iter.map(|[x, y, z]| vec3a(x, y, z)).collect::<Vec<_>>();
+ info!("{} vertex normals", a.len());
+ Ok::<_, anyhow::Error>(store.set(&a)?)
})
.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", texcoord_u.len());
- Ok::<_, anyhow::Error>([
- store.set(&AttributeArray(texcoord_u))?,
- store.set(&AttributeArray(texcoord_v))?,
- ])
+ let a = iter.into_f32().map(|[x, y]| vec2(x, y)).collect::<Vec<_>>();
+ info!("{} vertex texture coordinates", a.len());
+ Ok::<_, anyhow::Error>(store.set(&a)?)
})
.transpose()?;
let va_albedo = reader
.read_colors(0)
.map(|iter| {
- let mut color_r = vec![];
- let mut color_g = vec![];
- let mut color_b = vec![];
- for p in iter.into_rgb_f32() {
- color_r.push(p[0]);
- color_g.push(p[1]);
- color_b.push(p[2]);
- }
- info!("{} vertex colors", color_r.len());
- Ok::<_, anyhow::Error>([
- store.set(&AttributeArray(color_r))?,
- store.set(&AttributeArray(color_g))?,
- store.set(&AttributeArray(color_b))?,
- ])
+ let a = iter
+ .into_rgb_f32()
+ .map(|[x, y, z]| vec3a(x, y, z))
+ .collect::<Vec<_>>();
+ info!("{} vertex colors", a.len());
+ Ok::<_, anyhow::Error>(store.set(&a)?)
})
.transpose()?;
@@ -123,7 +86,7 @@ pub fn import_mesh(
}
let o = if color_a.iter().any(|x| *x != 1.) {
info!("{} vertex transmissions", color_a.len());
- Some(store.set(&AttributeArray(color_a))?)
+ Some(store.set(&color_a)?)
} else {
debug!("vertex transmission pruned");
None
@@ -141,7 +104,7 @@ pub fn import_mesh(
.array_chunks::<3>()
.collect::<Vec<_>>();
info!("{} indecies", index.len() * 3);
- let index = Some(store.set(&IndexArray(index))?);
+ let index = Some(store.set(&index)?);
let mut tex_albedo = None;
let mut tex_alpha = None;
@@ -370,13 +333,17 @@ pub fn import_mesh(
va_metallic: None,
va_roughness: None,
})?;
- let mat = node.transform().matrix();
- let aff = Affine3A::from_cols_array_2d(&[
- [mat[0][0], mat[0][1], mat[0][2]],
- [mat[1][0], mat[1][1], mat[1][2]],
- [mat[2][0], mat[2][1], mat[2][2]],
- [mat[3][0], mat[3][1], mat[3][2]],
- ]);
- prefab.mesh.push((aff, mesh))
+
+ prefab.mesh.push((node_transform_to_affine(node), mesh))
})
}
+
+pub fn node_transform_to_affine(node: &Node) -> Affine3A {
+ let mat = node.transform().matrix();
+ Affine3A::from_cols_array_2d(&[
+ [mat[0][0], mat[0][1], mat[0][2]],
+ [mat[1][0], mat[1][1], mat[1][2]],
+ [mat[2][0], mat[2][1], mat[2][2]],
+ [mat[3][0], mat[3][1], mat[3][2]],
+ ])
+}
diff --git a/world/src/physics.rs b/world/src/physics.rs
new file mode 100644
index 0000000..82bb28f
--- /dev/null
+++ b/world/src/physics.rs
@@ -0,0 +1,73 @@
+use anyhow::{Result, anyhow};
+use gltf::{Gltf, Node, buffer::Data, json::Value};
+use log::info;
+use weareshared::{
+ resources::{CollisionPart, Prefab},
+ store::ResourceStore,
+ vec3a,
+};
+
+use crate::mesh::node_transform_to_affine;
+
+pub fn import_physics(
+ gltf: &Gltf,
+ node: &Node,
+ prefab: &mut Prefab,
+ store: &ResourceStore,
+ buffers: &[Data],
+) -> Result<()> {
+ if let Some(physics) = node
+ .extensions()
+ .map(|e| e.get("KHR_physics_rigid_bodies"))
+ .flatten()
+ {
+ info!("--- COLLISION ---");
+ if let Some(collider) = physics.get("collider") {
+ if let Some(geometry) = collider.get("geometry") {
+ if geometry.get("convexHull") == Some(&Value::Bool(true)) {
+ let node = geometry
+ .get("node")
+ .map(|n| n.as_u64())
+ .flatten()
+ .ok_or(anyhow!("convexHull node missing"))?;
+ let node = gltf
+ .nodes()
+ .nth(node as usize)
+ .ok_or(anyhow!("convexHull node reference invalid"))?;
+ let mesh = node.mesh().ok_or(anyhow!("convexHull node has no mesh"))?;
+ for p in mesh.primitives() {
+ let reader = p.reader(|buf| Some(&buffers[buf.index()]));
+
+ let index = reader
+ .read_indices()
+ .ok_or(anyhow!("convexHull no index buffer"))?
+ .into_u32()
+ .map(|e| e as u16)
+ .array_chunks::<3>()
+ .collect::<Vec<_>>();
+ let position = reader
+ .read_positions()
+ .ok_or(anyhow!("convexHull no positions"))?
+ .map(|[x, y, z]| vec3a(x, y, z))
+ .collect::<Vec<_>>();
+
+ info!(
+ "convex hull has {} indecies and {} positions",
+ index.len(),
+ position.len()
+ );
+
+ prefab.collision.push((
+ node_transform_to_affine(&node),
+ store.set(&CollisionPart {
+ sh_mesh: Some((store.set(&index)?, store.set(&position)?)),
+ ..Default::default()
+ })?,
+ ));
+ }
+ }
+ }
+ }
+ }
+ Ok(())
+}