Collider via collide-Property + Quickhull, OBJ-Pfad entfernt

col_*-Namenspräfix raus: Rollen steuern nur noch Custom Properties
(collide=1 sichtbar+Collider, "proxy" unsichtbar, signal wie gehabt).
Collider sind die konvexe Hülle der Vertices — konkave Meshes erlaubt.
glb ist der einzige Modell-Pfad; suzanne.obj → suzanne.glb.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-16 19:14:42 +02:00
parent f7bfdb4a0b
commit 9db3929750
12 changed files with 371 additions and 2497 deletions
+8 -7
View File
@@ -24,7 +24,7 @@
use serde_json::Value;
use crate::engine::model::{apply_signal_rule, classify, Empty, Model, Object, Props};
use crate::engine::model::{apply_props, Empty, Model, Object, Props};
pub fn load(path: &str) -> Result<Model, String> {
let bytes = std::fs::read(path).map_err(|e| format!("gltf load {path}: {e}"))?;
@@ -81,14 +81,14 @@ fn walk_node(doc: &Value, bin: &[u8], idx: usize, parent: M4, model: &mut Model)
match node["mesh"].as_u64() {
Some(mesh) => {
let (visible, collider) = classify(&name);
let mut o = Object {
name, visible, collider, props,
name, props,
visible: true, collider: false, // bis apply_props entscheidet
verts: Vec::new(), uvs: Vec::new(),
tris: Vec::new(), tri_mats: Vec::new(),
};
append_mesh(doc, bin, mesh as usize, world, &mut o, &mut model.materials)?;
apply_signal_rule(&mut o); // Betretens-Zonen werden nie gerendert
apply_props(&mut o); // collide-/signal-Regeln (siehe engine::model)
if !o.tris.is_empty() { model.objects.push(o); }
}
// Node ohne Mesh = Empty (Entity-Marker); Position aus der
@@ -352,7 +352,7 @@ mod tests {
{"name": "Ding", "mesh": 0, "translation": [10, 0, 0],
"extras": {"signal": "tiffany", "hp": 3},
"children": [1]},
{"name": "col_Kind", "mesh": 0},
{"name": "Kind", "mesh": 0, "extras": {"collide": "proxy"}},
{"name": "spawn", "translation": [1, 2, 3]}
],
"meshes": [{"primitives": [{
@@ -388,9 +388,10 @@ mod tests {
assert!(!d.visible && !d.collider);
assert_eq!(m.materials, vec!["carpet".to_string()]);
// Kind erbt die Parent-Transform (10, 0, 0).
// Kind erbt die Parent-Transform (10, 0, 0);
// collide="proxy" → unsichtbarer Collider.
let k = &m.objects[1];
assert_eq!(k.name, "col_Kind");
assert_eq!(k.name, "Kind");
assert!(!k.visible && k.collider);
assert_eq!(k.verts[0], [10.0, 0.0, 0.0]);
}