BsAnimationManager.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsAnimationManager.h"
  4. #include "BsAnimation.h"
  5. #include "BsAnimationClip.h"
  6. #include "BsTaskScheduler.h"
  7. #include "BsTime.h"
  8. #include "BsCoreSceneManager.h"
  9. #include "BsCamera.h"
  10. #include "BsMorphShapes.h"
  11. #include "BsMeshData.h"
  12. #include "BsMeshUtility.h"
  13. namespace BansheeEngine
  14. {
  15. AnimationManager::AnimationManager()
  16. : mNextId(1), mUpdateRate(1.0f / 60.0f), mAnimationTime(0.0f), mLastAnimationUpdateTime(0.0f)
  17. , mNextAnimationUpdateTime(0.0f), mPaused(false), mWorkerRunning(false), mPoseReadBufferIdx(1)
  18. , mPoseWriteBufferIdx(0), mDataReadyCount(0), mDataReady(false)
  19. {
  20. mAnimationWorker = Task::create("Animation", std::bind(&AnimationManager::evaluateAnimation, this));
  21. mBlendShapeVertexDesc = VertexDataDesc::create();
  22. mBlendShapeVertexDesc->addVertElem(VET_FLOAT3, VES_POSITION, 1, 1);
  23. mBlendShapeVertexDesc->addVertElem(VET_UBYTE4_NORM, VES_NORMAL, 1, 1);
  24. }
  25. void AnimationManager::setPaused(bool paused)
  26. {
  27. mPaused = paused;
  28. }
  29. void AnimationManager::setUpdateRate(UINT32 fps)
  30. {
  31. if (fps == 0)
  32. fps = 1;
  33. mUpdateRate = 1.0f / fps;
  34. }
  35. void AnimationManager::preUpdate()
  36. {
  37. if (mPaused || !mWorkerRunning)
  38. return;
  39. mAnimationWorker->wait();
  40. // Make sure we don't load obsolete skeletal pose and other evaluation ouputs written by the animation thread
  41. std::atomic_thread_fence(std::memory_order_acquire);
  42. // Trigger events
  43. for (auto& anim : mAnimations)
  44. {
  45. anim.second->updateFromProxy();
  46. anim.second->triggerEvents(mAnimationTime, gTime().getFrameDelta());
  47. }
  48. mWorkerRunning = false;
  49. }
  50. void AnimationManager::postUpdate()
  51. {
  52. if (mPaused)
  53. return;
  54. mAnimationTime += gTime().getFrameDelta();
  55. if (mAnimationTime < mNextAnimationUpdateTime)
  56. return;
  57. mNextAnimationUpdateTime = Math::floor(mAnimationTime / mUpdateRate) * mUpdateRate + mUpdateRate;
  58. float timeDelta = mAnimationTime - mLastAnimationUpdateTime;
  59. mLastAnimationUpdateTime = mAnimationTime;
  60. // Update poses in the currently active buffer. Multi-buffering allows the core thread to safely read the
  61. // poses without worrying about them being overwritten by another call to postUpdate, as long as the simulation
  62. // thread doesn't go more than (CoreThread::NUM_SYNC_BUFFERS - 1) frames ahead.
  63. mProxies.clear();
  64. for (auto& anim : mAnimations)
  65. {
  66. anim.second->updateAnimProxy(timeDelta);
  67. mProxies.push_back(anim.second->mAnimProxy);
  68. }
  69. mCullFrustums.clear();
  70. auto& allCameras = gCoreSceneManager().getAllCameras();
  71. for(auto& entry : allCameras)
  72. {
  73. bool isOverlayCamera = entry.second.camera->getFlags().isSet(CameraFlag::Overlay);
  74. if (isOverlayCamera)
  75. continue;
  76. // TODO: Not checking if camera and animation renderable's layers match. If we checked more animations could
  77. // be culled.
  78. mCullFrustums.push_back(entry.second.camera->getWorldFrustum());
  79. }
  80. // Make sure thread finishes writing all changes to the anim proxies as they will be read by the animation thread
  81. std::atomic_thread_fence(std::memory_order_release);
  82. // Note: Animation thread will trigger about the same time as the core thread. The core thread will need to wait
  83. // until animation thread finishes, which might end up blocking it (and losing the multi-threading performance).
  84. // Consider delaying displayed animation for a single frame or pre-calculating animations (by advancing time the
  85. // previous frame) for non-dirty animations.
  86. TaskScheduler::instance().addTask(mAnimationWorker);
  87. mWorkerRunning = true;
  88. }
  89. void AnimationManager::evaluateAnimation()
  90. {
  91. // Make sure we don't load obsolete anim proxy data written by the simulation thread
  92. std::atomic_thread_fence(std::memory_order_acquire);
  93. // No need for locking, as we are sure that only postUpdate() writes to the proxy buffer, and increments the write
  94. // buffer index. And it's called sequentially ensuring previous call to evaluate finishes.
  95. UINT32 totalNumBones = 0;
  96. for (auto& anim : mProxies)
  97. {
  98. if (anim->skeleton != nullptr)
  99. totalNumBones += anim->skeleton->getNumBones();
  100. }
  101. RendererAnimationData& renderData = mAnimData[mPoseWriteBufferIdx];
  102. mPoseWriteBufferIdx = (mPoseWriteBufferIdx + 1) % CoreThread::NUM_SYNC_BUFFERS;
  103. renderData.transforms.resize(totalNumBones);
  104. UnorderedMap<UINT64, RendererAnimationData::AnimInfo> newAnimInfos;
  105. UINT32 curBoneIdx = 0;
  106. for(auto& anim : mProxies)
  107. {
  108. if(anim->mCullEnabled)
  109. {
  110. bool isVisible = false;
  111. for(auto& frustum : mCullFrustums)
  112. {
  113. if(frustum.intersects(anim->mBounds))
  114. {
  115. isVisible = true;
  116. break;
  117. }
  118. }
  119. if (!isVisible)
  120. continue;
  121. }
  122. RendererAnimationData::AnimInfo animInfo;
  123. bool hasAnimInfo = false;
  124. // Evaluate skeletal animation
  125. if (anim->skeleton != nullptr)
  126. {
  127. UINT32 numBones = anim->skeleton->getNumBones();
  128. RendererAnimationData::PoseInfo& poseInfo = animInfo.poseInfo;
  129. poseInfo.animId = anim->id;
  130. poseInfo.startIdx = curBoneIdx;
  131. poseInfo.numBones = numBones;
  132. memset(anim->skeletonPose.hasOverride, 0, sizeof(bool) * anim->skeletonPose.numBones);
  133. Matrix4* boneDst = renderData.transforms.data() + curBoneIdx;
  134. // Copy transforms from mapped scene objects
  135. UINT32 boneTfrmIdx = 0;
  136. for(UINT32 i = 0; i < anim->numSceneObjects; i++)
  137. {
  138. const AnimatedSceneObjectInfo& soInfo = anim->sceneObjectInfos[i];
  139. if (soInfo.boneIdx == -1)
  140. continue;
  141. boneDst[soInfo.boneIdx] = anim->sceneObjectTransforms[boneTfrmIdx];
  142. anim->skeletonPose.hasOverride[soInfo.boneIdx] = true;
  143. boneTfrmIdx++;
  144. }
  145. // Animate bones
  146. anim->skeleton->getPose(boneDst, anim->skeletonPose, anim->skeletonMask, anim->layers, anim->numLayers);
  147. curBoneIdx += numBones;
  148. hasAnimInfo = true;
  149. }
  150. else
  151. {
  152. RendererAnimationData::PoseInfo& poseInfo = animInfo.poseInfo;
  153. poseInfo.animId = anim->id;
  154. poseInfo.startIdx = 0;
  155. poseInfo.numBones = 0;
  156. }
  157. // Reset mapped SO transform
  158. for (UINT32 i = 0; i < anim->sceneObjectPose.numBones; i++)
  159. {
  160. anim->sceneObjectPose.positions[i] = Vector3::ZERO;
  161. anim->sceneObjectPose.rotations[i] = Quaternion::IDENTITY;
  162. anim->sceneObjectPose.scales[i] = Vector3::ONE;
  163. }
  164. // Update mapped scene objects
  165. memset(anim->sceneObjectPose.hasOverride, 1, sizeof(bool) * anim->numSceneObjects);
  166. // Update scene object transforms
  167. for(UINT32 i = 0; i < anim->numSceneObjects; i++)
  168. {
  169. const AnimatedSceneObjectInfo& soInfo = anim->sceneObjectInfos[i];
  170. // We already evaluated bones
  171. if (soInfo.boneIdx != -1)
  172. continue;
  173. if (soInfo.layerIdx == (UINT32)-1 || soInfo.stateIdx == (UINT32)-1)
  174. continue;
  175. const AnimationState& state = anim->layers[soInfo.layerIdx].states[soInfo.stateIdx];
  176. if (state.disabled)
  177. continue;
  178. {
  179. UINT32 curveIdx = soInfo.curveIndices.position;
  180. if (curveIdx != (UINT32)-1)
  181. {
  182. const TAnimationCurve<Vector3>& curve = state.curves->position[curveIdx].curve;
  183. anim->sceneObjectPose.positions[curveIdx] = curve.evaluate(state.time, state.positionCaches[curveIdx], state.loop);
  184. anim->sceneObjectPose.hasOverride[curveIdx] = false;
  185. }
  186. }
  187. {
  188. UINT32 curveIdx = soInfo.curveIndices.rotation;
  189. if (curveIdx != (UINT32)-1)
  190. {
  191. const TAnimationCurve<Quaternion>& curve = state.curves->rotation[curveIdx].curve;
  192. anim->sceneObjectPose.rotations[curveIdx] = curve.evaluate(state.time, state.rotationCaches[curveIdx], state.loop);
  193. anim->sceneObjectPose.rotations[curveIdx].normalize();
  194. anim->sceneObjectPose.hasOverride[curveIdx] = false;
  195. }
  196. }
  197. {
  198. UINT32 curveIdx = soInfo.curveIndices.scale;
  199. if (curveIdx != (UINT32)-1)
  200. {
  201. const TAnimationCurve<Vector3>& curve = state.curves->scale[curveIdx].curve;
  202. anim->sceneObjectPose.scales[curveIdx] = curve.evaluate(state.time, state.scaleCaches[curveIdx], state.loop);
  203. anim->sceneObjectPose.hasOverride[curveIdx] = false;
  204. }
  205. }
  206. }
  207. // Update generic curves
  208. // Note: No blending for generic animations, just use first animation
  209. if (anim->numLayers > 0 && anim->layers[0].numStates > 0)
  210. {
  211. const AnimationState& state = anim->layers[0].states[0];
  212. if (state.disabled)
  213. continue;
  214. {
  215. UINT32 numCurves = (UINT32)state.curves->generic.size();
  216. for (UINT32 i = 0; i < numCurves; i++)
  217. {
  218. const TAnimationCurve<float>& curve = state.curves->generic[i].curve;
  219. anim->genericCurveOutputs[i] = curve.evaluate(state.time, state.genericCaches[i], state.loop);
  220. }
  221. }
  222. }
  223. // Update morph shapes
  224. if(anim->numMorphShapes > 0)
  225. {
  226. auto iterFind = renderData.infos.find(anim->id);
  227. if (iterFind != renderData.infos.end())
  228. animInfo.morphShapeInfo = iterFind->second.morphShapeInfo;
  229. else
  230. animInfo.morphShapeInfo.version = 1; // 0 is considered invalid version
  231. // Recalculate weights if curves are present
  232. bool hasMorphCurves = false;
  233. for(UINT32 i = 0; i < anim->numMorphChannels; i++)
  234. {
  235. MorphChannelInfo& channelInfo = anim->morphChannelInfos[i];
  236. if(channelInfo.weightCurveIdx != (UINT32)-1)
  237. {
  238. channelInfo.weight = Math::clamp01(anim->genericCurveOutputs[channelInfo.weightCurveIdx]);
  239. hasMorphCurves = true;
  240. }
  241. float frameWeight;
  242. if (channelInfo.frameCurveIdx != (UINT32)-1)
  243. {
  244. frameWeight = Math::clamp01(anim->genericCurveOutputs[channelInfo.frameCurveIdx]);
  245. hasMorphCurves = true;
  246. }
  247. else
  248. frameWeight = 0.0f;
  249. if(channelInfo.shapeCount == 1)
  250. {
  251. MorphShapeInfo& shapeInfo = anim->morphShapeInfos[channelInfo.shapeStart];
  252. // Blend between base shape and the only available frame
  253. float relative = frameWeight - shapeInfo.frameWeight;
  254. if (relative <= 0.0f)
  255. {
  256. float diff = shapeInfo.frameWeight;
  257. if (diff > 0.0f)
  258. {
  259. float t = -relative / diff;
  260. shapeInfo.finalWeight = 1.0f - std::min(t, 1.0f);
  261. }
  262. else
  263. shapeInfo.finalWeight = 1.0f;
  264. }
  265. else // If past the final frame we clamp
  266. shapeInfo.finalWeight = 1.0f;
  267. }
  268. else if(channelInfo.shapeCount > 1)
  269. {
  270. for(UINT32 j = 0; j < channelInfo.shapeCount - 1; j++)
  271. {
  272. float prevShapeWeight;
  273. if (j > 0)
  274. prevShapeWeight = anim->morphShapeInfos[j - 1].frameWeight;
  275. else
  276. prevShapeWeight = 0.0f; // Base shape, blend between it and the first frame
  277. float nextShapeWeight = anim->morphShapeInfos[j + 1].frameWeight;
  278. MorphShapeInfo& shapeInfo = anim->morphShapeInfos[j];
  279. float relative = frameWeight - shapeInfo.frameWeight;
  280. if (relative <= 0.0f)
  281. {
  282. float diff = shapeInfo.frameWeight - prevShapeWeight;
  283. if (diff > 0.0f)
  284. {
  285. float t = -relative / diff;
  286. shapeInfo.finalWeight = 1.0f - std::min(t, 1.0f);
  287. }
  288. else
  289. shapeInfo.finalWeight = 1.0f;
  290. }
  291. else
  292. {
  293. float diff = nextShapeWeight - shapeInfo.frameWeight;
  294. if (diff > 0.0f)
  295. {
  296. float t = relative / diff;
  297. shapeInfo.finalWeight = std::min(t, 1.0f);
  298. }
  299. else
  300. shapeInfo.finalWeight = 0.0f;
  301. }
  302. }
  303. // Last frame
  304. {
  305. UINT32 lastFrame = channelInfo.shapeStart + channelInfo.shapeCount - 1;
  306. MorphShapeInfo& prevShapeInfo = anim->morphShapeInfos[lastFrame - 1];
  307. MorphShapeInfo& shapeInfo = anim->morphShapeInfos[lastFrame];
  308. float relative = frameWeight - shapeInfo.frameWeight;
  309. if (relative <= 0.0f)
  310. {
  311. float diff = shapeInfo.frameWeight - prevShapeInfo.frameWeight;
  312. if (diff > 0.0f)
  313. {
  314. float t = -relative / diff;
  315. shapeInfo.finalWeight = 1.0f - std::min(t, 1.0f);
  316. }
  317. else
  318. shapeInfo.finalWeight = 1.0f;
  319. }
  320. else // If past the final frame we clamp
  321. shapeInfo.finalWeight = 1.0f;
  322. }
  323. }
  324. for(UINT32 j = 0; j < channelInfo.shapeCount; j++)
  325. {
  326. MorphShapeInfo& shapeInfo = anim->morphShapeInfos[channelInfo.shapeStart + j];
  327. shapeInfo.finalWeight *= channelInfo.weight;
  328. }
  329. }
  330. // Generate morph shape vertices
  331. if(anim->morphChannelWeightsDirty || hasMorphCurves)
  332. {
  333. SPtr<MeshData> meshData = bs_shared_ptr_new<MeshData>(anim->numMorphVertices, 0, mBlendShapeVertexDesc);
  334. UINT8* bufferData = meshData->getData();
  335. memset(bufferData, 0, meshData->getSize());
  336. UINT32 tempDataSize = (sizeof(Vector3) + sizeof(float)) * anim->numMorphVertices;
  337. UINT8* tempData = (UINT8*)bs_stack_alloc(tempDataSize);
  338. memset(tempData, 0, tempDataSize);
  339. Vector3* tempNormals = (Vector3*)tempData;
  340. float* accumulatedWeight = (float*)(tempData + sizeof(Vector3) * anim->numMorphVertices);
  341. UINT8* positions = meshData->getElementData(VES_POSITION, 1, 1);
  342. UINT8* normals = meshData->getElementData(VES_NORMAL, 1, 1);
  343. UINT32 stride = mBlendShapeVertexDesc->getVertexStride(1);
  344. for(UINT32 i = 0; i < anim->numMorphShapes; i++)
  345. {
  346. const MorphShapeInfo& info = anim->morphShapeInfos[i];
  347. float absWeight = Math::abs(info.finalWeight);
  348. if (absWeight < 0.0001f)
  349. continue;
  350. const Vector<MorphVertex>& morphVertices = info.shape->getVertices();
  351. UINT32 numVertices = (UINT32)morphVertices.size();
  352. for(UINT32 j = 0; j < numVertices; j++)
  353. {
  354. const MorphVertex& vertex = morphVertices[j];
  355. Vector3* destPos = (Vector3*)(positions + vertex.sourceIdx * stride);
  356. *destPos += vertex.deltaPosition * info.finalWeight;
  357. tempNormals[vertex.sourceIdx] += vertex.deltaNormal * info.finalWeight;
  358. accumulatedWeight[vertex.sourceIdx] += absWeight;
  359. }
  360. }
  361. for(UINT32 i = 0; i < anim->numMorphVertices; i++)
  362. {
  363. PackedNormal* destNrm = (PackedNormal*)(normals + i * stride);
  364. if (accumulatedWeight[i] > 0.0001f)
  365. {
  366. Vector3 normal = tempNormals[i] / accumulatedWeight[i];
  367. normal /= 2.0f; // Accumulated normal is in range [-2, 2] but our normal packing method assumes [-1, 1] range
  368. MeshUtility::packNormals(&normal, (UINT8*)destNrm, 1, stride);
  369. destNrm->w = (UINT8)(std::min(1.0f, accumulatedWeight[i]) * 255.999f);
  370. }
  371. else
  372. {
  373. *destNrm = { 127, 127, 127, 0 };
  374. }
  375. }
  376. bs_stack_free(tempData);
  377. animInfo.morphShapeInfo.meshData = meshData;
  378. animInfo.morphShapeInfo.version++;
  379. anim->morphChannelWeightsDirty = false;
  380. }
  381. hasAnimInfo = true;
  382. }
  383. else
  384. animInfo.morphShapeInfo.version = 1;
  385. if (hasAnimInfo)
  386. newAnimInfos[anim->id] = animInfo;
  387. }
  388. renderData.infos = newAnimInfos;
  389. mDataReadyCount.fetch_add(1, std::memory_order_relaxed);
  390. // Make sure the thread finishes writing skeletal pose and other evaluation outputs as they will be read by sim and
  391. // core threads
  392. std::atomic_thread_fence(std::memory_order_release);
  393. }
  394. void AnimationManager::waitUntilComplete()
  395. {
  396. mAnimationWorker->wait();
  397. // Make sure we don't load obsolete skeletal pose and other evaluation ouputs written by the animation thread
  398. std::atomic_thread_fence(std::memory_order_acquire);
  399. INT32 dataReadyCount = mDataReadyCount.load(std::memory_order_relaxed);
  400. assert(dataReadyCount <= CoreThread::NUM_SYNC_BUFFERS);
  401. mDataReady = dataReadyCount > 0;
  402. if (!mDataReady)
  403. return;
  404. mDataReadyCount.fetch_add(-1, std::memory_order_relaxed);
  405. mPoseReadBufferIdx = (mPoseReadBufferIdx + 1) % CoreThread::NUM_SYNC_BUFFERS;
  406. }
  407. const RendererAnimationData& AnimationManager::getRendererData()
  408. {
  409. if (!mDataReady)
  410. {
  411. static RendererAnimationData dummy;
  412. return dummy;
  413. }
  414. return mAnimData[mPoseReadBufferIdx];
  415. }
  416. UINT64 AnimationManager::registerAnimation(Animation* anim)
  417. {
  418. mAnimations[mNextId] = anim;
  419. return mNextId++;
  420. }
  421. void AnimationManager::unregisterAnimation(UINT64 animId)
  422. {
  423. mAnimations.erase(animId);
  424. }
  425. AnimationManager& gAnimation()
  426. {
  427. return AnimationManager::instance();
  428. }
  429. }