当前位置: 首页 > news >正文

网站主机 分为域名查询网址

网站主机 分为,域名查询网址,网页装修设计,兰州装修公司ue5.5 gameanimationsample 先看动画蓝图 核心两个node 第一个是根据数据选择当前的pose 第二个是缓存一段历史记录,为第一个node选择的时候提供数据。 在animinstance的update方法中 每帧都更新这个函数,每帧更新trajectory的数据 看看第一个node的…

ue5.5   gameanimationsample

先看动画蓝图 核心两个node

第一个是根据数据选择当前的pose

 第二个是缓存一段历史记录,为第一个node选择的时候提供数据。

在animinstance的update方法中 每帧都更新这个函数,每帧更新trajectory的数据

看看第一个node的执行顺序

void FAnimNode_MotionMatching::UpdateAssetPlayer(const FAnimationUpdateContext& Context)void UPoseSearchLibrary::UpdateMotionMatchingState(const FAnimationUpdateContext& Context,const TArray<TObjectPtr<const UPoseSearchDatabase>>& Databases,float BlendTime,int32 MaxActiveBlends,const FFloatInterval& PoseJumpThresholdTime,float PoseReselectHistory,float SearchThrottleTime,const FFloatInterval& PlayRate,FMotionMatchingState& InOutMotionMatchingState,EPoseSearchInterruptMode InterruptMode,bool bShouldSearch,bool bShouldUseCachedChannelData,bool bDebugDrawQuery,bool bDebugDrawCurResult){...........//这里每帧都监听第二个节点,把history trajectory传过来const IPoseHistory* PoseHistory = nullptr;if (FPoseHistoryProvider* PoseHistoryProvider = Context.GetMessage<FPoseHistoryProvider>()){PoseHistory = &PoseHistoryProvider->GetPoseHistory();}FMemMark Mark(FMemStack::Get());const UAnimInstance* AnimInstance = Cast<const UAnimInstance>(Context.AnimInstanceProxy->GetAnimInstanceObject());check(AnimInstance);const UPoseSearchDatabase* CurrentResultDatabase = InOutMotionMatchingState.CurrentSearchResult.Database.Get();if (IsInvalidatingContinuingPose(InterruptMode, CurrentResultDatabase, Databases)){InOutMotionMatchingState.CurrentSearchResult.Reset();}FSearchContext SearchContext(0.f, &InOutMotionMatchingState.PoseIndicesHistory, InOutMotionMatchingState.CurrentSearchResult, PoseJumpThresholdTime);//addSearchContext.AddRole(DefaultRole, AnimInstance, PoseHistory);.........const FSearchResult NewSearchResult = Database->Search(SearchContext);.........
}UE::PoseSearch::FSearchResult UPoseSearchDatabase::Search(UE::PoseSearch::FSearchContext& SearchContext) const{.........Result = SearchPCAKDTree(SearchContext);.........
}UE::PoseSearch::FSearchResult UPoseSearchDatabase::SearchPCAKDTree(UE::PoseSearch::FSearchContext& SearchContext) const
{.........//channelTConstArrayView<float> QueryValues = SearchContext.GetOrBuildQuery(Schema);.........
}TConstArrayView<float> FSearchContext::GetOrBuildQuery(const UPoseSearchSchema* Schema)
{QUICK_SCOPE_CYCLE_COUNTER(STAT_PoseSearch_GetOrBuildQuery);check(Schema);if (const FCachedQuery* FoundCachedQuery = CachedQueries.FindByPredicate([Schema](const FCachedQuery& CachedQuery){return CachedQuery.GetSchema() == Schema;})){return FoundCachedQuery->GetValues();}return Schema->BuildQuery(*this);
}TConstArrayView<float> UPoseSearchSchema::BuildQuery(UE::PoseSearch::FSearchContext& SearchContext) const
{QUICK_SCOPE_CYCLE_COUNTER(STAT_PoseSearch_BuildQuery);SearchContext.AddNewFeatureVectorBuilder(this);for (const TObjectPtr<UPoseSearchFeatureChannel>& ChannelPtr : GetChannels()){ChannelPtr->BuildQuery(SearchContext);}return SearchContext.EditFeatureVector();
}void UPoseSearchFeatureChannel_GroupBase::BuildQuery(UE::PoseSearch::FSearchContext& SearchContext) const
{for (const TObjectPtr<UPoseSearchFeatureChannel>& SubChannelPtr : GetSubChannels()){if (const UPoseSearchFeatureChannel* SubChannel = SubChannelPtr.Get()){SubChannel->BuildQuery(SearchContext);}}
}//subchannel就是各种channel 的数组 比如position channel,velocity channelvoid UPoseSearchFeatureChannel_Position::BuildQuery(UE::PoseSearch::FSearchContext& SearchContext) const
{..............const FVector BonePosition = SearchContext.GetSamplePosition(SampleTimeOffset, OriginTimeOffset, SchemaBoneIdx, SchemaOriginBoneIdx, SampleRole, OriginRole, PermutationTimeType, &BonePositionWorld);...........}FVector FSearchContext::GetSamplePosition(float SampleTimeOffset, float OriginTimeOffset, int8 SchemaSampleBoneIdx, int8 SchemaOriginBoneIdx, const FRole& SampleRole, const FRole& OriginRole, EPermutationTimeType PermutationTimeType, const FVector* SampleBonePositionWorldOverride)
{float PermutationSampleTimeOffset = 0.f;float PermutationOriginTimeOffset = 0.f;UPoseSearchFeatureChannel::GetPermutationTimeOffsets(PermutationTimeType, DesiredPermutationTimeOffset, PermutationSampleTimeOffset, PermutationOriginTimeOffset);const float SampleTime = SampleTimeOffset + PermutationSampleTimeOffset;const float OriginTime = OriginTimeOffset + PermutationOriginTimeOffset;return GetSamplePositionInternal(SampleTime, OriginTime, SchemaSampleBoneIdx, SchemaOriginBoneIdx, SampleRole, OriginRole, SampleBonePositionWorldOverride);
}FVector FSearchContext::GetSamplePositionInternal(float SampleTime, float OriginTime, int8 SchemaSampleBoneIdx, int8 SchemaOriginBoneIdx, const FRole& SampleRole, const FRole& OriginRole, const FVector* SampleBonePositionWorldOverride)
{if (SampleBonePositionWorldOverride){const FTransform RootBoneTransform = GetWorldBoneTransformAtTime(OriginTime, OriginRole, RootSchemaBoneIdx);if (SchemaOriginBoneIdx == RootSchemaBoneIdx){return RootBoneTransform.InverseTransformPosition(*SampleBonePositionWorldOverride);}// @todo: validate this still works for when root bone is not Identityconst FTransform OriginBoneTransform = GetWorldBoneTransformAtTime(OriginTime, OriginRole, SchemaOriginBoneIdx);const FVector DeltaBoneTranslation = *SampleBonePositionWorldOverride - OriginBoneTransform.GetTranslation();return RootBoneTransform.InverseTransformVector(DeltaBoneTranslation);}const FTransform RootBoneTransform = GetWorldBoneTransformAtTime(OriginTime, OriginRole, RootSchemaBoneIdx);const FTransform SampleBoneTransform = GetWorldBoneTransformAtTime(SampleTime, SampleRole, SchemaSampleBoneIdx);if (SchemaOriginBoneIdx == RootSchemaBoneIdx){return RootBoneTransform.InverseTransformPosition(SampleBoneTransform.GetTranslation());}const FTransform OriginBoneTransform = GetWorldBoneTransformAtTime(OriginTime, OriginRole, SchemaOriginBoneIdx);const FVector DeltaBoneTranslation = SampleBoneTransform.GetTranslation() - OriginBoneTransform.GetTranslation();return RootBoneTransform.InverseTransformVector(DeltaBoneTranslation);
}//获得过程终于用到了const IPoseHistory* PoseHistory = GetPoseHistory(SampleRole);
FTransform FSearchContext::GetWorldBoneTransformAtTime(float SampleTime, const FRole& SampleRole, int8 SchemaBoneIdx)
{// CachedQueries.Last is the query we're building check(!CachedQueries.IsEmpty());const UPoseSearchSchema* Schema = CachedQueries.Last().GetSchema();check(Schema);TConstArrayView<FBoneReference> BoneReferences = Schema->GetBoneReferences(SampleRole);check(BoneReferences[SchemaBoneIdx].HasValidSetup());const FBoneIndexType BoneIndexType = BoneReferences[SchemaBoneIdx].BoneIndex;const uint32 SampleTimeHash = GetTypeHash(SampleTime);const uint32 SampleRoleHash = GetTypeHash(SampleRole);const uint32 SampleTimeAndRoleHash = HashCombineFast(SampleTimeHash, SampleRoleHash);const uint32 BoneIndexTypeHash = GetTypeHash(BoneIndexType);const uint32 BoneCachedTransformKey = HashCombineFast(SampleTimeAndRoleHash, BoneIndexTypeHash);if (const FTransform* CachedTransform = CachedTransforms.Find(BoneCachedTransformKey)){return *CachedTransform;}FTransform WorldBoneTransform;if (BoneIndexType == RootBoneIndexType){// we already tried querying the CachedTransforms so, let's search in TrajectoryWorldBoneTransform = GetWorldRootBoneTransformAtTime(SampleTime, SampleRole);}else // if (BoneIndexType != RootBoneIndexType){// searching for RootBoneIndexType in CachedTransformsstatic const uint32 RootBoneIndexTypeHash = GetTypeHash(RootBoneIndexType); // Note: static const, since RootBoneIndexType is a constantconst uint32 RootBoneCachedTransformKey = HashCombineFast(SampleTimeAndRoleHash, RootBoneIndexTypeHash);if (const FTransform* CachedTransform = CachedTransforms.Find(RootBoneCachedTransformKey)){WorldBoneTransform = *CachedTransform;}else{WorldBoneTransform = GetWorldRootBoneTransformAtTime(SampleTime, SampleRole);}// collecting the local bone transforms from the IPoseHistoryconst IPoseHistory* PoseHistory = GetPoseHistory(SampleRole);#if WITH_EDITORif (!PoseHistory){UE_LOG(LogPoseSearch, Error, TEXT("FSearchContext::GetWorldBoneTransformAtTime - Couldn't search for bones requested by %s, because no IPoseHistory has been found!"), *Schema->GetName());}else#endif // WITH_EDITOR{check(PoseHistory);const USkeleton* Skeleton = Schema->GetSkeleton(SampleRole);FTransform LocalBoneTransform;if (!PoseHistory->GetTransformAtTime(SampleTime, LocalBoneTransform, Skeleton, BoneIndexType, RootBoneIndexType)){if (Skeleton){if (!PoseHistory->IsEmpty()){UE_LOG(LogPoseSearch, Warning, TEXT("FSearchContext::GetWorldBoneTransformAtTime - Couldn't find BoneIndexType %d (%s) requested by %s"), BoneIndexType, *Skeleton->GetReferenceSkeleton().GetBoneName(BoneIndexType).ToString(), *Schema->GetName());}}else{UE_LOG(LogPoseSearch, Warning, TEXT("FSearchContext::GetWorldBoneTransformAtTime - Schema '%s' Skeleton is not properly set"), *Schema->GetName());}}WorldBoneTransform = LocalBoneTransform * WorldBoneTransform;}}CachedTransforms.Add(BoneCachedTransformKey) = WorldBoneTransform;return WorldBoneTransform;
}//这里就是第二个节点pose history  里面有 trajectory
bool FPoseHistory::GetTransformAtTime(float Time, FTransform& OutBoneTransform, const USkeleton* BoneIndexSkeleton, FBoneIndexType BoneIndexType, FBoneIndexType ReferenceBoneIndexType, bool bExtrapolate) const
{CheckThreadSafetyRead(ReadPoseDataThreadSafeCounter);static_assert(RootBoneIndexType == 0 && ComponentSpaceIndexType == FBoneIndexType(-1) && WorldSpaceIndexType == FBoneIndexType(-2)); // some assumptionscheck(BoneIndexType != ComponentSpaceIndexType && BoneIndexType != WorldSpaceIndexType);bool bSuccess = false;const bool bApplyComponentToWorld = ReferenceBoneIndexType == WorldSpaceIndexType;FTransform ComponentToWorld = FTransform::Identity;if (bApplyComponentToWorld){//就是这个和trajectory 联系上了ComponentToWorld = Trajectory.GetSampleAtTime(Time, bExtrapolate).GetTransform();ReferenceBoneIndexType = ComponentSpaceIndexType;}const FPoseData& ReadPoseData = GetReadPoseData();const int32 NumEntries = ReadPoseData.Entries.Num();if (NumEntries > 0){int32 NextIdx = 0;int32 PrevIdx = 0;if (NumEntries > 1){const int32 LowerBoundIdx = LowerBound(ReadPoseData.Entries.begin(), ReadPoseData.Entries.end(), Time, [](const FPoseHistoryEntry& Entry, float Value) { return Value > Entry.AccumulatedSeconds; });NextIdx = FMath::Clamp(LowerBoundIdx, 1, NumEntries - 1);PrevIdx = NextIdx - 1;}const FPoseHistoryEntry& PrevEntry = ReadPoseData.Entries[PrevIdx];const FPoseHistoryEntry& NextEntry = ReadPoseData.Entries[NextIdx];bSuccess = LerpEntries(Time, bExtrapolate, PrevEntry, NextEntry, BoneIndexSkeleton, ReadPoseData.LastUpdateSkeleton.Get(), ReadPoseData.BoneToTransformMap, BoneIndexType, ReferenceBoneIndexType, OutBoneTransform);if (bApplyComponentToWorld){OutBoneTransform *= ComponentToWorld;}}else{OutBoneTransform = ComponentToWorld;}return bSuccess;
}

关于pose history

FPoseHistory 里面有    FPoseSearchQueryTrajectory Trajectory;

就是

void FAnimNode_PoseSearchHistoryCollector::Evaluate_AnyThread(FPoseContext& Output)
{DECLARE_SCOPE_HIERARCHICAL_COUNTER_ANIMNODE(Evaluate_AnyThread);ANIM_MT_SCOPE_CYCLE_COUNTER_VERBOSE(PoseSearchHistoryCollector, !IsInGameThread());check(Output.AnimInstanceProxy);Super::Evaluate_AnyThread(Output);Source.Evaluate(Output);const bool bNeedsReset = bResetOnBecomingRelevant && UpdateCounter.HasEverBeenUpdated() && !UpdateCounter.WasSynchronizedCounter(Output.AnimInstanceProxy->GetUpdateCounter());FCSPose<FCompactPose> ComponentSpacePose;ComponentSpacePose.InitPose(Output.Pose);TArray<FBoneIndexType> RequiredBones;if (bCacheBones){RequiredBones = GetRequiredBones(Output.AnimInstanceProxy);}PoseHistory.EvaluateComponentSpace_AnyThread(Output.AnimInstanceProxy->GetDeltaSeconds(), ComponentSpacePose, bStoreScales,RootBoneRecoveryTime, RootBoneTranslationRecoveryRatio, RootBoneRotationRecoveryRatio, bNeedsReset, bCacheBones, RequiredBones, Output.Curve, MakeConstArrayView(CollectedCurves));bCacheBones = false;#if ENABLE_DRAW_DEBUG && ENABLE_ANIM_DEBUGFColor Color;
#if WITH_EDITORONLY_DATAColor = DebugColor.ToFColor(true);
#else // WITH_EDITORONLY_DATAColor = FLinearColor::Red.ToFColor(true);
#endif // WITH_EDITORONLY_DATAPoseHistory.DebugDraw(*Output.AnimInstanceProxy, Color);
#endif // ENABLE_DRAW_DEBUG && ENABLE_ANIM_DEBUG
}

FPoseHistory中Trajectory能确定控件的世界空间下的 pos和rotation

再配合CollectedBones确定的骨骼的历史记录

就能确定某个骨骼的历史 的世界坐标

来作为选择某个pose的支撑数据

在FSearchContext中

const IPoseHistory* GetPoseHistory(const FRole& Role) const { return PoseHistories[RoleToIndex[Role]]; }

资产方面 最重要的是要建立 pose search database 

schema最重要的是定义channel,从不同的维度去解析查找符合预期的pose

各种channel的定义

http://www.15wanjia.com/news/51422.html

相关文章:

  • 如何给网站做后台网络seo关键词优化技术
  • 网站没有备案信息该怎么做网球新闻最新消息
  • 网站后台密码存在哪seo网站优化推广
  • 化州网站开发公司百度竞价排名公司
  • 自己怎么做商城网站视频教程竞价推广怎么样
  • 东台专业做网站的公司百度秒收录软件工具
  • 做旅游网站的项目背景网站建设公司地址在哪
  • 北京公司网站建设推荐chatgpt入口
  • 建网站的软件seo百度站长工具
  • 新乡住房与城乡建设厅网站痘痘该如何去除效果好
  • 正规网站建设代理电子商务网站有哪些?
  • 全国备案网站数量免费模式营销案例
  • 做网站还需要买服务器么人力资源管理师
  • 网站服务器解决方案游戏挂机赚钱一小时20
  • 四川省建筑人才网个人中心烟台seo
  • 手机网站 pc网站模板网站产品推广
  • 做微信的微网站软文营销软文推广
  • 做外贸要看哪些网站福州seo代理商
  • 成都网站建设报价推广普通话宣传周
  • wordpress域名设置方法霸屏seo服务
  • 网站开发通常叫什么部门宁波seo推广费用
  • 东莞做网站seo今日小说排行榜百度搜索风云榜
  • 怎样帮别人做网站建设企业营销型网站
  • 做网站3年厦门百度开户
  • 提升访问境外网站速度网络营销的目的是
  • 做条形码哪个网站比较好网站网页的优化方法
  • 合肥网站建设-中国互联google国际版
  • 北京专业网站建设公司排名北京seo推广
  • 装修公司加盟哪家最好seo合作
  • 无锡市住房城乡建设委网站google chrome官网入口