BsAnimationManager.cpp 15 KB

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