@satelliteoflove/godot-mcp 3.22.0 → 3.23.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/addon/command_router.gd +1 -0
- package/addon/commands/mesh_commands.gd +52 -0
- package/addon/commands/mesh_commands.gd.uid +1 -0
- package/addon/commands/screenshot_commands.gd +9 -2
- package/addon/core/mcp_debugger_plugin.gd +5 -0
- package/addon/game_bridge/mcp_game_bridge.gd +67 -1
- package/addon/game_bridge/mcp_runtime_state_sampler.gd +24 -23
- package/addon/game_bridge/mesh_validator.gd +361 -0
- package/addon/game_bridge/mesh_validator.gd.uid +1 -0
- package/addon/plugin.cfg +1 -1
- package/dist/__tests__/tools/editor.test.js +23 -0
- package/dist/__tests__/tools/editor.test.js.map +1 -1
- package/dist/__tests__/tools/validate-meshes.test.d.ts +2 -0
- package/dist/__tests__/tools/validate-meshes.test.d.ts.map +1 -0
- package/dist/__tests__/tools/validate-meshes.test.js +73 -0
- package/dist/__tests__/tools/validate-meshes.test.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -1
- package/dist/tools/editor.d.ts.map +1 -1
- package/dist/tools/editor.js +19 -1
- package/dist/tools/editor.js.map +1 -1
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +3 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/validate-meshes.d.ts +7 -0
- package/dist/tools/validate-meshes.d.ts.map +1 -0
- package/dist/tools/validate-meshes.js +59 -0
- package/dist/tools/validate-meshes.js.map +1 -0
- package/package.json +1 -1
package/addon/command_router.gd
CHANGED
|
@@ -24,6 +24,7 @@ func setup(plugin: EditorPlugin) -> void:
|
|
|
24
24
|
_register_handler(MCPRuntimeStateCommands.new(), plugin)
|
|
25
25
|
_register_handler(MCPGameTimeCommands.new(), plugin)
|
|
26
26
|
_register_handler(MCPExecCommands.new(), plugin)
|
|
27
|
+
_register_handler(MCPMeshCommands.new(), plugin)
|
|
27
28
|
|
|
28
29
|
|
|
29
30
|
func _register_handler(handler: MCPBaseCommand, plugin: EditorPlugin) -> void:
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
@tool
|
|
2
|
+
extends MCPBaseCommand
|
|
3
|
+
class_name MCPMeshCommands
|
|
4
|
+
## Relays mesh-integrity commands to the running game's bridge.
|
|
5
|
+
|
|
6
|
+
# Full validation walks every ArrayMesh surface — generous timeout for big scenes.
|
|
7
|
+
const VALIDATE_TIMEOUT := 20.0
|
|
8
|
+
|
|
9
|
+
var _last_error: Dictionary = {}
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
func get_commands() -> Dictionary:
|
|
13
|
+
return {
|
|
14
|
+
"validate_meshes": validate_meshes,
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
func validate_meshes(params: Dictionary) -> Dictionary:
|
|
19
|
+
var result = await _send_and_wait("validate_meshes", [params], VALIDATE_TIMEOUT)
|
|
20
|
+
if result == null:
|
|
21
|
+
return _last_error
|
|
22
|
+
if result is Dictionary:
|
|
23
|
+
return _success(result)
|
|
24
|
+
return _success({"data": result})
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
func _send_and_wait(msg_type: String, args: Array, timeout: float):
|
|
28
|
+
if not EditorInterface.is_playing_scene():
|
|
29
|
+
_last_error = _error("NOT_RUNNING", "No game is currently running")
|
|
30
|
+
return null
|
|
31
|
+
|
|
32
|
+
var debugger_plugin = _plugin.get_debugger_plugin() if _plugin else null
|
|
33
|
+
if debugger_plugin == null or not debugger_plugin.has_active_session():
|
|
34
|
+
_last_error = _error("NO_SESSION", "No active debug session")
|
|
35
|
+
return null
|
|
36
|
+
|
|
37
|
+
var sent: bool = debugger_plugin.send_game_message(msg_type, args)
|
|
38
|
+
if not sent:
|
|
39
|
+
_last_error = _error("SEND_FAILED", "Failed to send message to game")
|
|
40
|
+
return null
|
|
41
|
+
|
|
42
|
+
var start_time := Time.get_ticks_msec()
|
|
43
|
+
while not debugger_plugin.has_response(msg_type):
|
|
44
|
+
await Engine.get_main_loop().process_frame
|
|
45
|
+
if (Time.get_ticks_msec() - start_time) / 1000.0 > timeout:
|
|
46
|
+
debugger_plugin.clear_response(msg_type)
|
|
47
|
+
_last_error = _error("TIMEOUT", "Timed out waiting for %s response" % msg_type)
|
|
48
|
+
return null
|
|
49
|
+
|
|
50
|
+
var response = debugger_plugin.get_response(msg_type)
|
|
51
|
+
debugger_plugin.clear_response(msg_type)
|
|
52
|
+
return response
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
uid://60lww3uge36h
|
|
@@ -50,11 +50,18 @@ func capture_game_screenshot(params: Dictionary) -> Dictionary:
|
|
|
50
50
|
func _on_screenshot_received(success: bool, image_base64: String, width: int, height: int, error: String) -> void:
|
|
51
51
|
_screenshot_pending = false
|
|
52
52
|
if success:
|
|
53
|
-
|
|
53
|
+
var payload := {
|
|
54
54
|
"image_base64": image_base64,
|
|
55
55
|
"width": width,
|
|
56
56
|
"height": height
|
|
57
|
-
}
|
|
57
|
+
}
|
|
58
|
+
# Mesh-integrity warnings ride the same game message (no extra
|
|
59
|
+
# round-trip, no version-skew timeout); pass them through so the
|
|
60
|
+
# server can attach the advisory to the image.
|
|
61
|
+
var dp = _plugin.get_debugger_plugin() if _plugin else null
|
|
62
|
+
if dp != null and not (dp.last_screenshot_warnings as Array).is_empty():
|
|
63
|
+
payload["mesh_warnings"] = dp.last_screenshot_warnings
|
|
64
|
+
_screenshot_result = _success(payload)
|
|
58
65
|
else:
|
|
59
66
|
_screenshot_result = _error("CAPTURE_FAILED", error)
|
|
60
67
|
|
|
@@ -19,6 +19,10 @@ var _active_session_id: int = -1
|
|
|
19
19
|
# has_active_session() alone is not enough to know input will land (#241).
|
|
20
20
|
var _bridge_ready: bool = false
|
|
21
21
|
var _pending_screenshot: bool = false
|
|
22
|
+
# Mesh-integrity warnings that rode along with the last screenshot result
|
|
23
|
+
# (element 6 of screenshot_result; empty for bridges that predate it). Held
|
|
24
|
+
# here instead of widening the screenshot_received signal signature.
|
|
25
|
+
var last_screenshot_warnings: Array = []
|
|
22
26
|
var _pending_debug_output: bool = false
|
|
23
27
|
var _pending_performance_metrics: bool = false
|
|
24
28
|
var _pending_find_nodes: bool = false
|
|
@@ -151,6 +155,7 @@ func _handle_screenshot_result(data: Array) -> void:
|
|
|
151
155
|
var width: int = data[2]
|
|
152
156
|
var height: int = data[3]
|
|
153
157
|
var error: String = data[4]
|
|
158
|
+
last_screenshot_warnings = data[5] if data.size() > 5 and data[5] is Array else []
|
|
154
159
|
screenshot_received.emit(success, image_base64, width, height, error)
|
|
155
160
|
|
|
156
161
|
|
|
@@ -3,6 +3,7 @@ class_name MCPGameBridge
|
|
|
3
3
|
|
|
4
4
|
const DEFAULT_MAX_WIDTH := 1024
|
|
5
5
|
const Onscreen := preload("onscreen.gd")
|
|
6
|
+
const MeshValidator := preload("mesh_validator.gd")
|
|
6
7
|
|
|
7
8
|
# Cap on frames waited for the main scene to appear before announcing ready
|
|
8
9
|
# anyway. The scene is normally added within a frame or two of the bridge
|
|
@@ -18,6 +19,17 @@ var _sampler: MCPRuntimeStateSampler
|
|
|
18
19
|
# announcement against firing twice and lets the headless test observe it.
|
|
19
20
|
var _ready_announced := false
|
|
20
21
|
|
|
22
|
+
# On-scene-load mesh-integrity sniff. Corrupt procedural meshes render with no
|
|
23
|
+
# error anywhere (inside-out winding, dropped triangles), so the warning must
|
|
24
|
+
# come TO the agent: the server appends these one-liners to screenshot results
|
|
25
|
+
# — the moment the agent looks at the game is the moment a wrong-looking render
|
|
26
|
+
# becomes actionable. Full diagnosis lives in the validate_meshes command.
|
|
27
|
+
const SNIFF_DELAY_FRAMES := 30 # let _ready-time procedural level builds finish
|
|
28
|
+
const SNIFF_MAX_WARNINGS := 8
|
|
29
|
+
var _mesh_warnings: Array[String] = []
|
|
30
|
+
var _sniff_scene_id: int = 0
|
|
31
|
+
var _sniff_countdown: int = -1
|
|
32
|
+
|
|
21
33
|
|
|
22
34
|
func _ready() -> void:
|
|
23
35
|
# The bridge must keep processing while the scene tree is paused. Input
|
|
@@ -95,6 +107,52 @@ func _emit_bridge_ready(scene_path: String) -> void:
|
|
|
95
107
|
func _process(delta: float) -> void:
|
|
96
108
|
_game_time_process(delta)
|
|
97
109
|
_sequence_process(delta)
|
|
110
|
+
_mesh_sniff_process()
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
func _mesh_sniff_process() -> void:
|
|
114
|
+
# The autoload ships in exports and _process runs even when _ready bailed
|
|
115
|
+
# out early — without this gate, non-debug runs (including shipped games)
|
|
116
|
+
# would pay full mesh-array copies on every scene load for a result
|
|
117
|
+
# nothing consumes.
|
|
118
|
+
if not EngineDebugger.is_active():
|
|
119
|
+
return
|
|
120
|
+
var tree := get_tree()
|
|
121
|
+
if tree == null or tree.current_scene == null:
|
|
122
|
+
return
|
|
123
|
+
var sid := tree.current_scene.get_instance_id()
|
|
124
|
+
if sid != _sniff_scene_id:
|
|
125
|
+
_sniff_scene_id = sid
|
|
126
|
+
_sniff_countdown = SNIFF_DELAY_FRAMES
|
|
127
|
+
if _sniff_countdown > 0:
|
|
128
|
+
_sniff_countdown -= 1
|
|
129
|
+
if _sniff_countdown == 0:
|
|
130
|
+
_run_mesh_sniff(tree.current_scene)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
func _run_mesh_sniff(scene_root: Node) -> void:
|
|
134
|
+
_mesh_warnings.clear()
|
|
135
|
+
var stack: Array[Node] = [scene_root]
|
|
136
|
+
while not stack.is_empty():
|
|
137
|
+
var n: Node = stack.pop_back()
|
|
138
|
+
for child in n.get_children():
|
|
139
|
+
stack.push_back(child)
|
|
140
|
+
for w in MeshValidator.sniff(n):
|
|
141
|
+
_mesh_warnings.append(w)
|
|
142
|
+
if _mesh_warnings.size() >= SNIFF_MAX_WARNINGS:
|
|
143
|
+
return
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
func _handle_validate_meshes(data: Array) -> void:
|
|
147
|
+
var params: Dictionary = data[0] if data.size() > 0 and data[0] is Dictionary else {}
|
|
148
|
+
var max_findings: int = params.get("max_findings", 25)
|
|
149
|
+
var tree := get_tree()
|
|
150
|
+
var result: Dictionary
|
|
151
|
+
if tree == null or tree.current_scene == null:
|
|
152
|
+
result = {"checked_meshes": 0, "checked_surfaces": 0, "total_findings": 0, "findings": [], "note": "no current scene"}
|
|
153
|
+
else:
|
|
154
|
+
result = MeshValidator.validate(tree.current_scene, max_findings)
|
|
155
|
+
EngineDebugger.send_message("godot_mcp:game_response", ["validate_meshes", result])
|
|
98
156
|
|
|
99
157
|
|
|
100
158
|
# Processing is needed by three independent features; only switch it off when
|
|
@@ -415,6 +473,9 @@ func _on_debugger_message(message: String, data: Array) -> bool:
|
|
|
415
473
|
"exec_clear":
|
|
416
474
|
_handle_exec_clear(data)
|
|
417
475
|
return true
|
|
476
|
+
"validate_meshes":
|
|
477
|
+
_handle_validate_meshes(data)
|
|
478
|
+
return true
|
|
418
479
|
return false
|
|
419
480
|
|
|
420
481
|
|
|
@@ -442,12 +503,17 @@ func _capture_and_send_screenshot(max_width: int) -> void:
|
|
|
442
503
|
image.resize(max_width, new_height, Image.INTERPOLATE_LANCZOS)
|
|
443
504
|
var png_buffer := image.save_png_to_buffer()
|
|
444
505
|
var base64 := Marshalls.raw_to_base64(png_buffer)
|
|
506
|
+
# Element 6 piggybacks the scene's cached mesh-integrity warnings: the
|
|
507
|
+
# moment the agent LOOKS at a wrong-looking render is when they're
|
|
508
|
+
# actionable, and riding the same message costs no extra round-trip and
|
|
509
|
+
# cannot time out on version skew (older receivers ignore the element).
|
|
445
510
|
EngineDebugger.send_message("godot_mcp:screenshot_result", [
|
|
446
511
|
true,
|
|
447
512
|
base64,
|
|
448
513
|
image.get_width(),
|
|
449
514
|
image.get_height(),
|
|
450
|
-
""
|
|
515
|
+
"",
|
|
516
|
+
_mesh_warnings.duplicate()
|
|
451
517
|
])
|
|
452
518
|
|
|
453
519
|
|
|
@@ -13,8 +13,10 @@ var _active: bool = false
|
|
|
13
13
|
var _specs: Array = [] # [{node, fields: [{key, resolver}]}]
|
|
14
14
|
var _hz: int = 20
|
|
15
15
|
var _duration_ms: int = 1000
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
# GAME time accumulated (unpaused, time_scale-scaled), NOT wall clock: under a
|
|
17
|
+
# godot_game_time freeze the tree is paused between steps, and counting wall time
|
|
18
|
+
# there would run the window down / log stale samples before the step that moves.
|
|
19
|
+
var _elapsed_ms: float = 0.0
|
|
18
20
|
var _frame_index: int = 0
|
|
19
21
|
var _sample_interval: int = 1 # sample every N frames
|
|
20
22
|
var _samples: Dictionary = {} # field_key -> Array of {t_ms, value}
|
|
@@ -41,7 +43,7 @@ func start(specs: Array, hz: int, duration_ms: int, signal_specs: Array = []) ->
|
|
|
41
43
|
_field_truncated = {}
|
|
42
44
|
_hz = clampi(hz, 1, 60)
|
|
43
45
|
_duration_ms = clampi(duration_ms, 100, 5000)
|
|
44
|
-
|
|
46
|
+
_elapsed_ms = 0.0
|
|
45
47
|
_frame_index = 0
|
|
46
48
|
_sample_interval = max(1, int(Engine.get_frames_per_second() / _hz)) if Engine.get_frames_per_second() > 0 else max(1, int(60.0 / _hz))
|
|
47
49
|
|
|
@@ -70,7 +72,6 @@ func start(specs: Array, hz: int, duration_ms: int, signal_specs: Array = []) ->
|
|
|
70
72
|
if not resolved_fields.is_empty():
|
|
71
73
|
_specs.append({"node": node, "node_path": node_path, "fields": resolved_fields})
|
|
72
74
|
|
|
73
|
-
_stop_time = 0
|
|
74
75
|
_active = true
|
|
75
76
|
set_process(true)
|
|
76
77
|
|
|
@@ -174,7 +175,7 @@ func _record_event(source: String, sig_name: String, args: Array) -> void:
|
|
|
174
175
|
_events_truncated = true
|
|
175
176
|
return
|
|
176
177
|
var ev := {
|
|
177
|
-
"t_ms":
|
|
178
|
+
"t_ms": int(_elapsed_ms),
|
|
178
179
|
"source": source,
|
|
179
180
|
"signal": sig_name,
|
|
180
181
|
}
|
|
@@ -217,18 +218,26 @@ func _exit_tree() -> void:
|
|
|
217
218
|
_disconnect_all()
|
|
218
219
|
|
|
219
220
|
|
|
220
|
-
func _process(
|
|
221
|
+
func _process(delta: float) -> void:
|
|
221
222
|
if not _active:
|
|
222
223
|
return
|
|
223
224
|
|
|
224
|
-
|
|
225
|
+
# Measure the window in GAME time and only sample while it actually advances.
|
|
226
|
+
# The sampler inherits PROCESS_MODE_ALWAYS, so _process keeps firing under a
|
|
227
|
+
# godot_game_time freeze (tree paused) even though gameplay is static. Counting
|
|
228
|
+
# those frames would (1) fill the window with stale values and (2) run the
|
|
229
|
+
# auto-stop down during frozen idle, so a later step lands outside the window.
|
|
230
|
+
# Skipping while paused makes the window span only live gameplay / step time.
|
|
231
|
+
var tree := get_tree()
|
|
232
|
+
if tree != null and tree.paused:
|
|
233
|
+
return
|
|
234
|
+
_elapsed_ms += delta * 1000.0 # time_scale-scaled, unpaused-only == game time
|
|
225
235
|
|
|
226
|
-
if
|
|
236
|
+
if _elapsed_ms >= float(_duration_ms):
|
|
227
237
|
_active = false
|
|
228
|
-
_stop_time = Time.get_ticks_msec()
|
|
229
238
|
set_process(false)
|
|
230
239
|
# Window over: stop recording signal emissions too. An emission landing
|
|
231
|
-
# between
|
|
240
|
+
# between the window closing and this frame is recorded with t_ms
|
|
232
241
|
# slightly past the window -- harmless and honest.
|
|
233
242
|
_disconnect_all()
|
|
234
243
|
return
|
|
@@ -246,7 +255,7 @@ func _process(_delta: float) -> void:
|
|
|
246
255
|
for field_info in spec.fields:
|
|
247
256
|
var arr: Array = _samples.get(field_info.full_key, [])
|
|
248
257
|
if arr.size() < MAX_SAMPLES_PER_FIELD:
|
|
249
|
-
arr.append({"t_ms":
|
|
258
|
+
arr.append({"t_ms": int(_elapsed_ms), "value": "freed"})
|
|
250
259
|
else:
|
|
251
260
|
_field_truncated[field_info.full_key] = true
|
|
252
261
|
continue
|
|
@@ -257,19 +266,13 @@ func _process(_delta: float) -> void:
|
|
|
257
266
|
continue
|
|
258
267
|
var arr: Array = _samples.get(field_info.full_key, [])
|
|
259
268
|
if arr.size() < MAX_SAMPLES_PER_FIELD:
|
|
260
|
-
arr.append({"t_ms":
|
|
269
|
+
arr.append({"t_ms": int(_elapsed_ms), "value": value})
|
|
261
270
|
else:
|
|
262
271
|
_field_truncated[field_info.full_key] = true
|
|
263
272
|
|
|
264
273
|
|
|
265
274
|
func collect() -> Dictionary:
|
|
266
|
-
var elapsed
|
|
267
|
-
if _stop_time > 0:
|
|
268
|
-
elapsed = _stop_time - _start_time
|
|
269
|
-
elif _start_time > 0:
|
|
270
|
-
elapsed = Time.get_ticks_msec() - _start_time
|
|
271
|
-
else:
|
|
272
|
-
elapsed = 0 # never started
|
|
275
|
+
var elapsed := int(_elapsed_ms)
|
|
273
276
|
var total_samples := 0
|
|
274
277
|
for key in _samples:
|
|
275
278
|
total_samples += (_samples[key] as Array).size()
|
|
@@ -288,11 +291,9 @@ func collect() -> Dictionary:
|
|
|
288
291
|
|
|
289
292
|
|
|
290
293
|
func stop() -> Dictionary:
|
|
294
|
+
# _elapsed_ms already holds the game-time window and freezes once _active is
|
|
295
|
+
# false, so a late manual stop can't inflate window_ms past the real window end.
|
|
291
296
|
_active = false
|
|
292
|
-
# Don't clobber an auto-stop's timestamp: a late manual stop would inflate
|
|
293
|
-
# window_ms to the call time instead of the actual window end.
|
|
294
|
-
if _stop_time == 0:
|
|
295
|
-
_stop_time = Time.get_ticks_msec()
|
|
296
297
|
set_process(false)
|
|
297
298
|
_disconnect_all()
|
|
298
299
|
return collect()
|
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
extends RefCounted
|
|
2
|
+
## Mesh-integrity validation for procedurally generated geometry.
|
|
3
|
+
##
|
|
4
|
+
## Corrupt mesh data renders WITHOUT errors — inside-out winding shows up as
|
|
5
|
+
## "too dark" or "invisible walls", dropped triangles as see-through geometry,
|
|
6
|
+
## degenerate UVs as black shading after generate_tangents(). Nothing in the
|
|
7
|
+
## engine reports any of it, so an agent's first hypothesis is usually wrong
|
|
8
|
+
## (it tunes lighting). This validator turns those silent signatures into
|
|
9
|
+
## findings that carry their own cause and fix.
|
|
10
|
+
##
|
|
11
|
+
## Two entry points:
|
|
12
|
+
## - validate(): full scan, on demand (the validate_meshes tool).
|
|
13
|
+
## - sniff(): cheap per-surface check run automatically on scene load; its
|
|
14
|
+
## one-line warnings get appended to screenshot results.
|
|
15
|
+
|
|
16
|
+
# Godot front faces wind CLOCKWISE seen from the normal side: a front
|
|
17
|
+
# triangle's right-hand cross points AWAY from its vertex normal. Verified
|
|
18
|
+
# against PlaneMesh — its first triangle has cross.dot(normal) == -1.
|
|
19
|
+
const _WINDING_EPS := 0.1
|
|
20
|
+
# Fraction thresholds: a few stray triangles are normal in hand-built or
|
|
21
|
+
# decimated meshes; systematic generator bugs corrupt a large share.
|
|
22
|
+
const _FRACTION_WARN := 0.05
|
|
23
|
+
# Per-surface work budget for the full scan (GDScript-speed bound). Larger
|
|
24
|
+
# surfaces are stride-sampled and the finding says so.
|
|
25
|
+
const _MAX_TRIS_SCANNED := 50000
|
|
26
|
+
const _SNIFF_SAMPLE_TRIS := 48
|
|
27
|
+
const _SNIFF_MAX_ELEMENTS := 300000
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
static func validate(root: Node, max_findings: int) -> Dictionary:
|
|
31
|
+
var findings: Array[Dictionary] = []
|
|
32
|
+
var checked_meshes := 0
|
|
33
|
+
var checked_surfaces := 0
|
|
34
|
+
# A mesh RESOURCE shared by many instances has one set of data — validate
|
|
35
|
+
# it once, attributed to the first node found, instead of N duplicate
|
|
36
|
+
# findings.
|
|
37
|
+
var seen: Dictionary = {}
|
|
38
|
+
var stack: Array[Node] = [root]
|
|
39
|
+
while not stack.is_empty():
|
|
40
|
+
var n: Node = stack.pop_back()
|
|
41
|
+
for child in n.get_children():
|
|
42
|
+
stack.push_back(child)
|
|
43
|
+
var mesh: ArrayMesh = _array_mesh_of(n)
|
|
44
|
+
if mesh == null or seen.has(mesh.get_instance_id()):
|
|
45
|
+
continue
|
|
46
|
+
seen[mesh.get_instance_id()] = true
|
|
47
|
+
checked_meshes += 1
|
|
48
|
+
for s in mesh.get_surface_count():
|
|
49
|
+
if mesh.surface_get_primitive_type(s) != Mesh.PRIMITIVE_TRIANGLES:
|
|
50
|
+
continue
|
|
51
|
+
checked_surfaces += 1
|
|
52
|
+
for f in _check_surface(mesh, s, _surface_cull_disabled(n, mesh, s)):
|
|
53
|
+
f["node"] = str(root.get_path_to(n)) if root.is_ancestor_of(n) else str(n.name)
|
|
54
|
+
f["surface"] = s
|
|
55
|
+
findings.append(f)
|
|
56
|
+
var total := findings.size()
|
|
57
|
+
if findings.size() > max_findings:
|
|
58
|
+
findings.resize(max_findings)
|
|
59
|
+
var result := {
|
|
60
|
+
"checked_meshes": checked_meshes,
|
|
61
|
+
"checked_surfaces": checked_surfaces,
|
|
62
|
+
"total_findings": total,
|
|
63
|
+
"findings": findings,
|
|
64
|
+
}
|
|
65
|
+
if total > max_findings:
|
|
66
|
+
result["note"] = "%d findings truncated to %d (max_findings)" % [total, max_findings]
|
|
67
|
+
return result
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
## Cheap integrity sniff for one node, used by the on-scene-load pass.
|
|
71
|
+
## Returns short one-line warnings ("" entries never appear).
|
|
72
|
+
static func sniff(n: Node) -> Array[String]:
|
|
73
|
+
var warnings: Array[String] = []
|
|
74
|
+
var mesh: ArrayMesh = _array_mesh_of(n)
|
|
75
|
+
if mesh == null:
|
|
76
|
+
return warnings
|
|
77
|
+
for s in mesh.get_surface_count():
|
|
78
|
+
if mesh.surface_get_primitive_type(s) != Mesh.PRIMITIVE_TRIANGLES:
|
|
79
|
+
continue
|
|
80
|
+
var vlen := mesh.surface_get_array_len(s)
|
|
81
|
+
var ilen := mesh.surface_get_array_index_len(s)
|
|
82
|
+
# O(1) red flag for surfaces too big to walk here: fewer index slots
|
|
83
|
+
# than vertices means triangles were lost. (Weak — orphans can hide
|
|
84
|
+
# behind ilen >= vlen — so below a size budget we count for real.)
|
|
85
|
+
if ilen > 0 and vlen > 0 and ilen < vlen:
|
|
86
|
+
warnings.append("%s surf %d: %d verts but only %d indices — dropped triangles" % [n.name, s, vlen, ilen])
|
|
87
|
+
continue
|
|
88
|
+
# The budget bounds the ARRAY COPY too: surface_get_arrays() duplicates
|
|
89
|
+
# every channel, a multi-MB scene-load hitch on big imported meshes.
|
|
90
|
+
# Oversized surfaces keep only the O(1) check; the on-demand full
|
|
91
|
+
# validate (stride-sampled) is the path that inspects them.
|
|
92
|
+
if vlen + ilen > _SNIFF_MAX_ELEMENTS:
|
|
93
|
+
continue
|
|
94
|
+
var arrays: Array = mesh.surface_get_arrays(s)
|
|
95
|
+
var verts: PackedVector3Array = arrays[Mesh.ARRAY_VERTEX]
|
|
96
|
+
var norms = arrays[Mesh.ARRAY_NORMAL]
|
|
97
|
+
if verts.is_empty() or norms == null:
|
|
98
|
+
continue
|
|
99
|
+
var idx = arrays[Mesh.ARRAY_INDEX]
|
|
100
|
+
# Real orphan count when affordable (integer-only pass): the definitive
|
|
101
|
+
# dropped-triangles signature regardless of how the counts balance.
|
|
102
|
+
if idx != null and vlen + ilen < _SNIFF_MAX_ELEMENTS:
|
|
103
|
+
var pidx := idx as PackedInt32Array
|
|
104
|
+
var used := PackedByteArray()
|
|
105
|
+
used.resize(verts.size())
|
|
106
|
+
for i in pidx.size():
|
|
107
|
+
var v := pidx[i]
|
|
108
|
+
if v >= 0 and v < used.size():
|
|
109
|
+
used[v] = 1
|
|
110
|
+
var orphans := 0
|
|
111
|
+
for i in used.size():
|
|
112
|
+
if used[i] == 0:
|
|
113
|
+
orphans += 1
|
|
114
|
+
if float(orphans) / float(verts.size()) > _FRACTION_WARN:
|
|
115
|
+
warnings.append("%s surf %d: %d%% of vertices unreferenced — dropped triangles" % [n.name, s, orphans * 100 / verts.size()])
|
|
116
|
+
continue
|
|
117
|
+
var tri_count: int = ((idx as PackedInt32Array).size() if idx != null else verts.size()) / 3
|
|
118
|
+
if tri_count == 0:
|
|
119
|
+
continue
|
|
120
|
+
var stride := maxi(1, tri_count / _SNIFF_SAMPLE_TRIS)
|
|
121
|
+
var sampled := 0
|
|
122
|
+
var inside_out := 0
|
|
123
|
+
var non_finite := 0
|
|
124
|
+
for t in range(0, tri_count, stride):
|
|
125
|
+
sampled += 1
|
|
126
|
+
var o := _orientation(verts, norms, idx, t * 3)
|
|
127
|
+
if o == 1:
|
|
128
|
+
inside_out += 1
|
|
129
|
+
elif o == -2:
|
|
130
|
+
non_finite += 1
|
|
131
|
+
if non_finite > 0:
|
|
132
|
+
warnings.append("%s surf %d: non-finite vertex data (NaN/INF)" % [n.name, s])
|
|
133
|
+
elif inside_out * 2 > sampled:
|
|
134
|
+
warnings.append("%s surf %d: ~%d%% of sampled triangles wind inside-out" % [n.name, s, inside_out * 100 / sampled])
|
|
135
|
+
return warnings
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
static func _array_mesh_of(n: Node) -> ArrayMesh:
|
|
139
|
+
# Engine primitives (BoxMesh, CylinderMesh, ...) are generator-correct by
|
|
140
|
+
# construction; only code-built ArrayMeshes carry these bug classes.
|
|
141
|
+
if n is MeshInstance3D and (n as MeshInstance3D).mesh is ArrayMesh:
|
|
142
|
+
return (n as MeshInstance3D).mesh
|
|
143
|
+
if n is MultiMeshInstance3D:
|
|
144
|
+
var mm: MultiMesh = (n as MultiMeshInstance3D).multimesh
|
|
145
|
+
if mm != null and mm.mesh is ArrayMesh:
|
|
146
|
+
return mm.mesh
|
|
147
|
+
return null
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
## Orientation of one triangle: 0 = correct (CW from normal side),
|
|
151
|
+
## 1 = inside-out, -1 = degenerate (skip), -2 = non-finite data.
|
|
152
|
+
static func _orientation(verts: PackedVector3Array, norms: PackedVector3Array, idx, base: int) -> int:
|
|
153
|
+
var ia: int
|
|
154
|
+
var ib: int
|
|
155
|
+
var ic: int
|
|
156
|
+
if idx != null and (idx as PackedInt32Array).size() > 0:
|
|
157
|
+
var pidx := idx as PackedInt32Array
|
|
158
|
+
ia = pidx[base]
|
|
159
|
+
ib = pidx[base + 1]
|
|
160
|
+
ic = pidx[base + 2]
|
|
161
|
+
else:
|
|
162
|
+
ia = base
|
|
163
|
+
ib = base + 1
|
|
164
|
+
ic = base + 2
|
|
165
|
+
if ic >= verts.size() or ic >= norms.size():
|
|
166
|
+
return -1
|
|
167
|
+
var a := verts[ia]
|
|
168
|
+
var b := verts[ib]
|
|
169
|
+
var c := verts[ic]
|
|
170
|
+
if not (a.is_finite() and b.is_finite() and c.is_finite()
|
|
171
|
+
and norms[ia].is_finite() and norms[ib].is_finite() and norms[ic].is_finite()):
|
|
172
|
+
return -2
|
|
173
|
+
var cross := (b - a).cross(c - a)
|
|
174
|
+
var cl := cross.length()
|
|
175
|
+
if cl < 1e-12:
|
|
176
|
+
return -1
|
|
177
|
+
var vn := norms[ia] + norms[ib] + norms[ic]
|
|
178
|
+
if vn.length_squared() < 0.01:
|
|
179
|
+
return -1
|
|
180
|
+
var d := cross.dot(vn) / (cl * vn.length())
|
|
181
|
+
if d > _WINDING_EPS:
|
|
182
|
+
return 1
|
|
183
|
+
if d < -_WINDING_EPS:
|
|
184
|
+
return 0
|
|
185
|
+
return -1
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
# Effective material for one surface, in Godot's own precedence order. A
|
|
189
|
+
# double-sided material makes wrong winding invisible (nothing is culled), so
|
|
190
|
+
# winding findings on such surfaces are downgraded — but not dropped, because
|
|
191
|
+
# the inverted normals still break lighting.
|
|
192
|
+
static func _surface_cull_disabled(n: Node, mesh: ArrayMesh, s: int) -> bool:
|
|
193
|
+
var mat: Material = null
|
|
194
|
+
if n is GeometryInstance3D and (n as GeometryInstance3D).material_override != null:
|
|
195
|
+
mat = (n as GeometryInstance3D).material_override
|
|
196
|
+
elif n is MeshInstance3D and (n as MeshInstance3D).get_surface_override_material(s) != null:
|
|
197
|
+
mat = (n as MeshInstance3D).get_surface_override_material(s)
|
|
198
|
+
else:
|
|
199
|
+
mat = mesh.surface_get_material(s)
|
|
200
|
+
return mat is BaseMaterial3D and (mat as BaseMaterial3D).cull_mode == BaseMaterial3D.CULL_DISABLED
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
static func _check_surface(mesh: ArrayMesh, s: int, cull_disabled: bool = false) -> Array[Dictionary]:
|
|
204
|
+
var findings: Array[Dictionary] = []
|
|
205
|
+
var arrays: Array = mesh.surface_get_arrays(s)
|
|
206
|
+
var verts: PackedVector3Array = arrays[Mesh.ARRAY_VERTEX]
|
|
207
|
+
if verts.is_empty():
|
|
208
|
+
return findings
|
|
209
|
+
var norms = arrays[Mesh.ARRAY_NORMAL]
|
|
210
|
+
var uvs = arrays[Mesh.ARRAY_TEX_UV]
|
|
211
|
+
var tans = arrays[Mesh.ARRAY_TANGENT]
|
|
212
|
+
var idx = arrays[Mesh.ARRAY_INDEX]
|
|
213
|
+
var indexed: bool = idx != null and (idx as PackedInt32Array).size() > 0
|
|
214
|
+
var tri_count: int = ((idx as PackedInt32Array).size() if indexed else verts.size()) / 3
|
|
215
|
+
|
|
216
|
+
# 1. Orphaned vertices (indexed only): vertices no triangle references.
|
|
217
|
+
# The signature of triangles lost during construction.
|
|
218
|
+
if indexed:
|
|
219
|
+
var pidx := idx as PackedInt32Array
|
|
220
|
+
var used := PackedByteArray()
|
|
221
|
+
used.resize(verts.size())
|
|
222
|
+
for i in pidx.size():
|
|
223
|
+
var v := pidx[i]
|
|
224
|
+
if v >= 0 and v < verts.size():
|
|
225
|
+
used[v] = 1
|
|
226
|
+
var orphans := 0
|
|
227
|
+
for i in used.size():
|
|
228
|
+
if used[i] == 0:
|
|
229
|
+
orphans += 1
|
|
230
|
+
var ofrac := float(orphans) / float(verts.size())
|
|
231
|
+
if ofrac > _FRACTION_WARN:
|
|
232
|
+
findings.append({
|
|
233
|
+
"severity": "error",
|
|
234
|
+
"kind": "dropped_triangles",
|
|
235
|
+
"stat": "%d of %d vertices (%d%%) are never referenced by the index buffer" % [orphans, verts.size(), int(ofrac * 100.0)],
|
|
236
|
+
"fix": "Triangles were lost while building this mesh. Typical cause: SurfaceTool.append_from() of an INDEXED mesh into a SurfaceTool that already holds raw add_vertex data corrupts index()/commit(). Deindex the source first (SurfaceTool.create_from -> deindex -> commit) or keep indexed and raw geometry in separate SurfaceTools.",
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
# Work budget: stride-sample huge surfaces instead of silently skipping.
|
|
240
|
+
var stride := maxi(1, tri_count / _MAX_TRIS_SCANNED)
|
|
241
|
+
var sampled_note := "" if stride == 1 else " (sampled 1/%d triangles)" % stride
|
|
242
|
+
|
|
243
|
+
# 2. Winding vs normals, 3. degenerate UV / position triangles.
|
|
244
|
+
var sampled := 0
|
|
245
|
+
var inside_out := 0
|
|
246
|
+
var correct := 0
|
|
247
|
+
var non_finite_tris := 0
|
|
248
|
+
var degen_pos := 0
|
|
249
|
+
var degen_uv := 0
|
|
250
|
+
var has_uv: bool = uvs != null and (uvs as PackedVector2Array).size() == verts.size()
|
|
251
|
+
var puv: PackedVector2Array = uvs if has_uv else PackedVector2Array()
|
|
252
|
+
var pidx2: PackedInt32Array = idx if indexed else PackedInt32Array()
|
|
253
|
+
if norms != null and (norms as PackedVector3Array).size() == verts.size():
|
|
254
|
+
var pnorms := norms as PackedVector3Array
|
|
255
|
+
for t in range(0, tri_count, stride):
|
|
256
|
+
sampled += 1
|
|
257
|
+
var base := t * 3
|
|
258
|
+
var o := _orientation(verts, pnorms, idx, base)
|
|
259
|
+
match o:
|
|
260
|
+
0: correct += 1
|
|
261
|
+
1: inside_out += 1
|
|
262
|
+
-1: degen_pos += 1
|
|
263
|
+
-2: non_finite_tris += 1
|
|
264
|
+
if has_uv and o != -2:
|
|
265
|
+
var ia := pidx2[base] if indexed else base
|
|
266
|
+
var ib := pidx2[base + 1] if indexed else base + 1
|
|
267
|
+
var ic := pidx2[base + 2] if indexed else base + 2
|
|
268
|
+
var e1 := puv[ib] - puv[ia]
|
|
269
|
+
var e2 := puv[ic] - puv[ia]
|
|
270
|
+
if absf(e1.cross(e2)) < 1e-12 and o != -1:
|
|
271
|
+
degen_uv += 1
|
|
272
|
+
if sampled > 0:
|
|
273
|
+
var io_frac := float(inside_out) / float(sampled)
|
|
274
|
+
if io_frac > _FRACTION_WARN:
|
|
275
|
+
var wind_severity := "warning" if cull_disabled else "error"
|
|
276
|
+
var cull_note := " NOTE: this surface's material is double-sided (cull disabled), so wrong winding hides nothing here — but inverted normals still mislight; this may also be intentional (foliage cards, decals)." if cull_disabled else ""
|
|
277
|
+
if correct > sampled / 10:
|
|
278
|
+
findings.append({
|
|
279
|
+
"severity": wind_severity,
|
|
280
|
+
"kind": "mixed_winding",
|
|
281
|
+
"stat": "%d%% of triangles wind inside-out, %d%% correctly%s" % [int(io_frac * 100.0), correct * 100 / sampled, sampled_note],
|
|
282
|
+
"fix": "The generator's point ordering is inconsistent between face families, so no fixed fan order is right for all of them. Enforce winding PER FACE: Godot front faces wind clockwise seen from the normal side, i.e. (b-a).cross(c-a).dot(normal) must be < 0 for every front triangle — swap two indices when it is not. Symptoms: some faces invisible from the side their normal points (see-through floors/walls), others lit on the wrong side (black under any sun)." + cull_note,
|
|
283
|
+
})
|
|
284
|
+
else:
|
|
285
|
+
findings.append({
|
|
286
|
+
"severity": wind_severity,
|
|
287
|
+
"kind": "inside_out_winding",
|
|
288
|
+
"stat": "%d%% of triangles wind inside-out%s" % [int(io_frac * 100.0), sampled_note],
|
|
289
|
+
"fix": "Triangles wind counter-clockwise seen from their normal side, but Godot front faces wind CLOCKWISE — these faces are invisible from the side their normal points and/or are lit with an inverted normal (renders black under any light, looks like 'lighting is broken'). Fix the emission order so (b-a).cross(c-a).dot(normal) < 0, or as a stopgap set cull_mode = CULL_DISABLED to confirm the diagnosis visually." + cull_note,
|
|
290
|
+
})
|
|
291
|
+
if non_finite_tris > 0:
|
|
292
|
+
findings.append({
|
|
293
|
+
"severity": "error",
|
|
294
|
+
"kind": "non_finite_data",
|
|
295
|
+
"stat": "%d sampled triangles contain NaN/INF positions or normals%s" % [non_finite_tris, sampled_note],
|
|
296
|
+
"fix": "Non-finite vertex data poisons everything downstream (lighting, culling, shadows) with no error reported. Usually a division by zero or normalize() of a zero vector in the generator.",
|
|
297
|
+
})
|
|
298
|
+
var uv_frac := (float(degen_uv) / float(sampled)) if sampled > 0 else 0.0
|
|
299
|
+
if uv_frac > _FRACTION_WARN:
|
|
300
|
+
findings.append({
|
|
301
|
+
"severity": "error" if tans != null else "warning",
|
|
302
|
+
"kind": "degenerate_uvs",
|
|
303
|
+
"stat": "%d%% of triangles have zero UV area%s" % [int(uv_frac * 100.0), sampled_note],
|
|
304
|
+
"fix": "Zero-area UVs (a UV coordinate that is constant across a face, e.g. uv=(x+z, y) on a horizontal face) make generate_tangents() emit garbage tangents, which can corrupt GPU-side normals on some vertex formats — flat faces shade black while angled ones look fine. Project UVs onto each face's dominant axis plane (|n.y| max -> (x,z); |n.x| max -> (z,y); else (x,y)). Triplanar materials do NOT make UVs irrelevant: tangent generation still reads them.",
|
|
305
|
+
})
|
|
306
|
+
var dp_frac := float(degen_pos) / float(sampled)
|
|
307
|
+
if dp_frac > 0.25:
|
|
308
|
+
findings.append({
|
|
309
|
+
"severity": "warning",
|
|
310
|
+
"kind": "degenerate_triangles",
|
|
311
|
+
"stat": "%d%% of triangles have ~zero area or unusable normals%s" % [int(dp_frac * 100.0), sampled_note],
|
|
312
|
+
"fix": "Wasted vertices at best; if unexpected, the generator is emitting collapsed faces.",
|
|
313
|
+
})
|
|
314
|
+
|
|
315
|
+
# 4. Tangent sanity (only when present).
|
|
316
|
+
if tans != null:
|
|
317
|
+
var ptans := tans as PackedFloat32Array
|
|
318
|
+
var bad_tan := 0
|
|
319
|
+
var tcount := ptans.size() / 4
|
|
320
|
+
var tstride := maxi(1, tcount / _MAX_TRIS_SCANNED)
|
|
321
|
+
var tsampled := 0
|
|
322
|
+
for i in range(0, tcount, tstride):
|
|
323
|
+
tsampled += 1
|
|
324
|
+
var tx := ptans[i * 4]
|
|
325
|
+
var ty := ptans[i * 4 + 1]
|
|
326
|
+
var tz := ptans[i * 4 + 2]
|
|
327
|
+
if is_nan(tx) or is_inf(tx) or is_nan(ty) or is_inf(ty) or is_nan(tz) or is_inf(tz):
|
|
328
|
+
bad_tan += 1
|
|
329
|
+
elif tx * tx + ty * ty + tz * tz < 0.25:
|
|
330
|
+
bad_tan += 1
|
|
331
|
+
if tsampled > 0 and float(bad_tan) / float(tsampled) > _FRACTION_WARN:
|
|
332
|
+
findings.append({
|
|
333
|
+
"severity": "error",
|
|
334
|
+
"kind": "bad_tangents",
|
|
335
|
+
"stat": "%d%% of tangents are NaN/zero" % [bad_tan * 100 / tsampled],
|
|
336
|
+
"fix": "Broken tangents corrupt normal mapping and, with compressed vertex formats, the GPU normals themselves. Usual cause is generate_tangents() over degenerate UVs — fix the UVs (see degenerate_uvs) or skip tangents for untextured meshes.",
|
|
337
|
+
})
|
|
338
|
+
|
|
339
|
+
# 5. Normal sanity. NOTE: ArrayMesh stores normals octahedral-encoded, so
|
|
340
|
+
# zero/NaN SOURCE normals are usually laundered into arbitrary unit
|
|
341
|
+
# vectors at build time — post-storage they surface as orientation
|
|
342
|
+
# ambiguity (check 2's degenerate bucket), not here. This check still
|
|
343
|
+
# covers uncompressed/custom formats where raw values survive.
|
|
344
|
+
if norms != null:
|
|
345
|
+
var pn := norms as PackedVector3Array
|
|
346
|
+
var bad_n := 0
|
|
347
|
+
var nstride := maxi(1, pn.size() / _MAX_TRIS_SCANNED)
|
|
348
|
+
var nsampled := 0
|
|
349
|
+
for i in range(0, pn.size(), nstride):
|
|
350
|
+
nsampled += 1
|
|
351
|
+
var v := pn[i]
|
|
352
|
+
if not v.is_finite() or v.length_squared() < 0.25:
|
|
353
|
+
bad_n += 1
|
|
354
|
+
if nsampled > 0 and float(bad_n) / float(nsampled) > _FRACTION_WARN:
|
|
355
|
+
findings.append({
|
|
356
|
+
"severity": "error",
|
|
357
|
+
"kind": "zero_normals",
|
|
358
|
+
"stat": "%d%% of vertex normals are NaN or near-zero length" % [bad_n * 100 / nsampled],
|
|
359
|
+
"fix": "Unit-length normals are assumed by all lighting. The generator is forgetting set_normal() on some vertices or normalizing zero vectors.",
|
|
360
|
+
})
|
|
361
|
+
return findings
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
uid://dk531n7p1i2k
|
package/addon/plugin.cfg
CHANGED
|
@@ -223,6 +223,29 @@ describe('editor tool', () => {
|
|
|
223
223
|
const result = await editor.execute({ action: 'screenshot_game' }, ctx);
|
|
224
224
|
expect(result).toEqual({ type: 'image', data: base64, mimeType: 'image/png' });
|
|
225
225
|
});
|
|
226
|
+
it('appends a mesh-integrity advisory when warnings ride the screenshot response', async () => {
|
|
227
|
+
const base64 = 'iVBORw0KGgoAAAANSUhEUg==';
|
|
228
|
+
mock.mockResponse({
|
|
229
|
+
image_base64: base64,
|
|
230
|
+
width: 800,
|
|
231
|
+
height: 600,
|
|
232
|
+
mesh_warnings: ['Floor surf 0: 66% of vertices unreferenced — dropped triangles'],
|
|
233
|
+
});
|
|
234
|
+
const ctx = createToolContext(mock);
|
|
235
|
+
const result = await editor.execute({ action: 'screenshot_game' }, ctx);
|
|
236
|
+
expect(Array.isArray(result)).toBe(true);
|
|
237
|
+
const blocks = result;
|
|
238
|
+
expect(blocks[0]).toEqual({ type: 'image', data: base64, mimeType: 'image/png' });
|
|
239
|
+
expect(blocks[1].type).toBe('text');
|
|
240
|
+
expect(blocks[1].text).toContain('Mesh integrity');
|
|
241
|
+
expect(blocks[1].text).toContain('godot_validate_meshes');
|
|
242
|
+
});
|
|
243
|
+
it('returns a bare image when the response carries no mesh warnings', async () => {
|
|
244
|
+
mock.mockResponse({ image_base64: 'abc', width: 8, height: 8, mesh_warnings: [] });
|
|
245
|
+
const ctx = createToolContext(mock);
|
|
246
|
+
const result = await editor.execute({ action: 'screenshot_game' }, ctx);
|
|
247
|
+
expect(result).toEqual({ type: 'image', data: 'abc', mimeType: 'image/png' });
|
|
248
|
+
});
|
|
226
249
|
it('passes viewport and max_width params for editor screenshot', async () => {
|
|
227
250
|
mock.mockResponse({ image_base64: 'abc', width: 800, height: 600 });
|
|
228
251
|
const ctx = createToolContext(mock);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor.test.js","sourceRoot":"","sources":["../../../src/__tests__/tools/editor.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAuB,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACjH,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAE/C,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,IAAI,IAAyB,CAAC;IAE9B,UAAU,CAAC,GAAG,EAAE;QACd,IAAI,GAAG,eAAe,EAAE,CAAC;IAC3B,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;QACjC,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;YAC9C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1E,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpG,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;YACzD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACnF,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,iBAAiB,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/F,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;QACzB,EAAE,CAAC,mEAAmE,EAAE,KAAK,IAAI,EAAE;YACjF,MAAM,KAAK,GAAG;gBACZ,aAAa,EAAE,iBAAiB;gBAChC,UAAU,EAAE,KAAK;gBACjB,aAAa,EAAE,KAAK;gBACpB,WAAW,EAAE,CAAC,iBAAiB,EAAE,mBAAmB,CAAC;gBACrD,WAAW,EAAE,IAAI;gBACjB,MAAM,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE;gBAC3C,WAAW,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE;aACnD,CAAC;YACF,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YACzB,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAEpC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,GAAG,CAAC,CAAC;YAElE,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;QAC7B,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;YACvD,IAAI,CAAC,YAAY,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;YACpC,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YACpC,MAAM,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;YAEzF,IAAI,CAAC,YAAY,CAAC,EAAE,QAAQ,EAAE,CAAC,mBAAmB,EAAE,kBAAkB,CAAC,EAAE,CAAC,CAAC;YAC3E,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,EAAE,GAAG,CAAC,CAAC;YACtE,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;YAC5C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE;QACxB,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;YACjD,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;YACtB,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAEpC,MAAM,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;YAC7E,MAAM,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,EAAE,GAAG,CAAC,CAAC;iBAChF,IAAI,CAAC,gCAAgC,CAAC,CAAC;YAC1C,MAAM,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAChF,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;YAChE,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;YACtB,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAEpC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC;YAC1E,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC;YAChD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAClD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;QACvB,EAAE,CAAC,uEAAuE,EAAE,KAAK,IAAI,EAAE;YACrF,IAAI,CAAC,YAAY,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YACpD,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAEpC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,GAAG,CAAC,CAAC;YAEhE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YACrD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC7C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;YACvC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;YACnE,IAAI,CAAC,YAAY,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YACrD,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAEpC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,GAAG,CAAC,CAAC;YAE7E,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC9C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;YACxE,uEAAuE;YACvE,0EAA0E;YAC1E,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC;YAC/C,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAEpC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,GAAG,CAAC,CAAC;YAChE,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gEAAgE,EAAE,KAAK,IAAI,EAAE;YAC9E,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC,CAAC;YAC7D,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAEpC,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAC9F,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,EAAE,CAAC,wEAAwE,EAAE,KAAK,IAAI,EAAE;YACtF,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YACpC,IAAI,CAAC,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;YAClG,MAAM,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,kBAAkB,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QACpG,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;YACvD,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YACpC,MAAM,YAAY,GAAG;gBACnB,WAAW,EAAE,CAAC;gBACd,cAAc,EAAE,CAAC;gBACjB,QAAQ,EAAE;oBACR,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,qBAAqB,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;oBACtI,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;iBACjI;aACF,CAAC;YACF,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;YAChC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,kBAAkB,EAAE,EAAE,GAAG,CAAC,CAAC;YACzE,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;YAC3C,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YACpC,IAAI,CAAC,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;YACvE,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,kBAAkB,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;YACrE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;YACzD,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YACpC,IAAI,CAAC,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;YAClG,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,kBAAkB,EAAE,EAAE,GAAG,CAAC,CAAC;YAC1D,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAClD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;YAClE,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YACpC,IAAI,CAAC,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;YAClG,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,kBAAkB,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;YACvF,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACpD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4DAA4D,EAAE,KAAK,IAAI,EAAE;YAC1E,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YACpC,MAAM,YAAY,GAAG;gBACnB,WAAW,EAAE,CAAC;gBACd,WAAW,EAAE,CAAC;gBACd,cAAc,EAAE,CAAC;gBACjB,MAAM,EAAE,CAAC;gBACT,QAAQ,EAAE;oBACR,EAAE,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;oBACxG,EAAE,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;iBACzG;aACF,CAAC;YACF,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;YAChC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,kBAAkB,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,GAAG,CAAC,CAAC;YAC5F,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0FAA0F,EAAE,KAAK,IAAI,EAAE;YACxG,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YACpC,IAAI,CAAC,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;YAClG,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,kBAAkB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;YACnF,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;QACzD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kEAAkE,EAAE,KAAK,IAAI,EAAE;YAChF,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YACpC,IAAI,CAAC,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;YAClG,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,kBAAkB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,GAAG,CAAC,CAAC;YACtG,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;QAC/D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yFAAyF,EAAE,KAAK,IAAI,EAAE;YACvG,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YACpC,MAAM,SAAS,GAAG;gBAChB,KAAK,EAAE,IAAI;gBACX,OAAO,EAAE,sIAAsI;gBAC/I,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;gBACrD,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;aACrB,CAAC;YACF,IAAI,CAAC,YAAY,CAAC;gBAChB,WAAW,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;gBAC5D,QAAQ,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,0BAA0B,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;gBAC/I,SAAS;aACV,CAAC,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,kBAAkB,EAAE,EAAE,GAAG,CAAC,CAAC;YACzE,MAAM,UAAU,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;YACxC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,yBAAyB,CAAC,CAAC;YACjE,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;YAC9D,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mEAAmE,EAAE,KAAK,IAAI,EAAE;YACjF,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YACpC,IAAI,CAAC,YAAY,CAAC;gBAChB,WAAW,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE;gBAC1E,SAAS,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,4BAA4B,EAAE;aAClE,CAAC,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,kBAAkB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;YACnF,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,iCAAiC,CAAC,CAAC;YAC5D,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,yBAAyB,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;YAC5E,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YACpC,MAAM,YAAY,GAAG,EAAE,WAAW,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC;YACjI,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;YAChC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,kBAAkB,EAAE,EAAE,GAAG,CAAC,CAAC;YACzE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;QAC/B,EAAE,CAAC,kEAAkE,EAAE,KAAK,IAAI,EAAE;YAChF,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAEpC,IAAI,CAAC,YAAY,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;YAChF,MAAM,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,iBAAiB,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;YAElG,MAAM,SAAS,GAAG;gBAChB,KAAK,EAAE,eAAe;gBACtB,UAAU,EAAE,eAAe;gBAC3B,IAAI,EAAE,iBAAiB;gBACvB,IAAI,EAAE,EAAE;gBACR,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;aACtE,CAAC;YACF,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;YAC7B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,iBAAiB,EAAE,EAAE,GAAG,CAAC,CAAC;YACxE,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;QAC3B,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;YAC9C,MAAM,MAAM,GAAG,0BAA0B,CAAC;YAC1C,IAAI,CAAC,YAAY,CAAC,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;YACrE,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAEpC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,iBAAiB,EAAE,EAAE,GAAG,CAAC,CAAC;YACxE,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,CAAC;QACjF,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4DAA4D,EAAE,KAAK,IAAI,EAAE;YAC1E,IAAI,CAAC,YAAY,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;YACpE,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAEpC,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,mBAAmB,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC;YAC3F,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;YAC5C,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC;YACjD,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAEpC,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,iBAAiB,EAAE,EAAE,GAAG,CAAC,CAAC;iBAC7D,OAAO,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;QAC/B,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;YACjE,IAAI,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;YACjE,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAEpC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC;gBAClC,MAAM,EAAE,iBAAiB;gBACzB,QAAQ,EAAE,GAAG;gBACb,QAAQ,EAAE,GAAG;gBACb,IAAI,EAAE,GAAG;aACV,EAAE,GAAG,CAAC,CAAC;YAER,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YAClC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YAClC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"editor.test.js","sourceRoot":"","sources":["../../../src/__tests__/tools/editor.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-meshes.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/tools/validate-meshes.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach } from 'vitest';
|
|
2
|
+
import { createMockGodot, createToolContext, structuredOf } from '../helpers/mock-godot.js';
|
|
3
|
+
import { validateMeshes } from '../../tools/validate-meshes.js';
|
|
4
|
+
describe('validate_meshes tool', () => {
|
|
5
|
+
let mock;
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
mock = createMockGodot();
|
|
8
|
+
});
|
|
9
|
+
describe('schema validation', () => {
|
|
10
|
+
it('accepts empty args and bounds max_findings to 1..100', () => {
|
|
11
|
+
expect(validateMeshes.schema.safeParse({}).success).toBe(true);
|
|
12
|
+
expect(validateMeshes.schema.safeParse({ max_findings: 1 }).success).toBe(true);
|
|
13
|
+
expect(validateMeshes.schema.safeParse({ max_findings: 100 }).success).toBe(true);
|
|
14
|
+
expect(validateMeshes.schema.safeParse({ max_findings: 0 }).success).toBe(false);
|
|
15
|
+
expect(validateMeshes.schema.safeParse({ max_findings: 101 }).success).toBe(false);
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
it('forwards max_findings with a default of 25', async () => {
|
|
19
|
+
mock.mockResponse({ checked_meshes: 1, checked_surfaces: 1, total_findings: 0, findings: [] });
|
|
20
|
+
await validateMeshes.execute({}, createToolContext(mock));
|
|
21
|
+
expect(mock.calls[0].command).toBe('validate_meshes');
|
|
22
|
+
expect(mock.calls[0].params.max_findings).toBe(25);
|
|
23
|
+
mock.mockResponse({ checked_meshes: 1, checked_surfaces: 1, total_findings: 0, findings: [] });
|
|
24
|
+
await validateMeshes.execute({ max_findings: 7 }, createToolContext(mock));
|
|
25
|
+
expect(mock.calls[1].params.max_findings).toBe(7);
|
|
26
|
+
});
|
|
27
|
+
it('returns a clean bill naming what was ruled out when surfaces were checked', async () => {
|
|
28
|
+
mock.mockResponse({ checked_meshes: 12, checked_surfaces: 16, total_findings: 0, findings: [] });
|
|
29
|
+
const result = await validateMeshes.execute({}, createToolContext(mock));
|
|
30
|
+
expect(typeof result).toBe('string');
|
|
31
|
+
expect(result).toContain('no integrity problems');
|
|
32
|
+
expect(result).toContain('12 meshes');
|
|
33
|
+
});
|
|
34
|
+
it('does NOT claim a clean bill when nothing was checked', async () => {
|
|
35
|
+
// "Checked 0 meshes - no problems" would rule things out on zero
|
|
36
|
+
// evidence, the exact confident-lie failure mode the tool exists to stop.
|
|
37
|
+
mock.mockResponse({ checked_meshes: 0, checked_surfaces: 0, total_findings: 0, findings: [] });
|
|
38
|
+
const result = await validateMeshes.execute({}, createToolContext(mock));
|
|
39
|
+
expect(typeof result).toBe('string');
|
|
40
|
+
expect(result).not.toContain('no integrity problems');
|
|
41
|
+
expect(result).toContain('NOT a clean bill');
|
|
42
|
+
});
|
|
43
|
+
it('surfaces the bridge note when nothing was checked for a stated reason', async () => {
|
|
44
|
+
mock.mockResponse({ checked_meshes: 0, checked_surfaces: 0, total_findings: 0, findings: [], note: 'no current scene' });
|
|
45
|
+
const result = await validateMeshes.execute({}, createToolContext(mock));
|
|
46
|
+
expect(result).toContain('no current scene');
|
|
47
|
+
});
|
|
48
|
+
it('returns findings as structured content', async () => {
|
|
49
|
+
const payload = {
|
|
50
|
+
checked_meshes: 3,
|
|
51
|
+
checked_surfaces: 4,
|
|
52
|
+
total_findings: 1,
|
|
53
|
+
findings: [
|
|
54
|
+
{
|
|
55
|
+
node: 'World/Level/Floor',
|
|
56
|
+
surface: 0,
|
|
57
|
+
severity: 'error',
|
|
58
|
+
kind: 'dropped_triangles',
|
|
59
|
+
stat: '132 of 199 vertices (66%) are never referenced by the index buffer',
|
|
60
|
+
fix: 'Deindex the source first',
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
};
|
|
64
|
+
mock.mockResponse(payload);
|
|
65
|
+
const result = await validateMeshes.execute({}, createToolContext(mock));
|
|
66
|
+
expect(structuredOf(result)).toEqual(payload);
|
|
67
|
+
});
|
|
68
|
+
it('propagates errors from Godot', async () => {
|
|
69
|
+
mock.mockError(new Error('No game is currently running'));
|
|
70
|
+
await expect(validateMeshes.execute({}, createToolContext(mock))).rejects.toThrow('No game is currently running');
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
//# sourceMappingURL=validate-meshes.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-meshes.test.js","sourceRoot":"","sources":["../../../src/__tests__/tools/validate-meshes.test.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAqBA,wBAAsB,IAAI,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAqBA,wBAAsB,IAAI,kBA2HzB"}
|
package/dist/index.js
CHANGED
|
@@ -21,6 +21,20 @@ export async function main() {
|
|
|
21
21
|
resources: {},
|
|
22
22
|
logging: {},
|
|
23
23
|
},
|
|
24
|
+
// Injected into the client's context at connect time: the traps below
|
|
25
|
+
// produce NO error anywhere, so guidance must arrive before the symptom
|
|
26
|
+
// is misread (e.g. "too dark" tuned as lighting when the mesh data is
|
|
27
|
+
// corrupt). Keep this short — it is paid by every session.
|
|
28
|
+
instructions: 'Godot pitfalls that produce no errors: ' +
|
|
29
|
+
'(1) If 3D rendering looks wrong with nothing in any log (black/too-dark surfaces, ' +
|
|
30
|
+
'invisible or one-sided walls/floors, lighting that ignores light changes), run ' +
|
|
31
|
+
'godot_validate_meshes BEFORE tuning lights or materials — procedurally generated ' +
|
|
32
|
+
'meshes are often silently corrupt (winding, dropped triangles, bad tangents). ' +
|
|
33
|
+
'(2) SDFGI replaces constant ambient light: to lift shadow sides, add a dim ' +
|
|
34
|
+
'shadowless DirectionalLight (light_specular=0) opposing the key light instead of ' +
|
|
35
|
+
'raising ambient_light_energy, which will appear to do nothing. ' +
|
|
36
|
+
'(3) After editing .gd files on disk, run godot_editor restart — the editor does ' +
|
|
37
|
+
'not reliably rescan externally modified scripts.',
|
|
24
38
|
});
|
|
25
39
|
setMcpServer(server);
|
|
26
40
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,0BAA0B,EAC1B,yBAAyB,GAC1B,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACrF,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD,gBAAgB,EAAE,CAAC;AACnB,oBAAoB,EAAE,CAAC;AAEvB,MAAM,CAAC,KAAK,UAAU,IAAI;IACxB,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB;QACE,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,gBAAgB,EAAE;KAC5B,EACD;QACE,YAAY,EAAE;YACZ,KAAK,EAAE,EAAE;YACT,SAAS,EAAE,EAAE;YACb,OAAO,EAAE,EAAE;SACZ;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../src/tools/editor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,KAAK,EAAE,iBAAiB,EAAyB,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../src/tools/editor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,KAAK,EAAE,iBAAiB,EAAyB,MAAM,kBAAkB,CAAC;AAsIjF,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BA6JjB,CAAC;AAEH,eAAO,MAAM,WAAW,EAAe,iBAAiB,EAAE,CAAC"}
|
package/dist/tools/editor.js
CHANGED
|
@@ -157,7 +157,25 @@ export const editor = defineTool({
|
|
|
157
157
|
}
|
|
158
158
|
case 'screenshot_game': {
|
|
159
159
|
const result = await godot.sendCommand('capture_game_screenshot', { max_width: args.max_width });
|
|
160
|
-
|
|
160
|
+
const image = toImageContent(result.image_base64);
|
|
161
|
+
// Mesh-integrity advisory: corrupt procedural meshes render as "too
|
|
162
|
+
// dark / invisible" with NO error anywhere, so an agent's first
|
|
163
|
+
// hypothesis is lighting and it tunes instead of validating. The
|
|
164
|
+
// warnings ride the screenshot response itself (no extra round-trip,
|
|
165
|
+
// no version-skew timeout) — the moment the agent LOOKS at the game
|
|
166
|
+
// is the moment they are actionable.
|
|
167
|
+
const warnings = result.mesh_warnings ?? [];
|
|
168
|
+
if (warnings.length > 0) {
|
|
169
|
+
return [
|
|
170
|
+
image,
|
|
171
|
+
{
|
|
172
|
+
type: 'text',
|
|
173
|
+
text: `⚠ Mesh integrity: ${warnings.join(' | ')}. ` +
|
|
174
|
+
'If the render looks wrong, this is likely why — run godot_validate_meshes for causes and fixes before tuning lights/materials.',
|
|
175
|
+
},
|
|
176
|
+
];
|
|
177
|
+
}
|
|
178
|
+
return image;
|
|
161
179
|
}
|
|
162
180
|
case 'screenshot_editor': {
|
|
163
181
|
const result = await godot.sendCommand('capture_editor_screenshot', { viewport: args.viewport, max_width: args.max_width });
|
package/dist/tools/editor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor.js","sourceRoot":"","sources":["../../src/tools/editor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAyB,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"editor.js","sourceRoot":"","sources":["../../src/tools/editor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAyB,MAAM,wBAAwB,CAAC;AA6B9E,SAAS,cAAc,CAAC,MAAc;IACpC,OAAO;QACL,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,WAAW;KACtB,CAAC;AACJ,CAAC;AAED,MAAM,YAAY,GAAG,CAAC;KACnB,kBAAkB,CAAC,QAAQ,EAAE;IAC5B,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,wEAAwE,CAAC,EAAE,CAAC;IAC/H,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,QAAQ,CAAC,kCAAkC,CAAC,EAAE,CAAC;IAC7F,CAAC,CAAC,MAAM,CAAC;QACP,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,6BAA6B,CAAC;QACnE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;KACzD,CAAC;IACF,CAAC,CAAC,MAAM,CAAC;QACP,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC;QACpD,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iDAAiD,CAAC;QAC7F,MAAM,EAAE,CAAC;aACN,OAAO,EAAE;aACT,QAAQ,EAAE;aACV,QAAQ,CAAC,kIAAkI,CAAC;KAChJ,CAAC;IACF,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,0BAA0B,CAAC,EAAE,CAAC;IAC5E,CAAC,CAAC,MAAM,CAAC;QACP,MAAM,EAAE,CAAC;aACN,OAAO,CAAC,SAAS,CAAC;aAClB,QAAQ,CACP,+TAA+T,CAChU;QACH,IAAI,EAAE,CAAC;aACJ,OAAO,EAAE;aACT,QAAQ,EAAE;aACV,QAAQ,CAAC,kGAAkG,CAAC;KAChH,CAAC;IACF,CAAC,CAAC,MAAM,CAAC;QACP,MAAM,EAAE,CAAC;aACN,OAAO,CAAC,kBAAkB,CAAC;aAC3B,QAAQ,CACP,umBAAumB,CACxmB;QACH,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6CAA6C,CAAC;QACrF,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oDAAoD,CAAC;QAC5G,QAAQ,EAAE,CAAC;aACR,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;aACjC,QAAQ,EAAE;aACV,QAAQ,CAAC,uJAAuJ,CAAC;QACpK,KAAK,EAAE,CAAC;aACL,MAAM,EAAE;aACR,GAAG,EAAE;aACL,WAAW,EAAE;aACb,QAAQ,EAAE;aACV,QAAQ,CAAC,gOAAgO,CAAC;KAC9O,CAAC;IACF,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,QAAQ,CAAC,uCAAuC,CAAC,EAAE,CAAC;IACpG,CAAC,CAAC,MAAM,CAAC;QACP,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,QAAQ,CAAC,uDAAuD,CAAC;QACtG,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wIAAwI,CAAC;KAC1L,CAAC;IACF,CAAC,CAAC,MAAM,CAAC;QACP,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC,QAAQ,CAAC,yDAAyD,CAAC;QAC1G,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;QACtF,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wIAAwI,CAAC;KAC1L,CAAC;IACF,CAAC,CAAC,MAAM,CAAC;QACP,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,QAAQ,CAAC,wCAAwC,CAAC;QACvF,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2CAA2C,CAAC;QACrF,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2CAA2C,CAAC;QACrF,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yCAAyC,CAAC;KAC3F,CAAC;CACH,CAAC;IACF,+EAA+E;KAC9E,MAAM,CACL,CAAC,IAAI,EAAE,EAAE,CACP,IAAI,CAAC,MAAM,KAAK,iBAAiB;IAC/B,CAAC,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;IACvF,CAAC,CAAC,IAAI,EACV,EAAE,OAAO,EAAE,sEAAsE,EAAE,CACpF,CAAC;AA2BJ,MAAM,CAAC,MAAM,MAAM,GAAG,UAAU,CAAC;IAC/B,IAAI,EAAE,cAAc;IACpB,WAAW,EAAE,EAAE,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE;IAC3G,WAAW,EACT,2KAA2K;IAC7K,MAAM,EAAE,YAAY;IACpB,KAAK,CAAC,OAAO,CAAC,IAAgB,EAAE,EAAE,KAAK,EAAE;QACvC,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC;YACpB,KAAK,WAAW,CAAC,CAAC,CAAC;gBACjB,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,WAAW,CAQnC,kBAAkB,CAAC,CAAC;gBACvB,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC;YAC5B,CAAC;YAED,KAAK,eAAe,CAAC,CAAC,CAAC;gBACrB,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,WAAW,CACpC,oBAAoB,CACrB,CAAC;gBACF,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACjC,OAAO,mBAAmB,CAAC;gBAC7B,CAAC;gBACD,OAAO,oBAAoB,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACjF,CAAC;YAED,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,MAAM,KAAK,CAAC,WAAW,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;gBACtE,OAAO,kBAAkB,IAAI,CAAC,SAAS,EAAE,CAAC;YAC5C,CAAC;YAED,KAAK,KAAK,CAAC,CAAC,CAAC;gBACX,MAAM,KAAK,CAAC,WAAW,CAAC,aAAa,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;gBAC7F,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;gBACzE,OAAO,IAAI,CAAC,MAAM;oBAChB,CAAC,CAAC,WAAW,MAAM,iEAAiE;oBACpF,CAAC,CAAC,WAAW,MAAM,EAAE,CAAC;YAC1B,CAAC;YAED,KAAK,MAAM,CAAC,CAAC,CAAC;gBACZ,MAAM,KAAK,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC;gBACxC,OAAO,iBAAiB,CAAC;YAC3B,CAAC;YAED,KAAK,SAAS,CAAC,CAAC,CAAC;gBACf,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC;gBAC/B,yEAAyE;gBACzE,uEAAuE;gBACvE,yEAAyE;gBACzE,0EAA0E;gBAC1E,gEAAgE;gBAChE,IAAI,CAAC;oBACH,MAAM,KAAK,CAAC,WAAW,CAAC,gBAAgB,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;gBACtD,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;oBACjE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;wBAC3C,MAAM,GAAG,CAAC;oBACZ,CAAC;gBACH,CAAC;gBACD,OAAO,uBAAuB,IAAI,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,iBAAiB,wFAAwF,CAAC;YAC5K,CAAC;YAED,KAAK,kBAAkB,CAAC,CAAC,CAAC;gBACxB,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,WAAW,CACpC,kBAAkB,EAClB;oBACE,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,KAAK;oBAC1B,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,EAAE;oBACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,KAAK;oBAChC,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,CAAC;iBACvB,CACF,CAAC;gBACF,yEAAyE;gBACzE,yEAAyE;gBACzE,yEAAyE;gBACzE,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;gBACjD,IAAI,MAAM,CAAC,cAAc,KAAK,CAAC,EAAE,CAAC;oBAChC,sEAAsE;oBACtE,mEAAmE;oBACnE,sEAAsE;oBACtE,gEAAgE;oBAChE,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;oBAChF,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,KAAK,SAAS;wBACnC,CAAC,CAAC,UAAU,GAAG,yBAAyB,MAAM,CAAC,MAAM,GAAG;wBACxD,CAAC,CAAC,MAAM,GAAG,oBAAoB,MAAM,CAAC,MAAM,IAAI,CAAC;oBACnD,OAAO,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;gBAClD,CAAC;gBACD,OAAO,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,GAAG,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YAC7E,CAAC;YAED,KAAK,iBAAiB,CAAC,CAAC,CAAC;gBACvB,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,WAAW,CAMnC,iBAAiB,CAAC,CAAC;gBACtB,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAChD,OAAO,0BAA0B,CAAC;gBACpC,CAAC;gBACD,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC;YAC5B,CAAC;YAED,KAAK,iBAAiB,CAAC,CAAC,CAAC;gBACvB,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,WAAW,CACpC,yBAAyB,EACzB,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAC9B,CAAC;gBACF,MAAM,KAAK,GAAG,cAAc,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;gBAClD,oEAAoE;gBACpE,gEAAgE;gBAChE,iEAAiE;gBACjE,qEAAqE;gBACrE,oEAAoE;gBACpE,qCAAqC;gBACrC,MAAM,QAAQ,GAAG,MAAM,CAAC,aAAa,IAAI,EAAE,CAAC;gBAC5C,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACxB,OAAO;wBACL,KAAK;wBACL;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EACF,qBAAqB,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI;gCAC7C,gIAAgI;yBACnI;qBACF,CAAC;gBACJ,CAAC;gBACD,OAAO,KAAK,CAAC;YACf,CAAC;YAED,KAAK,mBAAmB,CAAC,CAAC,CAAC;gBACzB,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,WAAW,CACpC,2BAA2B,EAC3B,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CACvD,CAAC;gBACF,OAAO,cAAc,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;YAC7C,CAAC;YAED,KAAK,iBAAiB,CAAC,CAAC,CAAC;gBACvB,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,WAAW,CAGnC,iBAAiB,EAAE;oBACpB,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,CAAC;oBAC5B,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,CAAC;oBAC5B,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,GAAG;iBACvB,CAAC,CAAC;gBACH,OAAO,8BAA8B,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;YACvI,CAAC;QACH,CAAC;IACH,CAAC;CACF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,MAAM,CAAwB,CAAC"}
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -13,4 +13,5 @@ export { profilerTools } from './profiler.js';
|
|
|
13
13
|
export { runtimeStateTools } from './runtime-state.js';
|
|
14
14
|
export { gameTimeTools } from './game-time.js';
|
|
15
15
|
export { execTools } from './exec.js';
|
|
16
|
+
export { validateMeshesTools } from './validate-meshes.js';
|
|
16
17
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAiBA,wBAAgB,gBAAgB,IAAI,IAAI,CAgBvC;AAED,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC"}
|
package/dist/tools/index.js
CHANGED
|
@@ -13,6 +13,7 @@ import { profilerTools } from './profiler.js';
|
|
|
13
13
|
import { runtimeStateTools } from './runtime-state.js';
|
|
14
14
|
import { gameTimeTools } from './game-time.js';
|
|
15
15
|
import { execTools } from './exec.js';
|
|
16
|
+
import { validateMeshesTools } from './validate-meshes.js';
|
|
16
17
|
export function registerAllTools() {
|
|
17
18
|
registry.registerTools(sceneTools);
|
|
18
19
|
registry.registerTools(nodeTools);
|
|
@@ -28,6 +29,7 @@ export function registerAllTools() {
|
|
|
28
29
|
registry.registerTools(runtimeStateTools);
|
|
29
30
|
registry.registerTools(gameTimeTools);
|
|
30
31
|
registry.registerTools(execTools);
|
|
32
|
+
registry.registerTools(validateMeshesTools);
|
|
31
33
|
}
|
|
32
34
|
export { sceneTools } from './scene.js';
|
|
33
35
|
export { nodeTools } from './node.js';
|
|
@@ -43,4 +45,5 @@ export { profilerTools } from './profiler.js';
|
|
|
43
45
|
export { runtimeStateTools } from './runtime-state.js';
|
|
44
46
|
export { gameTimeTools } from './game-time.js';
|
|
45
47
|
export { execTools } from './exec.js';
|
|
48
|
+
export { validateMeshesTools } from './validate-meshes.js';
|
|
46
49
|
//# sourceMappingURL=index.js.map
|
package/dist/tools/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE3D,MAAM,UAAU,gBAAgB;IAC9B,QAAQ,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IACnC,QAAQ,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;IAClC,QAAQ,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;IACpC,QAAQ,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;IACrC,QAAQ,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC;IACvC,QAAQ,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;IACrC,QAAQ,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;IACtC,QAAQ,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;IACrC,QAAQ,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;IAClC,QAAQ,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IACnC,QAAQ,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;IACtC,QAAQ,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAAC;IAC1C,QAAQ,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;IACtC,QAAQ,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;IAClC,QAAQ,CAAC,aAAa,CAAC,mBAAmB,CAAC,CAAC;AAC9C,CAAC;AAED,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { AnyToolDefinition } from '../core/types.js';
|
|
3
|
+
export declare const validateMeshes: import("../core/types.js").ToolDefinition<z.ZodObject<{
|
|
4
|
+
max_findings: z.ZodOptional<z.ZodNumber>;
|
|
5
|
+
}, z.core.$strip>>;
|
|
6
|
+
export declare const validateMeshesTools: AnyToolDefinition[];
|
|
7
|
+
//# sourceMappingURL=validate-meshes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-meshes.d.ts","sourceRoot":"","sources":["../../src/tools/validate-meshes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AA6B1D,eAAO,MAAM,cAAc;;kBAkDzB,CAAC;AAEH,eAAO,MAAM,mBAAmB,EAAuB,iBAAiB,EAAE,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { defineTool } from '../core/define-tool.js';
|
|
3
|
+
import { structured } from '../core/structured.js';
|
|
4
|
+
const ValidateMeshesSchema = z.object({
|
|
5
|
+
max_findings: z
|
|
6
|
+
.number()
|
|
7
|
+
.int()
|
|
8
|
+
.min(1)
|
|
9
|
+
.max(100)
|
|
10
|
+
.optional()
|
|
11
|
+
.describe('Cap on findings returned (default 25). The total count is always reported.'),
|
|
12
|
+
});
|
|
13
|
+
export const validateMeshes = defineTool({
|
|
14
|
+
name: 'godot_validate_meshes',
|
|
15
|
+
annotations: {
|
|
16
|
+
title: 'Validate Meshes',
|
|
17
|
+
readOnlyHint: true,
|
|
18
|
+
destructiveHint: false,
|
|
19
|
+
openWorldHint: false,
|
|
20
|
+
},
|
|
21
|
+
description: 'Check every code-built (ArrayMesh) surface in the RUNNING game for silent data corruption ' +
|
|
22
|
+
'that renders WITHOUT any error. Run this FIRST when rendering looks wrong and no error is ' +
|
|
23
|
+
'reported anywhere: surfaces pure black or far too dark, floors/walls invisible or ' +
|
|
24
|
+
'see-through, geometry visible from only one side, lighting that ignores light-energy ' +
|
|
25
|
+
'changes, scenes that "tuning" cannot fix. Detects: inside-out or mixed triangle winding ' +
|
|
26
|
+
'(Godot front faces wind clockwise — wrong winding = culled faces or inverted lighting ' +
|
|
27
|
+
'normals), dropped triangles / orphaned vertices (e.g. SurfaceTool.append_from of an ' +
|
|
28
|
+
'indexed mesh mixed with raw add_vertex silently discards most of the batch), degenerate ' +
|
|
29
|
+
'UVs that make generate_tangents() emit garbage, and NaN/zero normals or tangents. Every ' +
|
|
30
|
+
'finding includes its likely cause and the fix. Read-only and cheap. Walks the current ' +
|
|
31
|
+
'scene only (meshes parented elsewhere under root are not seen). Also run it after ' +
|
|
32
|
+
'writing or changing mesh-generation code — BEFORE spending time tuning lights or ' +
|
|
33
|
+
'materials to rescue a "too dark" scene.',
|
|
34
|
+
schema: ValidateMeshesSchema,
|
|
35
|
+
async execute(args, { godot }) {
|
|
36
|
+
const result = await godot.sendCommand('validate_meshes', {
|
|
37
|
+
max_findings: args.max_findings ?? 25,
|
|
38
|
+
});
|
|
39
|
+
// Nothing checked is NOT a clean bill — saying "no problems" over zero
|
|
40
|
+
// evidence is exactly the confident-lie failure mode this tool exists to
|
|
41
|
+
// prevent.
|
|
42
|
+
if (result.checked_surfaces === 0) {
|
|
43
|
+
const reason = result.note ?? 'the current scene has no code-built (ArrayMesh) triangle surfaces';
|
|
44
|
+
return (`No mesh data was validated (${reason}). ` +
|
|
45
|
+
'This is NOT a clean bill — nothing was checked. Engine primitives (BoxMesh, etc.) and ' +
|
|
46
|
+
'imported scenes parented outside the current scene are not covered.');
|
|
47
|
+
}
|
|
48
|
+
if (result.total_findings === 0) {
|
|
49
|
+
return (`Checked ${result.checked_meshes} meshes (${result.checked_surfaces} surfaces) — no integrity problems. ` +
|
|
50
|
+
'This rules out winding, dropped triangles, degenerate UVs/tangents, and NaN data. ' +
|
|
51
|
+
'If rendering still looks wrong, the cause is lighting or materials, not mesh data — ' +
|
|
52
|
+
'note that SDFGI replaces constant ambient light, so shadow-side fill must come from a ' +
|
|
53
|
+
'shadowless fill DirectionalLight rather than ambient_light_energy.');
|
|
54
|
+
}
|
|
55
|
+
return structured(result);
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
export const validateMeshesTools = [validateMeshes];
|
|
59
|
+
//# sourceMappingURL=validate-meshes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-meshes.js","sourceRoot":"","sources":["../../src/tools/validate-meshes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAoBnD,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,YAAY,EAAE,CAAC;SACZ,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,GAAG,CAAC;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,4EAA4E,CAAC;CAC1F,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,UAAU,CAAC;IACvC,IAAI,EAAE,uBAAuB;IAC7B,WAAW,EAAE;QACX,KAAK,EAAE,iBAAiB;QACxB,YAAY,EAAE,IAAI;QAClB,eAAe,EAAE,KAAK;QACtB,aAAa,EAAE,KAAK;KACrB;IACD,WAAW,EACT,4FAA4F;QAC5F,4FAA4F;QAC5F,oFAAoF;QACpF,uFAAuF;QACvF,0FAA0F;QAC1F,wFAAwF;QACxF,sFAAsF;QACtF,0FAA0F;QAC1F,0FAA0F;QAC1F,wFAAwF;QACxF,oFAAoF;QACpF,mFAAmF;QACnF,yCAAyC;IAC3C,MAAM,EAAE,oBAAoB;IAE5B,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE;QAC3B,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,WAAW,CAAyB,iBAAiB,EAAE;YAChF,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,EAAE;SACtC,CAAC,CAAC;QACH,uEAAuE;QACvE,yEAAyE;QACzE,WAAW;QACX,IAAI,MAAM,CAAC,gBAAgB,KAAK,CAAC,EAAE,CAAC;YAClC,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,IAAI,mEAAmE,CAAC;YAClG,OAAO,CACL,+BAA+B,MAAM,KAAK;gBAC1C,wFAAwF;gBACxF,qEAAqE,CACtE,CAAC;QACJ,CAAC;QACD,IAAI,MAAM,CAAC,cAAc,KAAK,CAAC,EAAE,CAAC;YAChC,OAAO,CACL,WAAW,MAAM,CAAC,cAAc,YAAY,MAAM,CAAC,gBAAgB,sCAAsC;gBACzG,oFAAoF;gBACpF,sFAAsF;gBACtF,wFAAwF;gBACxF,oEAAoE,CACrE,CAAC;QACJ,CAAC;QACD,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;CACF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,cAAc,CAAwB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@satelliteoflove/godot-mcp",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.23.1",
|
|
4
4
|
"description": "MCP server that gives AI assistants eyes and hands in the Godot editor: scene editing, input injection, deterministic game-time control, and live runtime state for agent-driven playtesting",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|