M2 Natur-Update t_7cf80244: Bibliothek 54 Objekte in Gruppen bäume/felsen/pflanzen/gras/pilze. library_browser: 39 deutsche Namen, alte Gruppe 'natur' thematisch aufgelöst (tree_pine->bäume, rock_large/boulder_small->felsen, bush_small->pflanzen). mesh_shapes: 'none' = flache Fußpunkt-Scheibe (Deko ohne Kollider bleibt sichtbar/wählbar). gen_thumbs: rendert jetzt ECHTE GLB-Meshes aus dem Mesh-Lager (Sibling-Repo, GLTFDocument ohne Import-System), Fallback weiter Platzhalter — alle 54 Thumbnails neu gerendert. test_library: 15->54 + Gruppen-Checks, Suite 56 Checks grün (alle 6 Editor-Suiten OK).
|
|
@ -16,6 +16,45 @@
|
||||||
"fass": { "poly": 128, "collision": { "shape": "cylinder", "radius": 0.31, "height": 0.88 } },
|
"fass": { "poly": 128, "collision": { "shape": "cylinder", "radius": 0.31, "height": 0.88 } },
|
||||||
"bruecke_holz": { "poly": 228, "collision": { "shape": "compound", "parts": [{ "shape": "box", "pos": [0, 0.85, 0], "size": [2, 0.3, 3] }, { "shape": "box", "pos": [0, 0.361, -2.806], "size": [2, 0.3, 2.89], "rot_deg": [21.8, 0, 0] }, { "shape": "box", "pos": [0, 0.361, 2.806], "size": [2, 0.3, 2.89], "rot_deg": [-21.8, 0, 0] }, { "shape": "box", "pos": [-0.93, 1.5, 0], "size": [0.14, 0.12, 3] }, { "shape": "box", "pos": [-0.93, 0.964, -2.564], "size": [0.14, 0.12, 2.69], "rot_deg": [21.8, 0, 0] }, { "shape": "box", "pos": [-0.93, 0.964, 2.564], "size": [0.14, 0.12, 2.69], "rot_deg": [-21.8, 0, 0] }, { "shape": "box", "pos": [0.93, 1.5, 0], "size": [0.14, 0.12, 3] }, { "shape": "box", "pos": [0.93, 0.964, -2.564], "size": [0.14, 0.12, 2.69], "rot_deg": [21.8, 0, 0] }, { "shape": "box", "pos": [0.93, 0.964, 2.564], "size": [0.14, 0.12, 2.69], "rot_deg": [-21.8, 0, 0] }] } },
|
"bruecke_holz": { "poly": 228, "collision": { "shape": "compound", "parts": [{ "shape": "box", "pos": [0, 0.85, 0], "size": [2, 0.3, 3] }, { "shape": "box", "pos": [0, 0.361, -2.806], "size": [2, 0.3, 2.89], "rot_deg": [21.8, 0, 0] }, { "shape": "box", "pos": [0, 0.361, 2.806], "size": [2, 0.3, 2.89], "rot_deg": [-21.8, 0, 0] }, { "shape": "box", "pos": [-0.93, 1.5, 0], "size": [0.14, 0.12, 3] }, { "shape": "box", "pos": [-0.93, 0.964, -2.564], "size": [0.14, 0.12, 2.69], "rot_deg": [21.8, 0, 0] }, { "shape": "box", "pos": [-0.93, 0.964, 2.564], "size": [0.14, 0.12, 2.69], "rot_deg": [-21.8, 0, 0] }, { "shape": "box", "pos": [0.93, 1.5, 0], "size": [0.14, 0.12, 3] }, { "shape": "box", "pos": [0.93, 0.964, -2.564], "size": [0.14, 0.12, 2.69], "rot_deg": [21.8, 0, 0] }, { "shape": "box", "pos": [0.93, 0.964, 2.564], "size": [0.14, 0.12, 2.69], "rot_deg": [-21.8, 0, 0] }] } },
|
||||||
"hoehleneingang": { "poly": 204, "collision": { "shape": "compound", "parts": [{ "shape": "box", "pos": [-1.8, 1.6, 0], "size": [1.4, 3.2, 4] }, { "shape": "box", "pos": [1.8, 1.6, 0], "size": [1.4, 3.2, 4] }, { "shape": "box", "pos": [0, 2.8, 0], "size": [5, 0.8, 4] }, { "shape": "box", "pos": [0, 1.2, 1.8], "size": [2.2, 2.4, 0.4] }] } },
|
"hoehleneingang": { "poly": 204, "collision": { "shape": "compound", "parts": [{ "shape": "box", "pos": [-1.8, 1.6, 0], "size": [1.4, 3.2, 4] }, { "shape": "box", "pos": [1.8, 1.6, 0], "size": [1.4, 3.2, 4] }, { "shape": "box", "pos": [0, 2.8, 0], "size": [5, 0.8, 4] }, { "shape": "box", "pos": [0, 1.2, 1.8], "size": [2.2, 2.4, 0.4] }] } },
|
||||||
"felsbogen": { "poly": 156, "collision": { "shape": "compound", "parts": [{ "shape": "box", "pos": [-1.9, 1.3, 0], "size": [1.2, 2.6, 2.4] }, { "shape": "box", "pos": [1.9, 1.3, 0], "size": [1.2, 2.6, 2.4] }, { "shape": "box", "pos": [0, 3.1, 0], "size": [5, 1, 2.4] }] } }
|
"felsbogen": { "poly": 156, "collision": { "shape": "compound", "parts": [{ "shape": "box", "pos": [-1.9, 1.3, 0], "size": [1.2, 2.6, 2.4] }, { "shape": "box", "pos": [1.9, 1.3, 0], "size": [1.2, 2.6, 2.4] }, { "shape": "box", "pos": [0, 3.1, 0], "size": [5, 1, 2.4] }] } },
|
||||||
|
"stein_kiesel_1": { "poly": 136, "collision": { "shape": "none" } },
|
||||||
|
"baum_kiefer_1": { "poly": 728, "collision": { "shape": "cylinder", "radius": 0.4, "height": 8.489 } },
|
||||||
|
"baum_kiefer_2": { "poly": 655, "collision": { "shape": "cylinder", "radius": 0.4, "height": 7.082 } },
|
||||||
|
"baum_kiefer_3": { "poly": 1012, "collision": { "shape": "cylinder", "radius": 0.4, "height": 7.141 } },
|
||||||
|
"baum_kiefer_4": { "poly": 1006, "collision": { "shape": "cylinder", "radius": 0.4, "height": 10.001 } },
|
||||||
|
"baum_laub_1": { "poly": 857, "collision": { "shape": "cylinder", "radius": 0.4, "height": 7.022 } },
|
||||||
|
"baum_laub_2": { "poly": 802, "collision": { "shape": "cylinder", "radius": 0.4, "height": 7.4 } },
|
||||||
|
"baum_laub_3": { "poly": 723, "collision": { "shape": "cylinder", "radius": 0.4, "height": 9.182 } },
|
||||||
|
"baum_laub_4": { "poly": 668, "collision": { "shape": "cylinder", "radius": 0.4, "height": 6.763 } },
|
||||||
|
"baum_tot_1": { "poly": 761, "collision": { "shape": "cylinder", "radius": 0.4, "height": 9.16 } },
|
||||||
|
"fels_moos_block_gross": { "poly": 46, "collision": { "shape": "compound", "parts": [{ "shape": "box", "pos": [0, 0.4, 0], "size": [2, 0.8, 2] }, { "shape": "box", "pos": [0, 1.1, 0], "size": [1.2, 0.7, 1.2] }] } },
|
||||||
|
"fels_moos_block_hoch": { "poly": 64, "collision": { "shape": "compound", "parts": [{ "shape": "box", "pos": [0, 0.48, 0], "size": [1.4, 0.95, 1.4] }, { "shape": "box", "pos": [0, 1.35, 0], "size": [0.9, 0.95, 0.9] }] } },
|
||||||
|
"fels_trocken_block": { "poly": 36, "collision": { "shape": "compound", "parts": [{ "shape": "box", "pos": [0, 0.5, 0], "size": [2.18, 1, 1.63] }, { "shape": "box", "pos": [0, 1.5, 0], "size": [1.5, 1.15, 1] }] } },
|
||||||
|
"fels_moos_platte": { "poly": 32, "collision": { "shape": "box", "size": [2, 0.915, 2] } },
|
||||||
|
"fels_moos_scharte": { "poly": 48, "collision": { "shape": "box", "size": [0.968, 0.289, 1.823] } },
|
||||||
|
"fels_trocken_platte": { "poly": 48, "collision": { "shape": "box", "size": [3.821, 0.662, 2] } },
|
||||||
|
"fels_trocken_klein": { "poly": 20, "collision": { "shape": "box", "size": [0.894, 0.724, 0.851] } },
|
||||||
|
"stein_mittel_1": { "poly": 342, "collision": { "shape": "box", "size": [3.225, 1.989, 2.989] } },
|
||||||
|
"stein_mittel_2": { "poly": 522, "collision": { "shape": "box", "size": [3.42, 2.001, 3.476] } },
|
||||||
|
"strauch_gruen": { "poly": 900, "collision": { "shape": "none" } },
|
||||||
|
"strauch_blumen": { "poly": 1368, "collision": { "shape": "none" } },
|
||||||
|
"pflanze_farn": { "poly": 288, "collision": { "shape": "none" } },
|
||||||
|
"pflanze_klee": { "poly": 379, "collision": { "shape": "none" } },
|
||||||
|
"blume_gross_1": { "poly": 285, "collision": { "shape": "none" } },
|
||||||
|
"blume_gross_2": { "poly": 642, "collision": { "shape": "none" } },
|
||||||
|
"blumen_strauss": { "poly": 755, "collision": { "shape": "none" } },
|
||||||
|
"pflanze_niedrig": { "poly": 120, "collision": { "shape": "none" } },
|
||||||
|
"pflanze_teppich": { "poly": 48, "collision": { "shape": "none" } },
|
||||||
|
"pflanze_teppich_gross": { "poly": 112, "collision": { "shape": "none" } },
|
||||||
|
"gras_kurz": { "poly": 155, "collision": { "shape": "none" } },
|
||||||
|
"gras_hoch": { "poly": 326, "collision": { "shape": "none" } },
|
||||||
|
"gras_bueschel": { "poly": 494, "collision": { "shape": "none" } },
|
||||||
|
"gras_wispy_hoch": { "poly": 622, "collision": { "shape": "none" } },
|
||||||
|
"pilz_fliegenpilz": { "poly": 80, "collision": { "shape": "none" } },
|
||||||
|
"pilz_pfifferling": { "poly": 112, "collision": { "shape": "none" } },
|
||||||
|
"pilz_steinpilz": { "poly": 80, "collision": { "shape": "none" } },
|
||||||
|
"pilz_shiitake": { "poly": 80, "collision": { "shape": "none" } },
|
||||||
|
"pilz_morchel": { "poly": 80, "collision": { "shape": "none" } },
|
||||||
|
"pilz_austernseitling": { "poly": 112, "collision": { "shape": "none" } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
BIN
library/thumbs/baum_kiefer_1.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
library/thumbs/baum_kiefer_2.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
library/thumbs/baum_kiefer_3.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
library/thumbs/baum_kiefer_4.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
library/thumbs/baum_laub_1.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
library/thumbs/baum_laub_2.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
library/thumbs/baum_laub_3.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
library/thumbs/baum_laub_4.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
library/thumbs/baum_tot_1.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
library/thumbs/blume_gross_1.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
library/thumbs/blume_gross_2.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
library/thumbs/blumen_strauss.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 1 KiB After Width: | Height: | Size: 751 B |
40
library/thumbs/bruecke_holz.png.import
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://du4ld5kl2rbyg"
|
||||||
|
path="res://.godot/imported/bruecke_holz.png-f770f1a2d554c7b92cef5575af6a53ae.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://library/thumbs/bruecke_holz.png"
|
||||||
|
dest_files=["res://.godot/imported/bruecke_holz.png-f770f1a2d554c7b92cef5575af6a53ae.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
|
Before Width: | Height: | Size: 1,003 B After Width: | Height: | Size: 566 B |
BIN
library/thumbs/fels_moos_block_gross.png
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
BIN
library/thumbs/fels_moos_block_hoch.png
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
BIN
library/thumbs/fels_moos_platte.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
library/thumbs/fels_moos_scharte.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
library/thumbs/fels_trocken_block.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
library/thumbs/fels_trocken_klein.png
Normal file
|
After Width: | Height: | Size: 4 KiB |
BIN
library/thumbs/fels_trocken_platte.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 941 B After Width: | Height: | Size: 725 B |
40
library/thumbs/felsbogen.png.import
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://cp5cmqxmoar51"
|
||||||
|
path="res://.godot/imported/felsbogen.png-9d9bf75ae86d41c640de187ee24b258f.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://library/thumbs/felsbogen.png"
|
||||||
|
dest_files=["res://.godot/imported/felsbogen.png-9d9bf75ae86d41c640de187ee24b258f.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
library/thumbs/gras_bueschel.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
library/thumbs/gras_hoch.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
library/thumbs/gras_kurz.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
library/thumbs/gras_wispy_hoch.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1,001 B After Width: | Height: | Size: 733 B |
40
library/thumbs/hoehleneingang.png.import
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://b2lyywg7e17o3"
|
||||||
|
path="res://.godot/imported/hoehleneingang.png-6c781859cfc4bd852de0b2e25697b38e.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://library/thumbs/hoehleneingang.png"
|
||||||
|
dest_files=["res://.godot/imported/hoehleneingang.png-6c781859cfc4bd852de0b2e25697b38e.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
library/thumbs/pflanze_farn.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
library/thumbs/pflanze_klee.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
library/thumbs/pflanze_niedrig.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
library/thumbs/pflanze_teppich.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
library/thumbs/pflanze_teppich_gross.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
library/thumbs/pilz_austernseitling.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
library/thumbs/pilz_fliegenpilz.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
library/thumbs/pilz_morchel.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
library/thumbs/pilz_pfifferling.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
library/thumbs/pilz_shiitake.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
library/thumbs/pilz_steinpilz.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
library/thumbs/stein_kiesel_1.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
library/thumbs/stein_mittel_1.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
library/thumbs/stein_mittel_2.png
Normal file
|
After Width: | Height: | Size: 3 KiB |
BIN
library/thumbs/strauch_blumen.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
library/thumbs/strauch_gruen.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
|
|
@ -25,21 +25,81 @@ const NAMES := {
|
||||||
"bruecke_holz": "Brücke (Holz)",
|
"bruecke_holz": "Brücke (Holz)",
|
||||||
"hoehleneingang": "Höhleneingang",
|
"hoehleneingang": "Höhleneingang",
|
||||||
"felsbogen": "Felsbogen",
|
"felsbogen": "Felsbogen",
|
||||||
|
# Natur-Update (Karte t_7cf80244): kuratierte CC0-Packs (Quaternius
|
||||||
|
# MegaKit, Kyle's Rock/Mushroom) — Namen aus stage/kuration.json.
|
||||||
|
"baum_kiefer_1": "Kiefer (schlank)",
|
||||||
|
"baum_kiefer_2": "Kiefer (kräftig)",
|
||||||
|
"baum_kiefer_3": "Kiefer (mittel)",
|
||||||
|
"baum_kiefer_4": "Kiefer (hoch)",
|
||||||
|
"baum_laub_1": "Laubbaum (rund)",
|
||||||
|
"baum_laub_2": "Laubbaum (breit)",
|
||||||
|
"baum_laub_3": "Laubbaum (schlank)",
|
||||||
|
"baum_laub_4": "Laubbaum (klein)",
|
||||||
|
"baum_tot_1": "Totholz-Baum",
|
||||||
|
"fels_moos_block_gross": "Moosfelsen (groß)",
|
||||||
|
"fels_moos_block_hoch": "Moosfelsen (hoch)",
|
||||||
|
"fels_moos_platte": "Moosfelsen (Platte)",
|
||||||
|
"fels_moos_scharte": "Moosfelsen (klein)",
|
||||||
|
"fels_trocken_block": "Trockenfelsen (hoch)",
|
||||||
|
"fels_trocken_platte": "Trockenfelsen (Platte)",
|
||||||
|
"fels_trocken_klein": "Trockenfelsen (klein)",
|
||||||
|
"stein_mittel_1": "Großer Stein 1",
|
||||||
|
"stein_mittel_2": "Großer Stein 2",
|
||||||
|
"stein_kiesel_1": "Kieselstein",
|
||||||
|
"strauch_gruen": "Strauch",
|
||||||
|
"strauch_blumen": "Blühender Strauch",
|
||||||
|
"pflanze_farn": "Farn",
|
||||||
|
"pflanze_klee": "Klee-Pflanze",
|
||||||
|
"blume_gross_1": "Blume (weiß)",
|
||||||
|
"blume_gross_2": "Blume (hoch)",
|
||||||
|
"blumen_strauss": "Blumenstrauß",
|
||||||
|
"pflanze_niedrig": "Bodendecker",
|
||||||
|
"pflanze_teppich": "Moospolster",
|
||||||
|
"pflanze_teppich_gross": "Moospolster (groß)",
|
||||||
|
"gras_kurz": "Kurzes Gras",
|
||||||
|
"gras_hoch": "Hohes Gras",
|
||||||
|
"gras_bueschel": "Grasbüschel",
|
||||||
|
"gras_wispy_hoch": "Wispy-Gras (hoch)",
|
||||||
|
"pilz_fliegenpilz": "Fliegenpilz",
|
||||||
|
"pilz_pfifferling": "Pfifferling",
|
||||||
|
"pilz_steinpilz": "Steinpilz",
|
||||||
|
"pilz_shiitake": "Shiitake",
|
||||||
|
"pilz_morchel": "Morchel",
|
||||||
|
"pilz_austernseitling": "Austernseitling",
|
||||||
}
|
}
|
||||||
|
|
||||||
## Gruppen für den Bibliothek-Browser (Anzeige-Reihenfolge = Reihenfolge hier).
|
## Gruppen für den Bibliothek-Browser (Anzeige-Reihenfolge = Reihenfolge hier).
|
||||||
const GROUP_ORDER := ["kisten", "bauwerke", "natur", "sonstiges"]
|
## Natur-Update (t_7cf80244): die alte Gruppe "natur" ist in thematische
|
||||||
|
## Gruppen aufgelöst (die 4 Alt-Objekte wanderten mit).
|
||||||
|
const GROUP_ORDER := ["kisten", "bauwerke", "bäume", "felsen", "pflanzen", "gras", "pilze", "sonstiges"]
|
||||||
const GROUP_LABELS := {
|
const GROUP_LABELS := {
|
||||||
"kisten": "Kisten & Barrieren",
|
"kisten": "Kisten & Barrieren",
|
||||||
"bauwerke": "Bauwerke",
|
"bauwerke": "Bauwerke",
|
||||||
"natur": "Natur",
|
"bäume": "Bäume",
|
||||||
|
"felsen": "Felsen",
|
||||||
|
"pflanzen": "Pflanzen",
|
||||||
|
"gras": "Gras",
|
||||||
|
"pilze": "Pilze",
|
||||||
"sonstiges": "Sonstiges",
|
"sonstiges": "Sonstiges",
|
||||||
}
|
}
|
||||||
const GROUP_IDS := {
|
const GROUP_IDS := {
|
||||||
"kisten": ["crate_wood", "crate_metal", "barrier_sandbag", "wall_concrete"],
|
"kisten": ["crate_wood", "crate_metal", "barrier_sandbag", "wall_concrete"],
|
||||||
"bauwerke": ["bunker_concrete", "watchtower_wood", "fence_metal",
|
"bauwerke": ["bunker_concrete", "watchtower_wood", "fence_metal",
|
||||||
"bruecke_holz", "hoehleneingang", "felsbogen"],
|
"bruecke_holz", "hoehleneingang", "felsbogen"],
|
||||||
"natur": ["tree_pine", "bush_small", "rock_large", "boulder_small"],
|
"bäume": ["tree_pine",
|
||||||
|
"baum_kiefer_1", "baum_kiefer_2", "baum_kiefer_3", "baum_kiefer_4",
|
||||||
|
"baum_laub_1", "baum_laub_2", "baum_laub_3", "baum_laub_4", "baum_tot_1"],
|
||||||
|
"felsen": ["rock_large", "boulder_small",
|
||||||
|
"fels_moos_block_gross", "fels_moos_block_hoch", "fels_moos_platte",
|
||||||
|
"fels_moos_scharte", "fels_trocken_block", "fels_trocken_platte",
|
||||||
|
"fels_trocken_klein", "stein_mittel_1", "stein_mittel_2", "stein_kiesel_1"],
|
||||||
|
"pflanzen": ["bush_small",
|
||||||
|
"strauch_gruen", "strauch_blumen", "pflanze_farn", "pflanze_klee",
|
||||||
|
"blume_gross_1", "blume_gross_2", "blumen_strauss", "pflanze_niedrig",
|
||||||
|
"pflanze_teppich", "pflanze_teppich_gross"],
|
||||||
|
"gras": ["gras_kurz", "gras_hoch", "gras_bueschel", "gras_wispy_hoch"],
|
||||||
|
"pilze": ["pilz_fliegenpilz", "pilz_pfifferling", "pilz_steinpilz",
|
||||||
|
"pilz_shiitake", "pilz_morchel", "pilz_austernseitling"],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,19 @@ const SHAPE_BOX := "box"
|
||||||
const SHAPE_SPHERE := "sphere"
|
const SHAPE_SPHERE := "sphere"
|
||||||
const SHAPE_CYLINDER := "cylinder"
|
const SHAPE_CYLINDER := "cylinder"
|
||||||
const SHAPE_COMPOUND := "compound"
|
const SHAPE_COMPOUND := "compound"
|
||||||
|
const SHAPE_NONE := "none"
|
||||||
|
|
||||||
|
|
||||||
static func make_placeholder(shape: String, col: Dictionary, scale: float) -> Mesh:
|
static func make_placeholder(shape: String, col: Dictionary, scale: float) -> Mesh:
|
||||||
match shape:
|
match shape:
|
||||||
|
SHAPE_NONE:
|
||||||
|
# Rein dekorativ (Natur-Update, t_7cf80244): kein Kollider — aber
|
||||||
|
# im Editor trotzdem sichtbar/wählbar: flache Fußpunkt-Scheibe.
|
||||||
|
var d := CylinderMesh.new()
|
||||||
|
d.top_radius = 0.4 * scale
|
||||||
|
d.bottom_radius = d.top_radius
|
||||||
|
d.height = maxf(0.02, 0.02 * scale)
|
||||||
|
return d
|
||||||
SHAPE_SPHERE:
|
SHAPE_SPHERE:
|
||||||
var s := SphereMesh.new()
|
var s := SphereMesh.new()
|
||||||
var r := maxf(0.01, float(col.get("radius", 1.0)) * scale)
|
var r := maxf(0.01, float(col.get("radius", 1.0)) * scale)
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ func _test_manifest_load() -> void:
|
||||||
var manifest := _load_manifest()
|
var manifest := _load_manifest()
|
||||||
_check(not manifest.is_empty(), "Manifest lädt und ist ein Objekt")
|
_check(not manifest.is_empty(), "Manifest lädt und ist ein Objekt")
|
||||||
var lib: Dictionary = manifest.get("objects", {})
|
var lib: Dictionary = manifest.get("objects", {})
|
||||||
_check(lib.size() == 15, "Katalog hat die 15 etablierten Objekte (ist %d)" % lib.size())
|
_check(lib.size() == 54, "Katalog hat die 54 Objekte (15 Basis + 39 Natur-Update, ist %d)" % lib.size())
|
||||||
var all_ok := true
|
var all_ok := true
|
||||||
for oid in lib.keys():
|
for oid in lib.keys():
|
||||||
var entry: Dictionary = lib[oid]
|
var entry: Dictionary = lib[oid]
|
||||||
|
|
@ -87,9 +87,24 @@ func _test_groups() -> void:
|
||||||
seen[oid] = true
|
seen[oid] = true
|
||||||
_check(all_in, "keine ID in zwei Gruppen")
|
_check(all_in, "keine ID in zwei Gruppen")
|
||||||
_check(seen.size() == lib.size(), "alle %d IDs landen in einer Gruppe (ist %d)" % [lib.size(), seen.size()])
|
_check(seen.size() == lib.size(), "alle %d IDs landen in einer Gruppe (ist %d)" % [lib.size(), seen.size()])
|
||||||
_check(LibraryBrowser.group_of("tree_pine") == "natur", "group_of: tree_pine → natur")
|
_check(LibraryBrowser.group_of("tree_pine") == "bäume", "group_of: tree_pine → bäume (Natur-Update hat 'natur' aufgelöst)")
|
||||||
_check(LibraryBrowser.group_of("crate_wood") == "kisten", "group_of: crate_wood → kisten")
|
_check(LibraryBrowser.group_of("crate_wood") == "kisten", "group_of: crate_wood → kisten")
|
||||||
|
_check(LibraryBrowser.group_of("baum_kiefer_1") == "bäume", "group_of: baum_kiefer_1 → bäume")
|
||||||
|
_check(LibraryBrowser.group_of("fels_moos_platte") == "felsen", "group_of: fels_moos_platte → felsen")
|
||||||
|
_check(LibraryBrowser.group_of("gras_kurz") == "gras", "group_of: gras_kurz → gras")
|
||||||
|
_check(LibraryBrowser.group_of("pilz_morchel") == "pilze", "group_of: pilz_morchel → pilze")
|
||||||
_check(LibraryBrowser.group_of("fremdes_ding") == "sonstiges", "group_of: unbekannte ID → sonstiges")
|
_check(LibraryBrowser.group_of("fremdes_ding") == "sonstiges", "group_of: unbekannte ID → sonstiges")
|
||||||
|
var vorhanden := {}
|
||||||
|
for oid in lib.keys():
|
||||||
|
vorhanden[str(oid)] = true
|
||||||
|
var gruppen_komplett := true
|
||||||
|
for key in LibraryBrowser.GROUP_IDS:
|
||||||
|
if key == "sonstiges":
|
||||||
|
continue
|
||||||
|
for oid in (LibraryBrowser.GROUP_IDS[key] as Array):
|
||||||
|
if not vorhanden.has(str(oid)):
|
||||||
|
gruppen_komplett = false
|
||||||
|
_check(gruppen_komplett, "jede feste Gruppe listet nur IDs, die es im Katalog gibt")
|
||||||
# Gruppen, die im Katalog leer sind, werden nicht angezeigt (außer Sonstiges).
|
# Gruppen, die im Katalog leer sind, werden nicht angezeigt (außer Sonstiges).
|
||||||
var labels: Array = []
|
var labels: Array = []
|
||||||
for group in groups:
|
for group in groups:
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,18 @@ extends SceneTree
|
||||||
## xvfb-run -a godot4 --rendering-driver opengl3 --path . --script res://tools/gen_thumbs.gd
|
## xvfb-run -a godot4 --rendering-driver opengl3 --path . --script res://tools/gen_thumbs.gd
|
||||||
## (auf Slys PC auch ohne xvfb: godot4 --rendering-driver opengl3 --path . --script ...)
|
## (auf Slys PC auch ohne xvfb: godot4 --rendering-driver opengl3 --path . --script ...)
|
||||||
##
|
##
|
||||||
|
## Natur-Update (t_7cf80244): wird das echte Mesh im Mesh-Lager gefunden
|
||||||
|
## (Sibling-Repo scopedvr-match-server oder scopedvr-client, assets/objekte),
|
||||||
|
## wird das GLB direkt gerendert (GLTFDocument, ohne Import-System) — die
|
||||||
|
## Bibliothek zeigt dann die echten Bäume/Felsen/Pilze, nicht nur den
|
||||||
|
## Kollisions-Platzhalter. Ohne GLB: Platzhalter wie bisher.
|
||||||
|
##
|
||||||
## Exit 0 = alle Thumbnails geschrieben.
|
## Exit 0 = alle Thumbnails geschrieben.
|
||||||
|
|
||||||
const SIZE := 128
|
const SIZE := 128
|
||||||
const BG_COLOR := Color(0.16, 0.18, 0.21)
|
const BG_COLOR := Color(0.16, 0.18, 0.21)
|
||||||
|
## Relative Quellen für echte GLB-Meshes (vom Editor-Projektordner aus).
|
||||||
|
const GLB_QUELLEN := ["../scopedvr-match-server/assets/objekte", "../scopedvr-client/assets/objekte"]
|
||||||
|
|
||||||
var manifest: Dictionary = {}
|
var manifest: Dictionary = {}
|
||||||
var ids: Array = []
|
var ids: Array = []
|
||||||
|
|
@ -73,7 +81,7 @@ func _next() -> void:
|
||||||
var oid := str(ids[idx])
|
var oid := str(ids[idx])
|
||||||
var entry: Dictionary = (manifest["objects"] as Dictionary)[oid]
|
var entry: Dictionary = (manifest["objects"] as Dictionary)[oid]
|
||||||
var col: Dictionary = entry.get("collision", {})
|
var col: Dictionary = entry.get("collision", {})
|
||||||
var mesh := MeshShapes.make_placeholder(str(col.get("shape", "box")), col, 1.0)
|
var mesh := _mesh_fuer(oid, col)
|
||||||
mi.mesh = mesh
|
mi.mesh = mesh
|
||||||
# Kamera diagonal aufs Objekt, passend zur Mesh-Größe (Kiste nah, Turm weit).
|
# Kamera diagonal aufs Objekt, passend zur Mesh-Größe (Kiste nah, Turm weit).
|
||||||
var aabb := mesh.get_aabb()
|
var aabb := mesh.get_aabb()
|
||||||
|
|
@ -98,3 +106,46 @@ func _process(_delta: float) -> bool:
|
||||||
print(" thumb: %s (%dx%d)" % [oid, img.get_width(), img.get_height()])
|
print(" thumb: %s (%dx%d)" % [oid, img.get_width(), img.get_height()])
|
||||||
_next()
|
_next()
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------- echtes Mesh laden ------
|
||||||
|
|
||||||
|
## Mesh für ein Thumbnail: echtes GLB aus dem Mesh-Lager (Sibling-Repos),
|
||||||
|
## sonst Kollisions-Platzhalter (alte Fallback-Regel).
|
||||||
|
func _mesh_fuer(oid: String, col: Dictionary) -> Mesh:
|
||||||
|
var basis := ProjectSettings.globalize_path("res://")
|
||||||
|
for quelle in GLB_QUELLEN:
|
||||||
|
var pfad := basis.path_join(str(quelle)).path_join(oid + ".glb")
|
||||||
|
if FileAccess.file_exists(pfad):
|
||||||
|
var m := _glb_mesh(pfad)
|
||||||
|
if m != null:
|
||||||
|
return m
|
||||||
|
return MeshShapes.make_placeholder(str(col.get("shape", "box")), col, 1.0)
|
||||||
|
|
||||||
|
|
||||||
|
## GLB OHNE Import-System laden (GLTFDocument) und das erste Mesh liefern.
|
||||||
|
## null = Load-Fehlschlag → Aufrufer fällt auf den Platzhalter zurück.
|
||||||
|
func _glb_mesh(pfad: String) -> Mesh:
|
||||||
|
var gltf := GLTFDocument.new()
|
||||||
|
var state := GLTFState.new()
|
||||||
|
if gltf.append_from_file(pfad, state) != OK:
|
||||||
|
push_warning("gen_thumbs: GLB nicht ladbar: %s" % pfad)
|
||||||
|
return null
|
||||||
|
var szene: Node = gltf.generate_scene(state)
|
||||||
|
if szene == null:
|
||||||
|
return null
|
||||||
|
var m := _erstes_mesh(szene)
|
||||||
|
# Das Mesh ist eine Resource (RefCounted) — das Freigeben der Szene
|
||||||
|
# berührt die Referenz im Rückgabewert nicht.
|
||||||
|
szene.free()
|
||||||
|
return m
|
||||||
|
|
||||||
|
|
||||||
|
func _erstes_mesh(n: Node) -> Mesh:
|
||||||
|
if n is MeshInstance3D and (n as MeshInstance3D).mesh != null:
|
||||||
|
return (n as MeshInstance3D).mesh
|
||||||
|
for c in n.get_children():
|
||||||
|
var m := _erstes_mesh(c)
|
||||||
|
if m != null:
|
||||||
|
return m
|
||||||
|
return null
|
||||||
|
|
|
||||||