Example #1
0
        private static void EulerFilter(JointAnimManager anim)
        {
            foreach (var n in anim.Nodes)
            {
                foreach (var t in n.Tracks)
                {
                    if (t.JointTrackType == JointTrackType.HSD_A_J_ROTX ||
                        t.JointTrackType == JointTrackType.HSD_A_J_ROTY ||
                        t.JointTrackType == JointTrackType.HSD_A_J_ROTZ)
                    {
                        // filter
                        for (int i = 1; i < t.Keys.Count; i++)
                        {
                            var prevKey = t.Keys[i - 1];
                            var key     = t.Keys[i];

                            if (Math.Abs(prevKey.Value - key.Value) > Math.PI)
                            {
                                if (prevKey.Value < key.Value)
                                {
                                    key.Value -= (float)(2 * Math.PI);
                                }
                                else
                                {
                                    key.Value += (float)(2 * Math.PI);
                                }
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        ///
        /// </summary>
        public void SetJoint(HSD_JOBJ jobj, JointAnimManager animManager)
        {
            jointTree.BeginUpdate();
            jointTree.Nodes.Clear();

            var jobjs = jobj.BreathFirstList;

            Dictionary <HSD_JOBJ, JointNode> childToParent = new Dictionary <HSD_JOBJ, JointNode>();

            for (int i = 0; i < Math.Min(animManager.NodeCount, jobjs.Count); i++)
            {
                var node = new JointNode()
                {
                    JOBJ = jobjs[i], AnimNode = animManager.Nodes[i], Text = $"JOINT_{i}"
                };

                foreach (var c in jobjs[i].Children)
                {
                    childToParent.Add(c, node);
                }

                if (childToParent.ContainsKey(jobjs[i]))
                {
                    childToParent[jobjs[i]].Nodes.Add(node);
                }
                else
                {
                    jointTree.Nodes.Add(node);
                }
            }

            jointTree.ExpandAll();
            jointTree.EndUpdate();
        }
Example #3
0
        /*
         *
         * def flip_euler(euler, rotation_mode):
         * ret = euler.copy()
         * inner_axis = rotation_mode[0]
         * outer_axis = rotation_mode[2]
         * middle_axis = rotation_mode[1]
         *
         * ret[euler_axis_index(z)] += pi
         * ret[euler_axis_index(x)] += pi
         * ret[euler_axis_index(y)] *= -1
         * ret[euler_axis_index(y)] += pi
         * return ret
         * */


        /// <summary>
        ///
        /// </summary>
        private static void RemoveUnusedTracks(HSD_JOBJ model, HSD_AnimJoint animJoint)
        {
            JointAnimManager manager = new JointAnimManager();

            manager.FromAnimJoint(animJoint);

            var joints = model.BreathFirstList;

            if (joints.Count != manager.Nodes.Count)
            {
                return;
            }

            for (int i = 0; i < joints.Count; i++)
            {
                var fobjs = manager.Nodes[i].Tracks;
                var toRem = new List <FOBJ_Player>();

                foreach (var f in fobjs)
                {
                    bool remove = false;
                    switch (f.JointTrackType)
                    {
                    case JointTrackType.HSD_A_J_TRAX: remove = RemoveTrack(f, joints[i].TX); break;

                    case JointTrackType.HSD_A_J_TRAY: remove = RemoveTrack(f, joints[i].TY); break;

                    case JointTrackType.HSD_A_J_TRAZ: remove = RemoveTrack(f, joints[i].TZ); break;

                    case JointTrackType.HSD_A_J_ROTX: remove = RemoveTrack(f, joints[i].RX); break;

                    case JointTrackType.HSD_A_J_ROTY: remove = RemoveTrack(f, joints[i].RY); break;

                    case JointTrackType.HSD_A_J_ROTZ: remove = RemoveTrack(f, joints[i].RZ); break;

                    case JointTrackType.HSD_A_J_SCAX: remove = RemoveTrack(f, joints[i].SX); break;

                    case JointTrackType.HSD_A_J_SCAY: remove = RemoveTrack(f, joints[i].SY); break;

                    case JointTrackType.HSD_A_J_SCAZ: remove = RemoveTrack(f, joints[i].SZ); break;
                    }
                    if (remove)
                    {
                        toRem.Add(f);
                    }
                }

                foreach (var v in toRem)
                {
                    fobjs.Remove(v);
                }
            }

            var newAnimJoint = manager.ToAnimJoint(model, AOBJ_Flags.ANIM_LOOP);

            animJoint._s = newAnimJoint._s;
        }
        /// <summary>
        ///
        /// </summary>
        private void UpdateAnimationWithFSMs()
        {
            // load backup animation
            var tempanim = new JointAnimManager();

            tempanim.FromFigaTree(BackupAnim.ToFigaTree());
            var backup = BackupAnim;

            // apply fsms to backup animation
            tempanim.ApplyFSMs(FrameSpeedModifiers);

            // load edited anim
            LoadFigaTree(SelectedAction.Symbol, tempanim.ToFigaTree());
            BackupAnim = backup;

            // refresh fsm display tips
            UpdateFrameTips();
        }
Example #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void compressAllAnimationsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (AJManager == null)
            {
                return;
            }

            HashSet <string> edited = new HashSet <string>();
            int oldSize             = 0;
            int newSize             = 0;

            foreach (var a in AllActions)
            {
                if (string.IsNullOrEmpty(a.Symbol) || edited.Contains(a.Symbol))
                {
                    continue;
                }

                var anim = AJManager.GetAnimationData(a.Symbol);
                if (anim != null)
                {
                    JointAnimManager ja = new JointAnimManager();
                    var animfile        = new HSDRawFile(anim);
                    ja.FromFigaTree(animfile.Roots[0].Data as HSD_FigaTree);
                    //ja.Optimize(JointManager.GetJOBJ(0), 0.01f);
                    animfile.Roots[0].Data = ja.ToFigaTree(0.01f);
                    using (MemoryStream s = new MemoryStream())
                    {
                        animfile.Save(s);
                        var newfile = s.ToArray();
                        oldSize += anim.Length;
                        newSize += newfile.Length;
                        AJManager.SetAnimation(a.Symbol, newfile);
                    }
                }
                edited.Add(a.Symbol);
            }

            Console.WriteLine($"{oldSize.ToString("X")} => {newSize.ToString("X")}");
            Console.WriteLine($"Saved {(oldSize - newSize).ToString("X")} bytes");
        }
Example #6
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);
        }
Example #7
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="filePath"></param>
        public static JointAnimManager ImportFromMayaAnim(string filePath)
        {
            var mayaFile = new MayaAnim();

            mayaFile.Open(filePath);

            JointAnimManager animation = new JointAnimManager();

            animation.FrameCount = mayaFile.header.endTime - mayaFile.header.startTime;

            // process and encode FOBJ keys
            foreach (var mNode in mayaFile.Nodes)
            {
                AnimNode node = new AnimNode();
                //Debug.WriteLine(mNode.name);
                foreach (var mTrack in mNode.atts)
                {
                    FOBJ_Player t = new FOBJ_Player();
                    t.Keys           = new List <FOBJKey>();
                    t.JointTrackType = jointTrackToMayaTrack.FirstOrDefault(e => e.Value == mTrack.type).Key;

                    //Debug.WriteLine("\t" + mTrack.type);

                    var degrees   = mayaFile.header.angularUnit == "deg";
                    var trackUnit = (mTrack.IsAngular() && degrees);

                    for (int i = 0; i < mTrack.keys.Count; i++)
                    {
                        var mKey     = mTrack.keys[i];
                        var mKeyNext = i + 1 < mTrack.keys.Count ? mTrack.keys[i + 1] : mTrack.keys[i];

                        var k = new FOBJKey();
                        k.Frame = mKey.input - mayaFile.header.startTime;
                        k.Value = trackUnit ? MathHelper.DegreesToRadians(mKey.output) : mKey.output;
                        switch (mKey.outtan)
                        {
                        case "auto":
                        case "linear":
                            k.InterpolationType = GXInterpolationType.HSD_A_OP_LIN;

                            t.Keys.Add(k);
                            break;

                        case "step":
                            if (mTrack.keys.Count == 1)
                            {
                                k.InterpolationType = GXInterpolationType.HSD_A_OP_KEY;
                            }
                            else
                            {
                                k.InterpolationType = GXInterpolationType.HSD_A_OP_CON;
                            }

                            t.Keys.Add(k);
                            break;

                        case "fixed":
                        case "spline":
                            k.InterpolationType = GXInterpolationType.HSD_A_OP_SPL;
                            k.Tan = AngleToTan(mKey.t1, degrees);

                            if ((mKeyNext.input - mKey.input) <= 1)    // optimization
                            {
                                //k.InterpolationType = GXInterpolationType.HSD_A_OP_LIN;
                                t.Keys.Add(k);
                            }
                            else
                            if (mKey.t2 == 0)
                            {
                                k.InterpolationType = GXInterpolationType.HSD_A_OP_SPL0;
                                t.Keys.Add(k);
                            }
                            else
                            if (mKey.t1 != mKey.t2)
                            {
                                t.Keys.Add(k);

                                var slp = new FOBJKey();
                                slp.Frame             = mKeyNext.input - 1;
                                slp.InterpolationType = GXInterpolationType.HSD_A_OP_SLP;
                                slp.Tan = AngleToTan(mKey.t2, degrees);
                                t.Keys.Add(slp);
                            }
                            else
                            {
                                t.Keys.Add(k);
                            }

                            break;

                        default:
                            Console.WriteLine(mKey.outtan + " not supported!");
                            break;
                        }

                        if (mTrack.keys.Count == 1)
                        {
                            k.InterpolationType = GXInterpolationType.HSD_A_OP_KEY;
                        }

                        //foreach (var key in t.Keys)
                        //    Debug.WriteLine($"\t\t{key.Frame} {key.Value}");
                    }

                    node.Tracks.Add(t);
                }
                animation.Nodes.Add(node);
            }

            return(animation);
        }
Example #8
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="nodes"></param>
        public static void ExportToMayaAnim(string filePath, JointAnimManager animation, Dictionary <int, string> boneLabelMap)
        {
            using (PropertyDialog d = new PropertyDialog("Maya Settings", MayaSettings))
            {
                if (d.ShowDialog() != DialogResult.OK)
                {
                    return;
                }
            }

            MayaAnim a = new MayaAnim();

            if (!MayaSettings.UseRadians)
            {
                a.header.angularUnit = "deg";
            }

            int nodeIndex  = 0;
            int frameCount = 0;

            foreach (var n in animation.Nodes)
            {
                MayaAnim.MayaNode mnode = new MayaAnim.MayaNode();
                mnode.name = boneLabelMap.ContainsKey(nodeIndex) ? boneLabelMap[nodeIndex] : "JOBJ_" + nodeIndex;
                a.Nodes.Add(mnode);

                foreach (var t in n.Tracks)
                {
                    if (!jointTrackToMayaTrack.ContainsKey(t.JointTrackType))
                    {
                        continue;
                    }

                    MayaAnim.MayaTrack mtrack = new MayaAnim.MayaTrack();
                    mnode.atts.Add(mtrack);

                    mtrack.type = jointTrackToMayaTrack[t.JointTrackType];

                    if (mtrack.IsAngular())
                    {
                        mtrack.output = MayaAnim.OutputType.angular;
                    }

                    FOBJAnimState prevState = null;
                    for (int i = 0; i < t.Keys.Count; i++)
                    {
                        // get maximum frame to use as framecount
                        frameCount = (int)Math.Max(frameCount, t.Keys[i].Frame);

                        // get current state at this key frame
                        var  state     = t.GetState(t.Keys[i].Frame);
                        bool nextSlope = i + 1 < t.Keys.Count && t.Keys[i + 1].InterpolationType == GXInterpolationType.HSD_A_OP_SLP;

                        if (t.Keys[i].InterpolationType == GXInterpolationType.HSD_A_OP_SLP)
                        {
                            continue;
                        }


                        // assuming last frame
                        // if last frame shift frame information over
                        if (t.Keys[i].Frame == state.t1)
                        {
                            state.t0 = state.t1;
                            state.p0 = state.p1;
                            state.d0 = state.d1;
                            //state.op_intrp = state.op;
                        }

                        // generate key with time and value
                        var animkey = new MayaAnim.AnimKey()
                        {
                            input  = state.t0,
                            output = state.p0,
                        };

                        // nothing to do for linear
                        //if (op_intrp == GXInterpolationType.HSD_A_OP_LIN)

                        // set step type for constant and key
                        if (state.op_intrp == GXInterpolationType.HSD_A_OP_CON ||
                            state.op_intrp == GXInterpolationType.HSD_A_OP_KEY)
                        {
                            animkey.intan  = "auto";
                            animkey.outtan = "step";
                        }

                        // set tangents for weighted slopes
                        if (state.op_intrp == GXInterpolationType.HSD_A_OP_SLP ||
                            state.op_intrp == GXInterpolationType.HSD_A_OP_SPL0 ||
                            state.op_intrp == GXInterpolationType.HSD_A_OP_SPL)
                        {
                            animkey.t1 = state.d0;
                            animkey.t2 = state.d0;
                            if (nextSlope && prevState != null)
                            {
                                animkey.t1 = prevState.d1;
                            }
                            animkey.intan  = "spline";
                            animkey.outtan = "spline";
                        }

                        prevState = state;

                        animkey.t1 = (float)MathHelper.RadiansToDegrees(Math.Atan(animkey.t1));
                        animkey.t2 = (float)MathHelper.RadiansToDegrees(Math.Atan(animkey.t2));

                        if (mtrack.IsAngular() && !MayaSettings.UseRadians)
                        {
                            animkey.output = MathHelper.RadiansToDegrees(animkey.output);
                            animkey.t1     = MathHelper.RadiansToDegrees(animkey.t1);
                            animkey.t2     = MathHelper.RadiansToDegrees(animkey.t2);
                        }

                        // add final key
                        mtrack.keys.Add(animkey);
                    }
                }

                nodeIndex++;
            }

            // set framecount
            a.header.endTime   = animation.FrameCount;
            a.header.startTime = 0;

            // save to file
            a.Save(filePath);
        }
Example #9
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="cam"></param>
        /// <param name="frame"></param>
        public void Render(Camera cam, float frame)
        {
            if (frame == -1 && entryAnimation.Count > 0)
            {
                entryAnimation.Clear();
            }

            if (frame == 0)
            {
                entryAnimation.Clear();

                // Load Animation
                foreach (var i in Icons)
                {
                    if (i.AnimJoint == null)
                    {
                        continue;
                    }

                    var a = new JointAnimManager();
                    a.FromAnimJoint(i.AnimJoint);
                    entryAnimation.Add(i, a);
                }
            }

            for (int i = 0; i < Icons.Length; i++)
            {
                var ico = Icons[i];

                if (ico.Joint == null)
                {
                    continue;
                }

                var transform = Matrix4.Identity;

                if (entryAnimation.ContainsKey(ico))
                {
                    transform = entryAnimation[ico].GetAnimatedMatrix(frame, 0, ico.Joint);
                }
                else
                {
                    transform = Matrix4.CreateScale(ico.Joint.SX, ico.Joint.SY, ico.Joint.SZ) *
                                Matrix4.CreateFromQuaternion(Math3D.FromEulerAngles(ico.Joint.RZ, ico.Joint.RY, ico.Joint.RX)) *
                                Matrix4.CreateTranslation(ico.Joint.TX, ico.Joint.TY, ico.Joint.TZ);
                }

                if (IconJOBJManager.JointCount > 0)
                {
                    IconJOBJManager.SetWorldTransform(0, transform);
                    ico.IconTOBJ.Flags = TOBJ_FLAGS.LIGHTMAP_DIFFUSE | TOBJ_FLAGS.COLORMAP_MODULATE | TOBJ_FLAGS.ALPHAMAP_MODULATE;
                    IconJOBJManager.GetJOBJ(0).Child.Dobj.Next.Mobj.Textures = ico.IconTOBJ;
                    IconJOBJManager.Render(cam, false);
                }

                if (sssEditor.SelectedIndices.Contains(i))
                {
                    if (sssEditor.SelectedIndices.Count == 1 && StageNameJOBJManager.JointCount > 0)
                    {
                        ico.NameTOBJ.Flags = TOBJ_FLAGS.LIGHTMAP_DIFFUSE | TOBJ_FLAGS.COLORMAP_MODULATE | TOBJ_FLAGS.ALPHAMAP_MODULATE;
                        StageNameJOBJManager.GetJOBJ(0).Child.Child.Dobj.Mobj.Textures = ico.NameTOBJ;
                    }

                    var rect = ico.ToRectangle();

                    DrawShape.DrawRectangle(rect.X, rect.Y, rect.X + rect.Width, rect.Y + rect.Height, ico.Joint.TZ, 2, MEX_CSSIconEntry.SelectedIconColor);

                    if (Dragging)
                    {
                        DrawShape.Line(new Vector3(-100, rect.Y, 0), new Vector3(100, rect.Y, 0), SnapColor, 1);
                        DrawShape.Line(new Vector3(rect.X, -100, 0), new Vector3(rect.X, 100, 0), SnapColor, 1);
                        DrawShape.Line(new Vector3(-100, rect.Y + rect.Height, 0), new Vector3(100, rect.Y + rect.Height, 0), SnapColor, 1);
                        DrawShape.Line(new Vector3(rect.X + rect.Width, -100, 0), new Vector3(rect.X + rect.Width, 100, 0), SnapColor, 1);
                    }
                }
            }

            StageNameJOBJManager.Render(cam);
        }
Example #10
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public static JointAnimManager LoadCHR0(string filePath, JointMap jointMap)
        {
            JointAnimManager anim = new JointAnimManager();

            for (int i = 0; i < jointMap.Count; i++)
            {
                anim.Nodes.Add(new AnimNode());
            }

            using (BinaryReaderExt r = new BinaryReaderExt(new FileStream(filePath, FileMode.Open)))
            {
                r.BigEndian = true;
                if (r.BaseStream.Length < 4 || new string(r.ReadChars(4)) != "CHR0")
                {
                    throw new InvalidDataException("CHR0 file is not valid");
                }

                r.Skip(4);

                int versionNum = r.ReadInt32();

                if (versionNum != 4)
                {
                    throw new InvalidDataException($"CHR0 version {versionNum} not supported");
                }

                r.Seek(0x10);

                var indexGroupOffset = r.ReadUInt32();
                var animName         = r.ReadString(r.ReadInt32(), -1);

                r.Skip(4);
                anim.FrameCount = r.ReadUInt16() - 1;
                int animDataCount = r.ReadUInt16();
                r.Skip(8);

                r.Seek(indexGroupOffset);
                var sectionOffset = r.ReadUInt32() + indexGroupOffset;
                int sectionCount  = r.ReadInt32();

                for (uint i = 0; i < sectionCount; i++)
                {
                    r.Seek(indexGroupOffset + 8 + 16 * i);
                    r.Skip(4); // id and unknown
                    r.Skip(2); // let
                    r.Skip(2); // right
                    var boneName   = r.ReadString(r.ReadInt32() + (int)indexGroupOffset, -1);
                    var dataOffset = r.ReadUInt32() + indexGroupOffset;
                    if (dataOffset == indexGroupOffset)
                    {
                        sectionCount += 1;
                        continue;
                    }

                    if (jointMap.IndexOf(boneName) == -1)
                    {
                        continue;
                    }

                    r.Seek(dataOffset);

                    var nameOff = r.Position + r.ReadUInt32();
                    var flags   = r.ReadInt32();
                    //Console.WriteLine(boneName + " " + flags.ToString("X"));
                    //r.PrintPosition();
                    //01BFE019
                    int t_type = (flags >> 0x1e) & 0x3;
                    int r_type = (flags >> 0x1b) & 0x7;
                    int s_type = (flags >> 0x19) & 0x3;

                    int hasT = (flags >> 0x18) & 0x1;
                    int hasR = (flags >> 0x17) & 0x1;
                    int hasS = (flags >> 0x16) & 0x1;

                    int Zfixed = (flags >> 0x15) & 0x1;
                    int Yfixed = (flags >> 0x14) & 0x1;
                    int Xfixed = (flags >> 0x13) & 0x1;

                    int RZfixed = (flags >> 0x12) & 0x1;
                    int RYfixed = (flags >> 0x11) & 0x1;
                    int RXfixed = (flags >> 0x10) & 0x1;

                    int SZfixed = (flags >> 0xf) & 0x1;
                    int SYfixed = (flags >> 0xe) & 0x1;
                    int SXfixed = (flags >> 0xd) & 0x1;

                    int Tiso = (flags >> 0x6) & 0x1;
                    int Riso = (flags >> 0x5) & 0x1;
                    int Siso = (flags >> 0x4) & 0x1;

                    AnimNode    node   = new AnimNode();
                    FOBJ_Player trackX = new FOBJ_Player()
                    {
                        JointTrackType = JointTrackType.HSD_A_J_TRAX
                    };
                    FOBJ_Player trackY = new FOBJ_Player()
                    {
                        JointTrackType = JointTrackType.HSD_A_J_TRAY
                    };
                    FOBJ_Player trackZ = new FOBJ_Player()
                    {
                        JointTrackType = JointTrackType.HSD_A_J_TRAZ
                    };
                    FOBJ_Player trackRX = new FOBJ_Player()
                    {
                        JointTrackType = JointTrackType.HSD_A_J_ROTX
                    };
                    FOBJ_Player trackRY = new FOBJ_Player()
                    {
                        JointTrackType = JointTrackType.HSD_A_J_ROTY
                    };
                    FOBJ_Player trackRZ = new FOBJ_Player()
                    {
                        JointTrackType = JointTrackType.HSD_A_J_ROTZ
                    };
                    FOBJ_Player trackSX = new FOBJ_Player()
                    {
                        JointTrackType = JointTrackType.HSD_A_J_SCAX
                    };
                    FOBJ_Player trackSY = new FOBJ_Player()
                    {
                        JointTrackType = JointTrackType.HSD_A_J_SCAY
                    };
                    FOBJ_Player trackSZ = new FOBJ_Player()
                    {
                        JointTrackType = JointTrackType.HSD_A_J_SCAZ
                    };

                    if (hasS == 1)
                    {
                        ReadKeys(r, node, (int)anim.FrameCount, trackSX, trackSY, trackSZ, Siso == 1, SXfixed == 1, SYfixed == 1, SZfixed == 1, s_type, dataOffset);
                    }

                    if (hasR == 1)
                    {
                        ReadKeys(r, node, (int)anim.FrameCount, trackRX, trackRY, trackRZ, Riso == 1, RXfixed == 1, RYfixed == 1, RZfixed == 1, r_type, dataOffset);
                    }

                    if (hasT == 1)
                    {
                        ReadKeys(r, node, (int)anim.FrameCount, trackX, trackY, trackZ, Tiso == 1, Xfixed == 1, Yfixed == 1, Zfixed == 1, t_type, dataOffset);
                    }

                    if (trackX.Keys.Count > 0)
                    {
                        node.Tracks.Add(trackX);
                    }
                    if (trackY.Keys.Count > 0)
                    {
                        node.Tracks.Add(trackY);
                    }
                    if (trackZ.Keys.Count > 0)
                    {
                        node.Tracks.Add(trackZ);
                    }
                    if (trackRX.Keys.Count > 0)
                    {
                        node.Tracks.Add(trackRX);
                    }
                    if (trackRY.Keys.Count > 0)
                    {
                        node.Tracks.Add(trackRY);
                    }
                    if (trackRZ.Keys.Count > 0)
                    {
                        node.Tracks.Add(trackRZ);
                    }
                    if (trackSX.Keys.Count > 0)
                    {
                        node.Tracks.Add(trackSX);
                    }
                    if (trackSY.Keys.Count > 0)
                    {
                        node.Tracks.Add(trackSY);
                    }
                    if (trackSZ.Keys.Count > 0)
                    {
                        node.Tracks.Add(trackSZ);
                    }

                    foreach (var k in trackRX.Keys)
                    {
                        k.Value = MathHelper.DegreesToRadians(k.Value);
                        k.Tan   = MathHelper.DegreesToRadians(k.Tan);
                    }
                    foreach (var k in trackRY.Keys)
                    {
                        k.Value = MathHelper.DegreesToRadians(k.Value);
                        k.Tan   = MathHelper.DegreesToRadians(k.Tan);
                    }
                    foreach (var k in trackRZ.Keys)
                    {
                        k.Value = MathHelper.DegreesToRadians(k.Value);
                        k.Tan   = MathHelper.DegreesToRadians(k.Tan);
                    }

                    // make sure all tracks start at frame 0
                    foreach (var track in node.Tracks)
                    {
                        if (track.Keys.Count > 0 && track.Keys[0].Frame != 0)
                        {
                            track.Keys.Insert(0, new FOBJKey()
                            {
                                Frame             = 0,
                                Value             = track.Keys[0].Value,
                                InterpolationType = GXInterpolationType.HSD_A_OP_CON,
                            });
                        }
                    }

                    //Console.WriteLine(boneName + " Tracks:" + node.Tracks.Count + " " + flags.ToString("X"));
                    //Console.WriteLine($"{trackX.Keys.Count} {trackY.Keys.Count} {trackZ.Keys.Count}");
                    //Console.WriteLine($"{trackRX.Keys.Count} {trackRY.Keys.Count} {trackRZ.Keys.Count}");
                    //Console.WriteLine($"{trackSX.Keys.Count} {trackSY.Keys.Count} {trackSZ.Keys.Count}");
                    anim.Nodes[jointMap.IndexOf(boneName)] = node;
                }
            }

            return(anim);
        }
Example #11
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="node"></param>
        /// <param name="frame"></param>
        /// <param name="value"></param>
        /// <param name="track"></param>
        /// <param name="manager"></param>
        private static void AddKey(int node, int frame, float value, JointTrackType tracktype, JointAnimManager manager)
        {
            var track = manager.Nodes[node].Tracks.Find(e => e.JointTrackType == tracktype);

            if (track == null)
            {
                track = new FOBJ_Player()
                {
                    JointTrackType = tracktype
                };
                manager.Nodes[node].Tracks.Add(track);
            }

            track.Keys.Add(new FOBJKey()
            {
                Frame             = frame,
                Value             = value,
                InterpolationType = frame == 0 ? GXInterpolationType.HSD_A_OP_KEY : GXInterpolationType.HSD_A_OP_CON
            });
        }
Example #12
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);
        }
        /// <summary>
        ///
        /// </summary>
        private void LoadFigaTree(string treeSymbol, HSD_FigaTree tree)
        {
            // clear animation
            JointManager.SetFigaTree(null);
            ThrowDummyManager.SetFigaTree(null);

            // create new action
            var name = new Action()
            {
                Symbol = treeSymbol
            }.ToString();

            // load figatree to manager and anim editor
            JointManager.SetFigaTree(tree);
            _animEditor.SetJoint(JointManager.GetJOBJ(0), JointManager.Animation);

            // set backup anim
            BackupAnim = new JointAnimManager();
            BackupAnim.FromFigaTree(tree);

            // set frame
            viewport.MaxFrame = tree.FrameCount;


            // enable shield display
            if (FighterData != null && name.Equals("Guard"))
            {
                DisplayShieldSize = FighterData.Attributes.ShieldSize / 2;
            }


            // load throw dummy for thrown animations
            if (name.Contains("Throw") && !name.Contains("Taro"))
            {
                // find thrown anim
                Action throwAction = null;
                foreach (Action a in actionList.Items)
                {
                    if (a.Symbol != null &&
                        a.Symbol.Contains("Taro") &&
                        a.Symbol.Contains(name) &&
                        !a.Symbol.Equals(treeSymbol))
                    {
                        throwAction = a;
                        break;
                    }
                }

                // if throw animation is found
                if (throwAction != null &&
                    throwAction.Symbol != null)
                {
                    var throwData = AJManager.GetAnimationData(throwAction.Symbol);

                    if (throwData != null)
                    {
                        // load throw animation
                        var tanim = new HSDRawFile(throwData);
                        if (tanim.Roots[0].Data is HSD_FigaTree tree2)
                        {
                            ThrowDummyManager.SetFigaTree(tree2);
                            if (ThrowDummyLookupTable.Count > 0)
                            {
                                ThrowDummyManager.Animation.EnableBoneLookup = true;
                                ThrowDummyManager.Animation.BoneLookup       = ThrowDummyLookupTable;
                            }
                        }
                    }
                }
            }
        }
Example #14
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public static JointAnimManager LoadCHR0(string filePath, Dictionary <int, string> BoneLabelMap)
        {
            JointAnimManager anim = new JointAnimManager();

            Dictionary <string, int> nameToIndex = new Dictionary <string, int>();

            foreach (var v in BoneLabelMap)
            {
                nameToIndex.Add(v.Value, v.Key);
                anim.Nodes.Add(new AnimNode());
            }

            using (BinaryReaderExt r = new BinaryReaderExt(new FileStream(filePath, FileMode.Open)))
            {
                r.BigEndian = true;
                if (r.BaseStream.Length < 4 || new string(r.ReadChars(4)) != "CHR0")
                {
                    throw new InvalidDataException("CHR0 file is not valid");
                }

                r.Skip(4);

                int versionNum = r.ReadInt32();

                if (versionNum != 4)
                {
                    throw new InvalidDataException($"CHR0 version {versionNum} not supported");
                }

                System.Console.WriteLine("Reading Track ");

                r.Seek(0x10);

                var indexGroupOffset = r.ReadUInt32();
                var animName         = r.ReadString(r.ReadInt32(), -1);

                r.Skip(4);
                anim.FrameCount = r.ReadUInt16();
                int animDataCount = r.ReadUInt16();
                r.Skip(8);

                r.Seek(indexGroupOffset);
                var sectionOffset = r.ReadUInt32() + indexGroupOffset;
                int sectionCount  = r.ReadInt32();

                for (uint i = 0; i < sectionCount; i++)
                {
                    r.Seek(indexGroupOffset + 8 + 16 * i);
                    r.Skip(4); // id and unknown
                    r.Skip(2); // let
                    r.Skip(2); // right
                    var boneName   = r.ReadString(r.ReadInt32() + (int)indexGroupOffset, -1);
                    var dataOffset = r.ReadUInt32() + indexGroupOffset;
                    if (dataOffset == indexGroupOffset)
                    {
                        sectionCount += 1;
                        continue;
                    }

                    if (!nameToIndex.ContainsKey(boneName))
                    {
                        continue;
                    }

                    r.Seek(dataOffset);

                    var nameOff = r.Position + r.ReadUInt32();
                    var flags   = r.ReadInt32();

                    int t_type = (flags >> 0x1e) & 0x3;
                    int r_type = (flags >> 0x1b) & 0x7;
                    int s_type = (flags >> 0x19) & 0x3;

                    int hasT = (flags >> 0x18) & 0x1;
                    int hasR = (flags >> 0x17) & 0x1;
                    int hasS = (flags >> 0x16) & 0x1;

                    int Zfixed = (flags >> 0x15) & 0x1;
                    int Yfixed = (flags >> 0x14) & 0x1;
                    int Xfixed = (flags >> 0x13) & 0x1;

                    int RZfixed = (flags >> 0x12) & 0x1;
                    int RYfixed = (flags >> 0x11) & 0x1;
                    int RXfixed = (flags >> 0x10) & 0x1;

                    int SZfixed = (flags >> 0xf) & 0x1;
                    int SYfixed = (flags >> 0xe) & 0x1;
                    int SXfixed = (flags >> 0xd) & 0x1;

                    int Tiso = (flags >> 0x6) & 0x1;
                    int Riso = (flags >> 0x5) & 0x1;
                    int Siso = (flags >> 0x4) & 0x1;

                    AnimNode    node   = new AnimNode();
                    FOBJ_Player trackX = new FOBJ_Player()
                    {
                        JointTrackType = JointTrackType.HSD_A_J_TRAX
                    };
                    FOBJ_Player trackY = new FOBJ_Player()
                    {
                        JointTrackType = JointTrackType.HSD_A_J_TRAY
                    };
                    FOBJ_Player trackZ = new FOBJ_Player()
                    {
                        JointTrackType = JointTrackType.HSD_A_J_TRAZ
                    };
                    FOBJ_Player trackRX = new FOBJ_Player()
                    {
                        JointTrackType = JointTrackType.HSD_A_J_ROTX
                    };
                    FOBJ_Player trackRY = new FOBJ_Player()
                    {
                        JointTrackType = JointTrackType.HSD_A_J_ROTY
                    };
                    FOBJ_Player trackRZ = new FOBJ_Player()
                    {
                        JointTrackType = JointTrackType.HSD_A_J_ROTZ
                    };
                    FOBJ_Player trackSX = new FOBJ_Player()
                    {
                        JointTrackType = JointTrackType.HSD_A_J_SCAX
                    };
                    FOBJ_Player trackSY = new FOBJ_Player()
                    {
                        JointTrackType = JointTrackType.HSD_A_J_SCAY
                    };
                    FOBJ_Player trackSZ = new FOBJ_Player()
                    {
                        JointTrackType = JointTrackType.HSD_A_J_SCAZ
                    };

                    if (hasS == 1)
                    {
                        ReadKeys(r, node, (int)anim.FrameCount, trackSX, trackSY, trackSZ, Siso == 1, SXfixed == 1, SYfixed == 1, SZfixed == 1, s_type, dataOffset);
                    }

                    if (hasR == 1)
                    {
                        ReadKeys(r, node, (int)anim.FrameCount, trackRX, trackRY, trackRZ, Riso == 1, RXfixed == 1, RYfixed == 1, RZfixed == 1, r_type, dataOffset);
                    }

                    if (hasT == 1)
                    {
                        ReadKeys(r, node, (int)anim.FrameCount, trackX, trackY, trackZ, Tiso == 1, Xfixed == 1, Yfixed == 1, Zfixed == 1, t_type, dataOffset);
                    }

                    if (trackX.Keys.Count > 1)
                    {
                        node.Tracks.Add(trackX);
                    }
                    if (trackY.Keys.Count > 1)
                    {
                        node.Tracks.Add(trackY);
                    }
                    if (trackZ.Keys.Count > 1)
                    {
                        node.Tracks.Add(trackZ);
                    }
                    if (trackRX.Keys.Count > 1)
                    {
                        node.Tracks.Add(trackRX);
                    }
                    if (trackRY.Keys.Count > 1)
                    {
                        node.Tracks.Add(trackRY);
                    }
                    if (trackRZ.Keys.Count > 1)
                    {
                        node.Tracks.Add(trackRZ);
                    }
                    if (trackSX.Keys.Count > 1)
                    {
                        node.Tracks.Add(trackSX);
                    }
                    if (trackSY.Keys.Count > 1)
                    {
                        node.Tracks.Add(trackSY);
                    }
                    if (trackSZ.Keys.Count > 1)
                    {
                        node.Tracks.Add(trackSZ);
                    }

                    foreach (var k in trackRX.Keys)
                    {
                        k.Value = MathHelper.DegreesToRadians(k.Value);
                        k.Tan   = MathHelper.DegreesToRadians(k.Value);
                    }
                    foreach (var k in trackRY.Keys)
                    {
                        k.Value = MathHelper.DegreesToRadians(k.Value);
                        k.Tan   = MathHelper.DegreesToRadians(k.Value);
                    }
                    foreach (var k in trackRZ.Keys)
                    {
                        k.Value = MathHelper.DegreesToRadians(k.Value);
                        k.Tan   = MathHelper.DegreesToRadians(k.Value);
                    }

                    Console.WriteLine(boneName + " Tracks:" + node.Tracks.Count);
                    Console.WriteLine($"{trackX.Keys.Count} {trackY.Keys.Count} {trackZ.Keys.Count}");
                    Console.WriteLine($"{trackRX.Keys.Count} {trackRY.Keys.Count} {trackRZ.Keys.Count}");
                    Console.WriteLine($"{trackSX.Keys.Count} {trackSY.Keys.Count} {trackSZ.Keys.Count}");
                    anim.Nodes[nameToIndex[boneName]] = node;
                }
            }

            return(anim);
        }
Example #15
0
        /// <summary>
        /// Opens editor for currently selected node if editor exists
        /// </summary>
        public void OpenEditor()
        {
            if (SelectedDataNode == null)
            {
                return;
            }

            var edit = PluginManager.GetEditorFromType(SelectedDataNode.Accessor.GetType());

            // Special animation override
            if (SelectedDataNode.Accessor is HSD_AnimJoint ||
                SelectedDataNode.Accessor is HSD_FigaTree ||
                SelectedDataNode.Accessor is HSD_MatAnimJoint ||
                SelectedDataNode.Accessor is HSD_ShapeAnimJoint ||
                SelectedDataNode.Accessor is HSD_FogDesc ||
                SelectedDataNode.Accessor is HSD_Camera ||
                SelectedDataNode.Accessor is SBM_ModelPart)
            {
                //foreach (var v in dockPanel.Contents)
                {
                    if (LastActiveContent is JobjEditorDock jedit && jedit.Visible)
                    {
                        if (SelectedDataNode.Accessor is HSD_MatAnimJoint matjoint)
                        {
                            jedit.LoadAnimation(matjoint);
                        }

                        if (SelectedDataNode.Accessor is HSD_ShapeAnimJoint shapeJoint)
                        {
                            jedit.LoadAnimation(shapeJoint);
                        }

                        if (SelectedDataNode.Accessor is HSD_AnimJoint joint)
                        {
                            jedit.LoadAnimation(new JointAnimManager(joint));
                        }

                        if (SelectedDataNode.Accessor is HSD_FigaTree tree)
                        {
                            jedit.LoadAnimation(new JointAnimManager(tree));
                        }

                        if (SelectedDataNode.Accessor is HSD_FogDesc fog)
                        {
                            jedit.Editor.SetFog(fog);
                        }

                        if (SelectedDataNode.Accessor is HSD_Camera camera)
                        {
                            jedit.Editor.SetCamera(camera);
                        }

                        if (SelectedDataNode.Accessor is SBM_ModelPart modelPart && modelPart.Anims.Length > 0)
                        {
                            if (prev_selected_part == modelPart)
                            {
                                part_select_index++;
                            }
                            else
                            {
                                part_select_index = 0;
                            }

                            prev_selected_part = modelPart;

                            if (part_select_index > modelPart.Anims.Length)
                            {
                                part_select_index = 0;
                            }

                            JointAnimManager manager = new JointAnimManager();
                            for (int i = 0; i < modelPart.StartingBone; i++)
                            {
                                manager.Nodes.Add(new AnimNode());
                            }
                            manager.Nodes.AddRange(new JointAnimManager(modelPart.Anims[part_select_index]).Nodes);
                            jedit.LoadAnimation(manager);
                        }
                    }
                }
            }

            if (IsOpened(SelectedDataNode))
            {
                var editor = GetEditors(SelectedDataNode);
                editor[0].BringToFront();
            }
            else
            if (!IsChildOpened(SelectedDataNode.Accessor._s) &&
                edit != null &&
                edit is DockContent dc)
            {
                //Editors.Add(edit);
                SelectedDataNode.Collapse();
                edit.Node = SelectedDataNode;

                dc.Show(dockPanel);

                dc.Text    = SelectedDataNode.Text;
                dc.TabText = SelectedDataNode.Text;
                //if (dc is EditorBase b)
                //    dc.DockState = b.DefaultDockState;
            }
        }
Example #16
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);
        }
Example #17
0
        public static JointAnimManager ToJointAnim(string filePath, JointMap jm)
        {
            var bke = BKE.Open(filePath);

            JointAnimManager anim = new JointAnimManager();

            anim.FrameCount = bke.CountFrames();
            for (int i = 0; i < bke.Nodes.Count; i++)
            {
                var node = new AnimNode();

                node.Tracks.Add(new FOBJ_Player()
                {
                    JointTrackType = JointTrackType.HSD_A_J_TRAX, Keys = new List <FOBJKey>()
                });
                node.Tracks.Add(new FOBJ_Player()
                {
                    JointTrackType = JointTrackType.HSD_A_J_TRAY, Keys = new List <FOBJKey>()
                });
                node.Tracks.Add(new FOBJ_Player()
                {
                    JointTrackType = JointTrackType.HSD_A_J_TRAZ, Keys = new List <FOBJKey>()
                });

                node.Tracks.Add(new FOBJ_Player()
                {
                    JointTrackType = JointTrackType.HSD_A_J_ROTX, Keys = new List <FOBJKey>()
                });
                node.Tracks.Add(new FOBJ_Player()
                {
                    JointTrackType = JointTrackType.HSD_A_J_ROTY, Keys = new List <FOBJKey>()
                });
                node.Tracks.Add(new FOBJ_Player()
                {
                    JointTrackType = JointTrackType.HSD_A_J_ROTZ, Keys = new List <FOBJKey>()
                });

                node.Tracks.Add(new FOBJ_Player()
                {
                    JointTrackType = JointTrackType.HSD_A_J_SCAX, Keys = new List <FOBJKey>()
                });
                node.Tracks.Add(new FOBJ_Player()
                {
                    JointTrackType = JointTrackType.HSD_A_J_SCAY, Keys = new List <FOBJKey>()
                });
                node.Tracks.Add(new FOBJ_Player()
                {
                    JointTrackType = JointTrackType.HSD_A_J_SCAZ, Keys = new List <FOBJKey>()
                });

                anim.Nodes.Add(node);
            }

            foreach (var n in bke.Nodes)
            {
                if (jm.IndexOf(n.Name) == -1)
                {
                    break;
                }

                var node = anim.Nodes[jm.IndexOf(n.Name)];
                Console.WriteLine(n.Name + " " + n.Parent?.Name);

                for (int f = 0; f < anim.FrameCount; f++)
                {
                    var matrix = n.GetLocal(f);
                    var tra    = matrix.ExtractTranslation();
                    var sca    = matrix.ExtractScale();
                    var rot    = Math3D.ToEulerAngles(matrix.ExtractRotation().Inverted());

                    node.Tracks.Find(e => e.JointTrackType == JointTrackType.HSD_A_J_TRAX).Keys.Add(new FOBJKey()
                    {
                        Frame = f, Value = tra.X, InterpolationType = GXInterpolationType.HSD_A_OP_LIN
                    });
                    node.Tracks.Find(e => e.JointTrackType == JointTrackType.HSD_A_J_TRAY).Keys.Add(new FOBJKey()
                    {
                        Frame = f, Value = tra.Y, InterpolationType = GXInterpolationType.HSD_A_OP_LIN
                    });
                    node.Tracks.Find(e => e.JointTrackType == JointTrackType.HSD_A_J_TRAZ).Keys.Add(new FOBJKey()
                    {
                        Frame = f, Value = tra.Z, InterpolationType = GXInterpolationType.HSD_A_OP_LIN
                    });

                    node.Tracks.Find(e => e.JointTrackType == JointTrackType.HSD_A_J_ROTX).Keys.Add(new FOBJKey()
                    {
                        Frame = f, Value = rot.X, InterpolationType = GXInterpolationType.HSD_A_OP_LIN
                    });
                    node.Tracks.Find(e => e.JointTrackType == JointTrackType.HSD_A_J_ROTY).Keys.Add(new FOBJKey()
                    {
                        Frame = f, Value = rot.Y, InterpolationType = GXInterpolationType.HSD_A_OP_LIN
                    });
                    node.Tracks.Find(e => e.JointTrackType == JointTrackType.HSD_A_J_ROTZ).Keys.Add(new FOBJKey()
                    {
                        Frame = f, Value = rot.Z, InterpolationType = GXInterpolationType.HSD_A_OP_LIN
                    });

                    node.Tracks.Find(e => e.JointTrackType == JointTrackType.HSD_A_J_SCAX).Keys.Add(new FOBJKey()
                    {
                        Frame = f, Value = sca.X, InterpolationType = GXInterpolationType.HSD_A_OP_LIN
                    });
                    node.Tracks.Find(e => e.JointTrackType == JointTrackType.HSD_A_J_SCAY).Keys.Add(new FOBJKey()
                    {
                        Frame = f, Value = sca.Y, InterpolationType = GXInterpolationType.HSD_A_OP_LIN
                    });
                    node.Tracks.Find(e => e.JointTrackType == JointTrackType.HSD_A_J_SCAZ).Keys.Add(new FOBJKey()
                    {
                        Frame = f, Value = sca.Z, InterpolationType = GXInterpolationType.HSD_A_OP_LIN
                    });
                }
            }

            return(anim);
        }