A6 (t_c5a27ca7): Editor loest Kategorie-GLBs aus der Registry auf (GlbMeshStore + gen_thumbs), Thumbs fuer Beispiel-Objekte
This commit is contained in:
parent
76f8143540
commit
310aa695e6
5 changed files with 74 additions and 9 deletions
BIN
library/thumbs/beispiel_fass_01.png
Normal file
BIN
library/thumbs/beispiel_fass_01.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 869 B |
BIN
library/thumbs/beispiel_fass_02.png
Normal file
BIN
library/thumbs/beispiel_fass_02.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 869 B |
|
|
@ -24,6 +24,10 @@ class_name GlbMeshStore
|
||||||
const QUELLEN_SETTING := "scopedvr/editor/glb_quellen"
|
const QUELLEN_SETTING := "scopedvr/editor/glb_quellen"
|
||||||
## Voreinstellung = dieselben Quellen wie tools/gen_thumbs.gd (Sibling-Repos).
|
## Voreinstellung = dieselben Quellen wie tools/gen_thumbs.gd (Sibling-Repos).
|
||||||
const DEFAULT_QUELLEN := ["../scopedvr-match-server/assets/objekte", "../scopedvr-client/assets/objekte"]
|
const DEFAULT_QUELLEN := ["../scopedvr-match-server/assets/objekte", "../scopedvr-client/assets/objekte"]
|
||||||
|
## Registry (A6): liefert das Feld "glb" für die Kategorie-verschachtelte Ablage.
|
||||||
|
const MANIFEST_PATH := "res://library/objects.json"
|
||||||
|
static var _manifest: Dictionary = {}
|
||||||
|
static var _manifest_geladen := false
|
||||||
|
|
||||||
# Cache pro OID: Mesh (normalisiert) oder `false` = GLB gefunden, aber nicht
|
# Cache pro OID: Mesh (normalisiert) oder `false` = GLB gefunden, aber nicht
|
||||||
# ladbar (Parse-Fehler — kein endloser Retry pro Rebuild). Fehlende Datei
|
# ladbar (Parse-Fehler — kein endloser Retry pro Rebuild). Fehlende Datei
|
||||||
|
|
@ -44,6 +48,36 @@ static func quellen() -> Array:
|
||||||
return out if not out.is_empty() else DEFAULT_QUELLEN.duplicate()
|
return out if not out.is_empty() else DEFAULT_QUELLEN.duplicate()
|
||||||
|
|
||||||
|
|
||||||
|
## Kandidaten-Pfade (absolut) in Ladereihenfolge: Registry-`glb` (A6, Kategorie-
|
||||||
|
## Ablage assets/objekte/military_desert/<kategorie>/<oid>.glb) VOR der flachen
|
||||||
|
## Alt-Ablage <quelle>/<oid>.glb. Die Quelle ist ein Mesh-Lager (<repo>/assets/
|
||||||
|
## objekte) — für den verschachtelten Pfad wird sie auf die Repo-Wurzel gekürzt.
|
||||||
|
static func _kandidaten(oid: String) -> Array:
|
||||||
|
var basis := ProjectSettings.globalize_path("res://")
|
||||||
|
var out: Array = []
|
||||||
|
var rel := str(_eintrag(oid).get("glb", ""))
|
||||||
|
if rel.begins_with("res://"):
|
||||||
|
var sub := rel.substr(6)
|
||||||
|
for quelle in quellen():
|
||||||
|
var q := str(quelle)
|
||||||
|
var marke := "/assets/objekte"
|
||||||
|
var wurzel := q.substr(0, q.length() - marke.length()) if q.ends_with(marke) else q
|
||||||
|
out.append(basis.path_join(wurzel).path_join(sub))
|
||||||
|
for quelle in quellen():
|
||||||
|
out.append(basis.path_join(str(quelle)).path_join(oid + ".glb"))
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
## Registry-Eintrag der OID (einmal gelesen, dann gecacht).
|
||||||
|
static func _eintrag(oid: String) -> Dictionary:
|
||||||
|
if not _manifest_geladen:
|
||||||
|
_manifest_geladen = true
|
||||||
|
var parsed: Variant = JSON.parse_string(FileAccess.get_file_as_string(MANIFEST_PATH))
|
||||||
|
if parsed is Dictionary:
|
||||||
|
_manifest = (parsed as Dictionary).get("objects", {})
|
||||||
|
return _manifest.get(oid, {})
|
||||||
|
|
||||||
|
|
||||||
## Echtes Mesh für eine Objekt-ID (normalisiert, Fußpunkt-Koordinaten) oder
|
## Echtes Mesh für eine Objekt-ID (normalisiert, Fußpunkt-Koordinaten) oder
|
||||||
## null = keine brauchbare GLB → Aufrufer zeigt den Platzhalter.
|
## null = keine brauchbare GLB → Aufrufer zeigt den Platzhalter.
|
||||||
static func mesh_fuer(oid: String) -> Mesh:
|
static func mesh_fuer(oid: String) -> Mesh:
|
||||||
|
|
@ -51,9 +85,7 @@ static func mesh_fuer(oid: String) -> Mesh:
|
||||||
return null
|
return null
|
||||||
if _cache.has(oid):
|
if _cache.has(oid):
|
||||||
return _cache[oid] if _cache[oid] is Mesh else null
|
return _cache[oid] if _cache[oid] is Mesh else null
|
||||||
for quelle in quellen():
|
for pfad in _kandidaten(oid):
|
||||||
var basis := ProjectSettings.globalize_path("res://")
|
|
||||||
var pfad := basis.path_join(quelle).path_join(oid + ".glb")
|
|
||||||
if FileAccess.file_exists(pfad):
|
if FileAccess.file_exists(pfad):
|
||||||
var m := _glb_mesh(pfad)
|
var m := _glb_mesh(pfad)
|
||||||
if m != null:
|
if m != null:
|
||||||
|
|
@ -73,9 +105,8 @@ static func fehlt(oid: String) -> bool:
|
||||||
return true
|
return true
|
||||||
if _cache.has(oid):
|
if _cache.has(oid):
|
||||||
return not (_cache[oid] is Mesh)
|
return not (_cache[oid] is Mesh)
|
||||||
var basis := ProjectSettings.globalize_path("res://")
|
for pfad in _kandidaten(oid):
|
||||||
for quelle in quellen():
|
if FileAccess.file_exists(pfad):
|
||||||
if FileAccess.file_exists(basis.path_join(quelle).path_join(oid + ".glb")):
|
|
||||||
return false
|
return false
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
|
@ -83,6 +114,8 @@ static func fehlt(oid: String) -> bool:
|
||||||
## Cache leeren (Tests / nach manuellem Eingriff ins Mesh-Lager).
|
## Cache leeren (Tests / nach manuellem Eingriff ins Mesh-Lager).
|
||||||
static func cache_leeren() -> void:
|
static func cache_leeren() -> void:
|
||||||
_cache.clear()
|
_cache.clear()
|
||||||
|
_manifest.clear()
|
||||||
|
_manifest_geladen = false
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------ Laden --------
|
# ------------------------------------------------------------ Laden --------
|
||||||
|
|
|
||||||
9
tests/probe_store_a6.gd
Normal file
9
tests/probe_store_a6.gd
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
extends SceneTree
|
||||||
|
func _initialize() -> void:
|
||||||
|
var m := GlbMeshStore.mesh_fuer("beispiel_fass_01")
|
||||||
|
var m2 := GlbMeshStore.mesh_fuer("crate_wood")
|
||||||
|
print("GlbMeshStore beispiel_fass_01: ", "MESH " + str((m as Mesh).get_surface_count()) + " Flaechen, AABB " + str((m as Mesh).get_aabb().size) if m != null else "null")
|
||||||
|
print("GlbMeshStore crate_wood: ", "MESH" if m2 != null else "null (erwartet: kein GLB im Lager)")
|
||||||
|
print("GlbMeshStore.fehlt(fass)=", GlbMeshStore.fehlt("beispiel_fass_01"), " fehlt(crate_wood)=", GlbMeshStore.fehlt("crate_wood"))
|
||||||
|
print("STORE_PROBE_OK")
|
||||||
|
quit(0)
|
||||||
|
|
@ -119,10 +119,15 @@ func _process(_delta: float) -> bool:
|
||||||
|
|
||||||
## Mesh für ein Thumbnail: echtes GLB aus dem Mesh-Lager (Sibling-Repos),
|
## Mesh für ein Thumbnail: echtes GLB aus dem Mesh-Lager (Sibling-Repos),
|
||||||
## sonst Kollisions-Platzhalter (alte Fallback-Regel).
|
## sonst Kollisions-Platzhalter (alte Fallback-Regel).
|
||||||
|
##
|
||||||
|
## A6-Fundament (19.10.): Military-Objekte liegen KATEGORIE-verschachtelt
|
||||||
|
## (assets/objekte/military_desert/<kategorie>/<oid>.glb, Pfad im Registry-Feld
|
||||||
|
## "glb"). Deshalb stehen die Kandidaten jetzt in dieser Reihenfolge:
|
||||||
|
## 1. Registry-`glb` gegen jede QUELLEN-WURZEL (deren "/assets/objekte"-Suffix
|
||||||
|
## entfernt, damit derselbe relative Pfad aufgeht),
|
||||||
|
## 2. flache Alt-Ablage <quelle>/<oid>.glb.
|
||||||
func _mesh_fuer(oid: String, col: Dictionary) -> Mesh:
|
func _mesh_fuer(oid: String, col: Dictionary) -> Mesh:
|
||||||
var basis := ProjectSettings.globalize_path("res://")
|
for pfad in _kandidaten(oid):
|
||||||
for quelle in GLB_QUELLEN:
|
|
||||||
var pfad := basis.path_join(str(quelle)).path_join(oid + ".glb")
|
|
||||||
if FileAccess.file_exists(pfad):
|
if FileAccess.file_exists(pfad):
|
||||||
var m := _glb_mesh(pfad)
|
var m := _glb_mesh(pfad)
|
||||||
if m != null:
|
if m != null:
|
||||||
|
|
@ -130,6 +135,24 @@ func _mesh_fuer(oid: String, col: Dictionary) -> Mesh:
|
||||||
return MeshShapes.make_placeholder(str(col.get("shape", "box")), col, 1.0)
|
return MeshShapes.make_placeholder(str(col.get("shape", "box")), col, 1.0)
|
||||||
|
|
||||||
|
|
||||||
|
## Kandidaten-Pfade (absolut) für eine OID — Registry-Pfad vor flacher Alt-Ablage.
|
||||||
|
func _kandidaten(oid: String) -> Array:
|
||||||
|
var basis := ProjectSettings.globalize_path("res://")
|
||||||
|
var out: Array = []
|
||||||
|
var eintrag: Dictionary = (manifest.get("objects", {}) as Dictionary).get(oid, {})
|
||||||
|
var rel := str(eintrag.get("glb", ""))
|
||||||
|
if rel.begins_with("res://"):
|
||||||
|
var sub := rel.substr(6)
|
||||||
|
for quelle in GLB_QUELLEN:
|
||||||
|
var q := str(quelle)
|
||||||
|
var marke := "/assets/objekte"
|
||||||
|
var wurzel := q.substr(0, q.length() - marke.length()) if q.ends_with(marke) else q
|
||||||
|
out.append(basis.path_join(wurzel).path_join(sub))
|
||||||
|
for quelle in GLB_QUELLEN:
|
||||||
|
out.append(basis.path_join(str(quelle)).path_join(oid + ".glb"))
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
## GLB OHNE Import-System laden (GLTFDocument) und das erste Mesh liefern.
|
## GLB OHNE Import-System laden (GLTFDocument) und das erste Mesh liefern.
|
||||||
## null = Load-Fehlschlag → Aufrufer fällt auf den Platzhalter zurück.
|
## null = Load-Fehlschlag → Aufrufer fällt auf den Platzhalter zurück.
|
||||||
func _glb_mesh(pfad: String) -> Mesh:
|
func _glb_mesh(pfad: String) -> Mesh:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue