예제 #1
0
        public static Quaternion GetQuaternion(IBcx bcx, int jointIndex, float time)
        {
            var animatedJoint = bcx.Anx1.Joints[jointIndex];
            var values        = animatedJoint.Values;

            var xRadians = animatedJoint.GetAnimValue(values.rotationsX, time);
            var yRadians = animatedJoint.GetAnimValue(values.rotationsY, time);
            var zRadians = animatedJoint.GetAnimValue(values.rotationsZ, time);

            return(QuaternionUtil.Create(xRadians, yRadians, zRadians));
        }
예제 #2
0
 public static IFinMatrix4x4 FromRotation(IRotation rotation)
 => MatrixTransformUtil.FromRotation(QuaternionUtil.Create(rotation));
            public Quaternion GetInterpolatedFrame(
                float frame,
                IOptional <float[]>?defaultAxes = null,
                bool useLoopingInterpolation    = false)
            {
                var xTrack = this.axisTracks_[0];
                var yTrack = this.axisTracks_[1];
                var zTrack = this.axisTracks_[2];

                var keyframe = (int)frame;

                // TODO: Properly interpolate between first and final keyframe
                // TODO: Fix gimbal lock

                /*xTrack.FindIndexOfKeyframe(keyframe,
                 *                         out var xKeyframeIndex,
                 *                         out var xRadiansKeyframe,
                 *                         out var xKeyframeDefined,
                 *                         out var xPastEnd);
                 * yTrack.FindIndexOfKeyframe(keyframe,
                 *                         out var yKeyframeIndex,
                 *                         out var yRadiansKeyframe,
                 *                         out var yKeyframeDefined,
                 *                         out var yPastEnd);
                 * zTrack.FindIndexOfKeyframe(keyframe,
                 *                         out var zKeyframeIndex,
                 *                         out var zRadiansKeyframe,
                 *                         out var zKeyframeDefined,
                 *                         out var zPastEnd);
                 *
                 * var fromXRadians = xRadiansKeyframe.Pluck(keyframe => keyframe.Value)
                 *                             .Or(this.defaultRotation_)
                 *                             .Assert();
                 * var fromYRadians = yRadiansKeyframe.Pluck(keyframe => keyframe.Value)
                 *                             .Or(this.defaultRotation_)
                 *                             .Assert();
                 * var fromZRadians = zRadiansKeyframe.Pluck(keyframe => keyframe.Value)
                 *                             .Or(this.defaultRotation_)
                 *                             .Assert();
                 *
                 * var xKeyframes = this.axisTracks_[0].Keyframes;
                 * if (xKeyframeIndex < xKeyframes.Count) {
                 *
                 * }*/

                var defaultX = defaultAxes == null
                           ? this.defaultRotation_
                           : defaultAxes.Pluck(axes => axes[0])
                               .Or(this.defaultRotation_);
                var defaultY = defaultAxes == null
                           ? this.defaultRotation_
                           : defaultAxes.Pluck(axes => axes[1])
                               .Or(this.defaultRotation_);
                var defaultZ = defaultAxes == null
                           ? this.defaultRotation_
                           : defaultAxes.Pluck(axes => axes[2])
                               .Or(this.defaultRotation_);

                xTrack.GetInterpolationData(
                    frame,
                    defaultX,
                    out var fromXFrame,
                    out var toXFrame,
                    useLoopingInterpolation);
                yTrack.GetInterpolationData(
                    frame,
                    defaultY,
                    out var fromYFrame,
                    out var toYFrame,
                    useLoopingInterpolation);
                zTrack.GetInterpolationData(
                    frame,
                    defaultZ,
                    out var fromZFrame,
                    out var toZFrame,
                    useLoopingInterpolation);

                if (!RadiansRotationTrackImpl.CanInterpolateWithQuaternions_(
                        fromXFrame, fromYFrame, fromZFrame,
                        toXFrame, toYFrame, toZFrame))
                {
                    var xRadians =
                        xTrack.GetInterpolatedFrame(frame, defaultX,
                                                    useLoopingInterpolation)
                        .Assert();
                    var yRadians =
                        yTrack.GetInterpolatedFrame(frame, defaultY,
                                                    useLoopingInterpolation)
                        .Assert();
                    var zRadians =
                        zTrack.GetInterpolatedFrame(frame, defaultZ,
                                                    useLoopingInterpolation)
                        .Assert();

                    return(QuaternionUtil.Create(xRadians, yRadians, zRadians));
                }

                var fromFrame  = fromXFrame.Value.frame;
                var toFrame    = toXFrame.Value.frame;
                var frameDelta = (frame - fromFrame) / (toFrame - fromFrame);

                var q1 = QuaternionUtil.Create(
                    fromXFrame.Value.value,
                    fromYFrame.Value.value,
                    fromZFrame.Value.value);
                var q2 = QuaternionUtil.Create(
                    toXFrame.Value.value,
                    toYFrame.Value.value,
                    toZFrame.Value.value);

                if (Quaternion.Dot(q1, q2) < 0)
                {
                    q2 = -q2;
                }

                var interp = Quaternion.Slerp(q1, q2, frameDelta);

                return(Quaternion.Normalize(interp));
            }