This commit is contained in:
2026-05-02 05:35:16 +09:00
parent 57aeba4bb8
commit e40a2a568e
36 changed files with 3198 additions and 411 deletions

View File

@@ -5,6 +5,7 @@ using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using KAsyncEngineLib;
using Tornado3_2026Election.Services;
if (args.Length > 0 && string.Equals(args[0], "--reflect-api", StringComparison.OrdinalIgnoreCase))
{
@@ -737,6 +738,70 @@ static Task<SaveSceneImageProbeResult> SaveSceneImageAsync(SaveSceneImageOptions
return;
}
if (options.CloneObject is not null)
{
Console.WriteLine(
$"[SAVE-IMAGE] Adding clone source={options.CloneObject.SourceObjectName} " +
$"variable={options.CloneObject.VariableName}...");
var sceneObject = scene.GetObject(options.CloneObject.SourceObjectName);
if (sceneObject is null)
{
completion.TrySetResult(
new SaveSceneImageProbeResult(true, "SUCCESS", "FAILED", options.OutputPath, $"Object '{options.CloneObject.SourceObjectName}' was not found."));
return;
}
handler.ResetAddCloneObjectTask();
scene.AddCloneObject(sceneObject, options.CloneObject.VariableName);
if (!WaitForTaskWithMessagePump(handler.AddCloneObjectTask, options.Connection.Timeout))
{
completion.TrySetResult(
new SaveSceneImageProbeResult(true, "SUCCESS", "TIMEOUT", options.OutputPath, $"OnAddCloneObject timed out for '{options.CloneObject.SourceObjectName}'." ));
return;
}
var cloneResult = handler.AddCloneObjectTask.Result;
if (cloneResult != eKResult.RESULT_SUCCESS)
{
completion.TrySetResult(
new SaveSceneImageProbeResult(true, "SUCCESS", cloneResult.ToString(), options.OutputPath, $"OnAddCloneObject result={cloneResult} source={options.CloneObject.SourceObjectName} variable={options.CloneObject.VariableName}"));
return;
}
}
if (options.VariableName is not null)
{
Console.WriteLine(
$"[SAVE-IMAGE] Setting variable name object={options.VariableName.ObjectName} " +
$"value={options.VariableName.VariableName}...");
var sceneObject = scene.GetObject(options.VariableName.ObjectName);
if (sceneObject is null)
{
completion.TrySetResult(
new SaveSceneImageProbeResult(true, "SUCCESS", "FAILED", options.OutputPath, $"Object '{options.VariableName.ObjectName}' was not found."));
return;
}
handler.ResetVariableNameTask();
sceneObject.SetVariableName(options.VariableName.VariableName);
if (!WaitForTaskWithMessagePump(handler.VariableNameTask, options.Connection.Timeout))
{
completion.TrySetResult(
new SaveSceneImageProbeResult(true, "SUCCESS", "TIMEOUT", options.OutputPath, $"OnSetVariableName timed out for '{options.VariableName.ObjectName}'." ));
return;
}
var variableNameResult = handler.VariableNameTask.Result;
if (variableNameResult != eKResult.RESULT_SUCCESS)
{
completion.TrySetResult(
new SaveSceneImageProbeResult(true, "SUCCESS", variableNameResult.ToString(), options.OutputPath, $"OnSetVariableName result={variableNameResult} object={options.VariableName.ObjectName}"));
return;
}
}
if (!string.IsNullOrWhiteSpace(options.SetObjectName))
{
Console.WriteLine($"[SAVE-IMAGE] Setting value object={options.SetObjectName}...");
@@ -797,6 +862,46 @@ static Task<SaveSceneImageProbeResult> SaveSceneImageAsync(SaveSceneImageOptions
}
}
if (options.MaterialOpacity is not null)
{
Console.WriteLine(
$"[SAVE-IMAGE] Setting material opacity object={options.MaterialOpacity.ObjectName} " +
$"value={options.MaterialOpacity.Opacity}...");
var sceneObject = scene.GetObject(options.MaterialOpacity.ObjectName);
if (sceneObject is null)
{
completion.TrySetResult(
new SaveSceneImageProbeResult(true, "SUCCESS", "FAILED", options.OutputPath, $"Object '{options.MaterialOpacity.ObjectName}' was not found."));
return;
}
var material = sceneObject.GetTargetMaterial(eKMaterialTarget.MATERIAL_TARGET_DEFAULT);
if (material is not IKAMaterial targetMaterial)
{
completion.TrySetResult(
new SaveSceneImageProbeResult(true, "SUCCESS", "FAILED", options.OutputPath, $"Object '{options.MaterialOpacity.ObjectName}' did not return a material."));
return;
}
handler.ResetMaterialOpacityTask();
targetMaterial.SetTransparencyOpacity(options.MaterialOpacity.Opacity);
if (!WaitForTaskWithMessagePump(handler.MaterialOpacityTask, options.Connection.Timeout))
{
completion.TrySetResult(
new SaveSceneImageProbeResult(true, "SUCCESS", "TIMEOUT", options.OutputPath, $"OnSetTransparencyOpacity timed out for '{options.MaterialOpacity.ObjectName}'." ));
return;
}
var opacityResult = handler.MaterialOpacityTask.Result;
if (opacityResult != eKResult.RESULT_SUCCESS)
{
completion.TrySetResult(
new SaveSceneImageProbeResult(true, "SUCCESS", opacityResult.ToString(), options.OutputPath, $"OnSetTransparencyOpacity result={opacityResult} object={options.MaterialOpacity.ObjectName}"));
return;
}
}
if (options.Size is not null)
{
Console.WriteLine(
@@ -828,30 +933,37 @@ static Task<SaveSceneImageProbeResult> SaveSceneImageAsync(SaveSceneImageOptions
}
}
var positionUpdates = new List<PositionUpdate>();
if (options.Position is not null)
{
positionUpdates.Add(options.Position);
}
positionUpdates.AddRange(options.Positions);
foreach (var positionUpdate in positionUpdates)
{
Console.WriteLine(
$"[SAVE-IMAGE] Setting position object={options.Position.ObjectName} " +
$"value=({options.Position.X},{options.Position.Y},{options.Position.Z}) vector={options.Position.VectorType}...");
var sceneObject = scene.GetObject(options.Position.ObjectName);
$"[SAVE-IMAGE] Setting position object={positionUpdate.ObjectName} " +
$"value=({positionUpdate.X},{positionUpdate.Y},{positionUpdate.Z}) vector={positionUpdate.VectorType}...");
var sceneObject = scene.GetObject(positionUpdate.ObjectName);
if (sceneObject is null)
{
completion.TrySetResult(
new SaveSceneImageProbeResult(true, "SUCCESS", "FAILED", options.OutputPath, $"Object '{options.Position.ObjectName}' was not found."));
new SaveSceneImageProbeResult(true, "SUCCESS", "FAILED", options.OutputPath, $"Object '{positionUpdate.ObjectName}' was not found."));
return;
}
handler.ResetPositionTask();
sceneObject.SetPosition(
options.Position.X,
options.Position.Y,
options.Position.Z,
options.Position.VectorType);
positionUpdate.X,
positionUpdate.Y,
positionUpdate.Z,
positionUpdate.VectorType);
if (!WaitForTaskWithMessagePump(handler.PositionTask, options.Connection.Timeout))
{
completion.TrySetResult(
new SaveSceneImageProbeResult(true, "SUCCESS", "TIMEOUT", options.OutputPath, $"OnSetPosition timed out for '{options.Position.ObjectName}'." ));
new SaveSceneImageProbeResult(true, "SUCCESS", "TIMEOUT", options.OutputPath, $"OnSetPosition timed out for '{positionUpdate.ObjectName}'." ));
return;
}
@@ -859,7 +971,7 @@ static Task<SaveSceneImageProbeResult> SaveSceneImageAsync(SaveSceneImageOptions
if (positionResult != eKResult.RESULT_SUCCESS)
{
completion.TrySetResult(
new SaveSceneImageProbeResult(true, "SUCCESS", positionResult.ToString(), options.OutputPath, $"OnSetPosition result={positionResult} object={options.Position.ObjectName}"));
new SaveSceneImageProbeResult(true, "SUCCESS", positionResult.ToString(), options.OutputPath, $"OnSetPosition result={positionResult} object={positionUpdate.ObjectName}"));
return;
}
}
@@ -3279,8 +3391,12 @@ internal sealed record SaveSceneImageOptions(
string? SetObjectValue,
string? VisibleObjectName,
bool? VisibleObjectValue,
VariableNameUpdate? VariableName,
CloneObjectUpdate? CloneObject,
MaterialOpacityUpdate? MaterialOpacity,
SizeUpdate? Size,
PositionUpdate? Position,
IReadOnlyList<PositionUpdate> Positions,
PositionKeyUpdate? PositionKey,
string? ChartObjectName,
string? ChartCsvPath,
@@ -3299,10 +3415,17 @@ internal sealed record SaveSceneImageOptions(
string? setObjectValue = null;
string? visibleObjectName = null;
bool? visibleObjectValue = null;
string? variableNameObjectName = null;
string? variableNameValue = null;
string? cloneSourceObjectName = null;
string? cloneVariableName = null;
string? materialOpacityObjectName = null;
float? materialOpacityValue = null;
string? sizeObjectName = null;
string? sizeRaw = null;
string? positionObjectName = null;
string? positionRaw = null;
string? positionsRaw = null;
string? positionKeyObjectName = null;
int positionKeyIndex = 1;
string? positionKeyRaw = null;
@@ -3346,6 +3469,25 @@ internal sealed record SaveSceneImageOptions(
_ => throw new ArgumentException("--visible must be true/false/1/0.")
};
break;
case "--variable-name-object" when index + 1 < args.Length:
variableNameObjectName = args[++index];
break;
case "--variable-name" when index + 1 < args.Length:
variableNameValue = args[++index];
break;
case "--clone-source" when index + 1 < args.Length:
cloneSourceObjectName = args[++index];
break;
case "--clone-name" when index + 1 < args.Length:
cloneVariableName = args[++index];
break;
case "--material-opacity-object" when index + 1 < args.Length:
materialOpacityObjectName = args[++index];
break;
case "--material-opacity" when index + 1 < args.Length && float.TryParse(args[index + 1], out var parsedMaterialOpacity):
materialOpacityValue = parsedMaterialOpacity;
index++;
break;
case "--size-object" when index + 1 < args.Length:
sizeObjectName = args[++index];
break;
@@ -3358,6 +3500,9 @@ internal sealed record SaveSceneImageOptions(
case "--position" when index + 1 < args.Length:
positionRaw = args[++index];
break;
case "--positions" when index + 1 < args.Length:
positionsRaw = args[++index];
break;
case "--position-key-object" when index + 1 < args.Length:
positionKeyObjectName = args[++index];
break;
@@ -3426,8 +3571,12 @@ internal sealed record SaveSceneImageOptions(
setObjectValue,
visibleObjectName,
visibleObjectValue,
ParseVariableName(variableNameObjectName, variableNameValue),
ParseCloneObject(cloneSourceObjectName, cloneVariableName),
ParseMaterialOpacity(materialOpacityObjectName, materialOpacityValue),
ParseSize(sizeObjectName, sizeRaw),
ParsePosition(positionObjectName, positionRaw),
ParsePositions(positionsRaw),
ParsePositionKey(positionKeyObjectName, positionKeyIndex, positionKeyRaw),
chartObjectName,
chartCsvPath,
@@ -3437,6 +3586,36 @@ internal sealed record SaveSceneImageOptions(
ParsePathModifications(modifyPathRaw));
}
private static CloneObjectUpdate? ParseCloneObject(string? sourceObjectName, string? variableName)
{
if (string.IsNullOrWhiteSpace(sourceObjectName) || string.IsNullOrWhiteSpace(variableName))
{
return null;
}
return new CloneObjectUpdate(sourceObjectName, variableName);
}
private static MaterialOpacityUpdate? ParseMaterialOpacity(string? objectName, float? opacity)
{
if (string.IsNullOrWhiteSpace(objectName) || !opacity.HasValue)
{
return null;
}
return new MaterialOpacityUpdate(objectName, opacity.Value);
}
private static VariableNameUpdate? ParseVariableName(string? objectName, string? variableName)
{
if (string.IsNullOrWhiteSpace(objectName) || string.IsNullOrWhiteSpace(variableName))
{
return null;
}
return new VariableNameUpdate(objectName, variableName);
}
private static SizeUpdate? ParseSize(string? objectName, string? raw)
{
if (string.IsNullOrWhiteSpace(objectName) || string.IsNullOrWhiteSpace(raw))
@@ -3487,6 +3666,32 @@ internal sealed record SaveSceneImageOptions(
return new PositionUpdate(objectName, x, y, z, vectorType);
}
private static IReadOnlyList<PositionUpdate> ParsePositions(string? raw)
{
if (string.IsNullOrWhiteSpace(raw))
{
return Array.Empty<PositionUpdate>();
}
var updates = new List<PositionUpdate>();
foreach (var token in raw.Split(';', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries))
{
var nameParts = token.Split('=', 2, StringSplitOptions.TrimEntries);
if (nameParts.Length != 2)
{
throw new ArgumentException($"Invalid position update: {token}");
}
var update = ParsePosition(nameParts[0], nameParts[1]);
if (update is not null)
{
updates.Add(update);
}
}
return updates;
}
private static PositionKeyUpdate? ParsePositionKey(string? objectName, int keyIndex, string? raw)
{
if (string.IsNullOrWhiteSpace(objectName) || string.IsNullOrWhiteSpace(raw))
@@ -3642,7 +3847,7 @@ internal sealed record SceneCatalogOptions(
public static SceneCatalogOptions Parse(string[] args)
{
var connection = ProbeOptions.Parse(args);
string? rootPath = null;
var rootPath = TornadoPathResolver.GetDefaultT3CutPath();
string? outputPath = null;
string? sceneFilter = null;
int? maxScenes = null;
@@ -3652,7 +3857,7 @@ internal sealed record SceneCatalogOptions(
switch (args[index])
{
case "--root" when index + 1 < args.Length:
rootPath = args[++index];
index++;
break;
case "--output" when index + 1 < args.Length:
outputPath = args[++index];
@@ -3667,12 +3872,6 @@ internal sealed record SceneCatalogOptions(
}
}
rootPath ??= Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
"Tornado3 Data",
"T3_Cut",
"T3_Cut");
if (!Directory.Exists(rootPath))
{
throw new DirectoryNotFoundException($"Catalog root path does not exist: {rootPath}");
@@ -3986,7 +4185,7 @@ internal sealed record FolderInspectionOptions(ProbeOptions Connection, string R
public static FolderInspectionOptions Parse(string[] args)
{
var connection = ProbeOptions.Parse(args);
string? rootPath = null;
var rootPath = TornadoPathResolver.GetDefaultT3CutPath();
string? outputPath = null;
string? sceneFilter = null;
int? maxScenes = null;
@@ -3996,7 +4195,7 @@ internal sealed record FolderInspectionOptions(ProbeOptions Connection, string R
switch (args[index])
{
case "--root" when index + 1 < args.Length:
rootPath = args[++index];
index++;
break;
case "--output" when index + 1 < args.Length:
outputPath = args[++index];
@@ -4011,11 +4210,6 @@ internal sealed record FolderInspectionOptions(ProbeOptions Connection, string R
}
}
if (string.IsNullOrWhiteSpace(rootPath))
{
throw new ArgumentException("--root is required.");
}
rootPath = Path.GetFullPath(rootPath);
outputPath ??= Path.Combine(Environment.CurrentDirectory, "TSCN_VARIABLE_DISCOVERY.md");
outputPath = Path.GetFullPath(outputPath);
@@ -4029,6 +4223,9 @@ internal sealed record ChartCellSnapshot(int Row, int Column, string Value);
internal sealed record ChartCellUpdate(int Row, int Column, float Value);
internal sealed record PathPoint3(float X, float Y, float Z);
internal sealed record SizeUpdate(string ObjectName, float Width, float Height);
internal sealed record VariableNameUpdate(string ObjectName, string VariableName);
internal sealed record CloneObjectUpdate(string SourceObjectName, string VariableName);
internal sealed record MaterialOpacityUpdate(string ObjectName, float Opacity);
internal sealed record PositionUpdate(string ObjectName, float X, float Y, float Z, eKVectorType VectorType);
internal sealed record PositionKeyUpdate(string ObjectName, int KeyIndex, float X, float Y, float Z, eKVectorType VectorType);
internal sealed record PathPointModification(int Index, float X, float Y, float Z, eKVectorType VectorType);
@@ -4176,6 +4373,9 @@ internal sealed class ProbeEventHandler : KAEventHandler
private TaskCompletionSource<eKResult> _counterNumberKeyTask = new(TaskCreationOptions.RunContinuationsAsynchronously);
private TaskCompletionSource<eKResult> _styleColorTask = new(TaskCreationOptions.RunContinuationsAsynchronously);
private TaskCompletionSource<eKResult> _visibleTask = new(TaskCreationOptions.RunContinuationsAsynchronously);
private TaskCompletionSource<eKResult> _variableNameTask = new(TaskCreationOptions.RunContinuationsAsynchronously);
private TaskCompletionSource<eKResult> _addCloneObjectTask = new(TaskCreationOptions.RunContinuationsAsynchronously);
private TaskCompletionSource<eKResult> _materialOpacityTask = new(TaskCreationOptions.RunContinuationsAsynchronously);
private TaskCompletionSource<eKResult> _setValueTask = new(TaskCreationOptions.RunContinuationsAsynchronously);
private TaskCompletionSource<eKResult> _sizeTask = new(TaskCreationOptions.RunContinuationsAsynchronously);
private TaskCompletionSource<eKResult> _saveSceneImageTask = new(TaskCreationOptions.RunContinuationsAsynchronously);
@@ -4203,6 +4403,12 @@ internal sealed class ProbeEventHandler : KAEventHandler
public Task<eKResult> VisibleTask => _visibleTask.Task;
public Task<eKResult> VariableNameTask => _variableNameTask.Task;
public Task<eKResult> AddCloneObjectTask => _addCloneObjectTask.Task;
public Task<eKResult> MaterialOpacityTask => _materialOpacityTask.Task;
public Task<eKResult> SetValueTask => _setValueTask.Task;
public Task<eKResult> SizeTask => _sizeTask.Task;
@@ -4235,6 +4441,12 @@ internal sealed class ProbeEventHandler : KAEventHandler
public void ResetVisibleTask() => _visibleTask = new TaskCompletionSource<eKResult>(TaskCreationOptions.RunContinuationsAsynchronously);
public void ResetVariableNameTask() => _variableNameTask = new TaskCompletionSource<eKResult>(TaskCreationOptions.RunContinuationsAsynchronously);
public void ResetAddCloneObjectTask() => _addCloneObjectTask = new TaskCompletionSource<eKResult>(TaskCreationOptions.RunContinuationsAsynchronously);
public void ResetMaterialOpacityTask() => _materialOpacityTask = new TaskCompletionSource<eKResult>(TaskCreationOptions.RunContinuationsAsynchronously);
public void ResetSetValueTask() => _setValueTask = new TaskCompletionSource<eKResult>(TaskCreationOptions.RunContinuationsAsynchronously);
public void ResetSizeTask() => _sizeTask = new TaskCompletionSource<eKResult>(TaskCreationOptions.RunContinuationsAsynchronously);
@@ -4363,7 +4575,6 @@ internal sealed class ProbeEventHandler : KAEventHandler
public void OnResetDuration(eKResult Result, string SceneName) { }
public void OnSetDuration(eKResult Result, string SceneName) { }
public void OnAddObject(eKResult Result, string SceneName) { }
public void OnAddCloneObject(eKResult Result, string SceneName) { }
public void OnUpdateThumbnail(eKResult Result, string SceneName) { }
public void OnExportVideo(eKResult Result, string SceneName) { }
public void OnStopVideoExporting(eKResult Result) { }
@@ -4462,6 +4673,21 @@ internal sealed class ProbeEventHandler : KAEventHandler
_visibleTask.TrySetResult(Result);
}
public void OnSetVariableName(eKResult Result, string SceneName, string ObjectName)
{
Console.WriteLine($"[SDK] OnSetVariableName result={Result} scene={SceneName} object={ObjectName}");
_variableNameTask.TrySetResult(Result);
}
public void OnAddCloneObject(eKResult Result, string SceneName)
{
Console.WriteLine($"[SDK] OnAddCloneObject result={Result} scene={SceneName}");
_addCloneObjectTask.TrySetResult(Result);
}
public void OnSetTransparencyOpacity(eKResult Result, string SceneName, string ObjectName)
{
Console.WriteLine($"[SDK] OnSetTransparencyOpacity result={Result} scene={SceneName} object={ObjectName}");
_materialOpacityTask.TrySetResult(Result);
}
public void OnSetValue(eKResult Result, string SceneName, string ObjectName)
{
if (Result != eKResult.RESULT_ERROR_NO_VARIABLE_OBJECT)
@@ -4573,7 +4799,6 @@ internal sealed class ProbeEventHandler : KAEventHandler
public void OnAddScrollObject(eKResult Result, string SceneName, string ObjectName) { }
public void OnAdjustScrollSpeed(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetScrollSpeed(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetVariableName(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetLoftPositionKey(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetChangeOut(eKResult Result, string SceneName) { }
public void OnModifyPathPoint(eKResult Result, string SceneName, string ObjectName)
@@ -4596,7 +4821,6 @@ internal sealed class ProbeEventHandler : KAEventHandler
public void OnSetColorKey(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetEmissiveColor(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetEmissiveColorKey(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetTransparencyOpacity(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetTransparencyOpacityKey(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetExposure(eKResult Result, string SceneName, string ObjectName) { }
public void OnSetExposureKey(eKResult Result, string SceneName, string ObjectName) { }