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)); }
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)); }