Example #1
0
        public void ProcessAnimation(AnimationStream stream)
        {
            jobWeight.Set(stream, 1f);

            var drivenPos = driven.GetLocalPosition(stream);
            var offset    = drivenOffset.Get(stream);

            var lPos = drivenPos - offset;

            var parentTx = new AffineTransform();

            if (drivenParent.IsValid(stream))
            {
                drivenParent.GetGlobalTR(stream, out Vector3 parentWPos, out Quaternion parentWRot);
                parentTx = new AffineTransform(parentWPos, parentWRot);
            }

            var wPos = parentTx.Transform(lPos);

            for (int i = 0; i < sourceTransforms.Length; ++i)
            {
                sourceWeights[i].SetFloat(stream, 1f);

                ReadWriteTransformHandle sourceTransform = sourceTransforms[i];

                sourceTransform.SetPosition(stream, wPos - sourceOffsets[i]);

                // Required to update handles with binding info.
                sourceTransforms[i] = sourceTransform;
            }
        }
        /// <summary>
        /// Defines what to do when processing the animation.
        /// </summary>
        /// <param name="stream">The animation stream to work on.</param>
        public void ProcessAnimation(AnimationStream stream)
        {
            jobWeight.Set(stream, 1f);

            var lRot   = driven.GetLocalRotation(stream);
            var offset = drivenOffset.Get(stream);

            if (Vector3.Dot(offset, offset) > 0f)
            {
                lRot *= Quaternion.Inverse(Quaternion.Euler(offset));
            }

            var wRot = lRot;

            if (drivenParent.IsValid(stream))
            {
                wRot = drivenParent.GetRotation(stream) * wRot;
            }

            for (int i = 0; i < sourceTransforms.Length; ++i)
            {
                sourceWeights[i].SetFloat(stream, 1f);

                ReadWriteTransformHandle sourceTransform = sourceTransforms[i];

                sourceTransform.SetRotation(stream, wRot * sourceOffsets[i]);

                // Required to update handles with binding info.
                sourceTransforms[i] = sourceTransform;
            }
        }
        public void ProcessAnimation(AnimationStream stream)
        {
            jobWeight.Set(stream, 1f);

            var lRot   = driven.GetLocalRotation(stream);
            var offset = drivenOffset.Get(stream);

            if (Vector3.Dot(offset, offset) > 0f)
            {
                lRot *= Quaternion.Inverse(Quaternion.Euler(offset));
            }

            var localToWorld = Quaternion.identity;
            var wPos         = driven.GetPosition(stream);

            if (drivenParent.IsValid(stream))
            {
                localToWorld = drivenParent.GetRotation(stream);
            }

            for (int i = 0; i < sourceTransforms.Length; ++i)
            {
                sourceWeights[i].SetFloat(stream, 1f);

                var sourceTransform = sourceTransforms[i];

                sourceTransform.SetPosition(stream, wPos + localToWorld * sourceOffsets[i] * lRot * aimAxis);

                // Required to update handles with binding info.
                sourceTransforms[i] = sourceTransform;
            }
        }
Example #4
0
    public void ProcessAnimation(AnimationStream stream)
    {
        var w = jobWeight.Get(stream);

        if (w == 0f)
        {
            return;
        }

        var offset = ikOffset.Get(stream);

        var leftToePos  = leftToe.GetPosition(stream);
        var rightToePos = rightToe.GetPosition(stream);

        var leftIkOffset  = offset.x * w;
        var rightIkOffset = offset.y * w;

        leftToePos  += new Vector3(0f, leftIkOffset, 0f);
        rightToePos += new Vector3(0f, rightIkOffset, 0f);


        var leftAnklePos  = leftAnkle.GetPosition(stream);
        var rightAnklePos = rightAnkle.GetPosition(stream);
        var leftAnkleRot  = leftAnkle.GetRotation(stream);
        var rightAnkleRot = rightAnkle.GetRotation(stream);

        var leftAnkleIkPos  = new Vector3(leftAnklePos.x, leftAnklePos.y + leftIkOffset, leftAnklePos.z);
        var rightAnkleIkPos = new Vector3(rightAnklePos.x, rightAnklePos.y + rightIkOffset, rightAnklePos.z);

        var hipHeightOffset = (leftIkOffset + rightIkOffset) * 0.5f;
        var forwardBackBias = (leftIkOffset - rightIkOffset) * weightShiftHorizontal.Get(stream);

        float maxRotationOffset = maxFootRotationOffset.Get(stream);

        // TODO: (sunek) Rework weight shift to move towards actual lower foot?
        hipHeightOffset += Mathf.Abs(leftIkOffset - rightIkOffset) * weightShiftVertical.Get(stream);
        var standAngle = Quaternion.AngleAxis(weightShiftAngle.Get(stream), Vector3.up) * Vector3.forward;

        hips.SetPosition(stream, hips.GetPosition(stream) + new Vector3(standAngle.x * forwardBackBias, hipHeightOffset, standAngle.z * forwardBackBias));

        // Figure out the normal rotation
        var leftNormalRot  = Quaternion.LookRotation(Vector3.forward, normalLeftFoot.Get(stream));
        var rightNormalRot = Quaternion.LookRotation(Vector3.forward, normalRightFoot.Get(stream));

        // Clamp normal rotation
        var leftAngle  = Quaternion.Angle(Quaternion.identity, leftNormalRot);
        var rightAngle = Quaternion.Angle(Quaternion.identity, rightNormalRot);

        if (leftAngle > maxRotationOffset && maxRotationOffset > 0f)
        {
            var fraction = maxRotationOffset / leftAngle;
            leftNormalRot = Quaternion.Lerp(Quaternion.identity, leftNormalRot, fraction);
        }

        if (rightAngle > maxRotationOffset && maxRotationOffset > 0f)
        {
            var fraction = maxRotationOffset / rightAngle;
            rightNormalRot = Quaternion.Lerp(Quaternion.identity, rightNormalRot, fraction);
        }

        // Apply rotation to ankle
        var leftToesMatrix  = Matrix4x4.TRS(leftToePos, Quaternion.identity, Vector3.one);
        var rightToesMatrix = Matrix4x4.TRS(rightToePos, Quaternion.identity, Vector3.one);

        var leftToesNormalDeltaMatrix  = Matrix4x4.TRS(leftToePos, leftNormalRot, Vector3.one) * leftToesMatrix.inverse;
        var rightToesNormalDeltaMatrix = Matrix4x4.TRS(rightToePos, rightNormalRot, Vector3.one) * rightToesMatrix.inverse;

        var leftAnkleMatrix  = Matrix4x4.TRS(leftAnkleIkPos, leftAnkleRot, Vector3.one) * leftToesMatrix.inverse;
        var rightAnkleMatrix = Matrix4x4.TRS(rightAnkleIkPos, rightAnkleRot, Vector3.one) * rightToesMatrix.inverse;

        leftAnkleMatrix  = leftToesNormalDeltaMatrix * leftAnkleMatrix * leftToesMatrix;
        rightAnkleMatrix = rightToesNormalDeltaMatrix * rightAnkleMatrix * rightToesMatrix;

        leftAnkleIkPos  = leftAnkleMatrix.GetColumn(3);
        rightAnkleIkPos = rightAnkleMatrix.GetColumn(3);

        leftAnkleRot  = Quaternion.Lerp(leftAnkleRot, leftAnkleMatrix.rotation, w);
        rightAnkleRot = Quaternion.Lerp(rightAnkleRot, rightAnkleMatrix.rotation, w);

        // Update ik position
        // TODO: (sunek) Consider combating leg overstretch
        var leftPosition  = Vector3.Lerp(leftAnklePos, leftAnkleIkPos, w);
        var rightPosition = Vector3.Lerp(rightAnklePos, rightAnkleIkPos, w);

        leftEffector.SetPosition(stream, leftPosition);
        rightEffector.SetPosition(stream, rightPosition);
        leftEffector.SetRotation(stream, leftAnkleRot);
        rightEffector.SetRotation(stream, rightAnkleRot);
    }
        public void ProcessAnimation(AnimationStream stream)
        {
            float w = jobWeight.Get(stream);

            if (w > 0f)
            {
                AffineTransform overrideTx;
                if (source.IsValid(stream))
                {
                    source.GetLocalTRS(stream, out Vector3 srcLPos, out Quaternion srcLRot, out _);
                    var sourceLocalTx    = new AffineTransform(srcLPos, srcLRot);
                    var sourceToSpaceRot = cache.Get <Quaternion>(sourceToCurrSpaceRotIdx);
                    overrideTx = Quaternion.Inverse(sourceToSpaceRot) * (sourceInvLocalBindTx * sourceLocalTx) * sourceToSpaceRot;
                }
                else
                {
                    overrideTx = new AffineTransform(position.Get(stream), Quaternion.Euler(rotation.Get(stream)));
                }

                Space overrideSpace = (Space)cache.GetRaw(spaceIdx);
                var   posW          = positionWeight.Get(stream) * w;
                var   rotW          = rotationWeight.Get(stream) * w;
                switch (overrideSpace)
                {
                case Space.World:
                {
                    driven.GetGlobalTR(stream, out Vector3 drivenWPos, out Quaternion drivenWRot);
                    driven.SetGlobalTR(
                        stream,
                        Vector3.Lerp(drivenWPos, overrideTx.translation, posW),
                        Quaternion.Lerp(drivenWRot, overrideTx.rotation, rotW)
                        );
                }
                break;

                case Space.Local:
                {
                    driven.GetLocalTRS(stream, out Vector3 drivenLPos, out Quaternion drivenLRot, out Vector3 drivenLScale);
                    driven.SetLocalTRS(
                        stream,
                        Vector3.Lerp(drivenLPos, overrideTx.translation, posW),
                        Quaternion.Lerp(drivenLRot, overrideTx.rotation, rotW),
                        drivenLScale
                        );
                }
                break;

                case Space.Pivot:
                {
                    driven.GetLocalTRS(stream, out Vector3 drivenLPos, out Quaternion drivenLRot, out Vector3 drivenLScale);
                    var drivenLocalTx = new AffineTransform(drivenLPos, drivenLRot);
                    overrideTx = drivenLocalTx * overrideTx;

                    driven.SetLocalTRS(
                        stream,
                        Vector3.Lerp(drivenLocalTx.translation, overrideTx.translation, posW),
                        Quaternion.Lerp(drivenLocalTx.rotation, overrideTx.rotation, rotW),
                        drivenLScale
                        );
                }
                break;

                default:
                    break;
                }
            }
            else
            {
                AnimationRuntimeUtils.PassThrough(stream, driven);
            }
        }