Search Unity

How to jobify this?

Discussion in 'Entity Component System' started by topitsky, Jul 25, 2019.

  1. topitsky

    topitsky

    Joined:
    Jan 12, 2016
    Posts:
    100
    Code (CSharp):
    1. protected override void OnUpdate()
    2.     {
    3.         var dt = Time.deltaTime;
    4.  
    5.         Entities.ForEach((BonesContainer BC, ref PoserV2 Poser, ref LocalVelocity Velocity, ref IsVisible IsVisible) =>
    6. {
    7.     if (IsVisible.Value == true)
    8.     {
    9.         //check for pose and switch if necessary
    10.         Pose currentPose = PoseManager.Poses[Poser.CurrentPoseId];
    11.         Pose idealPose = PoseManager.GetNearest(Velocity.Value);
    12.  
    13.         //If ideal pose is not the current pose, and currentPose is not the transition of the ideal pose
    14.         if (idealPose.Id != currentPose.Id && idealPose.TransitionId != currentPose.Id)
    15.         {
    16.             Poser.CurrentPoseId = idealPose.Id;
    17.             Poser.isAnimating = true;
    18.         }
    19.         else
    20.         {
    21.             if (Poser.isAnimating)
    22.             {
    23.                 bool ready = true;
    24.  
    25.                 for (int i = 0; i < BC.Bones.Length; i++)
    26.                 {
    27.                     BC.Bones[i].localRotation = math.slerp(BC.Bones[i].localRotation, currentPose.Rotations[i], currentPose.Speed * dt);
    28.  
    29.                     float angle = Quaternion.Angle(BC.Bones[i].localRotation, currentPose.Rotations[i]);
    30.                     if (angle > currentPose.Window) ready = false;
    31.                 }
    32.  
    33.                 if (ready)
    34.                 {
    35.                     Poser.isAnimating = false;
    36.                     if (currentPose.TransitionId != -1)
    37.                     {
    38.                         Pose trans = PoseManager.Poses[currentPose.TransitionId];
    39.                         if (idealPose.Id == trans.Id || idealPose.Id == trans.TransitionId)
    40.                         {
    41.                             Poser.CurrentPoseId = trans.Id;
    42.                             Poser.isAnimating = true;
    43.                         }
    44.                     }
    45.                 }
    46.  
    47.             }
    48.         }
    49.  
    50.     }
    51.  
    52. });
    I have a simple animation system that is done using the hybrid approach.
    1. I collect pose data from monobehaviour "skeletons", which I can edit in the editor view. These are saved into a static class which the systems then can access to find pose data
    2. I store the animators state inside a Poser IComponentData

    My problem is, that I can't really come up with a smart way to store the Animators bone transforms that need to be rotated according to the ideal pose. Currently I'm using a MonoBehaviour that collects all child transforms in the start.

    The performance is allright at the moment, and making new poses is very easy - but I'd really like to Jobify it. The biggest performance eater I've discovered seem to the this part
    Code (CSharp):
    1.                 for (int i = 0; i < BC.Bones.Length; i++)
    2.                 {
    3.                     BC.Bones[i].localRotation = math.slerp(BC.Bones[i].localRotation, currentPose.Rotations[i], currentPose.Speed * dt);
    4.  
    5.                     float angle = Quaternion.Angle(BC.Bones[i].localRotation, currentPose.Rotations[i]);
    6.                     if (angle > currentPose.Window) ready = false;
    7.                 }
    Do you have any suggestions of re-factoring or authoring data in a way that it is more ECS friendly / performant? Even if it is for a small part of the logic?
     
    Last edited: Jul 25, 2019