示例#1
0
        private void WriteBone(XmlWriter file, SBBone bone)
        {
            file.WriteStartElement("SBBone");
            file.WriteAttributeString("Name", bone.Name);
            file.WriteAttributeString("TranslateX", "" + bone.Translation.X);
            file.WriteAttributeString("TranslateY", "" + bone.Translation.Y);
            file.WriteAttributeString("TranslateZ", "" + bone.Translation.Z);
            file.WriteAttributeString("RotationEulerX", "" + bone.RotationEuler.X);
            file.WriteAttributeString("RotationEulerY", "" + bone.RotationEuler.Y);
            file.WriteAttributeString("RotationEulerZ", "" + bone.RotationEuler.Z);

            if ("" + bone.Scale.X != "1")
            {
                file.WriteAttributeString("ScaleX", "" + bone.Scale.X);
            }

            if ("" + bone.Scale.Y != "1")
            {
                file.WriteAttributeString("ScaleY", "" + bone.Scale.Y);
            }

            if ("" + bone.Scale.Z != "1")
            {
                file.WriteAttributeString("ScaleZ", "" + bone.Scale.Z);
            }

            foreach (var child in bone.Children)
            {
                WriteBone(file, child);
            }

            file.WriteEndElement();
        }
示例#2
0
        private bool HandleAttribute(XmlReader reader, SBBone bone, string attribute, bool required = true)
        {
            string value = reader.GetAttribute(attribute);
            float  val;

            if (value == null)
            {
                if (required)
                {
                    SBConsole.WriteLine("Expected attribute \"" + attribute + "\"");
                }
                return(false);
            }
            else if (!float.TryParse(value, out val))
            {
                SBConsole.WriteLine("Failed to parse attribute \"" + attribute + "\"");
                return(false);
            }

            if (!WriteValue(bone, attribute, val))
            {
                return(false);
            }

            return(true);
        }
示例#3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="limb"></param>
        /// <param name="parent"></param>
        /// <returns></returns>
        private static SBBone ConvertLimbToSBBone(FbxLimbNode limb, SBBone parent = null)
        {
            SBBone bone = new SBBone();

            bone.Name = limb.Name;

            bone.Transform = Matrix4.Identity;

            //who needs precision anyways
            bone.Translation   = new Vector3((float)limb.LclTranslation.X, (float)limb.LclTranslation.Y, (float)limb.LclTranslation.Z);
            bone.RotationEuler = new Vector3((float)limb.LclRotation.X * DegToRag, (float)limb.LclRotation.Y * DegToRag, (float)limb.LclRotation.Z * DegToRag);
            bone.Scale         = new Vector3((float)limb.LclScaling.X, (float)limb.LclScaling.Y, (float)limb.LclScaling.Z);

            if (bone.Scale == new Vector3(100))
            {
                bone.Scale /= 100;
            }

            if (parent != null)
            {
                bone.Parent = parent;
            }

            //process children
            foreach (var child in limb.Children)
            {
                ConvertLimbToSBBone(child, bone);
            }

            return(bone);
        }
示例#4
0
 public static void QueueBones(SBBone b, Queue <SBBone> q, SBSkeleton Skeleton)
 {
     q.Enqueue(b);
     foreach (SBBone c in b.Children)
     {
         QueueBones(c, q, Skeleton);
     }
 }
示例#5
0
 private void UpdateSBSkeleton(SBSkeleton skeleton, Dictionary <String, SBTransformAnimation> transformNodes, int frame)
 {
     foreach (var nodeName in transformNodes.Keys)
     {
         SBTransformAnimation a = transformNodes[nodeName];
         SBBone bone            = skeleton[nodeName];
         bone.AnimatedTransform = a.GetTransformAt(frame, bone);
     }
 }
示例#6
0
 public void BindBone(SBBone Bone)
 {
     NameLabel.Text = Bone.Name;
     X.Bind(Bone, "X");
     Y.Bind(Bone, "Y");
     Z.Bind(Bone, "Z");
     RX.Bind(Bone, "RX");
     RY.Bind(Bone, "RY");
     RZ.Bind(Bone, "RZ");
     SX.Bind(Bone, "SX");
     SY.Bind(Bone, "SY");
     SZ.Bind(Bone, "SZ");
 }
示例#7
0
 public void SetBone(SBBone Bone)
 {
     BoneName.Text = Bone.Name;
     X.BindValue(Bone, "X");
     Y.BindValue(Bone, "Y");
     Z.BindValue(Bone, "Z");
     RX.BindValue(Bone, "RX");
     RY.BindValue(Bone, "RY");
     RZ.BindValue(Bone, "RZ");
     SX.BindValue(Bone, "SX");
     SY.BindValue(Bone, "SY");
     SZ.BindValue(Bone, "SZ");
 }
示例#8
0
        private void UpdateBone(SBSkeleton skeleton, SBBone bone)
        {
            skeleton[bone.Name].X  = bone.X;
            skeleton[bone.Name].Y  = bone.Y;
            skeleton[bone.Name].Z  = bone.Z;
            skeleton[bone.Name].RX = bone.RX;
            skeleton[bone.Name].RY = bone.RY;
            skeleton[bone.Name].RZ = bone.RZ;

            foreach (var child in bone.Children)
            {
                UpdateBone(skeleton, child);
            }
        }
示例#9
0
        private void ReadTransformAnimations(Anim animFile, AnimGroup animGroup, SBAnimation animation)
        {
            var decoder = new SsbhAnimTrackDecoder(animFile);

            foreach (AnimNode animNode in animGroup.Nodes)
            {
                SBTransformAnimation tfrmAnim = new SBTransformAnimation()
                {
                    Name = animNode.Name
                };
                SBTransformTrack X  = new SBTransformTrack(SBTrackType.TranslateX);
                SBTransformTrack Y  = new SBTransformTrack(SBTrackType.TranslateY);
                SBTransformTrack Z  = new SBTransformTrack(SBTrackType.TranslateZ);
                SBTransformTrack RX = new SBTransformTrack(SBTrackType.RotateX);
                SBTransformTrack RY = new SBTransformTrack(SBTrackType.RotateY);
                SBTransformTrack RZ = new SBTransformTrack(SBTrackType.RotateZ);
                SBTransformTrack SX = new SBTransformTrack(SBTrackType.ScaleX);
                SBTransformTrack SY = new SBTransformTrack(SBTrackType.ScaleY);
                SBTransformTrack SZ = new SBTransformTrack(SBTrackType.ScaleZ);
                SBTransformTrack CompensateScale = new SBTransformTrack(SBTrackType.CompensateScale);
                tfrmAnim.Tracks.AddRange(new SBTransformTrack[] { X, Y, Z, RX, RY, RZ, SX, SY, SZ, CompensateScale });

                foreach (AnimTrack track in animNode.Tracks)
                {
                    object[] Transform = decoder.ReadTrack(track);

                    if (track.Name.Equals("Transform"))
                    {
                        for (int i = 0; i < Transform.Length; i++)
                        {
                            AnimTrackTransform t = (AnimTrackTransform)Transform[i];

                            SBBone transform = new SBBone();
                            transform.Transform = GetMatrix((AnimTrackTransform)Transform[i]);
                            X.AddKey(i, transform.X);
                            Y.AddKey(i, transform.Y);
                            Z.AddKey(i, transform.Z);
                            RX.AddKey(i, transform.RX);
                            RY.AddKey(i, transform.RY);
                            RZ.AddKey(i, transform.RZ);
                            SX.AddKey(i, transform.SX);
                            SY.AddKey(i, transform.SY);
                            SZ.AddKey(i, transform.SZ);
                            CompensateScale.AddKey(i, t.CompensateScale);
                        }
                    }
                }
                animation.TransformNodes.Add(tfrmAnim);
            }
        }
示例#10
0
        public void ExportSBAnimation(string FileName, SBAnimation animation, SBSkeleton skeleton)
        {
            SMD file = new SMD();

            var bonelist = new List <SBBone>(skeleton.Bones);

            foreach (var bone in bonelist)
            {
                file.nodes.Add(new SMDNode()
                {
                    Name = bone.Name, ID = bonelist.IndexOf(bone), ParentID = bonelist.IndexOf(bone.Parent)
                });
            }

            for (int i = 0; i < animation.FrameCount; i++)
            {
                var group = new SMDSkeletonFrame();
                group.time = i;
                file.skeleton.Add(group);

                foreach (var bone in bonelist)
                {
                    bool found = false;
                    foreach (var animbone in animation.TransformNodes)
                    {
                        if (animbone.Name.Equals(bone.Name))
                        {
                            var tempBone = new SBBone();
                            tempBone.Transform = animbone.GetTransformAt(i, skeleton);
                            group.skeletons.Add(new SMDSkeleton()
                            {
                                BoneID = bonelist.IndexOf(bone), Position = tempBone.Translation, Rotation = tempBone.RotationEuler
                            });
                            found = true;
                            break;
                        }
                    }
                    if (!found)
                    {
                        group.skeletons.Add(new SMDSkeleton()
                        {
                            BoneID = bonelist.IndexOf(bone), Position = bone.Translation, Rotation = bone.RotationEuler
                        });
                    }
                }
            }

            file.Save(FileName);
        }
示例#11
0
        private List <Bone> CreateChildBones(SBBone head, Bone parent)
        {
            List <Bone> bones = new List <Bone>();

            foreach (var tail in head.Children)
            {
                Bone bone = new Bone();
                bone.parent   = parent;
                bone.head     = head;
                bone.tail     = tail;
                bone.children = CreateChildBones(tail, bone);
                bones.Add(bone);
            }
            return(bones);
        }
示例#12
0
        private SBBone ReadBone(XmlReader reader, SBBone bone)
        {
            SBBone newBone = new SBBone();

            newBone.Transform = Matrix4.Identity;
            if (!reader.ReadToFollowing("SBBone") || reader.NodeType != XmlNodeType.Element || reader.Name != "SBBone")
            {
                SBConsole.WriteLine("Expected bone element");
                return(null);
            }

            string name = reader.GetAttribute("Name");

            if (name != bone.Name)
            {
                SBConsole.WriteLine("Expected bone definition for " + bone.Name +
                                    ", received \"" + name + "\"");
                return(null);
            }

            newBone.Name = bone.Name;
            if (!HandleAttribute(reader, newBone, "TranslateX") ||
                !HandleAttribute(reader, newBone, "TranslateY") ||
                !HandleAttribute(reader, newBone, "TranslateZ") ||
                !HandleAttribute(reader, newBone, "RotationEulerX") ||
                !HandleAttribute(reader, newBone, "RotationEulerY") ||
                !HandleAttribute(reader, newBone, "RotationEulerZ"))
            {
                return(null);
            }

            // Optional attributes
            HandleAttribute(reader, newBone, "ScaleX", false);
            HandleAttribute(reader, newBone, "ScaleY", false);
            HandleAttribute(reader, newBone, "ScaleZ", false);

            foreach (var child in bone.Children)
            {
                SBBone newChild = ReadBone(reader, child);
                if (newChild == null)
                {
                    return(null);
                }
                newBone.AddChild(newChild);
            }

            return(newBone);
        }
示例#13
0
        /// <summary>
        /// Gets matrix4 transform for model node
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        private static Matrix4 GetModelTransform(FbxModel model)
        {
            SBBone bone = new SBBone();

            bone.Transform = Matrix4.Identity;

            bone.Scale         = new Vector3((float)model.LclScaling.X, (float)model.LclScaling.Y, (float)model.LclScaling.Z);
            bone.RotationEuler = new Vector3((float)model.LclRotation.X * DegToRag, (float)model.LclRotation.Y * DegToRag, (float)model.LclRotation.Z * DegToRag);
            bone.Translation   = new Vector3((float)model.LclTranslation.X, (float)-model.LclTranslation.Z, (float)model.LclTranslation.Y);

            if (bone.Scale == new Vector3(100))
            {
                bone.Scale /= 100;
            }

            return(Matrix4.CreateScale(bone.Scale) * Matrix4.CreateFromQuaternion(bone.RotationQuaternion) * Matrix4.CreateTranslation(bone.Translation));
        }
示例#14
0
        private void Read(XmlReader reader, SBSkeleton skeleton)
        {
            List <SBBone> roots = new List <SBBone>();

            foreach (var bone in skeleton.Roots)
            {
                SBBone newBone = ReadBone(reader, bone);
                if (newBone == null)
                {
                    SBConsole.WriteLine("Failed to read XML skeleton.");
                    return;
                }
                roots.Add(newBone);
            }

            UpdateSkeleton(skeleton, roots);
        }
示例#15
0
        private bool WriteValue(SBBone bone, string attribute, float value)
        {
            if (attribute.Equals("TranslateX"))
            {
                bone.X = value;
            }
            else if (attribute.Equals("TranslateY"))
            {
                bone.Y = value;
            }
            else if (attribute.Equals("TranslateZ"))
            {
                bone.Z = value;
            }
            else if (attribute.Equals("RotationEulerX"))
            {
                bone.RX = value;
            }
            else if (attribute.Equals("RotationEulerY"))
            {
                bone.RY = value;
            }
            else if (attribute.Equals("RotationEulerZ"))
            {
                bone.RZ = value;
            }
            else if (attribute.Equals("ScaleX"))
            {
                bone.SX = value;
            }
            else if (attribute.Equals("ScaleY"))
            {
                bone.SY = value;
            }
            else if (attribute.Equals("ScaleZ"))
            {
                bone.SZ = value;
            }
            else
            {
                SBConsole.WriteLine("Internal failure");
                return(false);
            }

            return(true);
        }
示例#16
0
        private static float GetValue(Matrix4 transform, ControlType ctype, TrackType ttype)
        {
            SBBone temp = new SBBone();

            temp.Transform = transform;
            switch (ctype)
            {
            case ControlType.rotate:
                return(GetTrackValue(temp.RotationEuler, ttype));

            case ControlType.scale:
                return(GetTrackValue(temp.Scale, ttype));

            case ControlType.translate:
                return(GetTrackValue(temp.Translation, ttype));
            }
            return(0);
        }
示例#17
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="FileName"></param>
        /// <param name="animation"></param>
        /// <param name="skeleton"></param>
        public void ExportSBAnimation(string FileName, SBAnimation animation, SBSkeleton skeleton)
        {
            SEAnim seOut = new SEAnim();                   //init new SEAnim

            foreach (var node in animation.TransformNodes) //iterate through each node
            {
                for (int i = 0; i < animation.FrameCount; i++)
                {
                    SBBone temp = new SBBone();

                    temp.Transform = node.GetTransformAt(i, skeleton);

                    seOut.AddTranslationKey(node.Name, i, temp.X, temp.Y, temp.Z);
                    seOut.AddRotationKey(node.Name, i, temp.RotationQuaternion.X, temp.RotationQuaternion.Y, temp.RotationQuaternion.Z, temp.RotationQuaternion.W);
                    seOut.AddScaleKey(node.Name, i, temp.SX, temp.SY, temp.SZ);
                }
            }

            seOut.Write(FileName); //write it!
        }
示例#18
0
        private static float GetValue(Matrix4 transform, ControlType ctype, TrackType ttype)
        {
            SBBone temp = new SBBone();

            temp.Transform = transform;
            float rotationTransform = (float)(MayaSettings.UseRadians ? 1 : (180 / Math.PI));

            switch (ctype)
            {
            case ControlType.rotate:
                return(GetTrackValue(temp.RotationEuler, ttype) * rotationTransform);

            case ControlType.scale:
                return(GetTrackValue(temp.Scale, ttype));

            case ControlType.translate:
                return(GetTrackValue(temp.Translation, ttype));
            }
            return(0);
        }
示例#19
0
        private void CreateMesh()
        {
            Mesh.Clear();

            if (RootJOBJ == null)
            {
                return;
            }

            var dobjs = GetDOBJS();
            var jobjs = RootJOBJ.BreathFirstList;// GetAllOfType<HSD_JOBJ>(RootJOBJ);

            foreach (var dobj in dobjs)
            {
                //SBConsole.WriteLine(dobj + " " + dobj.List.Count);
                SBBone parent = null;
                if (Skeleton.Bones.Length > 0)
                {
                    parent = Skeleton.Bones[0];
                }
                foreach (var b in Skeleton.Bones)
                {
                    if (b is SBHsdBone bone)
                    {
                        if (bone.GetJOBJ().Dobj != null)
                        {
                            if (bone.GetJOBJ().Dobj.List.Contains(dobj))
                            {
                                parent = b;
                                break;
                            }
                        }
                    }
                }
                var mesh = new SBHsdMesh(dobj, parent);
                mesh.Name = $"DOBJ_{Mesh.Count}";
                Mesh.Add(mesh);
            }
        }
示例#20
0
        /// <summary>
        ///
        /// </summary>
        public void ConvertRotationToEuler(int FrameCount)
        {
            if (!UseQuat)
            {
                return;
            }

            var xtrack = Tracks.Find(e => e.Type == SBTrackType.RotateX);
            var ytrack = Tracks.Find(e => e.Type == SBTrackType.RotateY);
            var ztrack = Tracks.Find(e => e.Type == SBTrackType.RotateZ);
            var wtrack = Tracks.Find(e => e.Type == SBTrackType.RotateW);

            SBTransformTrack eulX = new SBTransformTrack(SBTrackType.RotateX);
            SBTransformTrack eulY = new SBTransformTrack(SBTrackType.RotateY);
            SBTransformTrack eulZ = new SBTransformTrack(SBTrackType.RotateZ);

            var dummyBone = new SBBone();

            dummyBone.Transform = Matrix4.Identity;

            for (int i = 0; i < FrameCount; i++)
            {
                var key = GetTransformAt(i, dummyBone);
                var eul = Tools.CrossMath.ToEulerAngles(key.ExtractRotation().Inverted());

                eulX.AddKey(i, eul.X);
                eulY.AddKey(i, eul.Y);
                eulZ.AddKey(i, eul.Z);
            }

            Tracks.Remove(xtrack);
            Tracks.Remove(ytrack);
            Tracks.Remove(ztrack);
            Tracks.Remove(wtrack);

            Tracks.Add(eulX);
            Tracks.Add(eulY);
            Tracks.Add(eulZ);
        }
示例#21
0
        private static AnimTrackTransform MatrixToTransform(Matrix4 matrix)
        {
            SBBone temp = new SBBone();

            temp.Transform = matrix;

            var t = new AnimTrackTransform()
            {
                X  = temp.X,
                Y  = temp.Y,
                Z  = temp.Z,
                Rx = temp.RotationQuaternion.X,
                Ry = temp.RotationQuaternion.Y,
                Rz = temp.RotationQuaternion.Z,
                Rw = temp.RotationQuaternion.W,
                Sx = temp.SX,
                Sy = temp.SY,
                Sz = temp.SZ
            };

            return(t);
        }
示例#22
0
        public static SBSkeleton Open(string FileName, SBScene Scene)
        {
            SsbhFile File;

            if (Ssbh.TryParseSsbhFile(FileName, out File))
            {
                if (File is Skel skel)
                {
                    var Skeleton = new SBSkeleton();
                    Scene.Skeleton = Skeleton;

                    Dictionary <int, SBBone> idToBone   = new Dictionary <int, SBBone>();
                    Dictionary <SBBone, int> needParent = new Dictionary <SBBone, int>();
                    foreach (var b in skel.BoneEntries)
                    {
                        SBBone bone = new SBBone();
                        bone.Name      = b.Name;
                        bone.Type      = b.Type;
                        bone.Transform = Skel_to_TKMatrix(skel.Transform[b.Id]);
                        idToBone.Add(b.Id, bone);
                        if (b.ParentId == -1)
                        {
                            Skeleton.AddRoot(bone);
                        }
                        else
                        {
                            needParent.Add(bone, b.ParentId);
                        }
                    }
                    foreach (var v in needParent)
                    {
                        v.Key.Parent = idToBone[v.Value];
                    }

                    return(Skeleton);
                }
            }
            return(null);
        }
示例#23
0
        public void ExportSBAnimation(string FileName, SBAnimation animation, SBSkeleton skeleton)
        {
            SEAnim seOut = new SEAnim();                   //init new SEAnim

            foreach (var node in animation.TransformNodes) //iterate through each node
            {
                for (int i = 0; i < animation.FrameCount; i++)
                {
                    SBBone temp = new SBBone();
                    temp.Transform = node.Transform.GetValue(i);

                    OpenTK.Vector3    pos = temp.Translation;
                    OpenTK.Quaternion rot = temp.RotationQuaternion;
                    OpenTK.Vector3    sca = temp.Scale;

                    seOut.AddTranslationKey(node.Name, i, pos.X, pos.Y, pos.Z);
                    seOut.AddRotationKey(node.Name, i, rot.X, rot.Y, rot.Z, rot.W);
                    seOut.AddScaleKey(node.Name, i, sca.X, sca.Y, sca.Z);
                }
            }

            seOut.Write(FileName); //write it!
        }
示例#24
0
        public static void Open(string FileName, SBScene Scene)
        {
            ISSBH_File File;

            if (SSBH.TryParseSSBHFile(FileName, out File))
            {
                if (File is SKEL skel)
                {
                    var Skeleton = new SBSkeleton();
                    Scene.Skeleton = Skeleton;

                    Dictionary <int, SBBone> idToBone   = new Dictionary <int, SBBone>();
                    Dictionary <SBBone, int> needParent = new Dictionary <SBBone, int>();
                    foreach (var b in skel.BoneEntries)
                    {
                        SBBone bone = new SBBone();
                        bone.Name      = b.Name;
                        bone.Type      = b.Type;
                        bone.Transform = Skel_to_TKMatrix(skel.Transform[b.ID]);
                        idToBone.Add(b.ID, bone);
                        if (b.ParentID == -1)
                        {
                            Skeleton.AddRoot(bone);
                        }
                        else
                        {
                            needParent.Add(bone, b.ParentID);
                        }
                    }
                    foreach (var v in needParent)
                    {
                        v.Key.Parent = idToBone[v.Value];
                    }
                }
            }
        }
示例#25
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;
            }
        }
示例#26
0
 /// <summary>
 /// Selects a bone and display the bone tool strip
 /// </summary>
 /// <param name="bone"></param>
 public void SelectBone(SBBone bone)
 {
     ResetControls();
     BoneEditor.BindBone(bone);
     BoneEditor.Visible = true;
 }
示例#27
0
        public IOModel ImportIOModel(string FileName)
        {
            IOModel    model    = new IOModel();
            SBSkeleton skeleton = new SBSkeleton();

            Dictionary <int, SBBone>    indexToBone    = new Dictionary <int, SBBone>();
            Dictionary <string, IOMesh> materialToMesh = new Dictionary <string, IOMesh>();
            List <SBBone> PostProcessBones             = new List <SBBone>();
            List <int>    boneParents = new List <int>();

            string[] lines          = File.ReadAllLines(FileName);
            string   CurrentSection = "";

            for (int i = 0; i < lines.Length; i++)
            {
                string[] args = Regex.Replace(lines[i].Trim(), @"\s+", " ").Split(' ');

                if (args[0].Equals("end"))
                {
                    CurrentSection = "";
                }
                else
                if (args[0].Equals("time"))
                {
                }
                else
                if (args[0].Equals("nodes"))
                {
                    CurrentSection = args[0];
                }
                else
                if (args[0].Equals("skeleton"))
                {
                    CurrentSection = args[0];
                }
                else
                if (args[0].Equals("triangles"))
                {
                    CurrentSection = args[0];
                }
                else
                {
                    switch (CurrentSection)
                    {
                    case "nodes":
                        var bone = new SBBone();
                        bone.Name = args[1].Replace("\"", "");
                        Console.WriteLine(bone.Name + " " + args[2]);
                        boneParents.Add(int.Parse(args[2]));
                        PostProcessBones.Add(bone);
                        indexToBone.Add(int.Parse(args[0]), bone);
                        break;

                    case "skeleton":
                        var skel = PostProcessBones[int.Parse(args[0])];
                        skel.Transform = Matrix4.Identity;
                        skel.X         = float.Parse(args[1]);
                        skel.Y         = float.Parse(args[2]);
                        skel.Z         = float.Parse(args[3]);
                        skel.RX        = float.Parse(args[4]);
                        skel.RY        = float.Parse(args[5]);
                        skel.RZ        = float.Parse(args[6]);
                        break;

                    case "triangles":
                        string material = args[0];
                        if (!materialToMesh.ContainsKey(material))
                        {
                            var iomesh = new IOMesh();
                            iomesh.HasPositions   = true;
                            iomesh.HasNormals     = true;
                            iomesh.HasUV0         = true;
                            iomesh.HasBoneWeights = true;
                            iomesh.Name           = material;
                            materialToMesh.Add(material, iomesh);
                        }
                        var mesh = materialToMesh[material];
                        mesh.Vertices.Add(ReadVertex(Regex.Replace(lines[i + 1].Trim(), @"\s+", " ").Split(' ')));
                        mesh.Vertices.Add(ReadVertex(Regex.Replace(lines[i + 2].Trim(), @"\s+", " ").Split(' ')));
                        mesh.Vertices.Add(ReadVertex(Regex.Replace(lines[i + 3].Trim(), @"\s+", " ").Split(' ')));
                        i += 3;
                        break;
                    }
                }
            }

            //PostProcessBones
            int boneIndex = 0;

            foreach (var bone in PostProcessBones)
            {
                if (boneParents[boneIndex] == -1)
                {
                    skeleton.AddRoot(bone);
                }
                else
                {
                    bone.Parent = indexToBone[boneParents[boneIndex]];
                }
                boneIndex++;
            }

            model.Skeleton = skeleton;
            // finalize meshes
            foreach (var pair in materialToMesh)
            {
                model.Meshes.Add(pair.Value);
                pair.Value.Optimize();
                SBConsole.WriteLine($"Imported {pair.Key} from SMD");

                //finalize rigging
                for (int i = 0; i < pair.Value.Vertices.Count; i++)
                {
                    var vertex = pair.Value.Vertices[i];
                    vertex.BoneIndices.X   = model.Skeleton.IndexOfBone(indexToBone[(int)vertex.BoneIndices.X]);
                    vertex.BoneIndices.Y   = model.Skeleton.IndexOfBone(indexToBone[(int)vertex.BoneIndices.Y]);
                    vertex.BoneIndices.Z   = model.Skeleton.IndexOfBone(indexToBone[(int)vertex.BoneIndices.Z]);
                    vertex.BoneIndices.W   = model.Skeleton.IndexOfBone(indexToBone[(int)vertex.BoneIndices.W]);
                    pair.Value.Vertices[i] = vertex;
                }
            }

            return(model);
        }
示例#28
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="Frame"></param>
        /// <param name="bone"></param>
        /// <returns></returns>
        public Matrix4 GetTransformAt(float Frame, SBBone bone)
        {
            if (bone == null)
            {
                return(Matrix4.Identity);
            }

            // temp for less matrix calculations
            Vector3 newPos = new Vector3(bone.X, bone.Y, bone.Z);
            Vector3 newRot = new Vector3(bone.RX, bone.RY, bone.RZ);
            Vector3 newSca = bone.Scale;

            if (bone is SBHsdBone hsdBone)
            {
                newRot = new Vector3(hsdBone.RX, hsdBone.RY, hsdBone.RZ);
            }

            bool  useQuatRotation = false;
            float f1 = 0;
            float f2 = 0;
            var   q1 = new Quaternion();
            var   q2 = new Quaternion();

            foreach (var track in Tracks)
            {
                switch (track.Type)
                {
                case SBTrackType.TranslateX:
                    newPos.X = track.Keys.GetValue(Frame);
                    break;

                case SBTrackType.TranslateY:
                    newPos.Y = track.Keys.GetValue(Frame);
                    break;

                case SBTrackType.TranslateZ:
                    newPos.Z = track.Keys.GetValue(Frame);
                    break;

                case SBTrackType.RotateX:
                    newRot.X = track.Keys.GetValue(Frame);
                    q1.X     = track.Keys.GetKey(Frame).Value;
                    q2.X     = track.Keys.GetNextKey(Frame).Value;
                    break;

                case SBTrackType.RotateY:
                    newRot.Y = track.Keys.GetValue(Frame);
                    q1.Y     = track.Keys.GetKey(Frame).Value;
                    q2.Y     = track.Keys.GetNextKey(Frame).Value;
                    break;

                case SBTrackType.RotateZ:
                    newRot.Z = track.Keys.GetValue(Frame);
                    q1.Z     = track.Keys.GetKey(Frame).Value;
                    q2.Z     = track.Keys.GetNextKey(Frame).Value;
                    break;

                case SBTrackType.ScaleX:
                    newSca.X = track.Keys.GetValue(Frame);
                    break;

                case SBTrackType.ScaleY:
                    newSca.Y = track.Keys.GetValue(Frame);
                    break;

                case SBTrackType.ScaleZ:
                    newSca.Z = track.Keys.GetValue(Frame);
                    break;

                case SBTrackType.RotateW:
                    useQuatRotation = true;
                    q1.W            = track.Keys.GetKey(Frame).Value;
                    q2.W            = track.Keys.GetNextKey(Frame).Value;
                    f1 = track.Keys.GetKey(Frame).Frame;
                    f2 = track.Keys.GetNextKey(Frame).Frame;
                    break;
                }
            }

            SBBone temp = new SBBone();

            temp.Transform = Matrix4.Identity;

            temp.Scale       = newSca;
            temp.Translation = newPos;
            if (useQuatRotation)
            {
                temp.RotationQuaternion = Quaternion.Slerp(q1, q2, (Frame - f1) / (f2 - f1));
            }
            else
            {
                temp.RotationEuler = newRot;
            }

            return(temp.Transform);
        }