Add bison model to default editor palette and object catalog
checkpoint / checkpoint (push) Successful in 6m10s
checkpoint / checkpoint (push) Successful in 6m10s
This commit is contained in:
@@ -36,6 +36,12 @@
|
|||||||
"display_name": "Buffalo Chip Coin",
|
"display_name": "Buffalo Chip Coin",
|
||||||
"category": "props"
|
"category": "props"
|
||||||
},
|
},
|
||||||
|
"bison": {
|
||||||
|
"asset_id": "props/bison.glb",
|
||||||
|
"type": "prop",
|
||||||
|
"display_name": "Bison",
|
||||||
|
"category": "nature"
|
||||||
|
},
|
||||||
"spawn_point": {
|
"spawn_point": {
|
||||||
"asset_id": "",
|
"asset_id": "",
|
||||||
"type": "spawn_point",
|
"type": "spawn_point",
|
||||||
|
|||||||
Binary file not shown.
@@ -0,0 +1,42 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="scene"
|
||||||
|
importer_version=1
|
||||||
|
type="PackedScene"
|
||||||
|
uid="uid://wa7kf5fvrdh1"
|
||||||
|
path="res://.godot/imported/bison.glb-caef5252d8e08046747c7628b6609f07.scn"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/props/bison.glb"
|
||||||
|
dest_files=["res://.godot/imported/bison.glb-caef5252d8e08046747c7628b6609f07.scn"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
nodes/root_type=""
|
||||||
|
nodes/root_name=""
|
||||||
|
nodes/root_script=null
|
||||||
|
nodes/apply_root_scale=true
|
||||||
|
nodes/root_scale=1.0
|
||||||
|
nodes/import_as_skeleton_bones=false
|
||||||
|
nodes/use_name_suffixes=true
|
||||||
|
nodes/use_node_type_suffixes=true
|
||||||
|
meshes/ensure_tangents=true
|
||||||
|
meshes/generate_lods=true
|
||||||
|
meshes/create_shadow_meshes=true
|
||||||
|
meshes/light_baking=1
|
||||||
|
meshes/lightmap_texel_size=0.2
|
||||||
|
meshes/force_disable_compression=false
|
||||||
|
skins/use_named_skins=true
|
||||||
|
animation/import=true
|
||||||
|
animation/fps=30
|
||||||
|
animation/trimming=false
|
||||||
|
animation/remove_immutable_tracks=true
|
||||||
|
animation/import_rest_as_RESET=false
|
||||||
|
import_script/path=""
|
||||||
|
materials/extract=0
|
||||||
|
materials/extract_format=0
|
||||||
|
materials/extract_path=""
|
||||||
|
_subresources={}
|
||||||
|
gltf/naming_version=2
|
||||||
|
gltf/embedded_image_handling=1
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 71 KiB |
@@ -0,0 +1,43 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://oemjaiyc1jor"
|
||||||
|
path="res://.godot/imported/bison_04bizontexture.jpg-ee62bcbf71190dd9c3260c488d0f5226.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
generator_parameters={
|
||||||
|
"md5": "62ac14285e2f49777af903582f16d021"
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/props/bison_04bizontexture.jpg"
|
||||||
|
dest_files=["res://.godot/imported/bison_04bizontexture.jpg-ee62bcbf71190dd9c3260c488d0f5226.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=true
|
||||||
|
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
|
||||||
@@ -48,11 +48,21 @@ func is_loaded() -> bool:
|
|||||||
func resolve(id: String) -> Dictionary:
|
func resolve(id: String) -> Dictionary:
|
||||||
if not _loaded:
|
if not _loaded:
|
||||||
return {}
|
return {}
|
||||||
return _catalog.get(id, {})
|
if _catalog.has(id):
|
||||||
|
return _catalog[id]
|
||||||
|
if (id.contains("bizon") or id.contains("bison")) and _catalog.has("bison"):
|
||||||
|
return _catalog["bison"]
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
func has_object(id: String) -> bool:
|
func has_object(id: String) -> bool:
|
||||||
return _loaded and _catalog.has(id)
|
if not _loaded:
|
||||||
|
return false
|
||||||
|
if _catalog.has(id):
|
||||||
|
return true
|
||||||
|
if (id.contains("bizon") or id.contains("bison")) and _catalog.has("bison"):
|
||||||
|
return true
|
||||||
|
return false
|
||||||
|
|
||||||
|
|
||||||
func get_all_ids() -> Array[String]:
|
func get_all_ids() -> Array[String]:
|
||||||
|
|||||||
@@ -115,6 +115,8 @@ func _setup_import_ui() -> void:
|
|||||||
sample_option.set_item_metadata(4, {"path": "res://assets/props/buffalo_chip_coin.glb", "name": "Buffalo Chip Coin"})
|
sample_option.set_item_metadata(4, {"path": "res://assets/props/buffalo_chip_coin.glb", "name": "Buffalo Chip Coin"})
|
||||||
sample_option.add_item("Small Crate", 5)
|
sample_option.add_item("Small Crate", 5)
|
||||||
sample_option.set_item_metadata(5, {"path": "res://assets/props/crate_small.glb", "name": "Small Crate"})
|
sample_option.set_item_metadata(5, {"path": "res://assets/props/crate_small.glb", "name": "Small Crate"})
|
||||||
|
sample_option.add_item("Bison", 6)
|
||||||
|
sample_option.set_item_metadata(6, {"path": "res://assets/props/bison.glb", "name": "Bison"})
|
||||||
sample_option.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
sample_option.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||||
sample_option.item_selected.connect(func(idx: int):
|
sample_option.item_selected.connect(func(idx: int):
|
||||||
if idx > 0:
|
if idx > 0:
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
extends SceneTree
|
||||||
|
## Test loading and instantiating bison.glb prop
|
||||||
|
|
||||||
|
func _init() -> void:
|
||||||
|
print("=== Smoke Test: Bison Model ===")
|
||||||
|
var path := "res://assets/props/bison.glb"
|
||||||
|
if not FileAccess.file_exists(path):
|
||||||
|
printerr("FAIL: bison.glb does not exist on disk at ", path)
|
||||||
|
quit(1)
|
||||||
|
return
|
||||||
|
|
||||||
|
var res := load(path)
|
||||||
|
if res == null:
|
||||||
|
printerr("FAIL: Could not load ", path)
|
||||||
|
quit(1)
|
||||||
|
return
|
||||||
|
|
||||||
|
print("PASS: Loaded PackedScene: ", res)
|
||||||
|
if res is PackedScene:
|
||||||
|
var inst = (res as PackedScene).instantiate()
|
||||||
|
if inst == null:
|
||||||
|
printerr("FAIL: Could not instantiate bison scene")
|
||||||
|
quit(1)
|
||||||
|
return
|
||||||
|
print("PASS: Instantiated bison: ", inst.name, " (", inst.get_class(), ")")
|
||||||
|
_print_node(inst, 0)
|
||||||
|
inst.queue_free()
|
||||||
|
|
||||||
|
print("=== Bison Model Smoke Test Passed ===")
|
||||||
|
quit(0)
|
||||||
|
|
||||||
|
|
||||||
|
func _print_node(n: Node, depth: int) -> void:
|
||||||
|
print(" ".repeat(depth), "- ", n.name, " [", n.get_class(), "]")
|
||||||
|
for c in n.get_children():
|
||||||
|
_print_node(c, depth + 1)
|
||||||
|
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
extends SceneTree
|
||||||
|
## Headless smoke test verifying Bison model is present in the editor palette
|
||||||
|
## and loads properly via StaticObjectNode and EditorCore.
|
||||||
|
|
||||||
|
const ChunkEditorModelClass := preload("res://scripts/editor/chunk_editor_model.gd")
|
||||||
|
const EditorObjectCatalogClass := preload("res://scripts/editor/object_catalog.gd")
|
||||||
|
const EditorCoreClass := preload("res://scripts/editor/editor_core.gd")
|
||||||
|
const PalettePanelClass := preload("res://scripts/editor/ui/palette_panel.gd")
|
||||||
|
const StaticObjectNodeClass := preload("res://scripts/static_object_node.gd")
|
||||||
|
const WorldObjectClass := preload("res://scripts/world_object.gd")
|
||||||
|
|
||||||
|
var passed := 0
|
||||||
|
var failed := 0
|
||||||
|
|
||||||
|
func _check(label: String, cond: bool) -> void:
|
||||||
|
if cond:
|
||||||
|
passed += 1
|
||||||
|
print(" PASS: ", label)
|
||||||
|
else:
|
||||||
|
failed += 1
|
||||||
|
printerr(" FAIL: ", label)
|
||||||
|
|
||||||
|
|
||||||
|
func _initialize() -> void:
|
||||||
|
await _run()
|
||||||
|
|
||||||
|
|
||||||
|
func _run() -> void:
|
||||||
|
print("=== Running Bison Model in Editor Palette Smoke Test ===")
|
||||||
|
var root := Node.new()
|
||||||
|
root.name = "TestRoot"
|
||||||
|
get_root().add_child(root)
|
||||||
|
|
||||||
|
# 1. Check catalog loading
|
||||||
|
var catalog := EditorObjectCatalogClass.new()
|
||||||
|
var err := catalog.load_catalog()
|
||||||
|
_check("Loaded EditorObjectCatalog from JSON", err == OK)
|
||||||
|
|
||||||
|
# 2. Check bison in default ids
|
||||||
|
var all_ids := catalog.get_all_ids()
|
||||||
|
_check("Catalog contains 'bison'", all_ids.has("bison"))
|
||||||
|
|
||||||
|
var bison_entry := catalog.resolve("bison")
|
||||||
|
_check("Bison entry has asset_id props/bison.glb", bison_entry.get("asset_id") == "props/bison.glb")
|
||||||
|
_check("Bison entry display_name is Bison", bison_entry.get("display_name") == "Bison")
|
||||||
|
_check("Bison asset file exists in project", FileAccess.file_exists("res://assets/props/bison.glb"))
|
||||||
|
|
||||||
|
# 3. Check alias resolution for legacy custom import id
|
||||||
|
var alias_entry := catalog.resolve("custom_bizon_by_madtrollstudio_rqk_lny_pnfx")
|
||||||
|
_check("Legacy custom id resolves to bison", alias_entry.get("asset_id") == "props/bison.glb")
|
||||||
|
|
||||||
|
# 4. Check PalettePanel populates bison in list
|
||||||
|
var palette := PalettePanelClass.new()
|
||||||
|
root.add_child(palette)
|
||||||
|
await process_frame
|
||||||
|
palette.set_catalog(catalog)
|
||||||
|
|
||||||
|
var found_in_palette := false
|
||||||
|
for i in range(palette._list.item_count):
|
||||||
|
var item_text := palette._list.get_item_text(i)
|
||||||
|
if item_text == "Bison":
|
||||||
|
found_in_palette = true
|
||||||
|
break
|
||||||
|
_check("PalettePanel list contains 'Bison'", found_in_palette)
|
||||||
|
|
||||||
|
# 5. Place bison in a chunk model
|
||||||
|
var model := ChunkEditorModelClass.new()
|
||||||
|
var core := EditorCoreClass.new(model, catalog)
|
||||||
|
var obj_id := core.place_object("bison", Vector3(10.0, 0.0, 15.0))
|
||||||
|
_check("Placed bison via EditorCore", not obj_id.is_empty())
|
||||||
|
|
||||||
|
var placed_obj := model.find_object(obj_id)
|
||||||
|
_check("Placed object has props/bison.glb", placed_obj != null and placed_obj.asset_id == "props/bison.glb")
|
||||||
|
|
||||||
|
# 6. StaticObjectNode with default props/bison.glb
|
||||||
|
var wo1 := WorldObjectClass.new()
|
||||||
|
wo1.id = "test_bison_1"
|
||||||
|
wo1.type = "prop"
|
||||||
|
wo1.asset_id = "props/bison.glb"
|
||||||
|
wo1.position = Vector3(10.0, 0.0, 15.0)
|
||||||
|
var node1 := StaticObjectNodeClass.new()
|
||||||
|
node1.world_object = wo1
|
||||||
|
root.add_child(node1)
|
||||||
|
await process_frame
|
||||||
|
_check("StaticObjectNode loaded visuals for props/bison.glb", node1.get_child_count() > 0)
|
||||||
|
|
||||||
|
# 7. StaticObjectNode with legacy user:// path as saved in World 6
|
||||||
|
var wo2 := WorldObjectClass.new()
|
||||||
|
wo2.id = "test_bison_legacy"
|
||||||
|
wo2.type = "prop"
|
||||||
|
wo2.asset_id = "user://custom_assets/Bizon by madtrollstudio - RqkLNYPnfx.glb"
|
||||||
|
wo2.properties = {"catalog_id": "custom_bizon_by_madtrollstudio_rqk_lny_pnfx"}
|
||||||
|
var node2 := StaticObjectNodeClass.new()
|
||||||
|
node2.world_object = wo2
|
||||||
|
root.add_child(node2)
|
||||||
|
await process_frame
|
||||||
|
_check("StaticObjectNode loaded visuals for legacy world chunk bison", node2.get_child_count() > 0)
|
||||||
|
|
||||||
|
print("Bison Palette Smoke Test complete. Passed: %d, Failed: %d" % [passed, failed])
|
||||||
|
if failed > 0:
|
||||||
|
quit(1)
|
||||||
|
else:
|
||||||
|
quit(0)
|
||||||
@@ -61,6 +61,8 @@ func _load_mesh() -> void:
|
|||||||
add_child(asset_node)
|
add_child(asset_node)
|
||||||
if asset_node is MeshInstance3D:
|
if asset_node is MeshInstance3D:
|
||||||
_mesh_instance = asset_node as MeshInstance3D
|
_mesh_instance = asset_node as MeshInstance3D
|
||||||
|
else:
|
||||||
|
_mesh_instance = asset_node.find_child("*", true, false) as MeshInstance3D
|
||||||
return
|
return
|
||||||
|
|
||||||
# 2. Build a stylized, recognizable 3D representation based on catalog ID / asset ID
|
# 2. Build a stylized, recognizable 3D representation based on catalog ID / asset ID
|
||||||
@@ -96,9 +98,13 @@ func _try_load_asset(asset_id: String) -> Node:
|
|||||||
var candidate_paths: Array[String] = [
|
var candidate_paths: Array[String] = [
|
||||||
asset_id,
|
asset_id,
|
||||||
"res://assets/%s" % asset_id,
|
"res://assets/%s" % asset_id,
|
||||||
|
"res://assets/props/%s" % asset_id.get_file(),
|
||||||
"user://custom_assets/%s" % asset_id,
|
"user://custom_assets/%s" % asset_id,
|
||||||
"user://custom_assets/%s" % asset_id.get_file()
|
"user://custom_assets/%s" % asset_id.get_file()
|
||||||
]
|
]
|
||||||
|
var lower_id := asset_id.to_lower()
|
||||||
|
if lower_id.contains("bizon") or lower_id.contains("bison") or lower_id.contains("madtrollstudio"):
|
||||||
|
candidate_paths.append("res://assets/props/bison.glb")
|
||||||
|
|
||||||
for cpath in candidate_paths:
|
for cpath in candidate_paths:
|
||||||
if FileAccess.file_exists(cpath):
|
if FileAccess.file_exists(cpath):
|
||||||
|
|||||||
Reference in New Issue
Block a user