diff options
Diffstat (limited to 'world/src/physics.rs')
-rw-r--r-- | world/src/physics.rs | 73 |
1 files changed, 73 insertions, 0 deletions
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(()) +} |