Пример #1
0
    private void Solve(AnimationStream stream)
    {
        AnimationHumanStream humanStream = stream.AsHuman();

        Vector3 bodyPosition      = humanStream.bodyPosition;
        Vector3 bodyPositionDelta = Vector3.zero;
        float   sumWeight         = 0;

        for (int goalIter = 0; goalIter < 4; goalIter++)
        {
            float weight = humanStream.GetGoalWeightPosition((AvatarIKGoal)goalIter);
            weight             = Mathf.Clamp01(weight);
            bodyPositionDelta += (humanStream.GetGoalPosition((AvatarIKGoal)goalIter) - humanStream.GetGoalPositionFromPose((AvatarIKGoal)goalIter)) * weight;
            sumWeight         += weight;
        }

        if (sumWeight > 1)
        {
            bodyPositionDelta /= sumWeight;
        }

        bodyPosition            += bodyPositionDelta;
        humanStream.bodyPosition = bodyPosition;

        if (bodyEffector.body.IsValid(stream))
        {
            bodyEffector.body.SetPosition(stream, bodyPosition);
        }

        humanStream.SolveIK();
    }
        public static void SwapMuscles(this AnimationHumanStream stream, MuscleHandle a, MuscleHandle b)
        {
            var t = stream.GetMuscle(a);

            stream.SetMuscle(a, stream.GetMuscle(b));
            stream.SetMuscle(b, t);
        }
 private void ApplyLookData(AnimationHumanStream stream, IKLookData.JobData data)
 {
     stream.SetLookAtPosition(data.position);
     stream.SetLookAtBodyWeight(data.bodyWeight);
     stream.SetLookAtHeadWeight(data.headWeight);
     stream.SetLookAtEyesWeight(data.eyesWeight);
     stream.SetLookAtClampWeight(data.weightClamp);
 }
Пример #4
0
 private void SetBodyEffector(AnimationStream stream, ref BodyEffectorHandle handle)
 {
     if (handle.body.IsValid(stream))
     {
         AnimationHumanStream humanStream = stream.AsHuman();
         humanStream.bodyRotation = handle.body.GetRotation(stream);
     }
 }
Пример #5
0
 private void SetHintEffector(AnimationStream stream, AvatarIKHint goal, ref HintEffectorHandle handle)
 {
     if (handle.hint.IsValid(stream) && handle.weight.IsValid(stream))
     {
         AnimationHumanStream humanStream = stream.AsHuman();
         humanStream.SetHintPosition(goal, handle.hint.GetPosition(stream));
         humanStream.SetHintWeightPosition(goal, handle.weight.GetFloat(stream));
     }
 }
Пример #6
0
 private void SetEffector(AnimationStream stream, AvatarIKGoal goal, ref EffectorHandle handle)
 {
     if (handle.effector.IsValid(stream) && handle.positionWeight.IsValid(stream) && handle.rotationWeight.IsValid(stream))
     {
         AnimationHumanStream humanStream = stream.AsHuman();
         humanStream.SetGoalPosition(goal, handle.effector.GetPosition(stream));
         humanStream.SetGoalRotation(goal, handle.effector.GetRotation(stream));
         humanStream.SetGoalWeightPosition(goal, handle.positionWeight.GetFloat(stream));
         humanStream.SetGoalWeightRotation(goal, handle.rotationWeight.GetFloat(stream));
     }
 }
Пример #7
0
    private void Solve(AnimationStream stream)
    {
        AnimationHumanStream humanStream = stream.AsHuman();

        bodyPosition = humanStream.bodyPosition;
        Vector3 bodyPositionDelta = SolvePull(stream);

        bodyPosition            += bodyPositionDelta;
        humanStream.bodyPosition = bodyPosition;

        humanStream.SolveIK();
    }
Пример #8
0
 private void SetLookAtEffector(AnimationStream stream, ref LookEffectorHandle handle)
 {
     if (handle.lookAt.IsValid(stream))
     {
         AnimationHumanStream humanStream = stream.AsHuman();
         humanStream.SetLookAtPosition(handle.lookAt.GetPosition(stream));
         humanStream.SetLookAtEyesWeight(handle.eyesWeight.GetFloat(stream));
         humanStream.SetLookAtHeadWeight(handle.headWeight.GetFloat(stream));
         humanStream.SetLookAtBodyWeight(handle.bodyWeight.GetFloat(stream));
         humanStream.SetLookAtClampWeight(handle.clampWeight.GetFloat(stream));
     }
 }
    private void Solve(AnimationStream stream)
    {
        AnimationHumanStream humanStream = stream.AsHuman();

        Vector3 bodyPosition      = humanStream.bodyPosition;
        Vector3 bodyPositionDelta = SolvePull(stream);

        bodyPosition            += bodyPositionDelta;
        humanStream.bodyPosition = bodyPosition;

        if (bodyEffector.body.IsValid(stream))
        {
            bodyEffector.body.SetPosition(stream, bodyPosition);
        }

        humanStream.SolveIK();
    }
Пример #10
0
    private void PrepareSolvePull(AnimationStream stream, NativeArray <LimbPart> limbParts)
    {
        AnimationHumanStream humanStream = stream.AsHuman();

        Vector3 bodyPosition = humanStream.bodyPosition;

        for (int goalIter = 0; goalIter < 4; goalIter++)
        {
            var     effector   = GetEffectorHandle((AvatarIKGoal)goalIter);
            var     limbHandle = GetIKLimbHandle((AvatarIKGoal)goalIter);
            Vector3 top        = limbHandle.top.GetPosition(stream);

            limbParts[goalIter] = new LimbPart {
                localPosition    = top - bodyPosition,
                goalPosition     = humanStream.GetGoalPosition((AvatarIKGoal)goalIter),
                goalWeight       = humanStream.GetGoalWeightPosition((AvatarIKGoal)goalIter),
                goalPullWeight   = effector.pullWeight.GetFloat(stream),
                maximumExtension = limbHandle.maximumExtension,
                stiffness        = stiffness
            };
        }
    }
Пример #11
0
    private Vector3 SolvePull(AnimationStream stream)
    {
        AnimationHumanStream humanStream = stream.AsHuman();

        Vector3 originalBodyPosition = humanStream.bodyPosition;
        Vector3 bodyPosition         = originalBodyPosition;

        NativeArray <LimbPart> limbParts = new NativeArray <LimbPart>(4, Allocator.Temp);

        PrepareSolvePull(stream, limbParts);

        for (int iter = 0; iter < maxPullIteration; iter++)
        {
            Vector3 deltaPosition = Vector3.zero;
            for (int goalIter = 0; goalIter < 4; goalIter++)
            {
                Vector3 top           = bodyPosition + limbParts[goalIter].localPosition;
                Vector3 localForce    = limbParts[goalIter].goalPosition - top;
                float   restLenght    = limbParts[goalIter].maximumExtension;
                float   currentLenght = localForce.magnitude;

                localForce.Normalize();

                var force = Mathf.Max(limbParts[goalIter].stiffness * (currentLenght - restLenght), 0.0f);

                deltaPosition += (localForce * force * limbParts[goalIter].goalPullWeight * limbParts[goalIter].goalWeight);
            }

            deltaPosition /= (maxPullIteration - iter);
            bodyPosition  += deltaPosition;
        }

        limbParts.Dispose();

        return(bodyPosition - originalBodyPosition);
    }
Пример #12
0
        public void ProcessAnimation(AnimationStream stream)
        {
            Vector3    rootPosition;
            Quaternion rootRotation;

            root.GetGlobalTR(stream, out rootPosition, out rootRotation);
            var rootTx = new AffineTransform(rootPosition, rootRotation);

            var mirroredTransforms = new NativeArray <AffineTransform> (mirroringTransforms.Length, Allocator.Temp);

            // 追加トランスフォームのミラーリング計算
            if (mirror)
            {
                for (int i = 0; i < mirroringTransforms.Length; i++)
                {
                    if (!mirroringTransforms[i].source.IsValid(stream))
                    {
                        continue;
                    }
                    if (!mirroringTransforms[i].driven.IsValid(stream))
                    {
                        continue;
                    }

                    Vector3    position;
                    Quaternion rotation;
                    mirroringTransforms[i].source.GetGlobalTR(stream, out position, out rotation);

                    var drivenTx = new AffineTransform(position, rotation);
                    drivenTx = rootTx.Inverse() * drivenTx;
                    drivenTx = AnimationStreamMirrorExtensions.Mirrored(drivenTx);
                    drivenTx = rootTx * drivenTx;
                    mirroredTransforms[i] = drivenTx;
                }
            }

            // Humanoid ミラーリング
            if (stream.isHumanStream)
            {
                AnimationHumanStream humanStream = stream.AsHuman();

                if (mirror)
                {
                    humanStream.MirrorPose();
                }

                humanStream.SolveIK();
            }

            // 追加トランスフォームのミラーリング適用
            if (mirror)
            {
                for (int i = 0; i < mirroringTransforms.Length; i++)
                {
                    if (!mirroringTransforms[i].source.IsValid(stream))
                    {
                        continue;
                    }
                    if (!mirroringTransforms[i].driven.IsValid(stream))
                    {
                        continue;
                    }

                    mirroringTransforms[i].driven.SetGlobalTR(stream, mirroredTransforms[i].position, mirroredTransforms[i].rotation, false);
                }
            }

            // 追加トランスフォームのミラーリング拘束
            if (mirror)
            {
                for (int i = 0; i < mirroringConstrants.Length; i++)
                {
                    if (!mirroringConstrants[i].source.IsValid(stream))
                    {
                        continue;
                    }
                    if (!mirroringConstrants[i].driven.IsValid(stream))
                    {
                        continue;
                    }

                    Vector3    position;
                    Quaternion rotation;
                    mirroringConstrants[i].source.GetGlobalTR(stream, out position, out rotation);
                    mirroringConstrants[i].driven.SetGlobalTR(stream, position, rotation, false);
                }
            }
        }
Пример #13
0
    private void SyncIKFromPose()
    {
        var selectedTransform = Selection.transforms;

        var stream = new AnimationStream();

        if (m_Animator.OpenAnimationStream(ref stream))
        {
            AnimationHumanStream humanStream = stream.AsHuman();

            // don't sync if transform is currently selected
            if (!Array.Exists(selectedTransform, tr => tr == m_LeftFootEffector.transform))
            {
                m_LeftFootEffector.transform.position = humanStream.GetGoalPositionFromPose(AvatarIKGoal.LeftFoot);
                m_LeftFootEffector.transform.rotation = humanStream.GetGoalRotationFromPose(AvatarIKGoal.LeftFoot);
            }

            if (!Array.Exists(selectedTransform, tr => tr == m_RightFootEffector.transform))
            {
                m_RightFootEffector.transform.position = humanStream.GetGoalPositionFromPose(AvatarIKGoal.RightFoot);
                m_RightFootEffector.transform.rotation = humanStream.GetGoalRotationFromPose(AvatarIKGoal.RightFoot);
            }

            if (!Array.Exists(selectedTransform, tr => tr == m_LeftHandEffector.transform))
            {
                m_LeftHandEffector.transform.position = humanStream.GetGoalPositionFromPose(AvatarIKGoal.LeftHand);
                m_LeftHandEffector.transform.rotation = humanStream.GetGoalRotationFromPose(AvatarIKGoal.LeftHand);
            }

            if (!Array.Exists(selectedTransform, tr => tr == m_RightHandEffector.transform))
            {
                m_RightHandEffector.transform.position = humanStream.GetGoalPositionFromPose(AvatarIKGoal.RightHand);
                m_RightHandEffector.transform.rotation = humanStream.GetGoalRotationFromPose(AvatarIKGoal.RightHand);
            }

            if (!Array.Exists(selectedTransform, tr => tr == m_LeftKneeHintEffector.transform))
            {
                m_LeftKneeHintEffector.transform.position = humanStream.GetHintPosition(AvatarIKHint.LeftKnee);
            }

            if (!Array.Exists(selectedTransform, tr => tr == m_RightKneeHintEffector.transform))
            {
                m_RightKneeHintEffector.transform.position = humanStream.GetHintPosition(AvatarIKHint.RightKnee);
            }

            if (!Array.Exists(selectedTransform, tr => tr == m_LeftElbowHintEffector.transform))
            {
                m_LeftElbowHintEffector.transform.position = humanStream.GetHintPosition(AvatarIKHint.LeftElbow);
            }

            if (!Array.Exists(selectedTransform, tr => tr == m_RightElbowHintEffector.transform))
            {
                m_RightElbowHintEffector.transform.position = humanStream.GetHintPosition(AvatarIKHint.RightElbow);
            }

            if (!Array.Exists(selectedTransform, tr => tr == m_BodyRotationEffector.transform))
            {
                m_BodyRotationEffector.transform.position = humanStream.bodyPosition;
                m_BodyRotationEffector.transform.rotation = humanStream.bodyRotation;
            }

            m_Animator.CloseAnimationStream(ref stream);
        }
    }
        private void ApplyLimbData(AnimationHumanStream stream, IKLimbData.JobData data, AvatarIKGoal goal, AvatarIKHint hint)
        {
            if (data.positionWeight > 0)
            {
                if (data.positionWeight >= 1)
                {
                    stream.SetGoalPosition(goal, data.position);
                    stream.SetGoalWeightPosition(goal, 1f);
                }
                else
                {
                    var position       = Vector3.Lerp(stream.GetGoalPosition(goal), data.position, data.positionWeight);
                    var positionWeight = Mathf.Lerp(stream.GetGoalWeightPosition(goal), 1f, data.positionWeight);

                    stream.SetGoalPosition(goal, position);
                    stream.SetGoalWeightPosition(goal, positionWeight);
                }
            }
            else
            {
                // For some reason, IK will be broken if same values are not reapplied before SolveIK is called
                stream.SetGoalPosition(goal, stream.GetGoalPosition(goal));
                stream.SetGoalWeightPosition(goal, stream.GetGoalWeightPosition(goal));
            }

            if (data.rotationWeight > 0)
            {
                if (data.rotationWeight >= 1)
                {
                    stream.SetGoalRotation(goal, data.rotation);
                    stream.SetGoalWeightRotation(goal, 1f);
                }
                else
                {
                    var rotation       = Quaternion.Slerp(stream.GetGoalRotation(goal), data.rotation, data.rotationWeight);
                    var rotationWeight = Mathf.Lerp(stream.GetGoalWeightRotation(goal), 1f, data.rotationWeight);

                    stream.SetGoalRotation(goal, rotation);
                    stream.SetGoalWeightRotation(goal, rotationWeight);
                }
            }
            else
            {
                // Same as above
                stream.SetGoalRotation(goal, stream.GetGoalRotation(goal));
                stream.SetGoalWeightRotation(goal, stream.GetGoalWeightRotation(goal));
            }

            if (data.hintWeight > 0)
            {
                if (data.hintWeight >= 1)
                {
                    stream.SetHintPosition(hint, data.hintPosition);
                    stream.SetHintWeightPosition(hint, 1f);
                }
                else
                {
                    var hintPosition = Vector3.Lerp(stream.GetHintPosition(hint), data.hintPosition, data.hintWeight);
                    var hintWeight   = Mathf.Lerp(stream.GetHintWeightPosition(hint), 1f, data.hintWeight);

                    stream.SetHintPosition(hint, hintPosition);
                    stream.SetHintWeightPosition(hint, hintWeight);
                }
            }
            else
            {
                // Same as above
                stream.SetHintPosition(hint, stream.GetHintPosition(hint));
                stream.SetHintWeightPosition(hint, stream.GetHintWeightPosition(hint));
            }
        }
        public static void MirrorPose(this AnimationHumanStream humanStream)
        {
            // mirror body
            for (int i = 0; i < (int)BodyDof.LastBodyDof; i++)
            {
                humanStream.MultMuscle(new MuscleHandle((BodyDof)i), BodyDoFMirror[i]);
            }

            // mirror head
            for (int i = 0; i < (int)HeadDof.LastHeadDof; i++)
            {
                humanStream.MultMuscle(new MuscleHandle((HeadDof)i), HeadDoFMirror[i]);
            }

            // swap arms
            for (int i = 0; i < (int)ArmDof.LastArmDof; i++)
            {
                humanStream.SwapMuscles(
                    new MuscleHandle(HumanPartDof.LeftArm, (ArmDof)i),
                    new MuscleHandle(HumanPartDof.RightArm, (ArmDof)i));
            }

            // swap legs
            for (int i = 0; i < (int)LegDof.LastLegDof; i++)
            {
                humanStream.SwapMuscles(
                    new MuscleHandle(HumanPartDof.LeftLeg, (LegDof)i),
                    new MuscleHandle(HumanPartDof.RightLeg, (LegDof)i));
            }

            // swap fingers
            for (int i = 0; i < (int)FingerDof.LastFingerDof; i++)
            {
                humanStream.SwapMuscles(
                    new MuscleHandle(HumanPartDof.LeftThumb, (FingerDof)i),
                    new MuscleHandle(HumanPartDof.RightThumb, (FingerDof)i));
                humanStream.SwapMuscles(
                    new MuscleHandle(HumanPartDof.LeftIndex, (FingerDof)i),
                    new MuscleHandle(HumanPartDof.RightIndex, (FingerDof)i));
                humanStream.SwapMuscles(
                    new MuscleHandle(HumanPartDof.LeftMiddle, (FingerDof)i),
                    new MuscleHandle(HumanPartDof.RightMiddle, (FingerDof)i));
                humanStream.SwapMuscles(
                    new MuscleHandle(HumanPartDof.LeftRing, (FingerDof)i),
                    new MuscleHandle(HumanPartDof.RightRing, (FingerDof)i));
                humanStream.SwapMuscles(
                    new MuscleHandle(HumanPartDof.LeftLittle, (FingerDof)i),
                    new MuscleHandle(HumanPartDof.RightLittle, (FingerDof)i));
            }


            humanStream.bodyLocalPosition = Mirrored(humanStream.bodyLocalPosition);

            // mirror rotation (invert Y axis angle)
            humanStream.bodyLocalRotation = Mirrored(humanStream.bodyLocalRotation);

            // swap ik
            Vector3[]    goalPositions       = new Vector3[4];
            Quaternion[] goalRotations       = new Quaternion[4];
            float[]      goalWeightPositons  = new float[4];
            float[]      goalWeightRotations = new float[4];
            Vector3[]    hintPositions       = new Vector3[4];
            float[]      hintWeightPositions = new float[4];
            for (int i = 0; i < 4; i++)
            {
                goalPositions[i]       = humanStream.GetGoalLocalPosition(AvatarIKGoal.LeftFoot + i);
                goalRotations[i]       = humanStream.GetGoalLocalRotation(AvatarIKGoal.LeftFoot + i);
                goalWeightPositons[i]  = humanStream.GetGoalWeightPosition(AvatarIKGoal.LeftFoot + i);
                goalWeightRotations[i] = humanStream.GetGoalWeightRotation(AvatarIKGoal.LeftFoot + i);
                hintPositions[i]       = humanStream.GetHintPosition(AvatarIKHint.LeftKnee + i);
                hintWeightPositions[i] = humanStream.GetHintWeightPosition(AvatarIKHint.LeftKnee + i);
            }
            for (int i = 0; i < 4; i++)
            {
                int j = (i + 1) % 2 + (i / 2) * 2;                  // make [1, 0, 3, 2]
                humanStream.SetGoalLocalPosition(AvatarIKGoal.LeftFoot + i, Mirrored(goalPositions[j]));
                humanStream.SetGoalLocalRotation(AvatarIKGoal.LeftFoot + i, Mirrored(goalRotations[j]));
                humanStream.SetGoalWeightPosition(AvatarIKGoal.LeftFoot + i, goalWeightPositons[j]);
                humanStream.SetGoalWeightRotation(AvatarIKGoal.LeftFoot + i, goalWeightRotations[j]);
                humanStream.SetHintPosition(AvatarIKHint.LeftKnee + i, hintPositions[j]);
                humanStream.SetHintWeightPosition(AvatarIKHint.LeftKnee + i, hintWeightPositions[j]);
            }
        }
 public static void MultMuscle(this AnimationHumanStream stream, MuscleHandle h, float f)
 {
     stream.SetMuscle(h, f * stream.GetMuscle(h));
 }