| 589 | } |
| 590 | |
| 591 | static void ApplyAnimation(RigInstance* instance, RigPlayer* player, dmArray<BonePose>& pose, dmArray<IKAnimation>& ik_animation, float blend_weight) |
| 592 | { |
| 593 | const dmRigDDF::RigAnimation* animation = player->m_Animation; |
| 594 | if (!animation) |
| 595 | return; |
| 596 | float duration = GetCursorDuration(player, animation); |
| 597 | float t = CursorToTime(player->m_Cursor, duration, player->m_Backwards, player->m_Playback == dmRig::PLAYBACK_ONCE_PINGPONG); |
| 598 | |
| 599 | float fraction = t * animation->m_SampleRate; |
| 600 | uint32_t sample = (uint32_t)fraction; |
| 601 | fraction -= sample; |
| 602 | // Sample skeletal tracks (skip when there is no skeleton / bone map, e.g. morph-only rigs) |
| 603 | const dmHashTable64<uint32_t>* bone_indices = instance->m_BoneIndices; |
| 604 | uint32_t track_count = animation->m_Tracks.m_Count; |
| 605 | if (bone_indices) |
| 606 | { |
| 607 | for (uint32_t ti = 0; ti < track_count; ++ti) |
| 608 | { |
| 609 | const dmRigDDF::AnimationTrack* track = &animation->m_Tracks[ti]; |
| 610 | |
| 611 | const uint32_t* bone_index = bone_indices->Get(track->m_BoneId); |
| 612 | if (!bone_index || *bone_index >= pose.Size()) { |
| 613 | continue; |
| 614 | } |
| 615 | dmTransform::Transform& transform = pose[*bone_index].m_Local; |
| 616 | |
| 617 | if (track->m_Positions.m_Count > 0) |
| 618 | { |
| 619 | Vector3 v; |
| 620 | if (track->m_Positions.m_Count == 3) |
| 621 | v = Vector3(track->m_Positions.m_Data[0], track->m_Positions.m_Data[1], track->m_Positions.m_Data[2]); |
| 622 | else |
| 623 | v = SampleVec3(sample, fraction, track->m_Positions.m_Data); |
| 624 | |
| 625 | transform.SetTranslation(lerp(blend_weight, transform.GetTranslation(), v)); |
| 626 | } |
| 627 | if (track->m_Rotations.m_Count > 0) |
| 628 | { |
| 629 | Quat q; |
| 630 | if (track->m_Rotations.m_Count == 4) |
| 631 | q = Quat(track->m_Rotations.m_Data[0], track->m_Rotations.m_Data[1], track->m_Rotations.m_Data[2], track->m_Rotations.m_Data[3]); |
| 632 | else |
| 633 | q = SampleQuat(sample, fraction, track->m_Rotations.m_Data); |
| 634 | |
| 635 | transform.SetRotation(slerp(blend_weight, transform.GetRotation(), q)); |
| 636 | } |
| 637 | if (track->m_Scale.m_Count > 0) |
| 638 | { |
| 639 | Vector3 s; |
| 640 | if (track->m_Scale.m_Count == 3) |
| 641 | s = Vector3(track->m_Scale.m_Data[0], track->m_Scale.m_Data[1], track->m_Scale.m_Data[2]); |
| 642 | else |
| 643 | s = SampleVec3(sample, fraction, track->m_Scale.m_Data); |
| 644 | |
| 645 | transform.SetScale(lerp(blend_weight, transform.GetScale(), s)); |
| 646 | } |
| 647 | } |
| 648 | } |
no test coverage detected