135 lines
4.4 KiB
C#
135 lines
4.4 KiB
C#
|
|
#if TOOLS
|
||
|
|
|
||
|
|
using Godot;
|
||
|
|
|
||
|
|
namespace Rokojori.Tools
|
||
|
|
{
|
||
|
|
using Rokojori;
|
||
|
|
|
||
|
|
public static class ReadSceneFragmentRoute
|
||
|
|
{
|
||
|
|
public static JSONObject ToolDefinition()
|
||
|
|
{
|
||
|
|
var filePathSchema = new JSONObject();
|
||
|
|
filePathSchema.Set( "type", "string" );
|
||
|
|
filePathSchema.Set( "description", "res:// path to the scene (.tscn)" );
|
||
|
|
|
||
|
|
var scenePathSchema = new JSONObject();
|
||
|
|
scenePathSchema.Set( "type", "array" );
|
||
|
|
scenePathSchema.Set( "description", "Child names from the scene root to the target node. Empty array = scene root." );
|
||
|
|
|
||
|
|
var levelSchema = new JSONObject();
|
||
|
|
levelSchema.Set( "type", "integer" );
|
||
|
|
levelSchema.Set( "description", "Descendant depth to include: 0 = all, 1 = direct children only, 2 = two levels, etc. Defaults to 0." );
|
||
|
|
|
||
|
|
var properties = new JSONObject();
|
||
|
|
properties.Set( "filePath", filePathSchema );
|
||
|
|
properties.Set( "scenePath", scenePathSchema );
|
||
|
|
properties.Set( "levelOfChildren", levelSchema );
|
||
|
|
|
||
|
|
var required = new JSONArray();
|
||
|
|
required.Push( "filePath" );
|
||
|
|
required.Push( "scenePath" );
|
||
|
|
|
||
|
|
var schema = new JSONObject();
|
||
|
|
schema.Set( "type", "object" );
|
||
|
|
schema.Set( "properties", properties );
|
||
|
|
schema.Set( "required", required );
|
||
|
|
|
||
|
|
var tool = new JSONObject();
|
||
|
|
tool.Set( "name", "read_scene_fragment" );
|
||
|
|
tool.Set( "description", "Read a node subtree out of a scene file without instantiating it." );
|
||
|
|
tool.Set( "inputSchema", schema );
|
||
|
|
|
||
|
|
return tool;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static ToolCallOutcome Execute( JSONObject arguments )
|
||
|
|
{
|
||
|
|
var filePath = JsonUtil.GetStringOrNull( arguments, "filePath" );
|
||
|
|
var scenePathArray = arguments != null ? arguments.GetArray( "scenePath" ) : null;
|
||
|
|
var levelData = arguments != null ? arguments.Get( "levelOfChildren" ) : null;
|
||
|
|
var levelOfChildren = levelData != null && levelData.isNumber ? levelData.intValue : 0;
|
||
|
|
|
||
|
|
if ( string.IsNullOrEmpty( filePath ) )
|
||
|
|
{
|
||
|
|
return ToolCallOutcome.Error( "Missing required argument: filePath" );
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( ! ResourceLoader.Exists( filePath, "PackedScene" ) )
|
||
|
|
{
|
||
|
|
return ToolCallOutcome.Error( "Scene not found: " + filePath );
|
||
|
|
}
|
||
|
|
|
||
|
|
var packedScene = ResourceLoader.Load<PackedScene>( filePath );
|
||
|
|
|
||
|
|
if ( packedScene == null )
|
||
|
|
{
|
||
|
|
return ToolCallOutcome.Error( "Failed to load scene: " + filePath );
|
||
|
|
}
|
||
|
|
|
||
|
|
var state = packedScene.GetState();
|
||
|
|
var scenePath = ScenePathResolver.ToStringArray( scenePathArray );
|
||
|
|
var targetRelativePath = ScenePathResolver.ToRelativePath( scenePath );
|
||
|
|
var targetIndex = ScenePathResolver.FindNodeIndex( state, targetRelativePath );
|
||
|
|
|
||
|
|
if ( targetIndex == -1 )
|
||
|
|
{
|
||
|
|
return ToolCallOutcome.Error( "Node not found at scenePath: " + targetRelativePath );
|
||
|
|
}
|
||
|
|
|
||
|
|
var startingLevels = levelOfChildren == 0 ? -1 : levelOfChildren;
|
||
|
|
var fragment = SerializeNode( state, targetIndex, targetRelativePath, startingLevels );
|
||
|
|
|
||
|
|
return ToolCallOutcome.Ok( JSON.Stringify( fragment ) );
|
||
|
|
}
|
||
|
|
|
||
|
|
static JSONObject SerializeNode( SceneState state, int index, string relativePath, int remainingLevels )
|
||
|
|
{
|
||
|
|
var obj = new JSONObject();
|
||
|
|
obj.Set( "name", state.GetNodeName( index ).ToString() );
|
||
|
|
obj.Set( "type", state.GetNodeType( index ).ToString() );
|
||
|
|
|
||
|
|
var properties = new JSONObject();
|
||
|
|
var propertyCount = state.GetNodePropertyCount( index );
|
||
|
|
|
||
|
|
for ( var i = 0; i < propertyCount; i++ )
|
||
|
|
{
|
||
|
|
var propName = state.GetNodePropertyName( index, i ).ToString();
|
||
|
|
var propValue = state.GetNodePropertyValue( index, i );
|
||
|
|
properties.Set( propName, VariantJson.ToJson( propValue ) );
|
||
|
|
}
|
||
|
|
|
||
|
|
obj.Set( "properties", properties );
|
||
|
|
|
||
|
|
if ( remainingLevels == 0 )
|
||
|
|
{
|
||
|
|
return obj;
|
||
|
|
}
|
||
|
|
|
||
|
|
var children = new JSONObject();
|
||
|
|
var nodeCount = state.GetNodeCount();
|
||
|
|
var nextLevels = remainingLevels == -1 ? -1 : remainingLevels - 1;
|
||
|
|
|
||
|
|
for ( var i = 0; i < nodeCount; i++ )
|
||
|
|
{
|
||
|
|
var candidatePath = state.GetNodePath( i, false ).ToString();
|
||
|
|
|
||
|
|
if ( ScenePathResolver.DepthOf( relativePath, candidatePath ) != 1 )
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
var childName = state.GetNodeName( i ).ToString();
|
||
|
|
children.Set( childName, SerializeNode( state, i, candidatePath, nextLevels ) );
|
||
|
|
}
|
||
|
|
|
||
|
|
obj.Set( "children", children );
|
||
|
|
|
||
|
|
return obj;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#endif
|