fix(camera-ai): smooth generated camera curves
This commit is contained in:
@@ -4169,31 +4169,122 @@ namespace Streamingle.Editor
|
||||
{
|
||||
var projectRoot = Directory.GetParent(Application.dataPath)?.FullName
|
||||
?? Environment.CurrentDirectory;
|
||||
return AICameraCliRunner.ResolveExecutable(
|
||||
return ResolveCliExecutablePath(
|
||||
ignoreConfigured ? string.Empty : _cliExecutable,
|
||||
_cwAiRoot,
|
||||
projectRoot);
|
||||
projectRoot,
|
||||
ResolvePhysicalPackageRoot());
|
||||
}
|
||||
|
||||
internal static string ResolveCliExecutablePath(
|
||||
string configuredExecutable,
|
||||
string cwAiRoot,
|
||||
string projectRoot,
|
||||
string packageRoot)
|
||||
{
|
||||
var normalizedConfigured = TryGetFullPath(configuredExecutable);
|
||||
if (!string.IsNullOrWhiteSpace(normalizedConfigured) &&
|
||||
!IsCameraAiPackageCachePath(normalizedConfigured) &&
|
||||
File.Exists(normalizedConfigured))
|
||||
{
|
||||
// A valid path outside PackageCache was explicitly selected by
|
||||
// the user and must remain authoritative.
|
||||
return normalizedConfigured;
|
||||
}
|
||||
|
||||
var normalizedPackageRoot = TryGetFullPath(packageRoot);
|
||||
if (!string.IsNullOrWhiteSpace(normalizedPackageRoot))
|
||||
{
|
||||
var packagedWorker = Path.Combine(
|
||||
normalizedPackageRoot,
|
||||
"Tools~",
|
||||
"CWCameraWorker",
|
||||
AICameraCliRunner.ExecutableName);
|
||||
if (File.Exists(packagedWorker))
|
||||
{
|
||||
return Path.GetFullPath(packagedWorker);
|
||||
}
|
||||
|
||||
packagedWorker = Path.Combine(
|
||||
normalizedPackageRoot,
|
||||
"Tools~",
|
||||
AICameraCliRunner.ExecutableName);
|
||||
if (File.Exists(packagedWorker))
|
||||
{
|
||||
return Path.GetFullPath(packagedWorker);
|
||||
}
|
||||
}
|
||||
|
||||
// Never fall back to a serialized worker or data root from an old
|
||||
// Git package revision merely because Unity has not evicted that
|
||||
// PackageCache directory yet.
|
||||
var safeConfigured = IsCameraAiPackageCachePath(configuredExecutable)
|
||||
? string.Empty
|
||||
: normalizedConfigured;
|
||||
var safeCwAiRoot = IsCameraAiPackageCachePath(cwAiRoot)
|
||||
? string.Empty
|
||||
: TryGetFullPath(cwAiRoot);
|
||||
return AICameraCliRunner.ResolveExecutable(
|
||||
safeConfigured,
|
||||
safeCwAiRoot,
|
||||
projectRoot,
|
||||
normalizedPackageRoot);
|
||||
}
|
||||
|
||||
internal static string ResolveDefaultCwAiRoot(
|
||||
string projectRoot,
|
||||
string configuredRoot)
|
||||
{
|
||||
return ResolveDefaultCwAiRoot(
|
||||
projectRoot,
|
||||
configuredRoot,
|
||||
ResolvePhysicalPackageRoot());
|
||||
}
|
||||
|
||||
internal static string ResolveDefaultCwAiRoot(
|
||||
string projectRoot,
|
||||
string configuredRoot,
|
||||
string packageRoot)
|
||||
{
|
||||
var normalizedProjectRoot = string.IsNullOrWhiteSpace(projectRoot)
|
||||
? Environment.CurrentDirectory
|
||||
: Path.GetFullPath(projectRoot);
|
||||
|
||||
var normalizedConfigured = TryGetFullPath(configuredRoot);
|
||||
if (!string.IsNullOrWhiteSpace(normalizedConfigured) &&
|
||||
!IsCameraAiPackageCachePath(normalizedConfigured) &&
|
||||
IsGenerationLibraryRoot(normalizedConfigured))
|
||||
{
|
||||
// Preserve a valid repository or data library that the user
|
||||
// explicitly selected outside Unity's PackageCache.
|
||||
return normalizedConfigured;
|
||||
}
|
||||
|
||||
var candidates = new List<string>();
|
||||
// Prefer the self-contained package, including Unity's resolved
|
||||
// Git PackageCache path. A stale serialized external CW-AI root
|
||||
// must not silently override the bundled reference library.
|
||||
candidates.AddRange(EnumeratePackagedRuntimeRoots(normalizedProjectRoot));
|
||||
candidates.Add(configuredRoot);
|
||||
candidates.Add(normalizedProjectRoot);
|
||||
var normalizedPackageRoot = TryGetFullPath(packageRoot);
|
||||
if (!string.IsNullOrWhiteSpace(normalizedPackageRoot))
|
||||
{
|
||||
candidates.Add(Path.Combine(
|
||||
normalizedPackageRoot,
|
||||
"RuntimeData~"));
|
||||
}
|
||||
|
||||
// This logical package path supports embedded/local packages when
|
||||
// FileUtil cannot resolve a physical path during early domain load.
|
||||
candidates.Add(Path.Combine(
|
||||
Directory.GetParent(normalizedProjectRoot)?.FullName ??
|
||||
normalizedProjectRoot,
|
||||
"CW-AI"));
|
||||
candidates.Add(Environment.CurrentDirectory);
|
||||
"Packages",
|
||||
"com.mingle.cw-ai",
|
||||
"RuntimeData~"));
|
||||
candidates.AddRange(new[]
|
||||
{
|
||||
normalizedProjectRoot,
|
||||
Path.Combine(
|
||||
Directory.GetParent(normalizedProjectRoot)?.FullName ??
|
||||
normalizedProjectRoot,
|
||||
"CW-AI"),
|
||||
Environment.CurrentDirectory
|
||||
});
|
||||
|
||||
foreach (var candidate in candidates)
|
||||
{
|
||||
@@ -4224,34 +4315,47 @@ namespace Streamingle.Editor
|
||||
"CW-AI");
|
||||
}
|
||||
|
||||
private static IEnumerable<string> EnumeratePackagedRuntimeRoots(
|
||||
string projectRoot)
|
||||
private static string ResolvePhysicalPackageRoot()
|
||||
{
|
||||
yield return Path.Combine(
|
||||
projectRoot,
|
||||
"Packages",
|
||||
"com.mingle.cw-ai",
|
||||
"RuntimeData~");
|
||||
var packageCache = Path.Combine(projectRoot, "Library", "PackageCache");
|
||||
if (!Directory.Exists(packageCache))
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
IEnumerable<string> matches;
|
||||
try
|
||||
{
|
||||
matches = Directory.EnumerateDirectories(
|
||||
packageCache,
|
||||
"com.mingle.cw-ai@*",
|
||||
SearchOption.TopDirectoryOnly);
|
||||
return TryGetFullPath(FileUtil.GetPhysicalPath(
|
||||
"Packages/com.mingle.cw-ai"));
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
yield break;
|
||||
return string.Empty;
|
||||
}
|
||||
foreach (var match in matches.OrderByDescending(path => path))
|
||||
}
|
||||
|
||||
private static bool IsCameraAiPackageCachePath(string candidate)
|
||||
{
|
||||
var fullPath = TryGetFullPath(candidate);
|
||||
if (string.IsNullOrWhiteSpace(fullPath))
|
||||
{
|
||||
yield return Path.Combine(match, "RuntimeData~");
|
||||
return false;
|
||||
}
|
||||
|
||||
var normalized = fullPath.Replace('\\', '/');
|
||||
return normalized.IndexOf(
|
||||
"/Library/PackageCache/com.mingle.cw-ai@",
|
||||
StringComparison.OrdinalIgnoreCase) >= 0;
|
||||
}
|
||||
|
||||
private static string TryGetFullPath(string candidate)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(candidate))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return Path.GetFullPath(candidate.Trim());
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4322,26 +4426,32 @@ namespace Streamingle.Editor
|
||||
currentRoot = string.Empty;
|
||||
}
|
||||
}
|
||||
if (string.Equals(
|
||||
currentRoot.TrimEnd('\\', '/'),
|
||||
resolvedRoot.TrimEnd('\\', '/'),
|
||||
var previousRoot = _cwAiRoot;
|
||||
var repairedLibraryRoot = !string.Equals(
|
||||
currentRoot.TrimEnd('\\', '/'),
|
||||
resolvedRoot.TrimEnd('\\', '/'),
|
||||
StringComparison.OrdinalIgnoreCase);
|
||||
if (repairedLibraryRoot)
|
||||
{
|
||||
_cwAiRoot = resolvedRoot;
|
||||
AppendLog(
|
||||
"[library-root-auto-repair] " +
|
||||
$"{previousRoot} -> {_cwAiRoot}");
|
||||
}
|
||||
|
||||
var previousExecutable = _cliExecutable;
|
||||
var resolvedExecutable = ResolveCliExecutable();
|
||||
if (!string.Equals(
|
||||
TryGetFullPath(previousExecutable),
|
||||
TryGetFullPath(resolvedExecutable),
|
||||
StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
_cliExecutable = resolvedExecutable;
|
||||
AppendLog(
|
||||
"[worker-path-auto-repair] " +
|
||||
$"{previousExecutable} -> {_cliExecutable}");
|
||||
}
|
||||
|
||||
var previousRoot = _cwAiRoot;
|
||||
_cwAiRoot = resolvedRoot;
|
||||
if (string.IsNullOrWhiteSpace(_cliExecutable) ||
|
||||
!File.Exists(_cliExecutable))
|
||||
{
|
||||
_cliExecutable = ResolveCliExecutable(true);
|
||||
}
|
||||
|
||||
AppendLog(
|
||||
"[library-root-auto-repair] " +
|
||||
$"{previousRoot} -> {_cwAiRoot}");
|
||||
return true;
|
||||
return repairedLibraryRoot;
|
||||
}
|
||||
|
||||
private static string ExistingDirectoryOrFallback(
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user