diff --git a/01-Diary/周小结/2024.10.md b/01-Diary/周小结/2024.10.md index aa8237c..00eb56c 100644 --- a/01-Diary/周小结/2024.10.md +++ b/01-Diary/周小结/2024.10.md @@ -18,4 +18,5 @@ 1. 给新棚所有的电脑重装系统,安装所有驱动、更新BIOS。以及安装P4与拉取ASoul工程。 2. 2024心仪生日会 1. 添加心仪呆毛以及物理效果。 -3. 解决新棚手柄输入反应慢的问题。 \ No newline at end of file +3. 解决新棚手柄输入反应慢的问题。 +4. 解决 道具新投影仪播放节目会有拖影的问题。 \ No newline at end of file diff --git a/02-Note/DAWA/ASoul/动画相关/动捕逻辑.md b/02-Note/DAWA/ASoul/动画相关/动捕逻辑.md index 9bdb3f7..72e7be8 100644 --- a/02-Note/DAWA/ASoul/动画相关/动捕逻辑.md +++ b/02-Note/DAWA/ASoul/动画相关/动捕逻辑.md @@ -5,11 +5,17 @@ - TsMotionSenderActor(MotionSenderActor) # TsChingmuMocapReceiverActor +***地图里只会有一个生成的TsChingmuMocapReceiverActor来管理动捕数据接收*** 1. Init():在Server才会Spawn TsChingmuMocapReceiverActor。 2. ConnectChingMu():**ChingmuComp.StartConnectServer()** 3. Multicast_AligmMotionTime():寻找场景中的BP_MotionReceiver,并且调用Receiver.AlignTimeStamp()。 ## ChingmuMocapReceiverActor +核心逻辑: +- ***FChingmuThread::Run()*** +- ***AChingmuMocapReceiverActor::Tick()*** +- AChingmuMocapReceiverActor::DoSample() + ```c++ void AChingmuMocapReceiverActor::BeginPlay() { @@ -30,8 +36,69 @@ void AChingmuMocapReceiverActor::BeginPlay() } ``` + +```c++ +void AChingmuMocapReceiverActor::Tick(float DeltaTime) +{ + Super::Tick(DeltaTime); + + if(!Sender) + { + Sender = GetMotionSender(); + } + const auto CurTime = ULiveDirectorStatics::GetUnixTime(); + if(UseThread) + { + // 线程方式 + // 在数据队列中获取青瞳数据 + while (!FrameQueue.IsEmpty()) + { + ST_MocapFrameData* Frame; + if (FrameQueue.Dequeue(Frame)) + { + PutMocapDataIntoFrameList(Frame); + } + } + } + + DoSample(AllHumanFrames); + DoSample(AllRigidBodyFrames); + + // 每隔1s计算一次平均包间隔 + if (CurTime - LastCheckIntervalTime > 1000) + { + if (AllHumanFrames.Num() > 0) + { + AllHumanFrames[0]->CalculatePackageAverageInterval(this->PackageAverageInterval); + LastCheckIntervalTime = CurTime; + } + } +} +``` + +```c++ +void AChingmuMocapReceiverActor::DoSample(TArray& Frames) +{ + for (auto i = 0; i < Frames.Num(); i++) + { + Frames[i]->CheckSize(CacheLimit); + if (SampleByTimeStamp(Frames[i]->Frames)) + { + SendFrameToCharacter(); + } + } +} +``` ### FChingmuThread 用途为: +- 获取当前系统时间。 +- 使用异步Task的方式,通过调用**UChingMUComponent::FullBodyMotionCapBaseBonesLocalSpaceRotation()** 来更新每个演员的动捕数据。动捕数据存储在**ChingMUComponent**中的***LocalRotationList***、***GlobalLocationList***中。 +- 管理HumanToLastReceiveTime,以此管理每个动捕演员的动画数据时长。 +- OwnerActor->OnGetHumanData_NotInGameThread(), + - 根据当前时间与当前Frames,从UChingMUComponent中将数据复制到[[#ST_MocapFrameData]]中。 + - 将[[#ST_MocapFrameData]]转换成JSON后,使用AMotionSenderActor::OnGetRawMocapData_NotInGameThread()发送。 + - 将当前帧数据加入FrameQueue队列。 +- 线程睡眠0.001s。 ```c++ uint32 FChingmuThread::Run() @@ -53,7 +120,7 @@ uint32 FChingmuThread::Run() { HumanToLastReceiveTime.Add(HumanIndex, 0); } - if (HumanToLastReceiveTime[HumanIndex] != TmpTimeCode.Frames)//接收端时间与 + if (HumanToLastReceiveTime[HumanIndex] != TmpTimeCode.Frames)//判断是否收到新的Frame数据 { HumanToLastReceiveTime[HumanIndex] = TmpTimeCode.Frames; OwnerActor->OnGetHumanData_NotInGameThread(HumanIndex, CurTime, TmpTimeCode.Frames); @@ -101,7 +168,7 @@ uint32 FChingmuThread::Run() } ``` -## MocapData +## ST_MocapFrameData ```c++ #define MOCAP_BONE_COUNT 23 @@ -197,12 +264,22 @@ public: 2. Connect 1. StartConnectServer():motionCapturePlugin->ConnectCommand = "ConnectServer"。具体逻辑会在FMotionCapture::Tick()处理。 2. DisConnectServer():motionCapturePlugin->ConnectCommand = "DisConnect"。 -3. CalculateBoneCSRotation(): -4. +3. [[#CalculateBoneCSRotation()]] +4. [[#FullBodyMotionCapBaseBonesLocalSpaceRotation]] ### CalculateBoneCSRotation +> Get Human Fullbody Tracker data ,including of 23joints localRotation and root joint world Position +1. m_motioncap->CMHuman():调用DLL的CMHumanExtern(),获取一个Double数组,前3个是RootLocation,后面全是Rotation。 +2. 计算最终的四元数旋转值。 +3. 返回的形参 FQuat* BonesComponentSpaceRotation,数组指针。 +### FullBodyMotionCapBaseBonesLocalSpaceRotation +相比CalculateBoneCSRotation,增加了时间码以及GlobalLocation的动捕数据获取。 +1. m_motioncap->CMHuman():调用DLL的CMHumanExtern(),获取一个Double数组,前3个是RootLocation,后面全是Rotation。 +2. motionCapturePlugin->CMHumanGlobalRTTC():调用DLL的CMHumanGlobalRTTC(),1-24 New Features。计算**VrpnTimeCode**以及**GlobalLocationList**。 + +数据存在**ChingMUComponent**中的***LocalRotationList***、***GlobalLocationList***。 ## FAnimNode_ChingMUPose 1. Initialize_AnyThread():取得**ChingMUComponent**。 2. Update_AnyThread():调用**ChingMUComponent->CalculateBoneCSRotation()** @@ -215,8 +292,6 @@ public: ### AnimNode_ChingMURetargetPose::Evaluate_AnyThread() - - # TsMotionReceiverActor 只在BeginPlay()中调用了this.MarkAsClientSeamlessTravel(); 具体逻辑在`AMotionReceiverActor`