/* wearechat - generic multiplayer game with voip Copyright (C) 2025 metamuffin This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, version 3 of the License only. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ use anyhow::{Result, anyhow}; use gltf::{Gltf, Node, buffer::Data, json::Value}; use log::{debug, info}; use weareshared::{ Affine3A, packets::Resource, resources::CollisionPart, store::ResourceStore, vec3a, }; pub fn import_physics( gltf: &Gltf, trans: Affine3A, node: &Node, store: &ResourceStore, buffers: &[Data], ) -> Result)>> { let mut collision = Vec::new(); if let Some(physics) = node .extensions() .and_then(|e| e.get("KHR_physics_rigid_bodies")) { debug!("--- COLLISION ---"); if let Some(collider) = physics.get("collider") { if let Some(geometry) = collider.get("geometry") { if let Some(&Value::Bool(chull)) = geometry.get("convexHull") { let node = geometry .get("node") .and_then(|n| n.as_u64()) .ok_or(anyhow!("coll geom node missing"))?; let node = gltf .nodes() .nth(node as usize) .ok_or(anyhow!("coll geom node reference invalid"))?; let mesh = node.mesh().ok_or(anyhow!("coll geom 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!("coll geom no index buffer"))? .into_u32() .array_chunks::<3>() .collect::>(); let position = reader .read_positions() .ok_or(anyhow!("coll geom no positions"))? .map(|[x, y, z]| vec3a(x, y, z)) .collect::>(); let mut collpart = CollisionPart::default(); collpart.name = node.name().map(|s| s.to_string()); if chull { debug!("convex hull has {} positions", position.len()); collpart.sh_convex_hull = Some(store.set(&position)?); } else { debug!( "mesh has {} indecies and {} positions", index.len(), position.len() ); collpart.sh_mesh = Some((store.set(&index)?, store.set(&position)?)); } info!("added collision {:?}", node.name().unwrap_or_default()); collision.push((trans, store.set(&collpart)?)); } } } } } Ok(collision) }