BsAnimation.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsAnimation.h"
  4. #include "BsAnimationManager.h"
  5. #include "BsAnimationClip.h"
  6. #include "BsAnimationUtility.h"
  7. #include "BsSceneObject.h"
  8. namespace BansheeEngine
  9. {
  10. AnimationClipInfo::AnimationClipInfo()
  11. : fadeDirection(0.0f), fadeTime(0.0f), fadeLength(0.0f), curveVersion(0), layerIdx((UINT32)-1), stateIdx((UINT32)-1)
  12. { }
  13. AnimationClipInfo::AnimationClipInfo(const HAnimationClip& clip)
  14. : fadeDirection(0.0f), fadeTime(0.0f), fadeLength(0.0f), clip(clip), curveVersion(0), layerIdx((UINT32)-1), stateIdx((UINT32)-1)
  15. { }
  16. Blend1DInfo::Blend1DInfo(UINT32 numClips)
  17. : clips(nullptr), numClips(numClips)
  18. {
  19. if (numClips > 0)
  20. clips = bs_newN<BlendClipInfo>(numClips);
  21. }
  22. Blend1DInfo::~Blend1DInfo()
  23. {
  24. if(clips != nullptr)
  25. bs_deleteN(clips, numClips);
  26. }
  27. AnimationProxy::AnimationProxy(UINT64 id)
  28. : id(id), layers(nullptr), numLayers(0), numSceneObjects(0), sceneObjectInfos(nullptr)
  29. , sceneObjectTransforms(nullptr), genericCurveOutputs(nullptr)
  30. { }
  31. AnimationProxy::~AnimationProxy()
  32. {
  33. clear();
  34. }
  35. void AnimationProxy::clear()
  36. {
  37. if (layers == nullptr)
  38. return;
  39. for(UINT32 i = 0; i < numLayers; i++)
  40. {
  41. AnimationStateLayer& layer = layers[i];
  42. for(UINT32 j = 0; j < layer.numStates; j++)
  43. {
  44. AnimationState& state = layer.states[j];
  45. if(state.curves != nullptr)
  46. {
  47. {
  48. UINT32 numCurves = (UINT32)state.curves->position.size();
  49. for (UINT32 k = 0; k < numCurves; k++)
  50. state.positionCaches[k].~TCurveCache();
  51. }
  52. {
  53. UINT32 numCurves = (UINT32)state.curves->rotation.size();
  54. for (UINT32 k = 0; k < numCurves; k++)
  55. state.rotationCaches[k].~TCurveCache();
  56. }
  57. {
  58. UINT32 numCurves = (UINT32)state.curves->scale.size();
  59. for (UINT32 k = 0; k < numCurves; k++)
  60. state.scaleCaches[k].~TCurveCache();
  61. }
  62. {
  63. UINT32 numCurves = (UINT32)state.curves->generic.size();
  64. for (UINT32 k = 0; k < numCurves; k++)
  65. state.genericCaches[k].~TCurveCache();
  66. }
  67. }
  68. if(skeleton != nullptr)
  69. {
  70. UINT32 numBones = skeleton->getNumBones();
  71. for (UINT32 k = 0; k < numBones; k++)
  72. state.boneToCurveMapping[k].~AnimationCurveMapping();
  73. }
  74. if(state.soToCurveMapping != nullptr)
  75. {
  76. for(UINT32 k = 0; k < numSceneObjects; k++)
  77. state.soToCurveMapping[k].~AnimationCurveMapping();
  78. }
  79. state.~AnimationState();
  80. }
  81. layer.~AnimationStateLayer();
  82. }
  83. // All of the memory is part of the same buffer, so we only need to free the first element
  84. bs_free(layers);
  85. layers = nullptr;
  86. genericCurveOutputs = nullptr;
  87. sceneObjectInfos = nullptr;
  88. sceneObjectTransforms = nullptr;
  89. numLayers = 0;
  90. numSceneObjects = 0;
  91. numGenericCurves = 0;
  92. }
  93. void AnimationProxy::rebuild(const SPtr<Skeleton>& skeleton, Vector<AnimationClipInfo>& clipInfos,
  94. const Vector<AnimatedSceneObject>& sceneObjects)
  95. {
  96. this->skeleton = skeleton;
  97. // Note: I could avoid having a separate allocation for LocalSkeletonPoses and use the same buffer as the rest
  98. // of AnimationProxy
  99. if (skeleton != nullptr)
  100. skeletonPose = LocalSkeletonPose(skeleton->getNumBones());
  101. numSceneObjects = (UINT32)sceneObjects.size();
  102. if (numSceneObjects > 0)
  103. sceneObjectPose = LocalSkeletonPose(numSceneObjects);
  104. else
  105. sceneObjectPose = LocalSkeletonPose();
  106. rebuild(clipInfos, sceneObjects);
  107. }
  108. void AnimationProxy::rebuild(Vector<AnimationClipInfo>& clipInfos, const Vector<AnimatedSceneObject>& sceneObjects)
  109. {
  110. clear();
  111. bs_frame_mark();
  112. {
  113. FrameVector<bool> clipLoadState(clipInfos.size());
  114. FrameVector<AnimationStateLayer> tempLayers;
  115. UINT32 clipIdx = 0;
  116. for (auto& clipInfo : clipInfos)
  117. {
  118. UINT32 layer = clipInfo.state.layer;
  119. if (layer == (UINT32)-1)
  120. layer = 0;
  121. else
  122. layer += 1;
  123. auto iterFind = std::find_if(tempLayers.begin(), tempLayers.end(),
  124. [&](auto& x)
  125. {
  126. return x.index == layer;
  127. });
  128. bool isLoaded = clipInfo.clip.isLoaded();
  129. clipLoadState[clipIdx] = isLoaded;
  130. if (iterFind == tempLayers.end())
  131. {
  132. tempLayers.push_back(AnimationStateLayer());
  133. AnimationStateLayer& newLayer = tempLayers.back();
  134. newLayer.index = layer;
  135. newLayer.additive = isLoaded && clipInfo.clip->isAdditive();
  136. }
  137. clipIdx++;
  138. }
  139. std::sort(tempLayers.begin(), tempLayers.end(),
  140. [&](auto& x, auto& y)
  141. {
  142. return x.index < y.index;
  143. });
  144. numLayers = (UINT32)tempLayers.size();
  145. UINT32 numClips = (UINT32)clipInfos.size();
  146. UINT32 numBones;
  147. if (skeleton != nullptr)
  148. numBones = skeleton->getNumBones();
  149. else
  150. numBones = 0;
  151. UINT32 numPosCurves = 0;
  152. UINT32 numRotCurves = 0;
  153. UINT32 numScaleCurves = 0;
  154. clipIdx = 0;
  155. for (auto& clipInfo : clipInfos)
  156. {
  157. bool isLoaded = clipLoadState[clipIdx++];
  158. if (!isLoaded)
  159. continue;
  160. SPtr<AnimationCurves> curves = clipInfo.clip->getCurves();
  161. numPosCurves += (UINT32)curves->position.size();
  162. numRotCurves += (UINT32)curves->rotation.size();
  163. numScaleCurves += (UINT32)curves->scale.size();
  164. }
  165. numGenericCurves = 0;
  166. if(clipInfos.size() > 0 && clipLoadState[0])
  167. {
  168. SPtr<AnimationCurves> curves = clipInfos[0].clip->getCurves();
  169. numGenericCurves = (UINT32)curves->generic.size();
  170. }
  171. UINT32* mappedBoneIndices = (UINT32*)bs_frame_alloc(sizeof(UINT32) * numSceneObjects);
  172. for (UINT32 i = 0; i < numSceneObjects; i++)
  173. mappedBoneIndices[i] = -1;
  174. UINT32 numBoneMappedSOs = 0;
  175. if (skeleton != nullptr)
  176. {
  177. for (UINT32 i = 0; i < numSceneObjects; i++)
  178. {
  179. for (UINT32 j = 0; j < numBones; j++)
  180. {
  181. if (sceneObjects[i].so.isDestroyed(true))
  182. continue;
  183. if (skeleton->getBoneInfo(j).name == sceneObjects[i].curveName)
  184. {
  185. mappedBoneIndices[i] = j;
  186. numBoneMappedSOs++;
  187. break;
  188. }
  189. }
  190. }
  191. }
  192. UINT32 numBoneMappings = numBones * numClips;
  193. UINT32 layersSize = sizeof(AnimationStateLayer) * numLayers;
  194. UINT32 clipsSize = sizeof(AnimationState) * numClips;
  195. UINT32 boneMappingSize = numBoneMappings * sizeof(AnimationCurveMapping);
  196. UINT32 posCacheSize = numPosCurves * sizeof(TCurveCache<Vector3>);
  197. UINT32 rotCacheSize = numRotCurves * sizeof(TCurveCache<Quaternion>);
  198. UINT32 scaleCacheSize = numScaleCurves * sizeof(TCurveCache<Vector3>);
  199. UINT32 genCacheSize = numGenericCurves * sizeof(TCurveCache<float>);
  200. UINT32 genericCurveOutputSize = numGenericCurves * sizeof(float);
  201. UINT32 sceneObjectIdsSize = numSceneObjects * sizeof(AnimatedSceneObjectInfo);
  202. UINT32 sceneObjectTransformsSize = numBoneMappedSOs * sizeof(Matrix4);
  203. UINT8* data = (UINT8*)bs_alloc(layersSize + clipsSize + boneMappingSize + posCacheSize + rotCacheSize +
  204. scaleCacheSize + genCacheSize + genericCurveOutputSize + sceneObjectIdsSize + sceneObjectTransformsSize);
  205. layers = (AnimationStateLayer*)data;
  206. memcpy(layers, tempLayers.data(), layersSize);
  207. data += layersSize;
  208. AnimationState* states = (AnimationState*)data;
  209. for(UINT32 i = 0; i < numClips; i++)
  210. new (&states[i]) AnimationState();
  211. data += clipsSize;
  212. AnimationCurveMapping* boneMappings = (AnimationCurveMapping*)data;
  213. for (UINT32 i = 0; i < numBoneMappings; i++)
  214. new (&boneMappings[i]) AnimationCurveMapping();
  215. data += boneMappingSize;
  216. TCurveCache<Vector3>* posCache = (TCurveCache<Vector3>*)data;
  217. for (UINT32 i = 0; i < numPosCurves; i++)
  218. new (&posCache[i]) TCurveCache<Vector3>();
  219. data += posCacheSize;
  220. TCurveCache<Quaternion>* rotCache = (TCurveCache<Quaternion>*)data;
  221. for (UINT32 i = 0; i < numRotCurves; i++)
  222. new (&rotCache[i]) TCurveCache<Quaternion>();
  223. data += rotCacheSize;
  224. TCurveCache<Vector3>* scaleCache = (TCurveCache<Vector3>*)data;
  225. for (UINT32 i = 0; i < numScaleCurves; i++)
  226. new (&scaleCache[i]) TCurveCache<Vector3>();
  227. data += scaleCacheSize;
  228. TCurveCache<float>* genCache = (TCurveCache<float>*)data;
  229. for (UINT32 i = 0; i < numGenericCurves; i++)
  230. new (&genCache[i]) TCurveCache<float>();
  231. data += genCacheSize;
  232. genericCurveOutputs = (float*)data;
  233. data += genericCurveOutputSize;
  234. sceneObjectInfos = (AnimatedSceneObjectInfo*)data;
  235. data += sceneObjectIdsSize;
  236. sceneObjectTransforms = (Matrix4*)data;
  237. for (UINT32 i = 0; i < numBoneMappedSOs; i++)
  238. sceneObjectTransforms[i] = Matrix4::IDENTITY;
  239. data += sceneObjectTransformsSize;
  240. UINT32 curLayerIdx = 0;
  241. UINT32 curStateIdx = 0;
  242. // Note: Hidden dependency. First clip info must be in layers[0].states[0] (needed for generic curves which only
  243. // use the primary clip).
  244. for(UINT32 i = 0; i < numLayers; i++)
  245. {
  246. AnimationStateLayer& layer = layers[i];
  247. layer.states = &states[curStateIdx];
  248. layer.numStates = 0;
  249. UINT32 localStateIdx = 0;
  250. for(UINT32 j = 0; j < (UINT32)clipInfos.size(); j++)
  251. {
  252. AnimationClipInfo& clipInfo = clipInfos[j];
  253. UINT32 clipLayer = clipInfo.state.layer;
  254. if (clipLayer == (UINT32)-1)
  255. clipLayer = 0;
  256. else
  257. clipLayer += 1;
  258. if (clipLayer != layer.index)
  259. continue;
  260. AnimationState& state = states[curStateIdx];
  261. state.loop = clipInfo.state.wrapMode == AnimWrapMode::Loop;
  262. state.time = clipInfo.state.time;
  263. // Calculate weight if fading is active
  264. float weight = clipInfo.state.weight;
  265. //// Assumes time is clamped to [0, fadeLength] and fadeLength != 0
  266. if(clipInfo.fadeDirection < 0.0f)
  267. {
  268. float t = clipInfo.fadeTime / clipInfo.fadeLength;
  269. weight *= (1.0f - t);
  270. }
  271. else if(clipInfo.fadeDirection > 0.0f)
  272. {
  273. float t = clipInfo.fadeTime / clipInfo.fadeLength;
  274. weight *= t;
  275. }
  276. state.weight = weight;
  277. // Set up individual curves and their caches
  278. bool isClipValid = clipLoadState[j];
  279. if (isClipValid)
  280. {
  281. state.curves = clipInfo.clip->getCurves();
  282. state.disabled = false;
  283. }
  284. else
  285. {
  286. static SPtr<AnimationCurves> zeroCurves = bs_shared_ptr_new<AnimationCurves>();
  287. state.curves = zeroCurves;
  288. state.disabled = true;
  289. }
  290. state.positionCaches = posCache;
  291. posCache += state.curves->position.size();
  292. state.rotationCaches = rotCache;
  293. rotCache += state.curves->rotation.size();
  294. state.scaleCaches = scaleCache;
  295. scaleCache += state.curves->scale.size();
  296. state.genericCaches = genCache;
  297. genCache += state.curves->generic.size();
  298. clipInfo.layerIdx = curLayerIdx;
  299. clipInfo.stateIdx = localStateIdx;
  300. if(isClipValid)
  301. clipInfo.curveVersion = clipInfo.clip->getVersion();
  302. // Set up bone mapping
  303. if (skeleton != nullptr)
  304. {
  305. state.boneToCurveMapping = &boneMappings[curStateIdx * numBones];
  306. if (isClipValid)
  307. {
  308. clipInfo.clip->getBoneMapping(*skeleton, state.boneToCurveMapping);
  309. }
  310. else
  311. {
  312. AnimationCurveMapping emptyMapping = { (UINT32)-1, (UINT32)-1, (UINT32)-1 };
  313. for (UINT32 i = 0; i < numBones; i++)
  314. state.boneToCurveMapping[i] = emptyMapping;
  315. }
  316. }
  317. else
  318. state.boneToCurveMapping = nullptr;
  319. layer.numStates++;
  320. curStateIdx++;
  321. localStateIdx++;
  322. }
  323. curLayerIdx++;
  324. // Must be larger than zero otherwise the layer.states pointer will point to data held by some other layer
  325. assert(layer.numStates > 0);
  326. }
  327. UINT32 boneIdx = 0;
  328. for(UINT32 i = 0; i < numSceneObjects; i++)
  329. {
  330. HSceneObject so = sceneObjects[i].so;
  331. AnimatedSceneObjectInfo& soInfo = sceneObjectInfos[i];
  332. soInfo.id = so.getInstanceId();
  333. soInfo.boneIdx = mappedBoneIndices[i];
  334. bool isSOValid = !so.isDestroyed(true);
  335. if (isSOValid)
  336. soInfo.hash = so->getTransformHash();
  337. else
  338. soInfo.hash = 0;
  339. // If no bone mapping, find curves directly
  340. if(soInfo.boneIdx == -1)
  341. {
  342. soInfo.curveIndices = { (UINT32)-1, (UINT32)-1, (UINT32)-1 };
  343. if (isSOValid)
  344. {
  345. for (UINT32 j = 0; j < (UINT32)clipInfos.size(); j++)
  346. {
  347. AnimationClipInfo& clipInfo = clipInfos[j];
  348. soInfo.layerIdx = clipInfo.layerIdx;
  349. soInfo.stateIdx = clipInfo.stateIdx;
  350. bool isClipValid = clipLoadState[j];
  351. if (isClipValid)
  352. {
  353. // Note: If there are multiple clips with the relevant curve name, we only use the first
  354. clipInfo.clip->getCurveMapping(sceneObjects[i].curveName, soInfo.curveIndices);
  355. break;
  356. }
  357. }
  358. }
  359. }
  360. else
  361. {
  362. // No need to check if SO is valid, if it has a bone connection it must be
  363. sceneObjectTransforms[boneIdx] = so->getWorldTfrm();
  364. boneIdx++;
  365. }
  366. }
  367. bs_frame_free(mappedBoneIndices);
  368. }
  369. bs_frame_clear();
  370. }
  371. void AnimationProxy::updateValues(const Vector<AnimationClipInfo>& clipInfos)
  372. {
  373. for(auto& clipInfo : clipInfos)
  374. {
  375. AnimationState& state = layers[clipInfo.layerIdx].states[clipInfo.stateIdx];
  376. state.loop = clipInfo.state.wrapMode == AnimWrapMode::Loop;
  377. state.weight = clipInfo.state.weight;
  378. state.time = clipInfo.state.time;
  379. }
  380. }
  381. void AnimationProxy::updateTransforms(const Vector<AnimatedSceneObject>& sceneObjects)
  382. {
  383. UINT32 boneIdx = 0;
  384. for (UINT32 i = 0; i < numSceneObjects; i++)
  385. {
  386. HSceneObject so = sceneObjects[i].so;
  387. if (so.isDestroyed(true))
  388. {
  389. sceneObjectInfos[i].hash = 0;
  390. continue;
  391. }
  392. sceneObjectInfos[i].hash = so->getTransformHash();
  393. if (sceneObjectInfos[i].boneIdx == -1)
  394. continue;
  395. sceneObjectTransforms[boneIdx] = sceneObjects[i].so->getWorldTfrm();
  396. boneIdx++;
  397. }
  398. }
  399. void AnimationProxy::updateTime(const Vector<AnimationClipInfo>& clipInfos)
  400. {
  401. for (auto& clipInfo : clipInfos)
  402. {
  403. AnimationState& state = layers[clipInfo.layerIdx].states[clipInfo.stateIdx];
  404. state.time = clipInfo.state.time;
  405. }
  406. }
  407. Animation::Animation()
  408. : mDefaultWrapMode(AnimWrapMode::Loop), mDefaultSpeed(1.0f), mDirty(AnimDirtyStateFlag::Skeleton)
  409. , mGenericCurveValuesValid(false)
  410. {
  411. mId = AnimationManager::instance().registerAnimation(this);
  412. mAnimProxy = bs_shared_ptr_new<AnimationProxy>(mId);
  413. }
  414. Animation::~Animation()
  415. {
  416. AnimationManager::instance().unregisterAnimation(mId);
  417. }
  418. void Animation::setSkeleton(const SPtr<Skeleton>& skeleton)
  419. {
  420. mSkeleton = skeleton;
  421. mDirty |= AnimDirtyStateFlag::Skeleton;
  422. }
  423. void Animation::setWrapMode(AnimWrapMode wrapMode)
  424. {
  425. mDefaultWrapMode = wrapMode;
  426. for (auto& clipInfo : mClipInfos)
  427. clipInfo.state.wrapMode = wrapMode;
  428. mDirty |= AnimDirtyStateFlag::Value;
  429. }
  430. void Animation::setSpeed(float speed)
  431. {
  432. mDefaultSpeed = speed;
  433. for (auto& clipInfo : mClipInfos)
  434. {
  435. // Special case: Ignore non-moving ones
  436. if(!clipInfo.state.stopped)
  437. clipInfo.state.speed = speed;
  438. }
  439. mDirty |= AnimDirtyStateFlag::Value;
  440. }
  441. void Animation::play(const HAnimationClip& clip)
  442. {
  443. AnimationClipInfo* clipInfo = addClip(clip, (UINT32)-1);
  444. if(clipInfo != nullptr)
  445. {
  446. clipInfo->state.time = 0.0f;
  447. clipInfo->state.speed = mDefaultSpeed;
  448. clipInfo->state.weight = 1.0f;
  449. clipInfo->state.wrapMode = mDefaultWrapMode;
  450. }
  451. mDirty |= AnimDirtyStateFlag::Value;
  452. }
  453. void Animation::blendAdditive(const HAnimationClip& clip, float weight, float fadeLength, UINT32 layer)
  454. {
  455. if(clip != nullptr && !clip->isAdditive())
  456. {
  457. LOGWRN("blendAdditive() called with a clip that doesn't contain additive animation. Ignoring.");
  458. // Stop any clips on this layer, even if invalid
  459. HAnimationClip nullClip;
  460. addClip(nullClip, layer);
  461. return;
  462. }
  463. AnimationClipInfo* clipInfo = addClip(clip, layer);
  464. if (clipInfo != nullptr)
  465. {
  466. clipInfo->state.time = 0.0f;
  467. clipInfo->state.speed = mDefaultSpeed;
  468. clipInfo->state.weight = weight;
  469. clipInfo->state.wrapMode = mDefaultWrapMode;
  470. if(fadeLength > 0.0f)
  471. {
  472. clipInfo->fadeDirection = 1.0f;
  473. clipInfo->fadeTime = 0.0f;
  474. clipInfo->fadeLength = fadeLength;
  475. }
  476. mDirty |= AnimDirtyStateFlag::Value;
  477. }
  478. }
  479. void Animation::blend1D(const Blend1DInfo& info, float t)
  480. {
  481. if (info.numClips == 0)
  482. return;
  483. // Find valid range
  484. float startPos = 0.0f;
  485. float endPos = 0.0f;
  486. for (UINT32 i = 0; i < info.numClips; i++)
  487. {
  488. startPos = std::min(startPos, info.clips[i].position);
  489. endPos = std::min(endPos, info.clips[i].position);
  490. }
  491. float length = endPos - startPos;
  492. if(Math::approxEquals(length, 0.0f) || info.numClips < 2)
  493. {
  494. play(info.clips[0].clip);
  495. return;
  496. }
  497. // Clamp or loop time
  498. bool loop = mDefaultWrapMode == AnimWrapMode::Loop;
  499. if (t < startPos)
  500. {
  501. if (loop)
  502. t = t - std::floor(t / length) * length;
  503. else // Clamping
  504. t = startPos;
  505. }
  506. if (t > endPos)
  507. {
  508. if (loop)
  509. t = t - std::floor(t / length) * length;
  510. else // Clamping
  511. t = endPos;
  512. }
  513. // Find keys to blend between
  514. UINT32 leftKey = 0;
  515. UINT32 rightKey = 0;
  516. INT32 start = 0;
  517. INT32 searchLength = (INT32)info.numClips;
  518. while (searchLength > 0)
  519. {
  520. INT32 half = searchLength >> 1;
  521. INT32 mid = start + half;
  522. if (t < info.clips[mid].position)
  523. {
  524. searchLength = half;
  525. }
  526. else
  527. {
  528. start = mid + 1;
  529. searchLength -= (half + 1);
  530. }
  531. }
  532. leftKey = std::max(0, start - 1);
  533. rightKey = std::min(start, (INT32)info.numClips - 1);
  534. float interpLength = info.clips[rightKey].position - info.clips[leftKey].position;
  535. t = (t - info.clips[leftKey].position) / interpLength;
  536. // Add clips and set weights
  537. for(UINT32 i = 0; i < info.numClips; i++)
  538. {
  539. AnimationClipInfo* clipInfo = addClip(info.clips[i].clip, (UINT32)-1, i == 0);
  540. if (clipInfo != nullptr)
  541. {
  542. clipInfo->state.time = 0.0f;
  543. clipInfo->state.stopped = true;
  544. clipInfo->state.speed = 0.0f;
  545. clipInfo->state.wrapMode = AnimWrapMode::Clamp;
  546. if (i == leftKey)
  547. clipInfo->state.weight = 1.0f - t;
  548. else if (i == rightKey)
  549. clipInfo->state.weight = t;
  550. else
  551. clipInfo->state.weight = 0.0f;
  552. }
  553. }
  554. mDirty |= AnimDirtyStateFlag::Value;
  555. }
  556. void Animation::blend2D(const Blend2DInfo& info, const Vector2& t)
  557. {
  558. AnimationClipInfo* topLeftClipInfo = addClip(info.topLeftClip, (UINT32)-1, true);
  559. if (topLeftClipInfo != nullptr)
  560. {
  561. topLeftClipInfo->state.time = 0.0f;
  562. topLeftClipInfo->state.stopped = true;
  563. topLeftClipInfo->state.speed = 0.0f;
  564. topLeftClipInfo->state.weight = (1.0f - t.x) * (1.0f - t.y);
  565. topLeftClipInfo->state.wrapMode = AnimWrapMode::Clamp;
  566. }
  567. AnimationClipInfo* topRightClipInfo = addClip(info.topRightClip, (UINT32)-1, false);
  568. if (topRightClipInfo != nullptr)
  569. {
  570. topRightClipInfo->state.time = 0.0f;
  571. topRightClipInfo->state.stopped = true;
  572. topLeftClipInfo->state.speed = 0.0f;
  573. topRightClipInfo->state.weight = t.x * (1.0f - t.y);
  574. topRightClipInfo->state.wrapMode = AnimWrapMode::Clamp;
  575. }
  576. AnimationClipInfo* botLeftClipInfo = addClip(info.botLeftClip, (UINT32)-1, false);
  577. if (botLeftClipInfo != nullptr)
  578. {
  579. botLeftClipInfo->state.time = 0.0f;
  580. botLeftClipInfo->state.stopped = true;
  581. topLeftClipInfo->state.speed = 0.0f;
  582. botLeftClipInfo->state.weight = (1.0f - t.x) * t.y;
  583. botLeftClipInfo->state.wrapMode = AnimWrapMode::Clamp;
  584. }
  585. AnimationClipInfo* botRightClipInfo = addClip(info.botRightClip, (UINT32)-1, false);
  586. if (botRightClipInfo != nullptr)
  587. {
  588. botRightClipInfo->state.time = 0.0f;
  589. botRightClipInfo->state.stopped = true;
  590. botRightClipInfo->state.speed = 0.0f;
  591. botRightClipInfo->state.weight = t.x * t.y;
  592. botRightClipInfo->state.wrapMode = AnimWrapMode::Clamp;
  593. }
  594. mDirty |= AnimDirtyStateFlag::Value;
  595. }
  596. void Animation::crossFade(const HAnimationClip& clip, float fadeLength)
  597. {
  598. bool isFading = fadeLength > 0.0f;
  599. if(!isFading)
  600. {
  601. play(clip);
  602. return;
  603. }
  604. AnimationClipInfo* clipInfo = addClip(clip, (UINT32)-1, false);
  605. if (clipInfo != nullptr)
  606. {
  607. clipInfo->state.time = 0.0f;
  608. clipInfo->state.speed = mDefaultSpeed;
  609. clipInfo->state.weight = 1.0f;
  610. clipInfo->state.wrapMode = mDefaultWrapMode;
  611. // Set up fade lengths
  612. clipInfo->fadeDirection = 1.0f;
  613. clipInfo->fadeTime = 0.0f;
  614. clipInfo->fadeLength = fadeLength;
  615. for (auto& entry : mClipInfos)
  616. {
  617. if (entry.state.layer == (UINT32)-1 && entry.clip != clip)
  618. {
  619. // If other clips are already cross-fading, we need to persist their current weight before starting
  620. // a new crossfade. We do that by adjusting the fade times.
  621. if(clipInfo->fadeDirection != 0 && clipInfo->fadeTime < clipInfo->fadeLength)
  622. {
  623. float t = clipInfo->fadeTime / clipInfo->fadeLength;
  624. if (clipInfo->fadeDirection < 0.0f)
  625. t = (1.0f - t);
  626. clipInfo->state.weight *= t;
  627. }
  628. clipInfo->fadeDirection = -1.0f;
  629. clipInfo->fadeTime = 0.0f;
  630. clipInfo->fadeLength = fadeLength;
  631. }
  632. }
  633. }
  634. mDirty |= AnimDirtyStateFlag::Value;
  635. }
  636. void Animation::stop(UINT32 layer)
  637. {
  638. bs_frame_mark();
  639. {
  640. FrameVector<AnimationClipInfo> newClips;
  641. for (auto& clipInfo : mClipInfos)
  642. {
  643. if (clipInfo.state.layer != layer)
  644. newClips.push_back(clipInfo);
  645. else
  646. mDirty |= AnimDirtyStateFlag::Layout;
  647. }
  648. mClipInfos.resize(newClips.size());
  649. memcpy(mClipInfos.data(), newClips.data(), sizeof(AnimationClipInfo) * newClips.size());
  650. }
  651. bs_frame_clear();
  652. }
  653. void Animation::stopAll()
  654. {
  655. mClipInfos.clear();
  656. mDirty |= AnimDirtyStateFlag::Layout;
  657. }
  658. AnimationClipInfo* Animation::addClip(const HAnimationClip& clip, UINT32 layer, bool stopExisting)
  659. {
  660. AnimationClipInfo* output = nullptr;
  661. bool hasExisting = false;
  662. // Search for existing
  663. for (auto& clipInfo : mClipInfos)
  664. {
  665. if (clipInfo.state.layer == layer)
  666. {
  667. if (clipInfo.clip == clip)
  668. output = &clipInfo;
  669. else if (stopExisting)
  670. hasExisting = true;
  671. }
  672. }
  673. // Doesn't exist or found extra animations, rebuild
  674. if (output == nullptr || hasExisting)
  675. {
  676. bs_frame_mark();
  677. {
  678. FrameVector<AnimationClipInfo> newClips;
  679. for (auto& clipInfo : mClipInfos)
  680. {
  681. if (!stopExisting || clipInfo.state.layer != layer || clipInfo.clip == clip)
  682. newClips.push_back(clipInfo);
  683. }
  684. if (output == nullptr && clip != nullptr)
  685. newClips.push_back(AnimationClipInfo());
  686. mClipInfos.resize(newClips.size());
  687. memcpy(mClipInfos.data(), newClips.data(), sizeof(AnimationClipInfo) * newClips.size());
  688. mDirty |= AnimDirtyStateFlag::Layout;
  689. }
  690. bs_frame_clear();
  691. }
  692. // If new clip was added, get its address
  693. if (output == nullptr && clip != nullptr)
  694. {
  695. AnimationClipInfo& newInfo = mClipInfos.back();
  696. newInfo.clip = clip;
  697. newInfo.layerIdx = layer;
  698. output = &newInfo;
  699. }
  700. return output;
  701. }
  702. bool Animation::isPlaying() const
  703. {
  704. for(auto& clipInfo : mClipInfos)
  705. {
  706. if (clipInfo.clip.isLoaded())
  707. return true;
  708. }
  709. return false;
  710. }
  711. bool Animation::getState(const HAnimationClip& clip, AnimationClipState& state)
  712. {
  713. if (clip == nullptr)
  714. return false;
  715. for (auto& clipInfo : mClipInfos)
  716. {
  717. if (clipInfo.clip == clip)
  718. {
  719. state = clipInfo.state;
  720. return true;
  721. }
  722. }
  723. return false;
  724. }
  725. void Animation::setState(const HAnimationClip& clip, AnimationClipState state)
  726. {
  727. AnimationClipInfo* clipInfo = addClip(clip, state.layer, false);
  728. if (clipInfo == nullptr)
  729. return;
  730. clipInfo->state = state;
  731. mDirty |= AnimDirtyStateFlag::Value;
  732. }
  733. void Animation::triggerEvents(float lastFrameTime, float delta)
  734. {
  735. for (auto& clipInfo : mClipInfos)
  736. {
  737. if (!clipInfo.clip.isLoaded())
  738. continue;
  739. const Vector<AnimationEvent>& events = clipInfo.clip->getEvents();
  740. bool loop = clipInfo.state.wrapMode == AnimWrapMode::Loop;
  741. float start = lastFrameTime;
  742. float end = start + delta;
  743. float clipLength = clipInfo.clip->getLength();
  744. AnimationUtility::wrapTime(start, 0.0f, clipLength, loop);
  745. AnimationUtility::wrapTime(end, 0.0f, clipLength, false);
  746. for (auto& event : events)
  747. {
  748. if (event.time > start && event.time <= end)
  749. onEventTriggered(clipInfo.clip, event.name);
  750. }
  751. // Check the looped portion
  752. if(loop && end >= clipLength)
  753. {
  754. start = 0.0f;
  755. end = end - clipLength;
  756. for (auto& event : events)
  757. {
  758. if (event.time > start && event.time <= end)
  759. onEventTriggered(clipInfo.clip, event.name);
  760. }
  761. }
  762. }
  763. }
  764. void Animation::mapCurveToSceneObject(const String& curve, const HSceneObject& so)
  765. {
  766. AnimatedSceneObject animSo = { so, curve };
  767. mSceneObjects[so.getInstanceId()] = animSo;
  768. mDirty |= AnimDirtyStateFlag::Skeleton;
  769. }
  770. void Animation::unmapSceneObject(const HSceneObject& so)
  771. {
  772. mSceneObjects.erase(so.getInstanceId());
  773. mDirty |= AnimDirtyStateFlag::Skeleton;
  774. }
  775. bool Animation::getGenericCurveValue(UINT32 curveIdx, float& value)
  776. {
  777. if (!mGenericCurveValuesValid || curveIdx >= (UINT32)mGenericCurveOutputs.size())
  778. return false;
  779. value = mGenericCurveOutputs[curveIdx];
  780. return true;
  781. }
  782. SPtr<Animation> Animation::create()
  783. {
  784. Animation* anim = new (bs_alloc<Animation>()) Animation();
  785. SPtr<Animation> animPtr = bs_core_ptr(anim);
  786. animPtr->_setThisPtr(animPtr);
  787. animPtr->initialize();
  788. return animPtr;
  789. }
  790. void Animation::updateAnimProxy(float timeDelta)
  791. {
  792. // Check if any of the clip curves are dirty and advance time, perform fading
  793. for (auto& clipInfo : mClipInfos)
  794. {
  795. float scaledTimeDelta = timeDelta * clipInfo.state.speed;
  796. clipInfo.state.time += scaledTimeDelta;
  797. if (clipInfo.clip.isLoaded() && clipInfo.curveVersion != clipInfo.clip->getVersion())
  798. mDirty |= AnimDirtyStateFlag::Layout;
  799. float fadeTime = clipInfo.fadeTime + scaledTimeDelta;
  800. clipInfo.fadeTime = Math::clamp(fadeTime, 0.0f, clipInfo.fadeLength);
  801. }
  802. if((UINT32)mDirty == 0) // Clean
  803. {
  804. mAnimProxy->updateTime(mClipInfos);
  805. }
  806. else
  807. {
  808. auto getAnimatedSOList = [&]()
  809. {
  810. Vector<AnimatedSceneObject> animatedSO(mSceneObjects.size());
  811. UINT32 idx = 0;
  812. for (auto& entry : mSceneObjects)
  813. animatedSO[idx++] = entry.second;
  814. return animatedSO;
  815. };
  816. bool didFullRebuild = false;
  817. if (mDirty.isSet(AnimDirtyStateFlag::Skeleton))
  818. {
  819. Vector<AnimatedSceneObject> animatedSOs = getAnimatedSOList();
  820. mAnimProxy->rebuild(mSkeleton, mClipInfos, animatedSOs);
  821. didFullRebuild = true;
  822. }
  823. else if (mDirty.isSet(AnimDirtyStateFlag::Layout))
  824. {
  825. Vector<AnimatedSceneObject> animatedSOs = getAnimatedSOList();
  826. mAnimProxy->rebuild(mClipInfos, animatedSOs);
  827. didFullRebuild = true;
  828. }
  829. else if (mDirty.isSet(AnimDirtyStateFlag::Value))
  830. mAnimProxy->updateValues(mClipInfos);
  831. // Check if there are dirty transforms
  832. if(!didFullRebuild)
  833. {
  834. UINT32 numSceneObjects = (UINT32)mSceneObjects.size();
  835. for (UINT32 i = 0; i < numSceneObjects; i++)
  836. {
  837. UINT32 hash;
  838. HSceneObject so = mSceneObjects[i].so;
  839. if (so.isDestroyed(true))
  840. hash = 0;
  841. else
  842. hash = so->getTransformHash();
  843. if(hash != mAnimProxy->sceneObjectInfos[i].hash)
  844. {
  845. Vector<AnimatedSceneObject> animatedSOs = getAnimatedSOList();
  846. mAnimProxy->updateTransforms(animatedSOs);
  847. break;
  848. }
  849. }
  850. }
  851. }
  852. mDirty = AnimDirtyState();
  853. }
  854. void Animation::updateFromProxy()
  855. {
  856. // Write TRS animation results to relevant SceneObjects
  857. for(UINT32 i = 0; i < mAnimProxy->numSceneObjects; i++)
  858. {
  859. const AnimatedSceneObjectInfo& soInfo = mAnimProxy->sceneObjectInfos[i];
  860. auto iterFind = mSceneObjects.find(soInfo.id);
  861. if (iterFind == mSceneObjects.end())
  862. continue;
  863. HSceneObject so = iterFind->second.so;
  864. if (so.isDestroyed(true))
  865. continue;
  866. if(soInfo.boneIdx != -1)
  867. {
  868. so->setPosition(mAnimProxy->skeletonPose.positions[soInfo.boneIdx]);
  869. so->setRotation(mAnimProxy->skeletonPose.rotations[soInfo.boneIdx]);
  870. so->setScale(mAnimProxy->skeletonPose.scales[soInfo.boneIdx]);
  871. }
  872. else
  873. {
  874. so->setPosition(mAnimProxy->sceneObjectPose.positions[i]);
  875. so->setRotation(mAnimProxy->sceneObjectPose.rotations[i]);
  876. so->setScale(mAnimProxy->sceneObjectPose.scales[i]);
  877. }
  878. }
  879. // Must ensure that clip in the proxy and current primary clip are the same
  880. mGenericCurveValuesValid = false;
  881. if(mAnimProxy->numLayers > 0 || mAnimProxy->layers[0].numStates > 0)
  882. {
  883. const AnimationState& state = mAnimProxy->layers[0].states[0];
  884. if(!state.disabled && mClipInfos.size() > 0)
  885. {
  886. const AnimationClipInfo& clipInfo = mClipInfos[0];
  887. if (clipInfo.stateIdx == 0 && clipInfo.layerIdx == 0)
  888. {
  889. if (clipInfo.clip.isLoaded() && clipInfo.curveVersion == clipInfo.clip->getVersion())
  890. {
  891. UINT32 numGenericCurves = (UINT32)clipInfo.clip->getCurves()->generic.size();
  892. mGenericCurveValuesValid = numGenericCurves == mAnimProxy->numGenericCurves;
  893. }
  894. }
  895. }
  896. }
  897. if(mGenericCurveValuesValid)
  898. {
  899. mGenericCurveOutputs.resize(mAnimProxy->numGenericCurves);
  900. memcpy(mGenericCurveOutputs.data(), mAnimProxy->genericCurveOutputs, mAnimProxy->numGenericCurves * sizeof(float));
  901. }
  902. }
  903. }