// Copyright Epic Games, Inc. All Rights Reserved. #include "RigLogic.h" #include "DNAReader.h" #include "FMemoryResource.h" #include "RigInstance.h" #include "RigLogicModule.h" #include "Stats/Stats.h" #include "Stats/StatsHierarchical.h" #include "riglogic/RigLogic.h" #if STATS DEFINE_STAT(STAT_RigLogic_CalculationType); DEFINE_STAT(STAT_RigLogic_FloatingPointType); DEFINE_STAT(STAT_RigLogic_LOD); DEFINE_STAT(STAT_RigLogic_RBFSolverCount); DEFINE_STAT(STAT_RigLogic_NeuralNetworkCount); DEFINE_STAT(STAT_RigLogic_PSDCount); DEFINE_STAT(STAT_RigLogic_JointCount); DEFINE_STAT(STAT_RigLogic_JointDeltaValueCount); DEFINE_STAT(STAT_RigLogic_BlendShapeChannelCount); DEFINE_STAT(STAT_RigLogic_AnimatedMapCount); DEFINE_STAT(STAT_RigLogic_MapGUIToRawControlsTime); DEFINE_STAT(STAT_RigLogic_MapRawToGUIControlsTime); DEFINE_STAT(STAT_RigLogic_CalculateRBFControlsTime); DEFINE_STAT(STAT_RigLogic_CalculateMLControlsTime); DEFINE_STAT(STAT_RigLogic_CalculateControlsTime); DEFINE_STAT(STAT_RigLogic_CalculateJointsTime); DEFINE_STAT(STAT_RigLogic_CalculateBlendShapesTime); DEFINE_STAT(STAT_RigLogic_CalculateAnimatedMapsTime); #endif // STATS void FRigLogic::FRigLogicDeleter::operator()(rl4::RigLogic* Pointer) { rl4::RigLogic::destroy(Pointer); } static rl4::Configuration AdaptToRigLogicConfig(const FRigLogicConfiguration& Config) { rl4::Configuration Copy = {}; Copy.calculationType = static_cast(Config.CalculationType); Copy.loadJoints = Config.LoadJoints; Copy.loadBlendShapes = Config.LoadBlendShapes; Copy.loadAnimatedMaps = Config.LoadAnimatedMaps; Copy.loadMachineLearnedBehavior = Config.LoadMachineLearnedBehavior; Copy.loadRBFBehavior = Config.LoadRBFBehavior; Copy.loadTwistSwingBehavior = Config.LoadTwistSwingBehavior; Copy.translationType = static_cast(Config.TranslationType); Copy.rotationType = static_cast(Config.RotationType); Copy.rotationOrder = static_cast(Config.RotationOrder); Copy.scaleType = static_cast(Config.ScaleType); Copy.translationPruningThreshold = Config.TranslationPruningThreshold; Copy.rotationPruningThreshold = Config.RotationPruningThreshold; Copy.scalePruningThreshold = Config.ScalePruningThreshold; return Copy; } static FRigLogicConfiguration AdaptFromRigLogicConfig(const rl4::Configuration& Config) { FRigLogicConfiguration Copy = {}; Copy.CalculationType = static_cast(Config.calculationType); Copy.LoadJoints = Config.loadJoints; Copy.LoadBlendShapes = Config.loadBlendShapes; Copy.LoadAnimatedMaps = Config.loadAnimatedMaps; Copy.LoadMachineLearnedBehavior = Config.loadMachineLearnedBehavior; Copy.LoadRBFBehavior = Config.loadRBFBehavior; Copy.LoadTwistSwingBehavior = Config.loadTwistSwingBehavior; Copy.TranslationType = static_cast(Config.translationType); Copy.RotationType = static_cast(Config.rotationType); Copy.RotationOrder = static_cast(Config.rotationOrder); Copy.ScaleType = static_cast(Config.scaleType); Copy.TranslationPruningThreshold = Config.translationPruningThreshold; Copy.RotationPruningThreshold = Config.rotationPruningThreshold; Copy.ScalePruningThreshold = Config.scalePruningThreshold; return Copy; } FRigLogic::FRigLogic(const IDNAReader* Reader, const FRigLogicConfiguration& Config) : MemoryResource{FMemoryResource::SharedInstance()}, RigLogic{rl4::RigLogic::create(Reader->Unwrap(), AdaptToRigLogicConfig(Config), FMemoryResource::Instance())}, Configuration{AdaptFromRigLogicConfig(RigLogic->getConfiguration())} { } FRigLogic::~FRigLogic() = default; const FRigLogicConfiguration& FRigLogic::GetConfiguration() const { return Configuration; } uint16 FRigLogic::GetLODCount() const { return RigLogic->getLODCount(); } TArrayView FRigLogic::GetRBFSolverIndicesForLOD(uint16_t LOD) const { rl4::ConstArrayView Indices = RigLogic->getRBFSolverIndicesForLOD(LOD); return TArrayView{Indices.data(), static_cast(Indices.size())}; } TArrayView FRigLogic::GetNeuralNetworkIndicesForLOD(uint16_t LOD) const { rl4::ConstArrayView Indices = RigLogic->getNeuralNetworkIndicesForLOD(LOD); return TArrayView{Indices.data(), static_cast(Indices.size())}; } TArrayView FRigLogic::GetBlendShapeChannelIndicesForLOD(uint16_t LOD) const { rl4::ConstArrayView Indices = RigLogic->getBlendShapeChannelIndicesForLOD(LOD); return TArrayView{Indices.data(), static_cast(Indices.size())}; } TArrayView FRigLogic::GetAnimatedMapIndicesForLOD(uint16_t LOD) const { rl4::ConstArrayView Indices = RigLogic->getAnimatedMapIndicesForLOD(LOD); return TArrayView{Indices.data(), static_cast(Indices.size())}; } TArrayView FRigLogic::GetJointIndicesForLOD(uint16_t LOD) const { rl4::ConstArrayView Indices = RigLogic->getJointIndicesForLOD(LOD); return TArrayView{Indices.data(), static_cast(Indices.size())}; } TArrayView FRigLogic::GetNeutralJointValues() const { rl4::ConstArrayView Values = RigLogic->getNeutralJointValues(); return TArrayView{Values.data(), static_cast(Values.size())}; } TArrayView FRigLogic::GetJointVariableAttributeIndices(uint16 LOD) const { rl4::ConstArrayView Indices = RigLogic->getJointVariableAttributeIndices(LOD); return TArrayView{Indices.data(), static_cast(Indices.size())}; } uint16 FRigLogic::GetJointGroupCount() const { return RigLogic->getJointGroupCount(); } uint16 FRigLogic::GetNeuralNetworkCount() const { return RigLogic->getNeuralNetworkCount(); } uint16 FRigLogic::GetRBFSolverCount() const { return RigLogic->getRBFSolverCount(); } uint16 FRigLogic::GetMeshCount() const { return RigLogic->getMeshCount(); } uint16 FRigLogic::GetMeshRegionCount(uint16 MeshIndex) const { return RigLogic->getMeshRegionCount(MeshIndex); } TArrayView FRigLogic::GetNeuralNetworkIndices(uint16 MeshIndex, uint16 RegionIndex) const { rl4::ConstArrayView Indices = RigLogic->getNeuralNetworkIndices(MeshIndex, RegionIndex); return TArrayView{Indices.data(), static_cast(Indices.size())}; } void FRigLogic::MapGUIToRawControls(FRigInstance* Instance) const { #if STATS DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC() SCOPE_CYCLE_COUNTER(STAT_RigLogic_MapGUIToRawControlsTime); #endif // STATS #if CPUPROFILERTRACE_ENABLED TRACE_CPUPROFILER_EVENT_SCOPE_STR("FRigLogic::MapGUIToRawControls"); #endif // CPUPROFILERTRACE_ENABLED RigLogic->mapGUIToRawControls(Instance->Unwrap()); } void FRigLogic::MapRawToGUIControls(FRigInstance* Instance) const { #if STATS DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC() SCOPE_CYCLE_COUNTER(STAT_RigLogic_MapRawToGUIControlsTime); #endif // STATS #if CPUPROFILERTRACE_ENABLED TRACE_CPUPROFILER_EVENT_SCOPE_STR("FRigLogic::MapRawToGUIControls"); #endif // CPUPROFILERTRACE_ENABLED RigLogic->mapRawToGUIControls(Instance->Unwrap()); } void FRigLogic::CalculateControls(FRigInstance* Instance) const { #if STATS DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC() SCOPE_CYCLE_COUNTER(STAT_RigLogic_CalculateControlsTime); #endif // STATS #if CPUPROFILERTRACE_ENABLED TRACE_CPUPROFILER_EVENT_SCOPE_STR("FRigLogic::CalculateControls"); #endif // CPUPROFILERTRACE_ENABLED RigLogic->calculateControls(Instance->Unwrap()); } void FRigLogic::CalculateMachineLearnedBehaviorControls(FRigInstance* Instance) const { #if STATS DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC() SCOPE_CYCLE_COUNTER(STAT_RigLogic_CalculateMLControlsTime); #endif // STATS #if CPUPROFILERTRACE_ENABLED TRACE_CPUPROFILER_EVENT_SCOPE_STR("FRigLogic::CalculateMachineLearnedBehaviorControls"); #endif // CPUPROFILERTRACE_ENABLED RigLogic->calculateMachineLearnedBehaviorControls(Instance->Unwrap()); } void FRigLogic::CalculateMachineLearnedBehaviorControls(FRigInstance* Instance, uint16 NeuralNetIndex) const { #if STATS DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC() SCOPE_CYCLE_COUNTER(STAT_RigLogic_CalculateMLControlsTime); #endif // STATS #if CPUPROFILERTRACE_ENABLED TRACE_CPUPROFILER_EVENT_SCOPE_STR("FRigLogic::CalculateMachineLearnedBehaviorControls"); #endif // CPUPROFILERTRACE_ENABLED RigLogic->calculateMachineLearnedBehaviorControls(Instance->Unwrap(), NeuralNetIndex); } void FRigLogic::CalculateRBFControls(FRigInstance* Instance) const { #if STATS DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC() SCOPE_CYCLE_COUNTER(STAT_RigLogic_CalculateRBFControlsTime); #endif // STATS #if CPUPROFILERTRACE_ENABLED TRACE_CPUPROFILER_EVENT_SCOPE_STR("FRigLogic::CalculateRBFControls"); #endif // CPUPROFILERTRACE_ENABLED RigLogic->calculateRBFControls(Instance->Unwrap()); } void FRigLogic::CalculateRBFControls(FRigInstance* Instance, uint16 SolverIndex) const { #if STATS DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC() SCOPE_CYCLE_COUNTER(STAT_RigLogic_CalculateRBFControlsTime); #endif // STATS #if CPUPROFILERTRACE_ENABLED TRACE_CPUPROFILER_EVENT_SCOPE_STR("FRigLogic::CalculateRBFControls"); #endif // CPUPROFILERTRACE_ENABLED RigLogic->calculateRBFControls(Instance->Unwrap(), SolverIndex); } void FRigLogic::CalculateJoints(FRigInstance* Instance) const { #if STATS DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC() SCOPE_CYCLE_COUNTER(STAT_RigLogic_CalculateJointsTime); #endif // STATS #if CPUPROFILERTRACE_ENABLED TRACE_CPUPROFILER_EVENT_SCOPE_STR("FRigLogic::CalculateJoints"); #endif // CPUPROFILERTRACE_ENABLED RigLogic->calculateJoints(Instance->Unwrap()); } void FRigLogic::CalculateJoints(FRigInstance* Instance, uint16 JointGroupIndex) const { #if STATS DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC() SCOPE_CYCLE_COUNTER(STAT_RigLogic_CalculateJointsTime); #endif // STATS #if CPUPROFILERTRACE_ENABLED TRACE_CPUPROFILER_EVENT_SCOPE_STR("FRigLogic::CalculateJoints"); #endif // CPUPROFILERTRACE_ENABLED RigLogic->calculateJoints(Instance->Unwrap(), JointGroupIndex); } void FRigLogic::CalculateBlendShapes(FRigInstance* Instance) const { #if STATS DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC() SCOPE_CYCLE_COUNTER(STAT_RigLogic_CalculateBlendShapesTime); #endif // STATS #if CPUPROFILERTRACE_ENABLED TRACE_CPUPROFILER_EVENT_SCOPE_STR("FRigLogic::CalculateBlendShapes"); #endif // CPUPROFILERTRACE_ENABLED RigLogic->calculateBlendShapes(Instance->Unwrap()); } void FRigLogic::CalculateAnimatedMaps(FRigInstance* Instance) const { #if STATS DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC() SCOPE_CYCLE_COUNTER(STAT_RigLogic_CalculateAnimatedMapsTime); #endif // STATS #if CPUPROFILERTRACE_ENABLED TRACE_CPUPROFILER_EVENT_SCOPE_STR("FRigLogic::CalculateAnimatedMaps"); #endif // CPUPROFILERTRACE_ENABLED RigLogic->calculateAnimatedMaps(Instance->Unwrap()); } void FRigLogic::Calculate(FRigInstance* Instance) const { #if STATS DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC() QUICK_SCOPE_CYCLE_COUNTER(STAT_RigLogic_Calculate); #endif // STATS #if CPUPROFILERTRACE_ENABLED TRACE_CPUPROFILER_EVENT_SCOPE_STR("FRigLogic::Calculate"); #endif // CPUPROFILERTRACE_ENABLED RigLogic->calculate(Instance->Unwrap()); } void FRigLogic::CollectCalculationStats(FRigInstance* Instance) const { #if STATS rl4::Stats Stats = {}; RigLogic->collectCalculationStats(Instance->Unwrap(), &Stats); SET_DWORD_STAT(STAT_RigLogic_CalculationType, Stats.calculationType); SET_DWORD_STAT(STAT_RigLogic_FloatingPointType, Stats.floatingPointType); SET_DWORD_STAT(STAT_RigLogic_LOD, Instance->GetLOD()); SET_DWORD_STAT(STAT_RigLogic_RBFSolverCount, Stats.rbfSolverCount); SET_DWORD_STAT(STAT_RigLogic_NeuralNetworkCount, Stats.neuralNetworkCount); SET_DWORD_STAT(STAT_RigLogic_PSDCount, Stats.psdCount); SET_DWORD_STAT(STAT_RigLogic_JointCount, Stats.jointCount); SET_DWORD_STAT(STAT_RigLogic_JointDeltaValueCount, Stats.jointDeltaValueCount); SET_DWORD_STAT(STAT_RigLogic_BlendShapeChannelCount, Stats.blendShapeChannelCount); SET_DWORD_STAT(STAT_RigLogic_AnimatedMapCount, Stats.animatedMapCount); #endif // STATS } rl4::RigLogic* FRigLogic::Unwrap() const { return RigLogic.Get(); }