tools/sync_models.sh: Texturen suchen + flach spiegeln + Textur-Ordner nicht mehr loeschen

Operator-Nachbesserung nach dem Eigenstaendigkeits-Beweis (exportierte App,
kein Client/Godot im Dateisystem):

- SRC_TEX wird GESUCHT statt fest verdrahtet: SCOPEDVR_TEX_DIR ->
  assets/textures/military_desert -> assets/textures -> Ordner der
  Demonstration_Textures*.png unter assets/. Findet er nichts, gibt es einen
  HINWEIS samt Loesung (SCOPEDVR_TEX_DIR=/pfad).
- Texturen werden FLACH nach models/textures/<name>.png gespiegelt — die App
  sucht sie dort; im Client liegen sie verschachtelt.
- Modell-Spiegel schliesst den Unterordner textures/ aus (skip_top): vorher
  galt er als 'ueberfluessig' und wurde bei JEDEM Lauf geloescht, der
  Textur-Spiegel legte ihn neu an -> Endlosschleife, --check nie sauber.

Belegt: 2. Lauf 0 Aenderungen, --check Exit 0; exportierte App findet
baum_kiefer_1/stein_mittel_1 aus models/, fehlende_glbs=0, ERGEBNIS: OK.
This commit is contained in:
scopedvr-operator 2026-10-20 09:55:05 +00:00 committed by Hermes (scopedvr-dev)
parent 7c7dc38566
commit 8c97d00871

View file

@ -85,10 +85,35 @@ fi
# (models/<oid>.glb) — NICHT verschachtelt in models/assets/objekte. # (models/<oid>.glb) — NICHT verschachtelt in models/assets/objekte.
# Deshalb wird $CLIENT/assets/objekte nach $TARGET (models/) gespiegelt. # Deshalb wird $CLIENT/assets/objekte nach $TARGET (models/) gespiegelt.
SRC_OBJEKTE="$CLIENT/assets/objekte" SRC_OBJEKTE="$CLIENT/assets/objekte"
SRC_TEX="$CLIENT/assets/textures/military_desert"
DST_OBJEKTE="$TARGET" DST_OBJEKTE="$TARGET"
DST_TEX="$TARGET/textures" DST_TEX="$TARGET/textures"
# Pack-Texturen FINDEN statt fest verdrahten (Operator-Nachbesserung 20.10.):
# Die Palette (Demonstration_Textures*.png) liegt je Client-Klon in einem anderen
# Unterordner und fehlt im Server-Container ganz. Reihenfolge: SCOPEDVR_TEX_DIR →
# assets/textures/military_desert → assets/textures → der Ordner, in dem die
# Palette irgendwo unter assets/ liegt. Erster Treffer gewinnt.
SRC_TEX="${SCOPEDVR_TEX_DIR:-}"
if [ -z "$SRC_TEX" ] || [ ! -d "$SRC_TEX" ]; then
for cand in "$CLIENT/assets/textures/military_desert" "$CLIENT/assets/textures"; do
if [ -d "$cand" ]; then SRC_TEX="$cand"; break; fi
done
fi
if [ -z "$SRC_TEX" ] || [ ! -d "$SRC_TEX" ]; then
PAL="$(find "$CLIENT/assets" -name 'Demonstration_Textures*.png' 2>/dev/null | head -1)"
if [ -n "$PAL" ]; then SRC_TEX="$(dirname "$PAL")"; fi
fi
if [ -z "$SRC_TEX" ] || [ ! -d "$SRC_TEX" ]; then
echo "HINWEIS: Pack-Texturen nicht gefunden — gesucht in SCOPEDVR_TEX_DIR,"
echo " assets/textures/military_desert, assets/textures und nach"
echo " Demonstration_Textures*.png unter assets/."
echo " Die Modelle werden trotzdem gespiegelt; die Optik nutzt dann"
echo " die Standardfarben. Nachreichen: SCOPEDVR_TEX_DIR=/pfad"
SRC_TEX="$CLIENT/assets/textures" # absichtlich nicht vorhanden -> HINWEIS statt stiller Leerlauf
fi
echo "Objekte: $SRC_OBJEKTE"
echo "Texturen: $SRC_TEX"
# Python macht das Spiegeln (copy2 + überflüssige Dateien löschen). # Python macht das Spiegeln (copy2 + überflüssige Dateien löschen).
# --check (Dry-Run) zeigt Abweichungen OHNE etwas zu verändern. # --check (Dry-Run) zeigt Abweichungen OHNE etwas zu verändern.
python3 - "$SRC_OBJEKTE" "$DST_OBJEKTE" "$SRC_TEX" "$DST_TEX" "$MODE" <<'PY' python3 - "$SRC_OBJEKTE" "$DST_OBJEKTE" "$SRC_TEX" "$DST_TEX" "$MODE" <<'PY'
@ -101,12 +126,12 @@ pairs = [
mode = sys.argv[5] mode = sys.argv[5]
def scan(root: str) -> dict: def scan(root: str, skip_top: set = frozenset()) -> dict:
out = {} out = {}
if not os.path.isdir(root): if not os.path.isdir(root):
return out return out
for r, dirs, files in os.walk(root): for r, dirs, files in os.walk(root):
dirs[:] = [d for d in dirs if d != ".godot"] dirs[:] = [d for d in dirs if d != ".godot" and d not in skip_top]
for f in files: for f in files:
if f.endswith(".import") or f == ".gdignore": if f.endswith(".import") or f == ".gdignore":
continue continue
@ -115,12 +140,20 @@ def scan(root: str) -> dict:
return out return out
def run(label: str, src: str, dst: str) -> int: def run(label: str, src: str, dst: str, flat: bool = False,
skip_top: set = frozenset()) -> int:
if not os.path.isdir(src): if not os.path.isdir(src):
print("ABWEICHUNG: Quelle fehlt: %s" % src) print("ABWEICHUNG: Quelle fehlt: %s" % src)
return 1 return 1
s_map = scan(src) s_map = scan(src, skip_top)
d_map = scan(dst) d_map = scan(dst, skip_top)
# flat=True (Pack-Texturen, Operator-Nachbesserung 20.10.): Die App sucht die
# Palette FLACH unter models/textures/<name>.png — im Client liegen die PNGs
# aber verschachtelt (assets/textures/<unterordner>/…). Deshalb ohne
# Unterordner spiegeln. Alte verschachtelte Reste erscheinen dadurch als
# "überflüssig" und werden automatisch entfernt (selbstheilend).
if flat:
s_map = {os.path.basename(p): p for p in s_map.values()}
changes = [] changes = []
for rel, sp in s_map.items(): for rel, sp in s_map.items():
dp = os.path.join(dst, rel) dp = os.path.join(dst, rel)
@ -156,8 +189,12 @@ def run(label: str, src: str, dst: str) -> int:
dev = 0 dev = 0
dev |= run("Objekte", pairs[0][1], pairs[0][2]) # skip_top: der Modell-Spiegel darf den Textur-Unterordner NICHT als
dev |= run("Texturen", pairs[1][1], pairs[1][2]) # "überflüssig" löschen (Operator-Nachbesserung 20.10. — sonst löscht jeder
# Lauf models/textures/, der Textur-Spiegel legt ihn neu an: Endlosschleife,
# --check nie sauber).
dev |= run("Objekte", pairs[0][1], pairs[0][2], skip_top={"textures"})
dev |= run("Texturen", pairs[1][1], pairs[1][2], flat=True)
sys.exit(dev) sys.exit(dev)
PY PY
DEVIATION=$? DEVIATION=$?