BVB Source Codes

CRYENGINE Show CharacterInstanceProcessing.cpp Source code

Return Download CRYENGINE: download CharacterInstanceProcessing.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. #include "stdafx.h"
  4. #include "CharacterInstanceProcessing.h"
  5.  
  6. #include "CharacterInstance.h"
  7. #include "CharacterManager.h"
  8. #include "Memory/Memory.h"
  9. #include "Memory/Pool.h"
  10. #include "Command_Buffer.h"
  11. #include <CryThreading/IJobManager_JobDelegator.h>
  12.  
  13. DECLARE_JOB("CommandBufferExecute", TCommandBufferExecuteJob, CharacterInstanceProcessing::CJob::Job_Execute);
  14.  
  15. namespace CharacterInstanceProcessing
  16. {
  17.  
  18. SContext::EState SStartAnimationProcessing::operator()(const SContext& ctx)
  19. {
  20.         DEFINE_PROFILER_FUNCTION();
  21.         CRY_ASSERT(ctx.state == SContext::EState::Unstarted);
  22.  
  23.         if (ctx.pParent)
  24.         {
  25.                 ctx.pInstance->SetupThroughParent(ctx.pParent);
  26.         }
  27.         else
  28.         {
  29.                 ctx.pInstance->SetupThroughParams(m_pParams);
  30.         }
  31.  
  32.         const uint32 wasAnimPlaying = ctx.pInstance->m_SkeletonAnim.m_IsAnimPlaying;
  33.  
  34.         ctx.pInstance->m_SkeletonAnim.m_IsAnimPlaying = false;
  35.         QuatTS location = ctx.pInstance->m_location;
  36.  
  37.         ctx.pInstance->m_SkeletonAnim.ProcessAnimations(location);
  38.  
  39.         if (!GetMemoryPool())
  40.                 return SContext::EState::Failure;
  41.  
  42.         CSkeletonPose* pSkeletonPose = ctx.pInstance->m_SkeletonAnim.m_pSkeletonPose;
  43.         if (!pSkeletonPose->PreparePoseDataAndLocatorWriteables(*GetMemoryPool()))
  44.                 return SContext::EState::Failure;
  45.  
  46.         ctx.pInstance->m_SkeletonAnim.PoseModifiersPrepare(location);
  47.  
  48.         auto result = ctx.pInstance->m_SkeletonAnim.FillCommandBuffer(location, *ctx.pCommandBuffer);
  49.         ctx.pInstance->m_SkeletonAnim.m_IsAnimPlaying = (result == CSkeletonAnim::EFillCommandBufferResult::AnimationPlaying);
  50.  
  51.         pSkeletonPose->m_physics.SetLocation(location);
  52.         pSkeletonPose->m_physics.Job_SynchronizeWithPhysicsPrepare(*GetMemoryPool());
  53.  
  54.         if (wasAnimPlaying && !ctx.pInstance->m_SkeletonAnim.m_IsAnimPlaying && ctx.pInstance->GetObjectType() == CGA)
  55.         {
  56.                 pSkeletonPose->m_physics.RequestForcedPostSynchronization();
  57.         }
  58.  
  59.         return SContext::EState::StartAnimationProcessed;
  60. }
  61.  
  62. SContext::EState SExecuteJob::operator()(const SContext& ctx)
  63. {
  64.         DEFINE_PROFILER_FUNCTION();
  65.         CRY_ASSERT(ctx.pInstance != nullptr);
  66.         CRY_ASSERT(ctx.pInstance->GetRefCount() > 0);
  67.  
  68.         if (ctx.state != SContext::EState::StartAnimationProcessed)
  69.                 return SContext::EState::Failure;
  70.  
  71.         if (ctx.pParent)
  72.         {
  73.                 CRY_ASSERT(ctx.pBone != nullptr);
  74.                 ctx.pInstance->m_location = ctx.pBone->GetAttWorldAbsolute();
  75.         }
  76.  
  77.         CSkeletonAnim& skelAnim = ctx.pInstance->m_SkeletonAnim;
  78.         if (!skelAnim.m_pSkeletonPose->m_bFullSkeletonUpdate)
  79.                 return SContext::EState::JobSkipped;
  80.  
  81.         CSkeletonPose* pSkeletonPose = skelAnim.m_pSkeletonPose;
  82.         if (!pSkeletonPose->GetPoseDataWriteable())
  83.                 return SContext::EState::Failure;
  84.  
  85.         if (!ctx.pCommandBuffer)
  86.                 return SContext::EState::Failure;
  87.  
  88.         ctx.pCommandBuffer->Execute();
  89.  
  90.         pSkeletonPose->GetPoseData().Validate(*pSkeletonPose->m_pInstance->m_pDefaultSkeleton);
  91.  
  92.         pSkeletonPose->m_pInstance->m_AttachmentManager.UpdateLocationsExceptExecute(
  93.                 *pSkeletonPose->GetPoseDataWriteable());
  94.  
  95.         pSkeletonPose->m_pInstance->m_AttachmentManager.UpdateLocationsExecute(
  96.           *pSkeletonPose->GetPoseDataWriteable());
  97.  
  98.         return SContext::EState::JobExecuted;
  99. }
  100.  
  101. SContext::EState SFinishAnimationComputations::operator()(const SContext& ctx)
  102. {
  103.         DEFINE_PROFILER_FUNCTION();
  104.         CRY_ASSERT(ctx.pInstance != nullptr);
  105.         CRY_ASSERT(ctx.pInstance->GetRefCount() > 0);
  106.  
  107.         // Finish Animation Computations has been called explicitly already
  108.         // earlier in the frame, so we don't need to process it again
  109.         if (ctx.state == SContext::EState::Finished)
  110.                 return ctx.state;
  111.  
  112.         CRY_ASSERT(ctx.state != SContext::EState::StartAnimationProcessed);
  113.         CRY_ASSERT(ctx.state != SContext::EState::Failure);
  114.  
  115.         // make sure that the job has been run or has been skipped
  116.         // for some reason (usually because we did not request a full skeleton update)
  117.         if (ctx.state == SContext::EState::JobExecuted || ctx.state == SContext::EState::JobSkipped)
  118.         {
  119.                 ctx.pInstance->m_SkeletonAnim.m_pSkeletonPose->SynchronizePoseDataAndLocatorWriteables();
  120.  
  121.                 ctx.pInstance->m_SkeletonAnim.m_pSkeletonPose->GetPoseData().ValidateRelative(
  122.                   *ctx.pInstance->m_pDefaultSkeleton);
  123.  
  124.                 // check if the oldest animation in the queue is still needed
  125.                 for (uint32 nVLayerNo = 0; nVLayerNo < numVIRTUALLAYERS; nVLayerNo++)
  126.                 {
  127.                         DynArray<CAnimation>& rAnimations =
  128.                           ctx.pInstance->m_SkeletonAnim.m_layers[nVLayerNo].m_transitionQueue.m_animations;
  129.  
  130.                         if (rAnimations.size() > 0 && rAnimations[0].GetRemoveFromQueue())
  131.                                 ctx.pInstance->m_SkeletonAnim.RemoveAnimFromFIFO(nVLayerNo, 0, true);
  132.                 }
  133.  
  134.                 // if the full job was executed, we do SkeletonPostProcess, otherwise we just do a
  135.                 // lightweight update to support fall&play
  136.                 if (ctx.state == SContext::EState::JobExecuted)
  137.                 {
  138.  
  139.                         ctx.pInstance->m_SkeletonAnim.m_pSkeletonPose->GetPoseData().ValidateRelative(
  140.                           *ctx.pInstance->m_pDefaultSkeleton);
  141.  
  142.                         QuatTS rPhysLocation = ctx.pInstance->m_location;
  143.                         ctx.pInstance->m_SkeletonPose.SkeletonPostProcess(
  144.                           ctx.pInstance->m_SkeletonPose.GetPoseDataExplicitWriteable());
  145.                         ctx.pInstance->m_skeletonEffectManager.Update(
  146.                           &ctx.pInstance->m_SkeletonAnim,
  147.                           &ctx.pInstance->m_SkeletonPose,
  148.                           rPhysLocation);
  149.  
  150.                         ctx.pInstance->m_SkeletonAnim.m_transformPinningPoseModifier.reset();
  151.                 }
  152.                 else
  153.                 {
  154.                         // This is currently not working 100%, if you look away while the character
  155.                         // is ragdollized, he will not blend into animation again.
  156.  
  157.                         // [*DavidR | 24/Jan/2011] Update Fall and Play's standup timer even when the postprocess step
  158.                         // is not invoked (usually when it is offscreen),
  159.                         // otherwise it would cause the character's pose to blend during 1 second after it reenters
  160.                         // the frustrum even if the standup anim has finished
  161.                         // (see CSkeletonPose::ProcessPhysicsFallAndPlay)
  162.                         // [*DavidR | 24/Jan/2011] ToDo: We may want to update more timers (e.g., lying timer) the
  163.                         // same way
  164.                         ctx.pInstance->m_SkeletonPose.m_physics.m_timeStandingUp +=
  165.                           static_cast<float>(__fsel(ctx.pInstance->m_SkeletonPose.m_physics.m_timeStandingUp,
  166.                                                     ctx.pInstance->m_fOriginalDeltaTime, 0.0f));
  167.                         ctx.pInstance->m_AttachmentManager.UpdateLocationsExecuteUnsafe(
  168.                           ctx.pInstance->m_SkeletonPose.GetPoseDataExplicitWriteable());
  169.                         ctx.pInstance->m_SkeletonAnim.PoseModifiersSwapBuffersAndClearActive();
  170.                 }
  171.         }
  172.  
  173.         ctx.pInstance->m_AttachmentManager.UpdateBindings();
  174.  
  175.         ctx.pInstance->ClearProcessingContext();
  176.  
  177.         return SContext::EState::Finished;
  178. }
  179.  
  180. void SContext::Initialize(CCharInstance* _pInst, const CAttachmentBONE* _pBone, const CCharInstance* _pParent, int _numChildren)
  181. {
  182.         pInstance = _pInst;
  183.         pBone = _pBone;
  184.         pParent = _pParent;
  185.         numChildren = _numChildren;
  186.         pCommandBuffer = (Command::CBuffer*)CharacterInstanceProcessing::GetMemoryPool()->Allocate(sizeof(Command::CBuffer));
  187.         job = CJob(this);
  188. }
  189.  
  190. bool SContext::IsInProgress() const
  191. {
  192.         return (state != EState::Unstarted)
  193.                 && (state != EState::Finished)
  194.                 && (state != EState::Failure);
  195. }
  196.  
  197. SContext& CContextQueue::AppendContext()
  198. {
  199.         CRY_ASSERT(m_numContexts < kMaxNumberOfCharacterInstanceProcessingContexts - 1);
  200.         m_contexts[m_numContexts] = SContext();
  201.         m_contexts[m_numContexts].slot = m_numContexts;
  202.         return m_contexts[m_numContexts++];
  203. }
  204.  
  205. void CContextQueue::ClearContexts()
  206. {
  207.         for (int i = 0; i < m_numContexts; ++i)
  208.         {
  209.                 auto& ctx = m_contexts[i];
  210.                 ctx.pInstance.reset();
  211.                 ctx.pBone = nullptr;
  212.                 ctx.pParent = nullptr;
  213.                 ctx.numChildren = 0;
  214.                 ctx.pCommandBuffer = nullptr;
  215.                 CRY_ASSERT(ctx.state == SContext::EState::Finished);
  216.                 ctx.state = SContext::EState::Unstarted;
  217.         }
  218.  
  219.         m_numContexts = 0;
  220. }
  221.  
  222. void CJob::Begin(bool bImmediate)
  223. {
  224.         if (m_jobState.IsRunning())
  225.         {
  226.                 CryFatalError("Animation Job started while already running!");
  227.                 return;
  228.         }
  229.  
  230.         if (bImmediate)
  231.         {
  232.                 Execute(true);
  233.                 return;
  234.         }
  235.  
  236.         TCommandBufferExecuteJob job;
  237.         job.SetClassInstance(this);
  238.         job.RegisterJobState(&m_jobState);
  239.         job.Run();
  240. }
  241.  
  242. void CJob::Wait() const
  243. {
  244.         DEFINE_PROFILER_FUNCTION();
  245.  
  246.         if (!m_jobState.IsRunning())
  247.                 return;
  248.         // wait for task to finish
  249.         gEnv->GetJobManager()->WaitForJob(m_jobState);
  250. }
  251.  
  252. void CJob::Job_Execute()
  253. {
  254.         // in the extremely unlikely case that there
  255.         // are two different character instances during the same frame
  256.         // that got the same address, the last one will be the only one
  257.         // that gets its AuxGeom drawn
  258.         Execute(false);
  259.         if (gEnv->pRenderer)
  260.         {
  261.                 gEnv->pRenderer->GetIRenderAuxGeom()->Commit(1);
  262.         }
  263. }
  264.  
  265. void CJob::Execute(bool bImmediate)
  266. {
  267.         CharacterInstanceProcessing::CContextQueue& queue = g_pCharacterManager->GetContextSyncQueue();
  268.  
  269.         CRY_ASSERT(m_pCtx->slot >= 0);
  270.         queue.ExecuteForContext(m_pCtx->slot, CharacterInstanceProcessing::SExecuteJob());
  271.         queue.ExecuteForDirectChildrenWithoutStateChange(
  272.           m_pCtx->slot, [bImmediate](CharacterInstanceProcessing::SContext& ctx)
  273.                 {
  274.                         ctx.pInstance->WaitForSkinningJob();
  275.                         ctx.job.Begin(bImmediate);
  276.           });
  277. }
  278.  
  279. Memory::CPoolFrameLocal* s_pMemoryPool = NULL;
  280.  
  281. bool InitializeMemoryPool()
  282. {
  283.         Memory::CContext& memoryContext = CAnimationContext::Instance().GetMemoryContext();
  284.         s_pMemoryPool = Memory::CPoolFrameLocal::Create(memoryContext, 256000);
  285.         if (!s_pMemoryPool)
  286.                 return false;
  287.  
  288.         return true;
  289. }
  290.  
  291. Memory::CPoolFrameLocal* GetMemoryPool()
  292. {
  293.         return s_pMemoryPool;
  294. }
  295.  
  296. }
  297.  
downloadCharacterInstanceProcessing.cpp Source code - Download CRYENGINE Source code
Related Source Codes/Software:
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top