Пример #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="animJoint"></param>
        public static int AdaptiveCompressAnimation(HSD_AnimJoint j, JointMap map, int index = 0)
        {
            float error = map == null ? 0.001f : map.GetError(index);

            if (j.AOBJ != null)
            {
                foreach (var t in j.AOBJ.FObjDesc.List)
                {
                    var player = new FOBJ_Player();
                    player.Keys = t.GetDecodedKeys();
                    BakeTrack(player);
                    CompressTrack(player, error);
                    t.SetKeys(player.Keys, t.TrackType);
                }
            }

            if (j.Child != null)
            {
                foreach (var c in j.Children)
                {
                    index = AdaptiveCompressAnimation(c, map, index + 1);
                }
            }

            return(index);
        }
Пример #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="source"></param>
        /// <param name="target"></param>
        /// <param name="animation"></param>
        /// <param name="sourceMap"></param>
        /// <param name="targetMap"></param>
        /// <returns></returns>
        public static JointAnimManager Port(JointAnimManager animation, JointMap sourceMap, JointMap targetMap)
        {
            JointAnimManager newAnim = new JointAnimManager();

            newAnim.FrameCount = animation.FrameCount;

            for (int i = 0; i < targetMap.Count; i++)
            {
                var bone = targetMap[i];

                var index = sourceMap.IndexOf(bone);

                if (index != -1 && index < animation.Nodes.Count)
                {
                    newAnim.Nodes.Add(animation.Nodes[index]);
                }
                else
                {
                    newAnim.Nodes.Add(new AnimNode());
                }
            }

            return(newAnim);
        }
Пример #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="source"></param>
        /// <param name="target"></param>
        /// <param name="animation"></param>
        /// <param name="sourceMap"></param>
        /// <param name="targetMap"></param>
        /// <returns></returns>
        public static JointAnimManager SmartPort(HSD_JOBJ source, HSD_JOBJ target, JointAnimManager animation, JointMap sourceMap = null, JointMap targetMap = null)
        {
            var sourceManager = new JOBJManager();

            sourceManager.SetJOBJ(source);

            var sourceInverseWorldTransforms = new List <Matrix4>();

            for (int i = 0; i < sourceManager.JointCount; i++)
            {
                sourceInverseWorldTransforms.Add(sourceManager.GetWorldTransform(i).Inverted());
            }

            sourceManager.Animation = animation;


            var targetManager = new JOBJManager();

            targetManager.SetJOBJ(target);

            JointAnimManager newAnim = new JointAnimManager();

            newAnim.FrameCount = sourceManager.Animation.FrameCount;

            newAnim.Nodes.Clear();
            for (int i = 0; i < targetManager.JointCount; i++)
            {
                newAnim.Nodes.Add(new AnimNode());
            }
            for (int i = 0; i < sourceManager.JointCount; i++)
            {
                int targetIndex = i;
                int sourceIndex = i;

                Console.WriteLine(sourceMap[i]);

                // remap bone if joint maps are present
                if (sourceMap != null && targetMap != null && !string.IsNullOrEmpty(sourceMap[i]))
                {
                    targetIndex = targetMap.IndexOf(sourceMap[i]);
                }

                if (targetIndex == -1)
                {
                    continue;
                }

                var sourceJoint = sourceManager.GetJOBJ(sourceIndex);
                var targetJoint = targetManager.GetJOBJ(targetIndex);

                Console.WriteLine($"\t {sourceJoint.RX} {sourceJoint.RY} {sourceJoint.RZ}");
                Console.WriteLine($"\t {targetJoint.RX} {targetJoint.RY} {targetJoint.RZ}");

                /*if(sourceMap[i] == "RLegJ")
                 * {
                 *  var track = animation.Nodes[sourceIndex].Tracks.Find(e => e.JointTrackType == JointTrackType.HSD_A_J_ROTX);
                 *
                 *  if (track != null)
                 *      foreach (var k in track.Keys)
                 *          k.Value += (float)Math.PI / 2;
                 *
                 *  track = animation.Nodes[sourceIndex].Tracks.Find(e => e.JointTrackType == JointTrackType.HSD_A_J_ROTZ);
                 *
                 *  if (track != null)
                 *      foreach (var k in track.Keys)
                 *          k.Value += (float)Math.PI / 2;
                 * }*/

                newAnim.Nodes[targetIndex].Tracks = animation.Nodes[sourceIndex].Tracks;;
            }

            return(newAnim);
        }
Пример #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="source"></param>
        /// <param name="target"></param>
        /// <param name="animation"></param>
        /// <returns></returns>
        public static JointAnimManager Retarget(HSD_JOBJ source, HSD_JOBJ target, JointAnimManager animation, JointMap sourceMap = null, JointMap targetMap = null)
        {
            var sourceManager = new JOBJManager();

            sourceManager.SetJOBJ(source);

            var sourceInverseWorldTransforms = new List <Matrix4>();

            for (int i = 0; i < sourceManager.JointCount; i++)
            {
                sourceInverseWorldTransforms.Add(sourceManager.GetWorldTransform(i).Inverted());
            }

            sourceManager.Animation = animation;


            var targetManager = new JOBJManager();

            targetManager.SetJOBJ(target);

            JointAnimManager newAnim = new JointAnimManager();

            newAnim.FrameCount = sourceManager.Animation.FrameCount;
            var targetWorldTransforms = new List <Matrix4>();

            for (int i = 0; i < targetManager.JointCount; i++)
            {
                targetWorldTransforms.Add(targetManager.GetWorldTransform(i));
                newAnim.Nodes.Add(new AnimNode());
            }

            targetManager.Animation = newAnim;
            for (int f = 0; f <= sourceManager.Animation.FrameCount; f++)
            {
                sourceManager.Frame = f - 1;
                sourceManager.UpdateNoRender();

                targetManager.Frame = f;
                targetManager.UpdateNoRender();

                // bake animation on target skeleton
                for (int i = 0; i < sourceManager.JointCount; i++)
                {
                    int targetIndex = i;
                    int sourceIndex = i;

                    // remap bone if joint maps are present
                    if (sourceMap != null && targetMap != null && !string.IsNullOrEmpty(sourceMap[i]))
                    {
                        targetIndex = targetMap.IndexOf(sourceMap[i]);
                    }

                    if (targetIndex == -1)
                    {
                        continue;
                    }

                    int targetParentIndex = targetManager.ParentIndex(targetManager.GetJOBJ(targetIndex));

                    var inverseSourceWorldRotation  = sourceInverseWorldTransforms[sourceIndex];
                    var sourceAnimatedWorldRotation = sourceManager.GetWorldTransform(sourceIndex);

                    var targetWorldRotation = targetWorldTransforms[targetIndex];

                    var rel = targetWorldRotation *
                              inverseSourceWorldRotation *
                              sourceAnimatedWorldRotation;

                    if (targetParentIndex != -1)
                    {
                        rel *= targetManager.GetWorldTransform(targetParentIndex).Inverted();
                    }

                    var rot = Math3D.ToEulerAngles(rel.ExtractRotation().Inverted());

                    var targetJOBJ = targetManager.GetJOBJ(targetIndex);
                    var sourceJOBJ = sourceManager.GetJOBJ(sourceIndex);


                    sourceManager.Animation.GetAnimatedState(f - 1, sourceIndex, sourceJOBJ, out float TX, out float TY, out float TZ, out float RX, out float RY, out float RZ, out float SX, out float SY, out float SZ);


                    var relTranslate = new Vector3(sourceJOBJ.TX - TX, sourceJOBJ.TY - TY, sourceJOBJ.TZ - TZ);
                    //relTranslate = Vector3.TransformNormal(relTranslate, Matrix4.CreateFromQuaternion(Math3D.FromEulerAngles(sourceJOBJ.RZ, sourceJOBJ.RY, sourceJOBJ.RX).Inverted()));
                    //relTranslate = Vector3.TransformNormal(relTranslate, Matrix4.CreateFromQuaternion(Math3D.FromEulerAngles(targetJOBJ.RZ, targetJOBJ.RY, targetJOBJ.RX)));


                    var relScale = new Vector3(sourceJOBJ.SX - SX, sourceJOBJ.SY - SY, sourceJOBJ.SZ - SZ);
                    //relScale = Vector3.TransformNormal(relScale, inverseSourceWorldRotation);
                    //relScale = Vector3.TransformNormal(relScale, targetWorldRotation);


                    AddKey(targetIndex, f, targetJOBJ.TX - relTranslate.X, JointTrackType.HSD_A_J_TRAX, newAnim);
                    AddKey(targetIndex, f, targetJOBJ.TY - relTranslate.Y, JointTrackType.HSD_A_J_TRAY, newAnim);
                    AddKey(targetIndex, f, targetJOBJ.TZ - relTranslate.Z, JointTrackType.HSD_A_J_TRAZ, newAnim);

                    AddKey(targetIndex, f, rot.X, JointTrackType.HSD_A_J_ROTX, newAnim);
                    AddKey(targetIndex, f, rot.Y, JointTrackType.HSD_A_J_ROTY, newAnim);
                    AddKey(targetIndex, f, rot.Z, JointTrackType.HSD_A_J_ROTZ, newAnim);

                    AddKey(targetIndex, f, targetJOBJ.SX - relScale.X, JointTrackType.HSD_A_J_SCAX, newAnim);
                    AddKey(targetIndex, f, targetJOBJ.SY - relScale.Y, JointTrackType.HSD_A_J_SCAY, newAnim);
                    AddKey(targetIndex, f, targetJOBJ.SZ - relScale.Z, JointTrackType.HSD_A_J_SCAZ, newAnim);

                    targetManager.UpdateNoRender();
                }
            }

            EulerFilter(newAnim);

            var targetAnim = newAnim.ToAnimJoint(target, AOBJ_Flags.ANIM_LOOP);

            AnimationCompressor.AdaptiveCompressAnimation(targetAnim, targetMap);
            RemoveUnusedTracks(target, targetAnim);
            newAnim.FromAnimJoint(targetAnim);

            // apply additional single frame filter check
            for (int i = 0; i < sourceManager.JointCount; i++)
            {
                int targetIndex = i;
                int sourceIndex = i;

                // remap bone if joint maps are present
                if (sourceMap != null && targetMap != null && !string.IsNullOrEmpty(sourceMap[i]))
                {
                    targetIndex = targetMap.IndexOf(sourceMap[i]);
                }

                if (targetIndex == -1)
                {
                    continue;
                }

                var sourceNode = animation.Nodes[sourceIndex];
                var targetNode = newAnim.Nodes[targetIndex];

                FOBJ_Player sourceXRot = null;
                FOBJ_Player sourceYRot = null;
                FOBJ_Player sourceZRot = null;

                foreach (var t in sourceNode.Tracks)
                {
                    if (t.JointTrackType == JointTrackType.HSD_A_J_ROTX)
                    {
                        sourceXRot = t;
                    }
                    if (t.JointTrackType == JointTrackType.HSD_A_J_ROTY)
                    {
                        sourceYRot = t;
                    }
                    if (t.JointTrackType == JointTrackType.HSD_A_J_ROTZ)
                    {
                        sourceZRot = t;
                    }
                }

                if (sourceXRot != null && sourceYRot != null && sourceZRot != null &&
                    sourceXRot.Keys.Count == 1 && sourceYRot.Keys.Count == 1 && sourceZRot.Keys.Count == 1)
                {
                    foreach (var t in targetNode.Tracks)
                    {
                        if (t.JointTrackType == JointTrackType.HSD_A_J_ROTX ||
                            t.JointTrackType == JointTrackType.HSD_A_J_ROTY ||
                            t.JointTrackType == JointTrackType.HSD_A_J_ROTZ)
                        {
                            t.Keys.RemoveAll(e => e.Frame > 0);
                            t.Keys[0].InterpolationType = GXInterpolationType.HSD_A_OP_KEY;
                        }
                    }
                }
            }

            return(newAnim);
        }