Ejemplo n.º 1
0
        /// <summary>
        /// Upgrades old animations (GR2 files with header version v6) to the new CurveData format
        /// </summary>
        public void UpgradeToGr7()
        {
            // Skip if we've already upgraded
            if (this.CurveData != null)
            {
                return;
            }

            if (this.Degree == 0)
            {
                // Degree 0 curves are identities in all cases
                var curve = new DaIdentity();
                curve.CurveDataHeader_DaIdentity        = new CurveDataHeader();
                curve.CurveDataHeader_DaIdentity.Format = (byte)CurveFormat.DaIdentity;
                curve.CurveDataHeader_DaIdentity.Degree = 0;
                this.CurveData = curve;
            }
            else if (this.Degree == 2)
            {
                if (this.Knots == null || this.Controls == null)
                {
                    throw new InvalidOperationException("Could not upgrade animation curve: knots/controls unavailable");
                }

                // Degree 2 curves are stored in K32fC32f (v6 didn't support multiple curve formats)
                var curve = new DaK32fC32f();
                curve.CurveDataHeader_DaK32fC32f        = new CurveDataHeader();
                curve.CurveDataHeader_DaK32fC32f.Format = (byte)CurveFormat.DaK32fC32f;
                curve.CurveDataHeader_DaK32fC32f.Degree = 2;
                curve.Controls = Controls;
                curve.Knots    = Knots;
                this.CurveData = curve;
            }
            else
            {
                throw new InvalidOperationException("Could not upgrade animation curve: Unsupported curve degree");
            }
        }
Ejemplo n.º 2
0
        public static TransformTrack FromKeyframes(KeyframeTrack keyframes)
        {
            var track = new TransformTrack();

            track.Flags = 0;

            var translateTimes = keyframes.Keyframes.Where(f => f.Value.HasTranslation).Select(f => f.Key).ToList();
            var translations   = keyframes.Keyframes.Where(f => f.Value.HasTranslation).Select(f => f.Value.Translation).ToList();

            if (translateTimes.Count == 1)
            {
                var posCurve = new D3Constant32f();
                posCurve.CurveDataHeader_D3Constant32f = new CurveDataHeader {
                    Format = (int)CurveFormat.D3Constant32f, Degree = 2
                };
                posCurve.Controls = new float[3] {
                    translations[0].X, translations[0].Y, translations[0].Z
                };
                track.PositionCurve = new AnimationCurve {
                    CurveData = posCurve
                };
            }
            else
            {
                var posCurve = new DaK32fC32f();
                posCurve.CurveDataHeader_DaK32fC32f = new CurveDataHeader {
                    Format = (int)CurveFormat.DaK32fC32f, Degree = 2
                };
                posCurve.SetKnots(translateTimes);
                posCurve.SetPoints(translations);
                track.PositionCurve = new AnimationCurve {
                    CurveData = posCurve
                };
            }

            var rotationTimes = keyframes.Keyframes.Where(f => f.Value.HasRotation).Select(f => f.Key).ToList();
            var rotations     = keyframes.Keyframes.Where(f => f.Value.HasRotation).Select(f => f.Value.Rotation).ToList();

            if (rotationTimes.Count == 1)
            {
                var rotCurve = new D4Constant32f();
                rotCurve.CurveDataHeader_D4Constant32f = new CurveDataHeader {
                    Format = (int)CurveFormat.D4Constant32f, Degree = 2
                };
                rotCurve.Controls = new float[4] {
                    rotations[0].X, rotations[0].Y, rotations[0].Z, rotations[0].W
                };
                track.OrientationCurve = new AnimationCurve {
                    CurveData = rotCurve
                };
            }
            else
            {
                var rotCurve = new DaK32fC32f();
                rotCurve.CurveDataHeader_DaK32fC32f = new CurveDataHeader {
                    Format = (int)CurveFormat.DaK32fC32f, Degree = 2
                };
                rotCurve.SetKnots(rotationTimes);
                rotCurve.SetQuaternions(rotations);
                track.OrientationCurve = new AnimationCurve {
                    CurveData = rotCurve
                };
            }

            var scaleTimes = keyframes.Keyframes.Where(f => f.Value.HasScaleShear).Select(f => f.Key).ToList();
            var scales     = keyframes.Keyframes.Where(f => f.Value.HasScaleShear).Select(f => f.Value.ScaleShear).ToList();

            if (scaleTimes.Count == 1)
            {
                var scaleCurve = new DaConstant32f();
                scaleCurve.CurveDataHeader_DaConstant32f = new CurveDataHeader {
                    Format = (int)CurveFormat.DaConstant32f, Degree = 2
                };
                var m = scales[0];
                scaleCurve.Controls = new List <float>
                {
                    m[0, 0], m[0, 1], m[0, 2],
                    m[1, 0], m[1, 1], m[1, 2],
                    m[2, 0], m[2, 1], m[2, 2]
                };
                track.ScaleShearCurve = new AnimationCurve {
                    CurveData = scaleCurve
                };
            }
            else
            {
                var scaleCurve = new DaK32fC32f();
                scaleCurve.CurveDataHeader_DaK32fC32f = new CurveDataHeader {
                    Format = (int)CurveFormat.DaK32fC32f, Degree = 2
                };
                scaleCurve.SetKnots(scaleTimes);
                scaleCurve.SetMatrices(scales);
                track.ScaleShearCurve = new AnimationCurve {
                    CurveData = scaleCurve
                };
            }

            return(track);
        }
Ejemplo n.º 3
0
        public TransformTrack MakeTrack()
        {
            var track = new TransformTrack();

            track.Flags = 0;
            track.Name  = Bone.Name;

            var positions = Transforms.Select(m => m.ExtractTranslation()).ToList();
            var rotations = Transforms.Select(m => m.ExtractRotation()).ToList();
            var scales    = Transforms.Select(m => ScaleToScaleShear(m.ExtractScale())).ToList();

            // Quaternion sign fixup
            // Since GR2 interpolation operates on the raw XYZ values of the quaternion, two subsequent quaternions
            // that express the same rotation (eg. [1, 0.5, 0.5, -0.5] and [1, -0.5, -0.5, 0.5]) will result in a 360 deg
            // rotation during the animation. Shuffle XYZ signs around to make this less likely to happen
            for (var i = 1; i < rotations.Count; i++)
            {
                var r0  = rotations[i - 1];
                var r1  = rotations[i];
                var dot = r0.W * r1.W + r0.X * r1.X + r0.Y * r1.Y + r0.Z * r1.Z;
                if (dot < 0.0)
                {
                    rotations[i] = new Quaternion(-r1.X, -r1.Y, -r1.Z, r1.W);
                }
            }

            var posTimes     = Times;
            var minPositions = positions;

            RemoveTrivialFrames(ref posTimes, ref minPositions);
            if (minPositions.Count == 1)
            {
                var posCurve = new D3Constant32f();
                posCurve.CurveDataHeader_D3Constant32f = new CurveDataHeader {
                    Format = (int)CurveFormat.D3Constant32f, Degree = 2
                };
                posCurve.Controls = new float[3] {
                    positions[0].X, positions[0].Y, positions[0].Z
                };
                track.PositionCurve = new AnimationCurve {
                    CurveData = posCurve
                };
            }
            else
            {
                var posCurve = new DaK32fC32f();
                posCurve.CurveDataHeader_DaK32fC32f = new CurveDataHeader {
                    Format = (int)CurveFormat.DaK32fC32f, Degree = 2
                };
                posCurve.SetKnots(Times);
                posCurve.SetPoints(positions);
                track.PositionCurve = new AnimationCurve {
                    CurveData = posCurve
                };
            }

            var rotTimes     = Times;
            var minRotations = rotations;

            RemoveTrivialFrames(ref rotTimes, ref minRotations);
            if (minRotations.Count == 1)
            {
                var rotCurve = new D4Constant32f();
                rotCurve.CurveDataHeader_D4Constant32f = new CurveDataHeader {
                    Format = (int)CurveFormat.D4Constant32f, Degree = 2
                };
                rotCurve.Controls = new float[4] {
                    rotations[0].X, rotations[0].Y, rotations[0].Z, rotations[0].W
                };
                track.OrientationCurve = new AnimationCurve {
                    CurveData = rotCurve
                };
            }
            else
            {
                var rotCurve = new DaK32fC32f();
                rotCurve.CurveDataHeader_DaK32fC32f = new CurveDataHeader {
                    Format = (int)CurveFormat.DaK32fC32f, Degree = 2
                };
                rotCurve.SetKnots(Times);
                rotCurve.SetQuaternions(rotations);
                track.OrientationCurve = new AnimationCurve {
                    CurveData = rotCurve
                };
            }

            var scaleTimes = Times;
            var minScales  = scales;

            RemoveTrivialFrames(ref scaleTimes, ref minScales);
            if (minScales.Count == 1)
            {
                var scaleCurve = new DaConstant32f();
                scaleCurve.CurveDataHeader_DaConstant32f = new CurveDataHeader {
                    Format = (int)CurveFormat.DaConstant32f, Degree = 2
                };
                var m = minScales[0];
                scaleCurve.Controls = new List <float>
                {
                    m[0, 0], m[0, 1], m[0, 2],
                    m[1, 0], m[1, 1], m[1, 2],
                    m[2, 0], m[2, 1], m[2, 2]
                };
                track.ScaleShearCurve = new AnimationCurve {
                    CurveData = scaleCurve
                };
            }
            else
            {
                var scaleCurve = new DaK32fC32f();
                scaleCurve.CurveDataHeader_DaK32fC32f = new CurveDataHeader {
                    Format = (int)CurveFormat.DaK32fC32f, Degree = 2
                };
                scaleCurve.SetKnots(Times);
                scaleCurve.SetMatrices(scales);
                track.ScaleShearCurve = new AnimationCurve {
                    CurveData = scaleCurve
                };
            }

            return(track);
        }