/// <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);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="animJoint"></param>
        public static void OptimizeTracks(HSD_JOBJ model, HSD_AnimJoint animJoint, float epsilon = 0.001f)
        {
            var joints      = model.BreathFirstList;
            var anim_joints = animJoint.BreathFirstList;

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

            for (int i = 0; i < joints.Count; i++)
            {
                if (anim_joints[i].AOBJ != null)
                {
                    Dictionary <JointTrackType, float> typeToDefaultValue = new Dictionary <JointTrackType, float>();
                    typeToDefaultValue.Add(JointTrackType.HSD_A_J_TRAX, joints[i].TX);
                    typeToDefaultValue.Add(JointTrackType.HSD_A_J_TRAY, joints[i].TY);
                    typeToDefaultValue.Add(JointTrackType.HSD_A_J_TRAZ, joints[i].TZ);
                    typeToDefaultValue.Add(JointTrackType.HSD_A_J_ROTX, joints[i].RX);
                    typeToDefaultValue.Add(JointTrackType.HSD_A_J_ROTY, joints[i].RY);
                    typeToDefaultValue.Add(JointTrackType.HSD_A_J_ROTZ, joints[i].RZ);
                    typeToDefaultValue.Add(JointTrackType.HSD_A_J_SCAX, joints[i].SX);
                    typeToDefaultValue.Add(JointTrackType.HSD_A_J_SCAY, joints[i].SY);
                    typeToDefaultValue.Add(JointTrackType.HSD_A_J_SCAZ, joints[i].SZ);

                    var tracks = anim_joints[i].AOBJ.FObjDesc.List;

                    HSD_FOBJDesc prev = null;
                    foreach (var t in tracks)
                    {
                        var keys = t.GetDecodedKeys();
                        if (typeToDefaultValue.ContainsKey(t.JointTrackType) &&
                            ConstantTrack(keys, typeToDefaultValue[t.JointTrackType], epsilon))
                        {
                            if (prev != null)
                            {
                                prev.Next = t;
                            }
                            else
                            {
                                anim_joints[i].AOBJ.FObjDesc = t;
                            }
                        }
                        else
                        {
                            prev = t;
                        }
                    }

                    if (anim_joints[i].AOBJ.FObjDesc != null)
                    {
                        System.Diagnostics.Debug.WriteLine($"{tracks.Count} -> {anim_joints[i].AOBJ.FObjDesc.List.Count}");
                    }
                    else
                    {
                        anim_joints[i].AOBJ = null;
                    }
                }
            }
        }
Exemple #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="joint"></param>
        public void FromAnimJoint(HSD_AnimJoint joint)
        {
            Nodes.Clear();
            FrameCount = 0;

            if (joint == null)
            {
                return;
            }

            foreach (var j in joint.BreathFirstList)
            {
                AnimNode n = new AnimNode();
                if (j.AOBJ != null)
                {
                    FrameCount = (int)Math.Max(FrameCount, j.AOBJ.EndFrame + 1);

                    foreach (var fdesc in j.AOBJ.FObjDesc.List)
                    {
                        var players = new FOBJ_Player(fdesc);
                        if (players.Keys != null && players.Keys.Count > 0)
                        {
                            FrameCount = Math.Max(FrameCount, players.Keys.Max(e => e.Frame + 1));
                        }
                        n.Tracks.Add(players);
                    }
                }

                Nodes.Add(n);
            }
        }
Exemple #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="joint"></param>
        public int SetAnimJoint(HSD_AnimJoint joint)
        {
            Nodes.Clear();
            int max = 0;

            if (joint == null)
            {
                return(0);
            }
            foreach (var j in joint.BreathFirstSearch)
            {
                AnimNode n = new AnimNode();
                if (j.AOBJ != null)
                {
                    max = (int)Math.Max(max, j.AOBJ.EndFrame);

                    foreach (var fdesc in j.AOBJ.FObjDesc.List)
                    {
                        AnimTrack track = new AnimTrack();
                        track.TrackType = fdesc.AnimationType;
                        track.Keys      = fdesc.GetDecodedKeys();
                        n.Tracks.Add(track);
                    }
                }
                Nodes.Add(n);
            }
            return(max);
        }
Exemple #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="FileName"></param>
        /// <param name="animation"></param>
        /// <param name="skeleton"></param>
        private void ExportAnimJoint(string FileName, SBAnimation animation, SBSkeleton skeleton)
        {
            HSDRawFile  file = new HSDRawFile();
            HSDRootNode root = new HSDRootNode();

            if (HSDSettings.RootName == "" || HSDSettings.RootName == null)
            {
                HSDSettings.RootName = System.IO.Path.GetFileNameWithoutExtension(FileName);
            }

            if (HSDSettings.RootName == "" || HSDSettings.RootName == null)
            {
                HSDSettings.RootName = animation.Name;
            }

            root.Name = HSDSettings.RootName;

            if (root.Name == null)
            {
                System.Windows.Forms.MessageBox.Show($"Warning, the root name does not end with \"_figatree\"\n{root.Name}");
            }

            file.Roots.Add(root);

            var joint = new HSD_AnimJoint();

            EncodeAnimJoint(skeleton.Bones[0], joint, animation);
            root.Data = joint;

            file.Save(FileName);
        }
        /*
         *
         * 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;
        }
Exemple #7
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public static HSD_AnimJoint GenerateAnimJointFromJOBJ(HSD_JOBJ node)
        {
            HSD_AnimJoint joint = new HSD_AnimJoint();

            foreach (var v in node.Children)
            {
                joint.AddChild(GenerateAnimJointFromJOBJ(v));
            }

            return(joint);
        }
Exemple #8
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="root"></param>
        /// <param name="nodes"></param>
        /// <param name="flags"></param>
        /// <returns></returns>
        private HSD_AnimJoint ToAnimJointRecursive(HSD_JOBJ root, AOBJ_Flags flags)
        {
            HSD_AnimJoint joint = new HSD_AnimJoint();

            joint.Flags = 1;

            AnimNode n = null;

            if (index >= Nodes.Count)
            {
                n = new AnimNode();
            }
            else
            {
                n = Nodes[index++];
            }

            // set flags
            if (n.Tracks.Count > 0)
            {
                joint.AOBJ       = new HSD_AOBJ();
                joint.AOBJ.Flags = flags;
            }

            // add all tracks
            foreach (var t in n.Tracks)
            {
                joint.AOBJ.EndFrame = Math.Max(joint.AOBJ.EndFrame, t.FrameCount);

                HSD_FOBJDesc fobj = t.ToFobjDesc();

                if (joint.AOBJ.FObjDesc == null)
                {
                    joint.AOBJ.FObjDesc = fobj;
                }
                else
                {
                    joint.AOBJ.FObjDesc.Add(fobj);
                }
            }

            // set particle flag
            if (n.Tracks.Any(e => e.JointTrackType == JointTrackType.HSD_A_J_PTCL))
            {
                joint.AOBJ.EndFrame += 0.1f;
            }

            foreach (var c in root.Children)
            {
                joint.AddChild(ToAnimJointRecursive(c, flags));
            }

            return(joint);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="root"></param>
        /// <param name="nodes"></param>
        /// <param name="flags"></param>
        /// <returns></returns>
        private HSD_AnimJoint ToAnimJointRecursive(HSD_JOBJ root, AOBJ_Flags flags)
        {
            HSD_AnimJoint joint = new HSD_AnimJoint();

            joint.Flags = 1;

            AnimNode n = null;

            if (index >= Nodes.Count)
            {
                n = new AnimNode();
            }
            else
            {
                n = Nodes[index++];
            }

            if (n.Tracks.Count > 0)
            {
                joint.AOBJ       = new HSD_AOBJ();
                joint.AOBJ.Flags = flags;
            }
            foreach (var t in n.Tracks)
            {
                joint.AOBJ.EndFrame = Math.Max(joint.AOBJ.EndFrame, t.FrameCount);

                HSD_FOBJDesc fobj = new HSD_FOBJDesc();
                fobj.SetKeys(t.Keys, (byte)t.TrackType);

                if (joint.AOBJ.FObjDesc == null)
                {
                    joint.AOBJ.FObjDesc = fobj;
                }
                else
                {
                    joint.AOBJ.FObjDesc.Add(fobj);
                }
            }

            foreach (var c in root.Children)
            {
                joint.AddChild(ToAnimJointRecursive(c, flags));
            }

            return(joint);
        }
 /// <summary>
 ///
 /// </summary>
 /// <param name="animJoint"></param>
 public static void CompressAnimation(HSD_AnimJoint animJoint, float epsilon = 0.001f)
 {
     foreach (var j in animJoint.BreathFirstList)
     {
         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, epsilon);
                 t.SetKeys(player.Keys, t.TrackType);
             }
         }
     }
 }
Exemple #11
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="icons"></param>
        /// <returns></returns>
        public static Tuple <HSD_JOBJ, HSD_AnimJoint, HSD_MatAnimJoint> GenerateIconModel(MEX_CSSIconEntry[] icons)
        {
            HSD_JOBJ position_joint = new HSD_JOBJ();

            position_joint.Flags = JOBJ_FLAG.CLASSICAL_SCALING | JOBJ_FLAG.ROOT_XLU;
            position_joint.SX    = 1; position_joint.SY = 1; position_joint.SZ = 1;

            HSD_AnimJoint anim_joint = new HSD_AnimJoint();

            HSD_MatAnimJoint matanim_joint = new HSD_MatAnimJoint();

            foreach (var ico in icons)
            {
                ico.Joint.Next        = null;
                ico.AnimJoint.Next    = null;
                ico.MatAnimJoint.Next = null;
                position_joint.AddChild(ico.Joint);
                anim_joint.AddChild(ico.AnimJoint);
                matanim_joint.AddChild(ico.MatAnimJoint);
            }

            return(new Tuple <HSD_JOBJ, HSD_AnimJoint, HSD_MatAnimJoint>(position_joint, anim_joint, matanim_joint));
        }
Exemple #12
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="joint"></param>
        public void FromAnimJoint(HSD_AnimJoint joint)
        {
            Nodes.Clear();
            FrameCount = 0;
            if (joint == null)
            {
                return;
            }
            foreach (var j in joint.BreathFirstList)
            {
                AnimNode n = new AnimNode();
                if (j.AOBJ != null)
                {
                    FrameCount = (int)Math.Max(FrameCount, j.AOBJ.EndFrame);

                    foreach (var fdesc in j.AOBJ.FObjDesc.List)
                    {
                        n.Tracks.Add(new FOBJ_Player(fdesc));
                    }
                }
                Nodes.Add(n);
            }
        }
Exemple #13
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="stage"></param>
        /// <param name="icons"></param>
        public static MEX_mexMapData GenerateMexMap(SBM_MnSelectStageDataTable stage, IEnumerable <MEXStageIconEntry> icons)
        {
            MEX_mexMapData mapData = new MEX_mexMapData();

            var nameTexAnim = new HSD_TexAnim();
            var nameKeys    = new List <FOBJKey>();

            var iconTexAnim = new HSD_TexAnim();
            var iconKeys    = new List <FOBJKey>();

            HSD_JOBJ root = new HSD_JOBJ()
            {
                SX    = 1, SY = 1, SZ = 1,
                Flags = JOBJ_FLAG.CLASSICAL_SCALING
            };

            HSD_AnimJoint animRoot = new HSD_AnimJoint();

            // extra
            {
                var tobjs = stage.IconLargeMatAnimJoint.Child.MaterialAnimation.Next.TextureAnimation.ToTOBJs();

                var index = iconTexAnim.AddImage(tobjs[0]);
                iconKeys.Add(new FOBJKey()
                {
                    Frame = index, Value = index, InterpolationType = GXInterpolationType.HSD_A_OP_CON
                });

                index = iconTexAnim.AddImage(tobjs[1]);
                iconKeys.Add(new FOBJKey()
                {
                    Frame = index, Value = index, InterpolationType = GXInterpolationType.HSD_A_OP_CON
                });
            }

            foreach (var v in icons)
            {
                var index = iconTexAnim.AddImage(v.IconTOBJ);
                if (index == -1)
                {
                    index = 0;
                }
                iconKeys.Add(new FOBJKey()
                {
                    Frame = index, Value = index, InterpolationType = GXInterpolationType.HSD_A_OP_CON
                });

                index = nameTexAnim.AddImage(v.NameTOBJ);
                if (index == -1)
                {
                    index = 0;
                }
                nameKeys.Add(new FOBJKey()
                {
                    Frame = index, Value = index, InterpolationType = GXInterpolationType.HSD_A_OP_CON
                });

                v.Joint.Next      = null;
                v.Joint.Child     = null;
                v.AnimJoint.Next  = null;
                v.AnimJoint.Child = null;

                root.AddChild(v.Joint);
                animRoot.AddChild(v.AnimJoint);
            }

            iconKeys.Add(new FOBJKey()
            {
                Frame = 1600, Value = 0, InterpolationType = GXInterpolationType.HSD_A_OP_CON
            });

            iconTexAnim.GXTexMapID               = HSDRaw.GX.GXTexMapID.GX_TEXMAP0;
            iconTexAnim.AnimationObject          = new HSD_AOBJ();
            iconTexAnim.AnimationObject.EndFrame = 1600;
            iconTexAnim.AnimationObject.FObjDesc = new HSD_FOBJDesc();
            iconTexAnim.AnimationObject.FObjDesc.SetKeys(iconKeys, (byte)TexTrackType.HSD_A_T_TIMG);
            iconTexAnim.AnimationObject.FObjDesc.Next = new HSD_FOBJDesc();
            iconTexAnim.AnimationObject.FObjDesc.Next.SetKeys(iconKeys, (byte)TexTrackType.HSD_A_T_TCLT);

            var iconJOBJ = HSDAccessor.DeepClone <HSD_JOBJ>(stage.IconDoubleModel);

            iconJOBJ.Child = iconJOBJ.Child.Next;

            var iconAnimJoint = HSDAccessor.DeepClone <HSD_AnimJoint>(stage.IconDoubleAnimJoint);

            iconAnimJoint.Child = iconAnimJoint.Child.Next;

            var iconMatAnimJoint = HSDAccessor.DeepClone <HSD_MatAnimJoint>(stage.IconDoubleMatAnimJoint);

            iconMatAnimJoint.Child = iconMatAnimJoint.Child.Next;
            iconMatAnimJoint.Child.MaterialAnimation.Next.TextureAnimation = iconTexAnim;

            var iconNameAnim = HSDAccessor.DeepClone <HSD_MatAnimJoint>(stage.StageNameMatAnimJoint);

            nameTexAnim.AnimationObject          = new HSD_AOBJ();
            nameTexAnim.AnimationObject.EndFrame = 1600;
            nameTexAnim.AnimationObject.FObjDesc = new HSD_FOBJDesc();
            nameTexAnim.AnimationObject.FObjDesc.SetKeys(nameKeys, (byte)TexTrackType.HSD_A_T_TIMG);
            iconNameAnim.Child.Child.MaterialAnimation.TextureAnimation = nameTexAnim;

            mapData.IconModel                  = iconJOBJ;
            mapData.IconAnimJoint              = iconAnimJoint;
            mapData.IconMatAnimJoint           = iconMatAnimJoint;
            mapData.PositionModel              = root;
            mapData.PositionAnimJoint          = animRoot;
            mapData.StageNameMaterialAnimation = iconNameAnim;

            return(mapData);
        }
Exemple #14
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="bone"></param>
        /// <param name="joint"></param>
        /// <param name="animation"></param>
        private void EncodeAnimJoint(SBBone bone, HSD_AnimJoint joint, SBAnimation animation)
        {
            var node = animation.TransformNodes.Find(e => e.Name == bone.Name);

            if (node != null)
            {
                // encode tracks
                joint.Flags         = 1;
                joint.AOBJ          = new HSD_AOBJ();
                joint.AOBJ.EndFrame = animation.FrameCount;
                joint.AOBJ.Flags    = AOBJ_Flags.ANIM_LOOP;

                if (!HSDSettings.LoopAnimation)
                {
                    joint.AOBJ.Flags = AOBJ_Flags.FIRST_PLAY;
                }

                if (node.Tracks.Count == 0)
                {
                    joint.AOBJ.Flags = AOBJ_Flags.NO_ANIM;
                }

                var prev = new HSD_FOBJDesc();

                foreach (var track in node.Tracks)
                {
                    var fobjdesc = new HSD_FOBJDesc();
                    fobjdesc.FromFOBJ(EncodeFOBJ(track));
                    fobjdesc.DataLength = fobjdesc.ToFOBJ().Buffer.Length;

                    if (joint.AOBJ.FObjDesc == null)
                    {
                        joint.AOBJ.FObjDesc = fobjdesc;
                    }
                    else
                    {
                        prev.Next = fobjdesc;
                    }

                    prev = fobjdesc;
                }
            }

            // continue adding children
            var prevChild = new HSD_AnimJoint();

            foreach (var c in bone.Children)
            {
                HSD_AnimJoint child = new HSD_AnimJoint();
                EncodeAnimJoint(c, child, animation);
                if (joint.Child == null)
                {
                    joint.Child = child;
                }
                else
                {
                    prevChild.Next = child;
                }
                prevChild = child;
            }
        }
Exemple #15
0
 /// <summary>
 ///
 /// </summary>
 public JointAnimManager(HSD_AnimJoint joint)
 {
     FromAnimJoint(joint);
 }
        /// <summary>
        /// Builds simple mex menu animation from anim joint using assumptions about the animation
        /// </summary>
        /// <param name="j"></param>
        /// <returns></returns>
        public static MexMenuAnimation FromAnimJoint(HSD_AnimJoint j, HSD_JOBJ jobj)
        {
            var anim = new MexMenuAnimation()
            {
                StartFrame        = 0,
                EndFrame          = 0,
                StartingPositionX = jobj.TX,
                StartingPositionY = jobj.TY,
                StartingPositionZ = jobj.TZ,
                StartingRotationX = jobj.RX,
                StartingRotationY = jobj.RY,
                StartingRotationZ = jobj.RZ,
                StartingScaleX    = jobj.SX,
                StartingScaleY    = jobj.SY,
                StartingScaleZ    = jobj.SZ,
            };

            if (j.AOBJ != null && j.AOBJ.FObjDesc != null)
            {
                foreach (var fobj in j.AOBJ.FObjDesc.List)
                {
                    // get when frame starts moving
                    // get frame
                    // get value
                    // that's all we, we assume final position is what the joint is currently at
                    var keys = fobj.GetDecodedKeys();
                    for (int i = 0; i < keys.Count; i++)
                    {
                        var k = keys[i];
                        if (k.InterpolationType != GXInterpolationType.HSD_A_OP_CON)
                        {
                            anim.StartFrame = (int)Math.Max(anim.StartFrame, k.Frame);
                            anim.EndFrame   = (int)Math.Max(anim.EndFrame, keys[i + 1].Frame);
                            switch ((JointTrackType)fobj.TrackType)
                            {
                            case JointTrackType.HSD_A_J_TRAX: anim.StartingPositionX = k.Value; break;

                            case JointTrackType.HSD_A_J_TRAY: anim.StartingPositionY = k.Value; break;

                            case JointTrackType.HSD_A_J_TRAZ: anim.StartingPositionZ = k.Value; break;

                            case JointTrackType.HSD_A_J_ROTX: anim.StartingRotationX = k.Value; break;

                            case JointTrackType.HSD_A_J_ROTY: anim.StartingRotationY = k.Value; break;

                            case JointTrackType.HSD_A_J_ROTZ: anim.StartingRotationZ = k.Value; break;

                            case JointTrackType.HSD_A_J_SCAX: anim.StartingScaleX = k.Value; break;

                            case JointTrackType.HSD_A_J_SCAY: anim.StartingScaleY = k.Value; break;

                            case JointTrackType.HSD_A_J_SCAZ: anim.StartingScaleZ = k.Value; break;
                            }
                            break;
                        }
                    }
                }
            }

            return(anim);
        }
    {/// <summary>
     ///
     /// </summary>
     /// <param name="space"></param>
     /// <returns></returns>
        public static HSD_AnimJoint GenerateAnimJoint(MexMenuAnimation anim, HSD_JOBJ joint)
        {
            HSD_AnimJoint aj = new HSD_AnimJoint();

            if (anim == null || anim.StartFrame >= anim.EndFrame)
            {
                return(aj);
            }

            var aobj = new HSD_AOBJ();

            aobj.EndFrame = 1600;
            aobj.Flags    = AOBJ_Flags.FIRST_PLAY;

            if (anim.StartingPositionX != joint.TX)
            {
                GenerateFOBJ(aobj, anim.StartingPositionX, joint.TX, anim.StartFrame, anim.EndFrame, JointTrackType.HSD_A_J_TRAX);
            }

            if (anim.StartingPositionY != joint.TY)
            {
                GenerateFOBJ(aobj, anim.StartingPositionY, joint.TY, anim.StartFrame, anim.EndFrame, JointTrackType.HSD_A_J_TRAY);
            }

            if (anim.StartingPositionZ != joint.TZ)
            {
                GenerateFOBJ(aobj, anim.StartingPositionZ, joint.TZ, anim.StartFrame, anim.EndFrame, JointTrackType.HSD_A_J_TRAZ);
            }

            if (anim.StartingRotationX != joint.RX)
            {
                GenerateFOBJ(aobj, anim.StartingRotationX, joint.RX, anim.StartFrame, anim.EndFrame, JointTrackType.HSD_A_J_ROTX);
            }

            if (anim.StartingRotationY != joint.RY)
            {
                GenerateFOBJ(aobj, anim.StartingRotationY, joint.RY, anim.StartFrame, anim.EndFrame, JointTrackType.HSD_A_J_ROTY);
            }

            if (anim.StartingRotationZ != joint.RZ)
            {
                GenerateFOBJ(aobj, anim.StartingRotationZ, joint.RZ, anim.StartFrame, anim.EndFrame, JointTrackType.HSD_A_J_ROTZ);
            }

            if (anim.StartingScaleX != joint.SX)
            {
                GenerateFOBJ(aobj, anim.StartingRotationX, joint.SX, anim.StartFrame, anim.EndFrame, JointTrackType.HSD_A_J_SCAX);
            }

            if (anim.StartingScaleY != joint.SY)
            {
                GenerateFOBJ(aobj, anim.StartingRotationY, joint.SY, anim.StartFrame, anim.EndFrame, JointTrackType.HSD_A_J_SCAY);
            }

            if (anim.StartingScaleZ != joint.SZ)
            {
                GenerateFOBJ(aobj, anim.StartingRotationZ, joint.SZ, anim.StartFrame, anim.EndFrame, JointTrackType.HSD_A_J_SCAZ);
            }

            if (aobj.FObjDesc != null)
            {
                aj.AOBJ = aobj;
            }

            return(aj);

            // starting frame-600
            // 1600 total frames

            /*if (space.AnimType == MexMapAnimType.SlideInFromRight)
             *  joint.AOBJ = GenerateAOBJ(36, space.JOBJ.TX, space.StartFrame, space.EndFrame, JointTrackType.HSD_A_J_TRAX);
             * if (space.AnimType == MexMapAnimType.SlideInFromLeft)
             *  joint.AOBJ = GenerateAOBJ(-40, space.JOBJ.TX, space.StartFrame, space.EndFrame, JointTrackType.HSD_A_J_TRAX);
             * if (space.AnimType == MexMapAnimType.SlideInFromTop)
             *  joint.AOBJ = GenerateAOBJ(36, space.JOBJ.TY, space.StartFrame, space.EndFrame, JointTrackType.HSD_A_J_TRAY);
             * if (space.AnimType == MexMapAnimType.SlideInFromBottom)
             *  joint.AOBJ = GenerateAOBJ(-40, space.JOBJ.TY, space.StartFrame, space.EndFrame, JointTrackType.HSD_A_J_TRAY);
             * if (space.AnimType == MexMapAnimType.GrowFromNothing)
             * {
             *  joint.AOBJ = GenerateAOBJ(0, space.JOBJ.SX, space.StartFrame, space.EndFrame, JointTrackType.HSD_A_J_SCAX);
             *  joint.AOBJ.FObjDesc.Next = GenerateAOBJ(0, space.JOBJ.SY, space.StartFrame, space.EndFrame, JointTrackType.HSD_A_J_SCAY).FObjDesc;
             * }
             * if (space.AnimType == MexMapAnimType.SpinIn)
             * {
             *  joint.AOBJ = GenerateAOBJ(0, space.JOBJ.SX, space.StartFrame, space.EndFrame, JointTrackType.HSD_A_J_SCAX);
             *  joint.AOBJ.FObjDesc.Add(GenerateAOBJ(0, space.JOBJ.SY, space.StartFrame, space.EndFrame, JointTrackType.HSD_A_J_SCAY).FObjDesc);
             *  joint.AOBJ.FObjDesc.Add(GenerateAOBJ(-4, 0, space.StartFrame, space.EndFrame, JointTrackType.HSD_A_J_ROTZ).FObjDesc);
             * }
             * if (space.AnimType == MexMapAnimType.FlipIn)
             * {
             *  joint.AOBJ = GenerateAOBJ(0, space.JOBJ.SX, space.StartFrame, space.EndFrame, JointTrackType.HSD_A_J_SCAX);
             *  joint.AOBJ.FObjDesc.Add(GenerateAOBJ(0, space.JOBJ.SY, space.StartFrame, space.EndFrame, JointTrackType.HSD_A_J_SCAY).FObjDesc);
             *  joint.AOBJ.FObjDesc.Add(GenerateAOBJ(-4, 0, space.StartFrame, space.EndFrame, JointTrackType.HSD_A_J_ROTY).FObjDesc);
             * }*/
        }
Exemple #18
0
        /// <summary>
        /// Opens dat file from stream
        /// </summary>
        /// <param name="stream"></param>
        public void Open(Stream stream)
        {
            using (BinaryReaderExt r = new BinaryReaderExt(stream))
            {
                r.BigEndian = true;

                // Parse Header -----------------------------
                var fsize       = r.ReadInt32(); // dat size
                int relocOffset = r.ReadInt32() + 0x20;
                int relocCount  = r.ReadInt32();
                int rootCount   = r.ReadInt32();
                int refCount    = r.ReadInt32();
                VersionChars = r.ReadChars(4);

                // Parse Relocation Table -----------------------------
                List <int>            Offsets       = new List <int>();
                HashSet <int>         OffsetContain = new HashSet <int>();
                Dictionary <int, int> relocOffsets  = new Dictionary <int, int>();
                Offsets.Add(relocOffset);

                r.BaseStream.Position = relocOffset;
                for (int i = 0; i < relocCount; i++)
                {
                    int offset = r.ReadInt32() + 0x20;

                    var temp = r.BaseStream.Position;

                    r.BaseStream.Position = offset;

                    var objectOff = r.ReadInt32() + 0x20;

                    // if we need to read past end of file then we need to include filesize as an offset
                    // this fixes files that had previously been manually relocated to end of file
                    if (objectOff > relocOffset && !Offsets.Contains(fsize))
                    {
                        Offsets.Add(fsize);
                    }

                    //
                    if (objectOff < 0)
                    {
                        r.BaseStream.Position = temp;
                        continue;
                    }

                    relocOffsets.Add(offset, objectOff);

                    if (!OffsetContain.Contains(objectOff))
                    {
                        OffsetContain.Add(objectOff);
                        Offsets.Add(objectOff);
                    }

                    r.BaseStream.Position = temp;
                }

                // Parse Roots---------------------------------
                List <int>    rootOffsets = new List <int>();
                List <string> rootStrings = new List <string>();
                List <int>    refOffsets  = new List <int>();
                List <string> refStrings  = new List <string>();
                var           stringStart = r.BaseStream.Position + (refCount + rootCount) * 8;
                for (int i = 0; i < rootCount; i++)
                {
                    rootOffsets.Add(r.ReadInt32() + 0x20);
                    rootStrings.Add(r.ReadString((int)stringStart + r.ReadInt32(), -1));
                }
                for (int i = 0; i < refCount; i++)
                {
                    var refp = r.ReadInt32() + 0x20;
                    refOffsets.Add(refp);
                    refStrings.Add(r.ReadString((int)stringStart + r.ReadInt32(), -1));

                    var temp = r.Position;

                    var special = refp;
                    while (true)
                    {
                        r.Seek((uint)special);
                        special = r.ReadInt32();

                        if (special == 0 || special == -1)
                        {
                            break;
                        }

                        special += 0x20;

                        relocOffsets.Add(refp, special);

                        refp = special;

                        if (!OffsetContain.Contains(special))
                        {
                            OffsetContain.Add(special);
                            Offsets.Add(special);
                        }
                    }

                    r.Seek(temp);
                }
                foreach (var v in rootOffsets)
                {
                    if (!OffsetContain.Contains(v))
                    {
                        OffsetContain.Add(v);
                        Offsets.Add(v);
                    }
                }
                foreach (var v in refOffsets)
                {
                    if (!OffsetContain.Contains(v))
                    {
                        OffsetContain.Add(v);
                        Offsets.Add(v);
                    }
                }


                // Split Raw Struct Data--------------------------
                Offsets.Sort();

                Dictionary <int, HSDStruct>   offsetToStruct       = new Dictionary <int, HSDStruct>();
                Dictionary <int, List <int> > offsetToOffsets      = new Dictionary <int, List <int> >();
                Dictionary <int, List <int> > offsetToInnerOffsets = new Dictionary <int, List <int> >();

                var relockeys = relocOffsets.Keys.ToList();
                for (int i = 0; i < Offsets.Count - 1; i++)
                {
                    r.BaseStream.Position = Offsets[i];
                    byte[] data = r.ReadBytes(Offsets[i + 1] - Offsets[i]);

                    if (!offsetToOffsets.ContainsKey(Offsets[i]))
                    {
                        var relocKets = relockeys.FindAll(e => e >= Offsets[i] && e < Offsets[i + 1]);
                        var list      = new List <int>();
                        foreach (var k in relocKets)
                        {
                            list.Add(relocOffsets[k]);
                        }
                        offsetToOffsets.Add(Offsets[i], list);
                        offsetToInnerOffsets.Add(Offsets[i], relocKets);
                    }

                    if (!offsetToStruct.ContainsKey(Offsets[i]))
                    {
                        var struture = new HSDStruct(data);

                        offsetToStruct.Add(Offsets[i], struture);
                    }
                }

                // set references-------------------------
                foreach (var str in offsetToStruct)
                {
                    var offsets      = offsetToOffsets[str.Key];
                    var innerOffsets = offsetToInnerOffsets[str.Key];
                    for (int i = 0; i < offsets.Count; i++)
                    {
                        if (offsetToStruct.ContainsKey(offsets[i]) && str.Value.Length >= innerOffsets[i] - str.Key + 4)
                        {
                            str.Value.SetReferenceStruct(innerOffsets[i] - str.Key, offsetToStruct[offsets[i]]);
                        }
                    }

                    _structCache.Add(str.Value);
                    _structCacheToOffset.Add(str.Value, str.Key);
                }

                // set roots
                for (int i = 0; i < rootOffsets.Count; i++)
                {
                    HSDStruct   str = offsetToStruct[rootOffsets[i]];
                    HSDAccessor a   = new HSDAccessor();
                    a._s = str;
                    if (rootStrings[i].EndsWith("shapeanim_joint"))
                    {
                        var acc = new HSDAccessor();
                        acc._s = str;
                        a      = acc;
                    }
                    else
                    if (rootStrings[i].EndsWith("matanim_joint"))
                    {
                        var acc = new HSD_MatAnimJoint();
                        acc._s = str;
                        a      = acc;
                    }
                    else
                    if (rootStrings[i].EndsWith("_joint"))
                    {
                        var jobj = new HSD_JOBJ();
                        jobj._s = str;
                        a       = jobj;
                    }
                    else
                    if (rootStrings[i].EndsWith("_animjoint"))
                    {
                        var jobj = new HSD_AnimJoint();
                        jobj._s = str;
                        a       = jobj;
                    }
                    else
                    if (rootStrings[i].EndsWith("_texanim"))
                    {
                        var jobj = new HSD_TexAnim();
                        jobj._s = str;
                        a       = jobj;
                    }
                    else
                    if (rootStrings[i].EndsWith("_figatree"))
                    {
                        var jobj = new HSD_FigaTree();
                        jobj._s = str;
                        a       = jobj;
                    }
                    else
                    if (rootStrings[i].EndsWith("_scene_models") ||
                        rootStrings[i].Equals("Stc_rarwmdls") ||
                        rootStrings[i].Equals("Stc_scemdls") ||
                        rootStrings[i].Equals("lupe") ||
                        rootStrings[i].Equals("tdsce"))
                    {
                        var jobj = new HSDNullPointerArrayAccessor <HSD_JOBJDesc>();
                        jobj._s = str;
                        a       = jobj;
                    }
                    else
                    if (rootStrings[i].StartsWith("ftData"))
                    {
                        var acc = new SBM_PlayerData();
                        acc._s = str;
                        a      = acc;
                    }
                    else
                    if (rootStrings[i].EndsWith("MnSelectChrDataTable"))
                    {
                        var acc = new SBM_SelectChrDataTable();
                        acc._s = str;
                        a      = acc;
                    }
                    else
                    if (rootStrings[i].EndsWith("MnSelectStageDataTable"))
                    {
                        var acc = new SBM_MnSelectStageDataTable();
                        acc._s = str;
                        a      = acc;
                    }
                    else
                    if (rootStrings[i].EndsWith("coll_data"))
                    {
                        var acc = new SBM_Coll_Data();
                        acc._s = str;
                        a      = acc;
                    }
                    else
                    if (rootStrings[i].EndsWith("scene_data") ||
                        rootStrings[i].Equals("pnlsce") ||
                        rootStrings[i].Equals("flmsce") ||
                        (rootStrings[i].StartsWith("Sc") && str.Length == 0x10))
                    {
                        var acc = new HSD_SOBJ();
                        acc._s = str;
                        a      = acc;
                    }
                    else
                    if (rootStrings[i].StartsWith("map_plit"))
                    {
                        var acc = new HSDNullPointerArrayAccessor <HSD_Light>();
                        acc._s = str;
                        a      = acc;
                    }

                    /*else
                     * if (rootStrings[i].StartsWith("grGroundParam"))
                     * {
                     *  var acc = new SBM_GroundParam();
                     *  acc._s = str;
                     *  a = acc;
                     * }*/
                    else
                    if (rootStrings[i].StartsWith("map_head"))
                    {
                        var acc = new SBM_Map_Head();
                        acc._s = str;
                        a      = acc;
                    }
                    else
                    if (rootStrings[i].StartsWith("grGroundParam"))
                    {
                        var acc = new SBM_GroundParam();
                        acc._s = str;
                        a      = acc;
                    }
                    else
                    if (rootStrings[i].StartsWith("vcDataStar"))
                    {
                        var acc = new KAR_vcDataStar();
                        acc._s = str;
                        a      = acc;
                    }
                    else
                    if (rootStrings[i].StartsWith("vcDataWheel"))
                    {
                        var acc = new KAR_vcDataWheel();
                        acc._s = str;
                        a      = acc;
                    }
                    else
                    if (rootStrings[i].StartsWith("grModelMotion"))
                    {
                        var acc = new KAR_grModelMotion();
                        acc._s = str;
                        a      = acc;
                    }
                    else
                    if (rootStrings[i].StartsWith("grModel"))
                    {
                        var acc = new KAR_grModel();
                        acc._s = str;
                        a      = acc;
                    }
                    else
                    if (rootStrings[i].StartsWith("grData"))
                    {
                        var acc = new KAR_grData();
                        acc._s = str;
                        a      = acc;
                    }
                    else
                    if (rootStrings[i].EndsWith("_texg"))
                    {
                        var acc = new HSD_TEXGraphicBank();
                        acc._s = str;
                        a      = acc;
                    }
                    else
                    if (rootStrings[i].EndsWith("_ptcl"))
                    {
                        var acc = new HSD_ParticleGroup();
                        acc._s = str;
                        a      = acc;
                    }
                    else
                    if (rootStrings[i].StartsWith("eff"))
                    {
                        var acc = new SBM_EffectTable();
                        acc._s = str;
                        a      = acc;
                    }

                    Roots.Add(new HSDRootNode()
                    {
                        Name = rootStrings[i], Data = a
                    });
                }


                // set references
                for (int i = 0; i < refOffsets.Count; i++)
                {
                    HSDStruct   str = offsetToStruct[refOffsets[i]];
                    HSDAccessor a   = new HSDAccessor();
                    a._s = str;
                    References.Add(new HSDRootNode()
                    {
                        Name = refStrings[i], Data = a
                    });
                }
            }
        }
Exemple #19
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="table"></param>
        /// <param name="icons"></param>
        /// <returns></returns>
        private static MEX_mexSelectChr GenerateMexSelectChrSymbol(SBM_SelectChrDataTable table, MEX_CSSIcon[] cssIcons)
        {
            // create mexSelectChr struct
            MEX_mexSelectChr mex = new MEX_mexSelectChr();

            // generate icon model
            var icon_joint = HSDAccessor.DeepClone <HSD_JOBJ>(table.MenuModel.Children[2].Child);

            icon_joint.TX   = 0;
            icon_joint.TY   = 0;
            icon_joint.TZ   = 0;
            icon_joint.Next = null;
            var center = RegenerateIcon(icon_joint);

            // generate material_anim_joint
            var icon_matanim_joint = HSDAccessor.DeepClone <HSD_MatAnimJoint>(table.MenuMaterialAnimation.Children[2].Child);

            icon_matanim_joint.Next = null;

            // general base models
            HSD_JOBJ position_joint = new HSD_JOBJ();

            position_joint.Flags = JOBJ_FLAG.CLASSICAL_SCALING | JOBJ_FLAG.ROOT_XLU;
            position_joint.SX    = 1; position_joint.SY = 1; position_joint.SZ = 1;

            HSD_AnimJoint anim_joint = new HSD_AnimJoint();

            HSD_MatAnimJoint matanim_joint = new HSD_MatAnimJoint();

            // create icon data
            var joints   = table.MenuModel.BreathFirstList;
            var matanims = table.MenuAnimation.BreathFirstList;

            foreach (var ico in cssIcons)
            {
                if (joints[ico.JointID].Dobj == null)
                {
                    continue;
                }

                HSD_JOBJ joint = HSDAccessor.DeepClone <HSD_JOBJ>(icon_joint);
                joint.Dobj.Pobj.Attributes      = icon_joint.Dobj.Pobj.Attributes;
                joint.Dobj.Next.Pobj.Attributes = icon_joint.Dobj.Pobj.Attributes;
                joint.Dobj.Next.Mobj.Textures   = HSDAccessor.DeepClone <HSD_TOBJ>(joints[ico.JointID].Dobj.Next.Mobj.Textures);

                var worldPosition = new GXVector3(joints[ico.JointID].TX, joints[ico.JointID].TY, joints[ico.JointID].TZ);

                // get anim
                var anim = matanims[ico.JointID].AOBJ;

                // if it's a clone get parent location
                if (ico.JointID < 15)
                {
                    worldPosition = new GXVector3(joints[ico.JointID - 1].TX, joints[ico.JointID - 1].TY, joints[ico.JointID - 1].TZ);
                    anim          = matanims[ico.JointID - 1].AOBJ;
                }

                // check animation for world position
                if (anim != null)
                {
                    foreach (var v in anim.FObjDesc.List)
                    {
                        System.Diagnostics.Debug.WriteLine(v.JointTrackType);
                        if (v.JointTrackType == JointTrackType.HSD_A_J_TRAX)
                        {
                            var keys = v.GetDecodedKeys();
                            worldPosition.X = keys[keys.Count - 1].Value;
                        }
                    }
                }

                joint.TX = worldPosition.X + center.X;
                joint.TY = worldPosition.Y + center.Y;
                joint.TZ = worldPosition.Z + center.Z;

                position_joint.AddChild(joint);
                anim_joint.AddChild(new HSD_AnimJoint());
                matanim_joint.AddChild(HSDAccessor.DeepClone <HSD_MatAnimJoint>(icon_matanim_joint));
            }

            mex.IconModel        = position_joint;
            mex.IconAnimJoint    = anim_joint;
            mex.IconMatAnimJoint = matanim_joint;
            mex.CSPMatAnim       = HSDAccessor.DeepClone <HSD_MatAnim>(table.MenuMaterialAnimation.Children[6].Child.MaterialAnimation);

            var cspkeys = mex.CSPMatAnim.TextureAnimation.AnimationObject.FObjDesc.GetDecodedKeys();

            foreach (var k in cspkeys)
            {
                if ((k.Frame % 30) >= 19)
                {
                    k.Frame++;
                }
            }

            mex.CSPMatAnim.TextureAnimation.AnimationObject.FObjDesc.SetKeys(cspkeys, (byte)TexTrackType.HSD_A_T_TIMG);
            mex.CSPMatAnim.TextureAnimation.AnimationObject.FObjDesc.Next.SetKeys(cspkeys, (byte)TexTrackType.HSD_A_T_TCLT);

            mex.CSPStride = 30;

            return(mex);
        }
Exemple #20
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="stage"></param>
        /// <returns></returns>
        public static MEX_mexMapData LoadIconDataFromVanilla(SBM_MnSelectStageDataTable stage)
        {
            List <HSD_TOBJ> nameTags = new List <HSD_TOBJ>();

            List <HSD_TOBJ> iconTOBJs = new List <HSD_TOBJ>();

            HSD_JOBJ root = new HSD_JOBJ()
            {
                SX    = 1,
                SY    = 1,
                SZ    = 1,
                Flags = JOBJ_FLAG.CLASSICAL_SCALING
            };

            HSD_AnimJoint animRoot = new HSD_AnimJoint();


            var tex0       = stage.IconDoubleMatAnimJoint.Child.Next.MaterialAnimation.Next.TextureAnimation.ToTOBJs();
            var tex0_extra = stage.IconDoubleMatAnimJoint.Child.MaterialAnimation.Next.TextureAnimation.ToTOBJs();
            var tex1       = stage.IconLargeMatAnimJoint.Child.MaterialAnimation.Next.TextureAnimation.ToTOBJs();
            var tex2       = stage.IconSpecialMatAnimJoint.Child.MaterialAnimation.Next.TextureAnimation.ToTOBJs();

            var nameTOBJs     = stage.StageNameMatAnimJoint.Child.Child.MaterialAnimation.TextureAnimation.ToTOBJs();
            var nameTOBJsAnim = stage.StageNameMatAnimJoint.Child.Child.MaterialAnimation.TextureAnimation.AnimationObject.FObjDesc.GetDecodedKeys();

            var positionAnimation = new List <HSD_AnimJoint>();

            foreach (var c in stage.PositionAnimation.Children)
            {
                var pos = new HSD_AnimJoint();
                pos.AOBJ = HSDAccessor.DeepClone <HSD_AOBJ>(c.AOBJ);
                positionAnimation.Add(pos);
            }

            var g1 = tex0.Length - 2;
            var g2 = tex0.Length - 2 + tex1.Length - 2;
            var g3 = tex0.Length - 2 + tex1.Length - 2 + tex2.Length - 2;

            for (int i = 0; i < stage.PositionModel.Children.Length; i++)
            {
                var childIndex = i;
                if (unswizzle.ContainsKey(i))
                {
                    childIndex = unswizzle[i];
                }

                HSD_TOBJ icon = null;
                HSD_TOBJ name = null;
                var      keys = positionAnimation[childIndex].AOBJ.FObjDesc.GetDecodedKeys();
                var      Y    = stage.PositionModel.Children[childIndex].TY;
                var      Z    = stage.PositionModel.Children[childIndex].TZ;
                var      SX   = 1f;
                var      SY   = 1f;

                if (i >= g3)
                {
                    //RandomIcon
                    name = nameTOBJs[(int)nameTOBJsAnim[nameTOBJsAnim.Count - 1].Value];
                }
                else
                if (i >= g2)
                {
                    name = nameTOBJs[(int)nameTOBJsAnim[24 + (i - g2)].Value];
                    icon = tex2[i - g2 + 2];
                    SX   = 0.8f;
                    SY   = 0.8f;
                }
                else
                if (i >= g1)
                {
                    name = nameTOBJs[(int)nameTOBJsAnim[22 + texunswizzle[i - g1]].Value];
                    icon = tex1[i - g1 + 2];
                    SY   = 1.1f;
                }
                else
                {
                    icon = tex0[texunswizzle[i] + 2];
                    name = nameTOBJs[(int)nameTOBJsAnim[texunswizzle[i]].Value * 2];

                    root.AddChild(new HSD_JOBJ()
                    {
                        TX    = keys[keys.Count - 1].Value,
                        TY    = Y,
                        TZ    = Z,
                        SX    = SX,
                        SY    = SY,
                        SZ    = 1,
                        Flags = JOBJ_FLAG.CLASSICAL_SCALING
                    });
                    iconTOBJs.Add(icon);
                    nameTags.Add(name);
                    animRoot.AddChild(HSDAccessor.DeepClone <HSD_AnimJoint>(positionAnimation[childIndex]));

                    Y   -= 5.6f;
                    Z    = 0;
                    icon = tex0_extra[texunswizzle[i] + 2];
                    name = nameTOBJs[(int)nameTOBJsAnim[texunswizzle[i]].Value * 2 + 1];
                }

                root.AddChild(new HSD_JOBJ()
                {
                    TX    = keys[keys.Count - 1].Value,
                    TY    = Y,
                    TZ    = Z,
                    SX    = SX,
                    SY    = SY,
                    SZ    = 1,
                    Flags = JOBJ_FLAG.CLASSICAL_SCALING
                });
                iconTOBJs.Add(icon);
                nameTags.Add(name);
                animRoot.AddChild(HSDAccessor.DeepClone <HSD_AnimJoint>(positionAnimation[childIndex]));
            }


            var extraIcons = stage.IconLargeMatAnimJoint.Child.MaterialAnimation.Next.TextureAnimation.ToTOBJs();

            iconTOBJs.Insert(0, extraIcons[0]);
            iconTOBJs.Insert(0, extraIcons[1]);
            iconTOBJs.Add(extraIcons[0]);


            var iconJOBJ = HSDAccessor.DeepClone <HSD_JOBJ>(stage.IconDoubleModel);

            iconJOBJ.Child = iconJOBJ.Child.Next;

            var iconAnimJoint = HSDAccessor.DeepClone <HSD_AnimJoint>(stage.IconDoubleAnimJoint);

            iconAnimJoint.Child = iconAnimJoint.Child.Next;

            var iconMatAnimJoint = HSDAccessor.DeepClone <HSD_MatAnimJoint>(stage.IconDoubleMatAnimJoint);

            iconMatAnimJoint.Child = iconMatAnimJoint.Child.Next;
            iconMatAnimJoint.Child.MaterialAnimation.Next.TextureAnimation.FromTOBJs(iconTOBJs.ToArray(), true);


            var mapdata = new MEX_mexMapData();

            mapdata.IconModel                  = iconJOBJ;
            mapdata.IconAnimJoint              = iconAnimJoint;
            mapdata.IconMatAnimJoint           = iconMatAnimJoint;
            mapdata.PositionModel              = root;
            mapdata.PositionAnimJoint          = animRoot;
            mapdata.StageNameMaterialAnimation = HSDAccessor.DeepClone <HSD_MatAnimJoint>(stage.StageNameMatAnimJoint);
            mapdata.StageNameMaterialAnimation.Child.Child.MaterialAnimation.TextureAnimation.FromTOBJs(nameTags, true);

            return(mapdata);
        }