| 1744 | } |
| 1745 | |
| 1746 | Result InstanceCreate(HRigContext context, const InstanceCreateParams& params, HRigInstance* out_instance) |
| 1747 | { |
| 1748 | if (context->m_Instances.Full()) |
| 1749 | { |
| 1750 | dmLogError("Rig instance could not be created since the buffer is full (%d).", context->m_Instances.Capacity()); |
| 1751 | return dmRig::RESULT_ERROR_BUFFER_FULL; |
| 1752 | } |
| 1753 | |
| 1754 | RigInstance* instance = new RigInstance; |
| 1755 | memset(instance, 0, sizeof(RigInstance)); |
| 1756 | |
| 1757 | uint32_t index = context->m_Instances.Alloc(); |
| 1758 | instance->m_Index = index; |
| 1759 | context->m_Instances.Set(index, instance); |
| 1760 | instance->m_ModelId = params.m_ModelId; |
| 1761 | |
| 1762 | instance->m_PoseCallback = params.m_PoseCallback; |
| 1763 | instance->m_PoseCBUserData1 = params.m_PoseCBUserData1; |
| 1764 | instance->m_PoseCBUserData2 = params.m_PoseCBUserData2; |
| 1765 | instance->m_EventCallback = params.m_EventCallback; |
| 1766 | instance->m_EventCBUserData1 = params.m_EventCBUserData1; |
| 1767 | instance->m_EventCBUserData2 = params.m_EventCBUserData2; |
| 1768 | |
| 1769 | instance->m_BindPose = params.m_BindPose; |
| 1770 | instance->m_BoneIndices = params.m_BoneIndices; |
| 1771 | instance->m_Skeleton = params.m_Skeleton; |
| 1772 | instance->m_MeshSet = params.m_MeshSet; |
| 1773 | instance->m_AnimationSet = params.m_AnimationSet; |
| 1774 | |
| 1775 | InitMorphSlots(instance); |
| 1776 | |
| 1777 | instance->m_PoseMatrixCacheIndex = INVALID_POSE_MATRIX_CACHE_ENTRY; |
| 1778 | |
| 1779 | instance->m_Enabled = 1; |
| 1780 | |
| 1781 | SetModel(instance, instance->m_ModelId); |
| 1782 | |
| 1783 | instance->m_MaxBoneCount = dmMath::Max(instance->m_MeshSet->m_MaxBoneCount, instance->m_Skeleton == 0x0 ? 0 : instance->m_Skeleton->m_Bones.m_Count); |
| 1784 | Result result = CreatePose(context, instance); |
| 1785 | if (result != dmRig::RESULT_OK) { |
| 1786 | DestroyInstance(context, index); |
| 1787 | return result; |
| 1788 | } |
| 1789 | |
| 1790 | if (params.m_DefaultAnimation != NULL_ANIMATION) |
| 1791 | { |
| 1792 | // Loop forward should be the most common for idle anims etc. |
| 1793 | (void)PlayAnimation(instance, params.m_DefaultAnimation, dmRig::PLAYBACK_LOOP_FORWARD, 0.0f, 0.0f, 1.0f); |
| 1794 | } |
| 1795 | |
| 1796 | // m_ForceAnimatePose should be set if the animation step needs to run once (with dt 0) |
| 1797 | // to setup the pose to the current cursor. |
| 1798 | // Useful if pose needs to be calculated before draw but dmRig::Update will not be called |
| 1799 | // before that happens, for example cloning a GUI spine node happens in script update, |
| 1800 | // which comes after the regular dmRig::Update. |
| 1801 | if (params.m_ForceAnimatePose) { |
| 1802 | DoAnimate(context, instance, 0.0f); |
| 1803 | } |