import { ToolDefinition, ToolResponse, ToolExecutor } from '../types';
export class SceneViewTools implements ToolExecutor {
getTools(): ToolDefinition[] {
return [
{
name: 'change_gizmo_tool',
description: 'Change Gizmo tool',
inputSchema: {
type: 'object',
properties: {
name: {
type: 'string',
description: 'Tool name',
enum: ['position', 'rotation', 'scale', 'rect']
}
},
required: ['name']
}
},
{
name: 'query_gizmo_tool_name',
description: 'Get current Gizmo tool name',
inputSchema: {
type: 'object',
properties: {}
}
},
{
name: 'change_gizmo_pivot',
description: 'Change transform pivot point',
inputSchema: {
type: 'object',
properties: {
name: {
type: 'string',
description: 'Pivot point',
enum: ['pivot', 'center']
}
},
required: ['name']
}
},
{
name: 'query_gizmo_pivot',
description: 'Get current Gizmo pivot point',
inputSchema: {
type: 'object',
properties: {}
}
},
{
name: 'query_gizmo_view_mode',
description: 'Query view mode (view/select)',
inputSchema: {
type: 'object',
properties: {}
}
},
{
name: 'change_gizmo_coordinate',
description: 'Change coordinate system',
inputSchema: {
type: 'object',
properties: {
type: {
type: 'string',
description: 'Coordinate system',
enum: ['local', 'global']
}
},
required: ['type']
}
},
{
name: 'query_gizmo_coordinate',
description: 'Get current coordinate system',
inputSchema: {
type: 'object',
properties: {}
}
},
{
name: 'change_view_mode_2d_3d',
description: 'Change 2D/3D view mode',
inputSchema: {
type: 'object',
properties: {
is2D: {
type: 'boolean',
description: '2D/3D view mode (true for 2D, false for 3D)'
}
},
required: ['is2D']
}
},
{
name: 'query_view_mode_2d_3d',
description: 'Get current view mode',
inputSchema: {
type: 'object',
properties: {}
}
},
{
name: 'set_grid_visible',
description: 'Show/hide grid',
inputSchema: {
type: 'object',
properties: {
visible: {
type: 'boolean',
description: 'Grid visibility'
}
},
required: ['visible']
}
},
{
name: 'query_grid_visible',
description: 'Query grid visibility status',
inputSchema: {
type: 'object',
properties: {}
}
},
{
name: 'set_icon_gizmo_3d',
description: 'Set IconGizmo to 3D or 2D mode',
inputSchema: {
type: 'object',
properties: {
is3D: {
type: 'boolean',
description: '3D/2D IconGizmo (true for 3D, false for 2D)'
}
},
required: ['is3D']
}
},
{
name: 'query_icon_gizmo_3d',
description: 'Query IconGizmo mode',
inputSchema: {
type: 'object',
properties: {}
}
},
{
name: 'set_icon_gizmo_size',
description: 'Set IconGizmo size',
inputSchema: {
type: 'object',
properties: {
size: {
type: 'number',
description: 'IconGizmo size',
minimum: 10,
maximum: 100
}
},
required: ['size']
}
},
{
name: 'query_icon_gizmo_size',
description: 'Query IconGizmo size',
inputSchema: {
type: 'object',
properties: {}
}
},
{
name: 'focus_camera_on_nodes',
description: 'Focus scene camera on nodes',
inputSchema: {
type: 'object',
properties: {
uuids: {
oneOf: [
{ type: 'array', items: { type: 'string' } },
{ type: 'null' }
],
description: 'Node UUIDs to focus on (null for all)'
}
},
required: ['uuids']
}
},
{
name: 'align_camera_with_view',
description: 'Apply scene camera position and angle to selected node',
inputSchema: {
type: 'object',
properties: {}
}
},
{
name: 'align_view_with_node',
description: 'Apply selected node position and angle to current view',
inputSchema: {
type: 'object',
properties: {}
}
},
{
name: 'get_scene_view_status',
description: 'Get comprehensive scene view status',
inputSchema: {
type: 'object',
properties: {}
}
},
{
name: 'reset_scene_view',
description: 'Reset scene view to default settings',
inputSchema: {
type: 'object',
properties: {}
}
}
];
}
async execute(toolName: string, args: any): Promise<ToolResponse> {
switch (toolName) {
case 'change_gizmo_tool':
return await this.changeGizmoTool(args.name);
case 'query_gizmo_tool_name':
return await this.queryGizmoToolName();
case 'change_gizmo_pivot':
return await this.changeGizmoPivot(args.name);
case 'query_gizmo_pivot':
return await this.queryGizmoPivot();
case 'query_gizmo_view_mode':
return await this.queryGizmoViewMode();
case 'change_gizmo_coordinate':
return await this.changeGizmoCoordinate(args.type);
case 'query_gizmo_coordinate':
return await this.queryGizmoCoordinate();
case 'change_view_mode_2d_3d':
return await this.changeViewMode2D3D(args.is2D);
case 'query_view_mode_2d_3d':
return await this.queryViewMode2D3D();
case 'set_grid_visible':
return await this.setGridVisible(args.visible);
case 'query_grid_visible':
return await this.queryGridVisible();
case 'set_icon_gizmo_3d':
return await this.setIconGizmo3D(args.is3D);
case 'query_icon_gizmo_3d':
return await this.queryIconGizmo3D();
case 'set_icon_gizmo_size':
return await this.setIconGizmoSize(args.size);
case 'query_icon_gizmo_size':
return await this.queryIconGizmoSize();
case 'focus_camera_on_nodes':
return await this.focusCameraOnNodes(args.uuids);
case 'align_camera_with_view':
return await this.alignCameraWithView();
case 'align_view_with_node':
return await this.alignViewWithNode();
case 'get_scene_view_status':
return await this.getSceneViewStatus();
case 'reset_scene_view':
return await this.resetSceneView();
default:
throw new Error(`Unknown tool: ${toolName}`);
}
}
private async changeGizmoTool(name: string): Promise<ToolResponse> {
return new Promise((resolve) => {
Editor.Message.request('scene', 'change-gizmo-tool', name).then(() => {
resolve({
success: true,
message: `Gizmo tool changed to '${name}'`
});
}).catch((err: Error) => {
resolve({ success: false, error: err.message });
});
});
}
private async queryGizmoToolName(): Promise<ToolResponse> {
return new Promise((resolve) => {
Editor.Message.request('scene', 'query-gizmo-tool-name').then((toolName: string) => {
resolve({
success: true,
data: {
currentTool: toolName,
message: `Current Gizmo tool: ${toolName}`
}
});
}).catch((err: Error) => {
resolve({ success: false, error: err.message });
});
});
}
private async changeGizmoPivot(name: string): Promise<ToolResponse> {
return new Promise((resolve) => {
Editor.Message.request('scene', 'change-gizmo-pivot', name).then(() => {
resolve({
success: true,
message: `Gizmo pivot changed to '${name}'`
});
}).catch((err: Error) => {
resolve({ success: false, error: err.message });
});
});
}
private async queryGizmoPivot(): Promise<ToolResponse> {
return new Promise((resolve) => {
Editor.Message.request('scene', 'query-gizmo-pivot').then((pivotName: string) => {
resolve({
success: true,
data: {
currentPivot: pivotName,
message: `Current Gizmo pivot: ${pivotName}`
}
});
}).catch((err: Error) => {
resolve({ success: false, error: err.message });
});
});
}
private async queryGizmoViewMode(): Promise<ToolResponse> {
return new Promise((resolve) => {
Editor.Message.request('scene', 'query-gizmo-view-mode').then((viewMode: string) => {
resolve({
success: true,
data: {
viewMode: viewMode,
message: `Current view mode: ${viewMode}`
}
});
}).catch((err: Error) => {
resolve({ success: false, error: err.message });
});
});
}
private async changeGizmoCoordinate(type: string): Promise<ToolResponse> {
return new Promise((resolve) => {
Editor.Message.request('scene', 'change-gizmo-coordinate', type).then(() => {
resolve({
success: true,
message: `Coordinate system changed to '${type}'`
});
}).catch((err: Error) => {
resolve({ success: false, error: err.message });
});
});
}
private async queryGizmoCoordinate(): Promise<ToolResponse> {
return new Promise((resolve) => {
Editor.Message.request('scene', 'query-gizmo-coordinate').then((coordinate: string) => {
resolve({
success: true,
data: {
coordinate: coordinate,
message: `Current coordinate system: ${coordinate}`
}
});
}).catch((err: Error) => {
resolve({ success: false, error: err.message });
});
});
}
private async changeViewMode2D3D(is2D: boolean): Promise<ToolResponse> {
return new Promise((resolve) => {
Editor.Message.request('scene', 'change-is2D', is2D).then(() => {
resolve({
success: true,
message: `View mode changed to ${is2D ? '2D' : '3D'}`
});
}).catch((err: Error) => {
resolve({ success: false, error: err.message });
});
});
}
private async queryViewMode2D3D(): Promise<ToolResponse> {
return new Promise((resolve) => {
Editor.Message.request('scene', 'query-is2D').then((is2D: boolean) => {
resolve({
success: true,
data: {
is2D: is2D,
viewMode: is2D ? '2D' : '3D',
message: `Current view mode: ${is2D ? '2D' : '3D'}`
}
});
}).catch((err: Error) => {
resolve({ success: false, error: err.message });
});
});
}
private async setGridVisible(visible: boolean): Promise<ToolResponse> {
return new Promise((resolve) => {
Editor.Message.request('scene', 'set-grid-visible', visible).then(() => {
resolve({
success: true,
message: `Grid ${visible ? 'shown' : 'hidden'}`
});
}).catch((err: Error) => {
resolve({ success: false, error: err.message });
});
});
}
private async queryGridVisible(): Promise<ToolResponse> {
return new Promise((resolve) => {
Editor.Message.request('scene', 'query-is-grid-visible').then((visible: boolean) => {
resolve({
success: true,
data: {
visible: visible,
message: `Grid is ${visible ? 'visible' : 'hidden'}`
}
});
}).catch((err: Error) => {
resolve({ success: false, error: err.message });
});
});
}
private async setIconGizmo3D(is3D: boolean): Promise<ToolResponse> {
return new Promise((resolve) => {
Editor.Message.request('scene', 'set-icon-gizmo-3d', is3D).then(() => {
resolve({
success: true,
message: `IconGizmo set to ${is3D ? '3D' : '2D'} mode`
});
}).catch((err: Error) => {
resolve({ success: false, error: err.message });
});
});
}
private async queryIconGizmo3D(): Promise<ToolResponse> {
return new Promise((resolve) => {
Editor.Message.request('scene', 'query-is-icon-gizmo-3d').then((is3D: boolean) => {
resolve({
success: true,
data: {
is3D: is3D,
mode: is3D ? '3D' : '2D',
message: `IconGizmo is in ${is3D ? '3D' : '2D'} mode`
}
});
}).catch((err: Error) => {
resolve({ success: false, error: err.message });
});
});
}
private async setIconGizmoSize(size: number): Promise<ToolResponse> {
return new Promise((resolve) => {
Editor.Message.request('scene', 'set-icon-gizmo-size', size).then(() => {
resolve({
success: true,
message: `IconGizmo size set to ${size}`
});
}).catch((err: Error) => {
resolve({ success: false, error: err.message });
});
});
}
private async queryIconGizmoSize(): Promise<ToolResponse> {
return new Promise((resolve) => {
Editor.Message.request('scene', 'query-icon-gizmo-size').then((size: number) => {
resolve({
success: true,
data: {
size: size,
message: `IconGizmo size: ${size}`
}
});
}).catch((err: Error) => {
resolve({ success: false, error: err.message });
});
});
}
private async focusCameraOnNodes(uuids: string[] | null): Promise<ToolResponse> {
return new Promise((resolve) => {
Editor.Message.request('scene', 'focus-camera', uuids || []).then(() => {
const message = uuids === null ?
'Camera focused on all nodes' :
`Camera focused on ${uuids.length} node(s)`;
resolve({
success: true,
message: message
});
}).catch((err: Error) => {
resolve({ success: false, error: err.message });
});
});
}
private async alignCameraWithView(): Promise<ToolResponse> {
return new Promise((resolve) => {
Editor.Message.request('scene', 'align-with-view').then(() => {
resolve({
success: true,
message: 'Scene camera aligned with current view'
});
}).catch((err: Error) => {
resolve({ success: false, error: err.message });
});
});
}
private async alignViewWithNode(): Promise<ToolResponse> {
return new Promise((resolve) => {
Editor.Message.request('scene', 'align-with-view-node').then(() => {
resolve({
success: true,
message: 'View aligned with selected node'
});
}).catch((err: Error) => {
resolve({ success: false, error: err.message });
});
});
}
private async getSceneViewStatus(): Promise<ToolResponse> {
return new Promise(async (resolve) => {
try {
// Gather all view status information
const [
gizmoTool,
gizmoPivot,
gizmoCoordinate,
viewMode2D3D,
gridVisible,
iconGizmo3D,
iconGizmoSize
] = await Promise.allSettled([
this.queryGizmoToolName(),
this.queryGizmoPivot(),
this.queryGizmoCoordinate(),
this.queryViewMode2D3D(),
this.queryGridVisible(),
this.queryIconGizmo3D(),
this.queryIconGizmoSize()
]);
const status: any = {
timestamp: new Date().toISOString()
};
// Extract data from fulfilled promises
if (gizmoTool.status === 'fulfilled' && gizmoTool.value.success) {
status.gizmoTool = gizmoTool.value.data.currentTool;
}
if (gizmoPivot.status === 'fulfilled' && gizmoPivot.value.success) {
status.gizmoPivot = gizmoPivot.value.data.currentPivot;
}
if (gizmoCoordinate.status === 'fulfilled' && gizmoCoordinate.value.success) {
status.coordinate = gizmoCoordinate.value.data.coordinate;
}
if (viewMode2D3D.status === 'fulfilled' && viewMode2D3D.value.success) {
status.is2D = viewMode2D3D.value.data.is2D;
status.viewMode = viewMode2D3D.value.data.viewMode;
}
if (gridVisible.status === 'fulfilled' && gridVisible.value.success) {
status.gridVisible = gridVisible.value.data.visible;
}
if (iconGizmo3D.status === 'fulfilled' && iconGizmo3D.value.success) {
status.iconGizmo3D = iconGizmo3D.value.data.is3D;
}
if (iconGizmoSize.status === 'fulfilled' && iconGizmoSize.value.success) {
status.iconGizmoSize = iconGizmoSize.value.data.size;
}
resolve({
success: true,
data: status
});
} catch (err: any) {
resolve({
success: false,
error: `Failed to get scene view status: ${err.message}`
});
}
});
}
private async resetSceneView(): Promise<ToolResponse> {
return new Promise(async (resolve) => {
try {
// Reset scene view to default settings
const resetActions = [
this.changeGizmoTool('position'),
this.changeGizmoPivot('pivot'),
this.changeGizmoCoordinate('local'),
this.changeViewMode2D3D(false), // 3D mode
this.setGridVisible(true),
this.setIconGizmo3D(true),
this.setIconGizmoSize(60)
];
await Promise.all(resetActions);
resolve({
success: true,
message: 'Scene view reset to default settings'
});
} catch (err: any) {
resolve({
success: false,
error: `Failed to reset scene view: ${err.message}`
});
}
});
}
}