SkinComponent.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <AnKi/Scene/Components/SkinComponent.h>
  6. #include <AnKi/Scene/SceneNode.h>
  7. #include <AnKi/Scene/SceneGraph.h>
  8. #include <AnKi/Resource/SkeletonResource.h>
  9. #include <AnKi/Resource/AnimationResource.h>
  10. #include <AnKi/Resource/ResourceManager.h>
  11. #include <AnKi/Util/BitSet.h>
  12. namespace anki {
  13. SkinComponent::SkinComponent(SceneNode* node)
  14. : SceneComponent(node, kClassType)
  15. {
  16. }
  17. SkinComponent::~SkinComponent()
  18. {
  19. }
  20. void SkinComponent::loadSkeletonResource(CString fname)
  21. {
  22. SkeletonResourcePtr rsrc;
  23. const Error err = ResourceManager::getSingleton().loadResource(fname, rsrc);
  24. if(err)
  25. {
  26. ANKI_SCENE_LOGE("Failed to load skeleton");
  27. return;
  28. }
  29. m_forceFullUpdate = true;
  30. m_skeleton = std::move(rsrc);
  31. // Cleanup
  32. m_boneTrfs[0].destroy();
  33. m_boneTrfs[1].destroy();
  34. m_animationTrfs.destroy();
  35. GpuSceneBuffer::getSingleton().deferredFree(m_gpuSceneBoneTransforms);
  36. // Create
  37. const U32 boneCount = m_skeleton->getBones().getSize();
  38. m_boneTrfs[0].resize(boneCount, Mat3x4::getIdentity());
  39. m_boneTrfs[1].resize(boneCount, Mat3x4::getIdentity());
  40. m_animationTrfs.resize(boneCount, Trf{Vec3(0.0f), Quat::getIdentity(), 1.0f});
  41. m_gpuSceneBoneTransforms = GpuSceneBuffer::getSingleton().allocate(sizeof(Mat4) * boneCount * 2, 4);
  42. }
  43. void SkinComponent::playAnimation(U32 track, AnimationResourcePtr anim, const AnimationPlayInfo& info)
  44. {
  45. const Second animDuration = anim->getDuration();
  46. m_tracks[track].m_anim = anim;
  47. m_tracks[track].m_absoluteStartTime = m_absoluteTime + info.m_startTime;
  48. m_tracks[track].m_relativeTimePassed = 0.0;
  49. if(info.m_repeatTimes > 0.0)
  50. {
  51. m_tracks[track].m_blendInTime = min(animDuration * info.m_repeatTimes, info.m_blendInTime);
  52. m_tracks[track].m_blendOutTime = min(animDuration * info.m_repeatTimes, info.m_blendOutTime);
  53. }
  54. else
  55. {
  56. m_tracks[track].m_blendInTime = info.m_blendInTime;
  57. m_tracks[track].m_blendOutTime = 0.0; // Irrelevant
  58. }
  59. m_tracks[track].m_repeatTimes = info.m_repeatTimes;
  60. }
  61. void SkinComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
  62. {
  63. updated = false;
  64. if(!m_skeleton.isCreated())
  65. {
  66. return;
  67. }
  68. const Second dt = info.m_dt;
  69. Vec4 minExtend(kMaxF32, kMaxF32, kMaxF32, 0.0f);
  70. Vec4 maxExtend(kMinF32, kMinF32, kMinF32, 0.0f);
  71. BitSet<128> bonesAnimated(false);
  72. for(Track& track : m_tracks)
  73. {
  74. if(!track.m_anim.isCreated())
  75. {
  76. continue;
  77. }
  78. if(track.m_absoluteStartTime > m_absoluteTime)
  79. {
  80. // Hasn't started yet
  81. continue;
  82. }
  83. const Second clipDuration = track.m_anim->getDuration();
  84. const Second animationDuration = track.m_repeatTimes * clipDuration;
  85. if(track.m_repeatTimes > 0.0 && track.m_relativeTimePassed > animationDuration)
  86. {
  87. // Animation finished
  88. continue;
  89. }
  90. updated = true;
  91. const Second animTime = track.m_relativeTimePassed;
  92. track.m_relativeTimePassed += dt;
  93. // Iterate the animation channels and interpolate
  94. for(U32 i = 0; i < track.m_anim->getChannels().getSize(); ++i)
  95. {
  96. const AnimationChannel& channel = track.m_anim->getChannels()[i];
  97. const Bone* bone = m_skeleton->tryFindBone(channel.m_name.toCString());
  98. if(!bone)
  99. {
  100. ANKI_SCENE_LOGW("Animation is referencing unknown bone \"%s\"", &channel.m_name[0]);
  101. continue;
  102. }
  103. const U32 boneIdx = bone->getIndex();
  104. // Interpolate
  105. Vec3 position;
  106. Quat rotation;
  107. F32 scale;
  108. track.m_anim->interpolate(i, animTime, position, rotation, scale);
  109. // Blend with previous track
  110. if(bonesAnimated.get(boneIdx) && (track.m_blendInTime > 0.0 || track.m_blendOutTime > 0.0))
  111. {
  112. F32 blendInFactor;
  113. if(track.m_blendInTime > 0.0)
  114. {
  115. blendInFactor = min(1.0f, F32(animTime / track.m_blendInTime));
  116. }
  117. else
  118. {
  119. blendInFactor = 1.0f;
  120. }
  121. F32 blendOutFactor;
  122. if(track.m_blendOutTime > 0.0)
  123. {
  124. blendOutFactor = min(1.0f, F32((animationDuration - animTime) / track.m_blendOutTime));
  125. }
  126. else
  127. {
  128. blendOutFactor = 1.0f;
  129. }
  130. const F32 factor = blendInFactor * blendOutFactor;
  131. if(factor < 1.0f)
  132. {
  133. const Trf& prevTrf = m_animationTrfs[boneIdx];
  134. position = linearInterpolate(prevTrf.m_translation, position, factor);
  135. rotation = prevTrf.m_rotation.slerp(rotation, factor);
  136. scale = linearInterpolate(prevTrf.m_scale, scale, factor);
  137. }
  138. }
  139. // Store
  140. bonesAnimated.set(boneIdx);
  141. m_animationTrfs[boneIdx] = {position, rotation, scale};
  142. }
  143. }
  144. // Always update the 1st time
  145. updated = updated || m_forceFullUpdate;
  146. m_forceFullUpdate = false;
  147. if(updated)
  148. {
  149. m_prevBoneTrfs = m_crntBoneTrfs;
  150. m_crntBoneTrfs = m_crntBoneTrfs ^ 1;
  151. // Walk the bone hierarchy to add additional transforms
  152. visitBones(m_skeleton->getRootBone(), Mat3x4::getIdentity(), bonesAnimated, minExtend, maxExtend);
  153. const Vec4 e(kEpsilonf, kEpsilonf, kEpsilonf, 0.0f);
  154. m_boneBoundingVolume.setMin(minExtend - e);
  155. m_boneBoundingVolume.setMax(maxExtend + e);
  156. // Update the GPU scene
  157. const U32 boneCount = m_skeleton->getBones().getSize();
  158. DynamicArray<Mat3x4, MemoryPoolPtrWrapper<StackMemoryPool>> trfs(info.m_framePool);
  159. trfs.resize(boneCount * 2);
  160. for(U32 i = 0; i < boneCount; ++i)
  161. {
  162. trfs[i * 2 + 0] = getBoneTransforms()[i];
  163. trfs[i * 2 + 1] = getPreviousFrameBoneTransforms()[i];
  164. }
  165. GpuSceneMicroPatcher::getSingleton().newCopy(*info.m_framePool, m_gpuSceneBoneTransforms, trfs.getSizeInBytes(), trfs.getBegin());
  166. }
  167. else
  168. {
  169. m_prevBoneTrfs = m_crntBoneTrfs;
  170. }
  171. m_absoluteTime += dt;
  172. }
  173. void SkinComponent::visitBones(const Bone& bone, const Mat3x4& parentTrf, const BitSet<128>& bonesAnimated, Vec4& minExtend, Vec4& maxExtend)
  174. {
  175. Mat3x4 outMat;
  176. if(bonesAnimated.get(bone.getIndex()))
  177. {
  178. const Trf& t = m_animationTrfs[bone.getIndex()];
  179. outMat = parentTrf.combineTransformations(Mat3x4(t.m_translation.xyz(), Mat3(t.m_rotation), Vec3(t.m_scale)));
  180. }
  181. else
  182. {
  183. outMat = parentTrf.combineTransformations(bone.getTransform());
  184. }
  185. m_boneTrfs[m_crntBoneTrfs][bone.getIndex()] = outMat.combineTransformations(bone.getVertexTransform());
  186. // Update volume
  187. const Vec3 bonePos = outMat * Vec4(0.0f, 0.0f, 0.0f, 1.0f);
  188. minExtend = minExtend.min(bonePos.xyz0());
  189. maxExtend = maxExtend.max(bonePos.xyz0());
  190. for(const Bone* child : bone.getChildren())
  191. {
  192. visitBones(*child, outMat, bonesAnimated, minExtend, maxExtend);
  193. }
  194. }
  195. } // end namespace anki