Analog zur Ink-Pipeline: eine .blend neben ihrer .glb im Map-Ordner (assets/maps/<map>/<name>.blend) wird von tools/build-models.sh headless zu <name>.glb exportiert, inkrementell per mtime. build.rs stößt das beim cargo-Build an, sobald sich eine .blend geändert hat. - Export: blender -b --factory-startup ... export_scene.gltf mit export_extras (collide/signal/role), export_apply, yup, image AUTO. - Blender über $BLENDER oder PATH; fehlt es, wird der Schritt still übersprungen — die committeten .glb reichen zum Bauen/Spielen. - Ein Export-Fehler bei vorhandenem Blender ist fatal (wie bei Ink). - build.rs teilt sich jetzt run_script/watch-Helfer für beide Pipelines. - Cinemaroom.blend -> assets/maps/cinema/cinema.blend verschoben und die .glb einmal daraus gebaut. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0196AM4UyAJEXVtPvp5DdKr8
83 lines
3.6 KiB
Rust
83 lines
3.6 KiB
Rust
//! Build-Hook: baut geänderte Assets automatisch beim Cargo-Build.
|
|
//!
|
|
//! Reines „Wann"-Stück — das eigentliche Bauen machen die Skripte unter
|
|
//! `tools/` (und bleiben von Hand aufrufbar). Hier melden wir Cargo nur, wann
|
|
//! es uns erneut ausführen soll, und stoßen die Skripte an:
|
|
//!
|
|
//! * `build-dialogues.sh` — `.ink` → `.ink.json` (inklecate)
|
|
//! * `build-models.sh` — `assets/maps/**/*.blend` → `.glb` (Blender)
|
|
//!
|
|
//! Cargo führt build.rs ausschließlich dann erneut aus, wenn eine der unten
|
|
//! via `rerun-if-changed` gemeldeten Dateien sich ändert. Unveränderte
|
|
//! Rebuilds kosten also nichts; nur nach einer Quell-Änderung läuft das
|
|
//! jeweilige Werkzeug (beide Skripte bauen intern inkrementell).
|
|
|
|
use std::path::{Path, PathBuf};
|
|
use std::process::Command;
|
|
|
|
fn main() {
|
|
let root = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
|
|
|
// --- Ink-Dialoge ------------------------------------------------------
|
|
println!("cargo:rerun-if-changed=tools/build-dialogues.sh");
|
|
println!("cargo:rerun-if-changed=tools/inklecate");
|
|
// Verzeichnis-mtime fängt neu hinzugekommene/gelöschte .ink-Dateien.
|
|
println!("cargo:rerun-if-changed=assets/interactions");
|
|
watch_ext(&root.join("assets/interactions"), "ink");
|
|
run_script(&root, "tools/build-dialogues.sh", "Dialog");
|
|
|
|
// --- Blender-Welten -------------------------------------------------
|
|
println!("cargo:rerun-if-changed=tools/build-models.sh");
|
|
// Ordner-mtime fängt neue/gelöschte Maps; die .blend selbst einzeln.
|
|
// Die erzeugten .glb werden NICHT beobachtet (das Skript schreibt sie).
|
|
watch_dirs_and_ext(&root.join("assets/maps"), "blend");
|
|
run_script(&root, "tools/build-models.sh", "Modell");
|
|
}
|
|
|
|
/// Jede Datei mit Endung `ext` direkt in `dir` einzeln bei Cargo anmelden.
|
|
fn watch_ext(dir: &Path, ext: &str) {
|
|
let Ok(entries) = std::fs::read_dir(dir) else { return };
|
|
for entry in entries.flatten() {
|
|
let p = entry.path();
|
|
if p.extension().and_then(|s| s.to_str()) == Some(ext) {
|
|
println!("cargo:rerun-if-changed={}", p.display());
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Wie [`watch_ext`], aber rekursiv — und jedes Unterverzeichnis wird selbst
|
|
/// beobachtet (fängt neu angelegte/entfernte Maps).
|
|
fn watch_dirs_and_ext(dir: &Path, ext: &str) {
|
|
let Ok(entries) = std::fs::read_dir(dir) else { return };
|
|
println!("cargo:rerun-if-changed={}", dir.display());
|
|
for entry in entries.flatten() {
|
|
let p = entry.path();
|
|
if p.is_dir() {
|
|
watch_dirs_and_ext(&p, ext);
|
|
} else if p.extension().and_then(|s| s.to_str()) == Some(ext) {
|
|
println!("cargo:rerun-if-changed={}", p.display());
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Ein `tools/`-Skript laufen lassen. Ausgabe einsammeln (Cargo blendet
|
|
/// Build-Script-stdout sonst aus); Fehlschlag ist fatal, ein nicht startbares
|
|
/// bash nur eine Warnung — die committeten Artefakte reichen dann.
|
|
fn run_script(root: &Path, rel: &str, label: &str) {
|
|
let script = root.join(rel);
|
|
match Command::new("bash").arg(&script).output() {
|
|
Ok(out) if out.status.success() => { /* still bei Erfolg — Detail via Hand-Aufruf */ }
|
|
Ok(out) => {
|
|
let stdout = String::from_utf8_lossy(&out.stdout);
|
|
let stderr = String::from_utf8_lossy(&out.stderr);
|
|
for line in stdout.lines().chain(stderr.lines()) {
|
|
println!("cargo:warning={line}");
|
|
}
|
|
panic!("{label}-Build fehlgeschlagen — siehe Warnungen oben. Einzeln debuggen: ./{rel}");
|
|
}
|
|
Err(e) => {
|
|
println!("cargo:warning={label}-Build übersprungen ({e}). Bei Bedarf von Hand: ./{rel}");
|
|
}
|
|
}
|
|
}
|