Beispiel #1
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="jobj"></param>
 /// <param name="figatree"></param>
 public AnimationPlayer(HSD_JOBJ jobj, float frameCount)
 {
     FrameCount = (int)frameCount;
     foreach (var j in jobj.BreathFirstList)
     {
         TrackNode t = new TrackNode(j);
         jobjToTrack.Add(j, t);
     }
     LoadParents(jobj);
 }
Beispiel #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="jobj"></param>
        /// <param name="source"></param>
        /// <param name="source_jobj"></param>
        public bool PortBoneTo(HSD_JOBJ jobj, AnimationPlayer source, HSD_JOBJ source_jobj)
        {
            if (jobjToParent[jobj] == null)
            {
                return(false);
            }

            var targetWorld = GetWorldTransform(jobj);
            var sourceWorld = source.GetWorldTransform(source_jobj);

            Matrix4x4.Invert(sourceWorld, out Matrix4x4 invSourceWorld);

            var targetRotation = TrackNode.FromEulerAngles(jobj.RZ, jobj.RY, jobj.RX);
            var sourceRotation = TrackNode.FromEulerAngles(source_jobj.RZ, source_jobj.RY, source_jobj.RX);

            sourceRotation = Quaternion.Inverse(sourceRotation);

            // if bones have same orientation we can copy keys directly?
            if (ApproximatelySameOrientation(targetWorld, sourceWorld))
            {
                jobjToTrack[jobj] = source.jobjToTrack[source_jobj];
                return(false);
            }

            // otherwise bake
            List <Matrix4x4> transforms = new List <Matrix4x4>();

            for (int i = 0; i <= FrameCount; i++)
            {
                var inTargetParentWorld = GetAnimatedWorldTransform(jobjToParent[jobj], i);
                Matrix4x4.Invert(inTargetParentWorld, out inTargetParentWorld);

                var sourceAnimatedWorld = source.GetAnimatedWorldTransform(source_jobj, i);

                var rel = targetWorld * invSourceWorld * sourceAnimatedWorld;

                var newT = rel * inTargetParentWorld;

                var relTranslate = (new Vector3(source_jobj.TX, source_jobj.TY, source_jobj.TZ) - source.GetAnimatedTransform(source_jobj, i).Translation);
                relTranslate = Vector3.Transform(relTranslate, sourceRotation);
                relTranslate = Vector3.Transform(relTranslate, targetRotation);

                //newT.Translation = new Vector3(jobj.TX, jobj.TY, jobj.TZ);// + relTranslate;

                transforms.Add(newT);
            }

            // then optimize
            jobjToTrack[jobj] = new TrackNode(transforms, source.jobjToTrack[source_jobj], source_jobj, jobj);

            return(true);
        }
Beispiel #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="jobj"></param>
        /// <param name="figatree"></param>
        public AnimationPlayer(HSD_JOBJ jobj, HSD_FigaTree figatree)
        {
            FrameCount = (int)figatree.FrameCount;

            int jobjIndex = 0;

            foreach (var j in jobj.BreathFirstList)
            {
                TrackNode t = new TrackNode(j);

                var node = figatree.Nodes[jobjIndex];

                foreach (var track in node.Tracks)
                {
                    var fobj = track.ToFOBJ();

                    switch (fobj.JointTrackType)
                    {
                    case JointTrackType.HSD_A_J_TRAX: t.X.Keys = fobj.GetDecodedKeys(); break;

                    case JointTrackType.HSD_A_J_TRAY: t.Y.Keys = fobj.GetDecodedKeys(); break;

                    case JointTrackType.HSD_A_J_TRAZ: t.Z.Keys = fobj.GetDecodedKeys(); break;

                    case JointTrackType.HSD_A_J_ROTX: t.RX.Keys = fobj.GetDecodedKeys(); break;

                    case JointTrackType.HSD_A_J_ROTY: t.RY.Keys = fobj.GetDecodedKeys(); break;

                    case JointTrackType.HSD_A_J_ROTZ: t.RZ.Keys = fobj.GetDecodedKeys(); break;

                    case JointTrackType.HSD_A_J_SCAX: t.SX.Keys = fobj.GetDecodedKeys(); break;

                    case JointTrackType.HSD_A_J_SCAY: t.SY.Keys = fobj.GetDecodedKeys(); break;

                    case JointTrackType.HSD_A_J_SCAZ: t.SZ.Keys = fobj.GetDecodedKeys(); break;
                    }
                }

                jobjToTrack.Add(j, t);

                jobjIndex++;
            }

            LoadParents(jobj);
        }
Beispiel #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="mat"></param>
        public TrackNode(List <Matrix4x4> transforms, TrackNode sourceTrack, HSD_JOBJ source, HSD_JOBJ dest)
        {
            List <float> x  = new List <float>();
            List <float> y  = new List <float>();
            List <float> z  = new List <float>();
            List <float> rx = new List <float>();
            List <float> ry = new List <float>();
            List <float> rz = new List <float>();
            List <float> sx = new List <float>();
            List <float> sy = new List <float>();
            List <float> sz = new List <float>();

            foreach (var t in transforms)
            {
                Vector3    sca, tra;
                Quaternion quat;
                Matrix4x4.Decompose(t, out sca, out quat, out tra);
                Vector3 rot = ToEulerAngles(quat);

                tra = t.Translation;

                x.Add(tra.X); y.Add(tra.Y); z.Add(tra.Z);
                rx.Add(rot.X); ry.Add(rot.Y); rz.Add(rot.Z);
                sx.Add(sca.X); sy.Add(sca.Y); sz.Add(sca.Z);
            }

            // check if any existing tracks match up and use those tracks when possible
            var xtrack  = sourceTrack.GetExistingTrack(x, source, dest);
            var ytrack  = sourceTrack.GetExistingTrack(y, source, dest);
            var ztrack  = sourceTrack.GetExistingTrack(z, source, dest);
            var rxtrack = sourceTrack.GetExistingTrack(rx, source, dest);
            var rytrack = sourceTrack.GetExistingTrack(ry, source, dest);
            var rztrack = sourceTrack.GetExistingTrack(rz, source, dest);
            var sxtrack = sourceTrack.GetExistingTrack(sx, source, dest);
            var sytrack = sourceTrack.GetExistingTrack(sy, source, dest);
            var sztrack = sourceTrack.GetExistingTrack(sz, source, dest);

            /*if (dest.ClassName != null && dest.ClassName == "RLegJA")
             * {
             *  System.Diagnostics.Debug.WriteLine(dest.ClassName);
             *
             *  System.Diagnostics.Debug.WriteLine($"{source.RX} {source.RY} {source.RZ}");
             *  System.Diagnostics.Debug.WriteLine($"{dest.RX} {dest.RY} {dest.RZ}");
             *
             *  Matrix4x4.Decompose(transforms[0], out Vector3 relScale, out Quaternion rot, out Vector3 trans);
             *
             *  System.Diagnostics.Debug.WriteLine($"{TrackNode.ToEulerAngles(rot).ToString()}");
             *  System.Diagnostics.Debug.WriteLine($"{sourceTrack.RX.Keys[0].Value} {sourceTrack.RY.Keys[0].Value} {sourceTrack.RZ.Keys[0].Value}");
             *
             *  System.Diagnostics.Debug.WriteLine($"{rxtrack != null} {rytrack != null} {rztrack != null}");
             * }*/

            if (xtrack != null || ytrack != null || ztrack != null ||
                rxtrack != null || rytrack != null || rztrack != null ||
                sxtrack != null || sytrack != null || sztrack != null)
            {
                //System.Diagnostics.Debug.WriteLine("Found Existing Track");
            }

            // otherwise we have to approximate

            var trans_error = 0.05f;
            var rot_error   = 0.01f;
            var scale_error = 0.1f;

            X.Keys  = xtrack != null ? xtrack : LineSimplification.Simplify(x, trans_error);
            Y.Keys  = ytrack != null ? ytrack : LineSimplification.Simplify(y, trans_error);
            Z.Keys  = ztrack != null ? ztrack : LineSimplification.Simplify(z, trans_error);
            RX.Keys = rxtrack != null ? rxtrack : LineSimplification.Simplify(rx, rot_error);
            RY.Keys = rytrack != null ? rytrack : LineSimplification.Simplify(ry, rot_error);
            RZ.Keys = rztrack != null ? rztrack : LineSimplification.Simplify(rz, rot_error);
            SX.Keys = sxtrack != null ? sxtrack : LineSimplification.Simplify(sx, scale_error, true);
            SY.Keys = sytrack != null ? sytrack : LineSimplification.Simplify(sy, scale_error, true);
            SZ.Keys = sztrack != null ? sztrack : LineSimplification.Simplify(sz, scale_error, true);

            /*
             * X.Keys = xtrack != null && xtrack.Count < transforms.Count * 0.85f ? xtrack : LineSimplification.Simplify(x, trans_error);
             * Y.Keys = ytrack != null && ytrack.Count < transforms.Count * 0.85f ? ytrack : LineSimplification.Simplify(y, trans_error);
             * Z.Keys = ztrack != null && ztrack.Count < transforms.Count * 0.85f ? ztrack : LineSimplification.Simplify(z, trans_error);
             * RX.Keys = rxtrack != null && rxtrack.Count < transforms.Count * 0.85f ? rxtrack : LineSimplification.Simplify(rx, rot_error);
             * RY.Keys = rytrack != null && rytrack.Count < transforms.Count * 0.85f ? rytrack : LineSimplification.Simplify(ry, rot_error);
             * RZ.Keys = rztrack != null && rztrack.Count < transforms.Count * 0.85f ? rztrack : LineSimplification.Simplify(rz, rot_error);
             * SX.Keys = sxtrack != null && sxtrack.Count < transforms.Count * 0.85f ? sxtrack : LineSimplification.Simplify(sx, scale_error, true);
             * SY.Keys = sytrack != null && sytrack.Count < transforms.Count * 0.85f ? sytrack : LineSimplification.Simplify(sy, scale_error, true);
             * SZ.Keys = sztrack != null && sztrack.Count < transforms.Count * 0.85f ? sztrack : LineSimplification.Simplify(sz, scale_error, true);
             */
        }
Beispiel #5
0
 /// <summary>
 ///
 /// </summary>
 /// <returns></returns>
 public Matrix4x4 GetWorldTransform(HSD_JOBJ jobj)
 {
     return(TrackNode.CalculateMatrix(jobj) * (jobjToParent[jobj] != null ? GetWorldTransform(jobjToParent[jobj]) : Matrix4x4.Identity));
 }