summaryrefslogtreecommitdiff
path: root/world/src/physics.rs
diff options
context:
space:
mode:
Diffstat (limited to 'world/src/physics.rs')
-rw-r--r--world/src/physics.rs73
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(())
+}