WeightedMaskMixerJob.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. // Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik //
  2. using Unity.Collections;
  3. using UnityEngine;
  4. using UnityEngine.Animations;
  5. namespace Animancer
  6. {
  7. /// <summary>
  8. /// An <see cref="IAnimationJob"/> which mixes its inputs based on individual <see cref="boneWeights"/>.
  9. /// </summary>
  10. public struct WeightedMaskMixerJob : IAnimationJob
  11. {
  12. /************************************************************************************************************************/
  13. /// <summary>The handles for each bone being mixed.</summary>
  14. /// <remarks>All animated bones must be included, even if their individual weight isn't modified.</remarks>
  15. public NativeArray<TransformStreamHandle> boneTransforms;
  16. /// <summary>The blend weight of each bone. This array corresponds to the <see cref="boneTransforms"/>.</summary>
  17. public NativeArray<float> boneWeights;
  18. /************************************************************************************************************************/
  19. /// <inheritdoc/>
  20. readonly void IAnimationJob.ProcessRootMotion(AnimationStream stream)
  21. {
  22. var stream0 = stream.GetInputStream(0);
  23. var stream1 = stream.GetInputStream(1);
  24. if (stream1.isValid)
  25. {
  26. var layerWeight = stream.GetInputWeight(1);
  27. var velocity = Vector3.LerpUnclamped(stream0.velocity, stream1.velocity, layerWeight);
  28. var angularVelocity = Vector3.LerpUnclamped(stream0.angularVelocity, stream1.angularVelocity, layerWeight);
  29. stream.velocity = velocity;
  30. stream.angularVelocity = angularVelocity;
  31. }
  32. else
  33. {
  34. stream.velocity = stream0.velocity;
  35. stream.angularVelocity = stream0.angularVelocity;
  36. }
  37. }
  38. /************************************************************************************************************************/
  39. /// <inheritdoc/>
  40. readonly void IAnimationJob.ProcessAnimation(AnimationStream stream)
  41. {
  42. var stream0 = stream.GetInputStream(0);
  43. var stream1 = stream.GetInputStream(1);
  44. if (stream1.isValid)
  45. {
  46. var layerWeight = stream.GetInputWeight(1);
  47. var handleCount = boneTransforms.Length;
  48. for (var i = 0; i < handleCount; i++)
  49. {
  50. var handle = boneTransforms[i];
  51. var weight = layerWeight * boneWeights[i];
  52. var position0 = handle.GetLocalPosition(stream0);
  53. var position1 = handle.GetLocalPosition(stream1);
  54. handle.SetLocalPosition(stream, Vector3.LerpUnclamped(position0, position1, weight));
  55. var rotation0 = handle.GetLocalRotation(stream0);
  56. var rotation1 = handle.GetLocalRotation(stream1);
  57. handle.SetLocalRotation(stream, Quaternion.SlerpUnclamped(rotation0, rotation1, weight));
  58. }
  59. }
  60. else
  61. {
  62. var handleCount = boneTransforms.Length;
  63. for (var i = 0; i < handleCount; i++)
  64. {
  65. var handle = boneTransforms[i];
  66. handle.SetLocalPosition(stream, handle.GetLocalPosition(stream0));
  67. handle.SetLocalRotation(stream, handle.GetLocalRotation(stream0));
  68. }
  69. }
  70. }
  71. /************************************************************************************************************************/
  72. }
  73. }