BlueRoseNote/02-Note/DAWA/AI/UE_Cmd_AnimationRetargetingTool.md

180 lines
6.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 大致步骤
使用UnrealEditor-Cmd执行资源导入、处理、输出功能。
1. 导入资产 (这段可以参考FBX)
1. 角色
2. 动画 FBX
2. 处理资产
1. IKRig
2. RetargetRig
3. ControlRig?
3. 输出资产
1. FBX
2. 使用MovieRenderQueue 渲染 MP4
## 短期需求
1. AI 动捕、或者GPT生成 BVH、FBX。
2. 特定骨骼结构。
3. UE骨骼确定。
4. 可能需要高并发(后面再考虑)
5. 输出视频。
6. 工期1~2周。
## 需要解决的问题是
- [ ] 支持多种格式的文件
- [ ] `CustomCommandFunction`编写以及生成**IKRig**、**IKRetarget**资产
- [ ] 输出FBX或者MP4
## 输出文件
- *.BVH
-
## 生产环境
使用Docker或者其他容器工具制作处理用的镜像之后使用群集系统控制运行
## CustomCommandFunction
关检测 UCommandlet
# 测试方法
```bash
D:\UnrealEngine\UE_5.1\Engine\Binaries\Win64\UnrealEditor-Cmd.exe D:\UnrealEngine\Project\AIAutomationTools\AIAutomationTools.uproject -run=AIAnimationAutomationCommandlet
```
如果带有配置文件
```bash
D:\UnrealEngine\UE_5.1\Engine\Binaries\Win64\UnrealEditor-Cmd.exe D:\UnrealEngine\Project\AIAutomationTools\AIAutomationTools.uproject -run=AIAnimationAutomationCommandlet -importsettings=C:\\Users\\BlueRose\\Desktop\\ImportJson.json
```
```json
{
"ImportGroups": [
{
"GroupName": "Group11",
//导入文件名
"Filenames": [
"C:\\Users\\BlueRose\\Desktop\\untitled2_Anim.FBX"
],
//生成资产的文件夹
"DestinationPath": "Animation",
//使用的Factory类名
"FactoryName": "FbxFactory",
"bReplaceExisting": 1,
"bSkipReadOnly": 0,
//导入动画资产的设置
"ImportSettings": {
"OriginalImportType": 2,
"MeshTypeToImport": 2,
"Skeleton": "/Game/1/untitled2_Skeleton.untitled2_Skeleton"
}
}
]
}
```
# 其他资料
## IKRig & IKRetarget=
`Engine\Plugins\Animation\IKRig`
- FAssetTypeActions_AnimationAssetRetarget
- FAssetTypeActions_IKRigDefinition:UIKRigDefinition
- FAssetTypeActions_IKRetargeter:UIKRetargeter
## Retarger
```c++
/** The runtime processor that converts an input pose from a source skeleton into an output pose on a target skeleton.
* To use:
* 1. Initialize a processor with a Source/Target skeletal mesh and a UIKRetargeter asset.
* 2. Call RunRetargeter and pass in a source pose as an array of global-space transforms
* 3. RunRetargeter returns an array of global space transforms for the target skeleton.
/
```
## UEditorUtilityLibrary
##
Python参考
`Plugins\MovieScene\MovieRenderPipeline\Content\Python`
## 渲染影片(旧版)
MovieRenderPipelineCommandLine
```bash
"D:\Program Files\UE_4.24\Engine\Binaries\Win64\UE4Editor.exe"
D:\Projects\UnrealProjects\renderMovieTest\renderMovieTest.uproject
/Game/maps/shot0010
-MovieSceneCaptureType="/Script/MovieSceneCapture.AutomatedLevelSequenceCapture"
-LevelSequence="/Game/Sequences/Shot0010"
-MovieFolder="D:\Projects\UnrealProjects\renderMovieTest\outputs"
-NoLoadingScreen -game
```
void FMovieRenderPipelineCoreModule::StartupModule() 处理CommandLine变量
```c++
// Look to see if they supplied arguments on the command line indicating they wish to render a movie.
if (IsTryingToRenderMovieFromCommandLine(SequenceAssetValue, SettingsAssetValue, MoviePipelineLocalExecutorClassType, MoviePipelineClassType))
{
UE_LOG(LogMovieRenderPipeline, Log, TEXT("Detected that the user intends to render a movie. Waiting until engine loop init is complete to ensure "));
// Register a hook to wait until the engine has finished loading to increase the likelihood that the desired classes are loaded.
FCoreUObjectDelegates::PostLoadMapWithWorld.AddRaw(this, &FMovieRenderPipelineCoreModule::OnMapLoadFinished);
}
```
通过委托调用渲染最终到void FMovieRenderPipelineCoreModule::InitializeCommandLineMovieRender()
```c++
void FMovieRenderPipelineCoreModule::InitializeCommandLineMovieRender()
{
#if WITH_EDITOR
//const bool bIsGameMode = !GEditor;
//if (!bIsGameMode)
//{
// UE_LOG(LogMovieRenderPipeline, Fatal, TEXT("Command Line Renders must be performed in -game mode, otherwise use the editor ui/python and PIE. Add -game to your command line arguments."));
// FPlatformMisc::RequestExitWithStatus(false, MoviePipelineErrorCodes::Critical);
// return;
//}
#endif
// Attempt to convert their command line arguments into the required objects.
UMoviePipelineExecutorBase* ExecutorBase = nullptr;
UMoviePipelineQueue* Queue = nullptr;
uint8 ReturnCode = ParseMovieRenderData(SequenceAssetValue, SettingsAssetValue, MoviePipelineLocalExecutorClassType, MoviePipelineClassType,
/*Out*/ Queue, /*Out*/ ExecutorBase);
if (!ensureMsgf(ExecutorBase, TEXT("There was a failure parsing the command line and a movie render cannot be started. Check the log for more details.")))
{
// Take the failure return code from the detection of our command line arguments.
FPlatformMisc::RequestExitWithStatus(/*Force*/ false, /*ReturnCode*/ ReturnCode);
return;
}
else
{
UE_LOG(LogMovieRenderPipeline, Log, TEXT("Successfully detected and loaded required movie arguments. Rendering will begin once the map is loaded."));
if (Queue)
{
UE_LOG(LogMovieRenderPipeline, Log, TEXT("NumJobs: %d ExecutorClass: %s"), Queue->GetJobs().Num(), *ExecutorBase->GetClass()->GetName());
}
else
{
UE_LOG(LogMovieRenderPipeline, Log, TEXT("ExecutorClass: %s"), *ExecutorBase->GetClass()->GetName());
}
}
// We add the Executor to the root set. It will own all of the configuration data so this keeps it nicely in memory until finished,
// and means we only have to add/remove one thing from the root set, everything else uses normal outer ownership.
ExecutorBase->AddToRoot();
ExecutorBase->OnExecutorFinished().AddRaw(this, &FMovieRenderPipelineCoreModule::OnCommandLineMovieRenderCompleted);
ExecutorBase->OnExecutorErrored().AddRaw(this, &FMovieRenderPipelineCoreModule::OnCommandLineMovieRenderErrored);
ExecutorBase->Execute(Queue);
}
```
# 多线程
https://blog.csdn.net/j756915370/article/details/122752719
Runtime\Core\Public\Async\
- FFutureState
- FTaskGraphImplementation
### 2.6 TaskGraph 系统中的 Wait
在 TaskGraph 中,无论是 Event->Wait() 还是 FTaskGraphInterface::Get().WaitUntilTaskCompletes() ,最终都是调用到 FTaskGraphImplementation::WaitUntilTasksComplete 中的。