Пример #1
0
        public void Apply(VBN vbn, int frame)
        {
            if (frame == 0)
            {
                vbn.reset();
            }

            OMOFrame keys = Frames[frame];

            foreach (OMONode node in Nodes)
            {
                foreach (Bone b in vbn.bones)
                {
                    if (b.boneId == node.hash)
                    {
                        // apply interpolation frames
                        Console.WriteLine(b.Text);
                        node.Apply(b, keys);
                        break;
                    }
                }
            }

            vbn.update();
        }
Пример #2
0
        public void Apply(VBN bone)
        {
            for (int i = 0; i < nodes.Count; i++)
            {
                List <AnimType> used = new List <AnimType>();

                Bone    b    = bone.bones[i];
                Vector3 erot = ANIM.quattoeul(b.rot);

                foreach (DATAnimTrack track in nodes[i])
                {
                    KeyNode node = track.keys[0];

                    if (Debug)
                    {
                        Console.WriteLine("Bone " + i + " " + track.type + " " + node.value);
                    }

                    switch (track.type)
                    {
                    case AnimType.XPOS:
                        b.pos.X = node.value;
                        break;

                    case AnimType.YPOS:
                        b.pos.Y = node.value;
                        break;

                    case AnimType.ZPOS:
                        b.pos.Z = node.value;
                        break;

                    case AnimType.XROT:
                        erot.X = node.value;
                        break;

                    case AnimType.YROT:
                        erot.Y = node.value;
                        break;

                    case AnimType.ZROT:
                        erot.Z = node.value;
                        break;
                    }
                }
                b.rot = VBN.FromEulerAngles(erot.Z, erot.Y, erot.X);
            }

            bone.update();
        }
Пример #3
0
        public void NextFrame(VBN skeleton, bool isChild = false)
        {
            if (frame >= frameCount)
            {
                return;
            }

            if (frame == 0 && !isChild)
            {
                skeleton.reset();
            }

            foreach (object child in children)
            {
                if (child is Animation)
                {
                    ((Animation)child).SetFrame(frame);
                    ((Animation)child).NextFrame(skeleton, isChild: true);
                }
                if (child is MTA)
                {
                    //foreach (ModelContainer con in Runtime.ModelContainers)
                    {
                        if (((ModelContainer)skeleton.Parent).NUD != null)
                        {
                            ((ModelContainer)skeleton.Parent).NUD.ApplyMta(((MTA)child), (int)frame);
                        }
                    }
                }
                if (child is BFRES.MTA) //For BFRES
                {
                    {
                        if (((ModelContainer)skeleton.Parent).Bfres != null)
                        {
                            ((ModelContainer)skeleton.Parent).Bfres.ApplyMta(((BFRES.MTA)child), (int)frame);
                        }
                    }
                }
            }

            bool updated = false; // no need to update skeleton of animations that didn't change

            foreach (KeyNode node in bones)
            {
                // Get Skeleton Node
                Bone b = null;
                if (node.hash == -1)
                {
                    b = skeleton.getBone(node.Text);
                }
                else
                {
                    b = skeleton.GetBone((uint)node.hash);
                }
                if (b == null)
                {
                    continue;
                }
                updated = true;

                if (node.xpos.HasAnimation() && b.boneType != 3)
                {
                    b.pos.X = node.xpos.GetValue(frame);
                }
                if (node.ypos.HasAnimation() && b.boneType != 3)
                {
                    b.pos.Y = node.ypos.GetValue(frame);
                }
                if (node.zpos.HasAnimation() && b.boneType != 3)
                {
                    b.pos.Z = node.zpos.GetValue(frame);
                }

                if (node.xsca.HasAnimation())
                {
                    b.sca.X = node.xsca.GetValue(frame);
                }
                else
                {
                    b.sca.X = 1;
                }
                if (node.ysca.HasAnimation())
                {
                    b.sca.Y = node.ysca.GetValue(frame);
                }
                else
                {
                    b.sca.Y = 1;
                }
                if (node.zsca.HasAnimation())
                {
                    b.sca.Z = node.zsca.GetValue(frame);
                }
                else
                {
                    b.sca.Z = 1;
                }


                if (node.xrot.HasAnimation() || node.yrot.HasAnimation() || node.zrot.HasAnimation())
                {
                    if (node.rotType == RotationType.Quaternion)
                    {
                        KeyFrame[] x  = node.xrot.GetFrame(frame);
                        KeyFrame[] y  = node.yrot.GetFrame(frame);
                        KeyFrame[] z  = node.zrot.GetFrame(frame);
                        KeyFrame[] w  = node.wrot.GetFrame(frame);
                        Quaternion q1 = new Quaternion(x[0].Value, y[0].Value, z[0].Value, w[0].Value);
                        Quaternion q2 = new Quaternion(x[1].Value, y[1].Value, z[1].Value, w[1].Value);
                        if (x[0].Frame == frame)
                        {
                            b.rot = q1;
                        }
                        else
                        if (x[1].Frame == frame)
                        {
                            b.rot = q2;
                        }
                        else
                        {
                            b.rot = Quaternion.Slerp(q1, q2, (frame - x[0].Frame) / (x[1].Frame - x[0].Frame));
                        }
                    }
                    else
                    if (node.rotType == RotationType.Euler)
                    {
                        float x = node.xrot.HasAnimation() ? node.xrot.GetValue(frame) : b.rotation[0];
                        float y = node.yrot.HasAnimation() ? node.yrot.GetValue(frame) : b.rotation[1];
                        float z = node.zrot.HasAnimation() ? node.zrot.GetValue(frame) : b.rotation[2];
                        b.rot = EulerToQuat(z, y, x);
                    }
                }
            }
            frame += 1f;
            if (frame >= frameCount)
            {
                frame = 0;
            }

            if (!isChild && updated)
            {
                skeleton.update();
            }
        }
Пример #4
0
        public VBN GetVBN(FileData d)
        {
            VBN v = new VBN();

            d.endian = Endianness.Big;
            d.Seek(8);
            int ver = d.ReadInt();

            d.Skip(4);             //outer offset to brres

            int boneHeader = 0x40; // for version 9 only

            int dlist   = d.ReadInt();
            int boneSec = d.ReadInt();
            int vertSec = d.ReadInt();
            int normSec = d.ReadInt();
            int colrSec = d.ReadInt();
            int texcSec = d.ReadInt();

            d.Skip(8);
            int polySec = d.ReadInt();

            d.Seek(0x40);
            d.Skip(16);
            int vertCount = d.ReadInt();
            int faceCount = d.ReadInt();

            d.Skip(4);
            int boneCount = d.ReadInt();

            v.totalBoneCount = (uint)boneCount;
            for (int i = 0; i < 3; i++)
            {
                v.boneCountPerType[i + 1] = 0;
            }
            d.Skip(4);
            int bonetableoff = d.ReadInt() + boneHeader;

            d.Seek(bonetableoff);
            int bcount = d.ReadInt();

            int[] nodeIndex = new int[bcount];
            for (int i = 0; i < bcount; i++)
            {
                nodeIndex[i] = d.ReadInt();
            }

            Random rng    = new Random();
            uint   boneID = (uint)rng.Next(1, 0xFFFFFF);

            // BONES-----------------------------------------------
            d.Seek(boneSec);
            d.Skip(4); // length
            int bseccount = d.ReadInt();

            for (int i = 0; i < bseccount; i++)
            {
                Debug.Write(i);
                d.Skip(4); // entry id and unknown
                d.Skip(4); // left and right index
                int name = d.ReadInt() + boneSec;
                int data = d.ReadInt() + boneSec;

                int temp = d.Pos();
                if (name != boneSec && data != boneSec)
                {
                    // read bone data
                    d.Seek(data);
                    d.Skip(8);
                    int nameOff = d.ReadInt() + data;
                    int index   = d.ReadInt(); // id
                    d.Skip(4);                 // index
                    d.Skip(8);                 // idk billboard settings and padding
                    Bone n = new Bone(v);

                    n.scale    = new float[3];
                    n.position = new float[3];
                    n.rotation = new float[3];
                    d.Skip(4);                     // index

                    n.scale[0]    = d.ReadFloat();
                    n.scale[1]    = d.ReadFloat();
                    n.scale[2]    = d.ReadFloat();
                    n.rotation[0] = toRadians(d.ReadFloat());
                    n.rotation[1] = toRadians(d.ReadFloat());
                    n.rotation[2] = toRadians(d.ReadFloat());
                    n.position[0] = d.ReadFloat();
                    n.position[1] = d.ReadFloat();
                    n.position[2] = d.ReadFloat();

                    n.pos = new Vector3(n.position[0], n.position[1], n.position[2]);
                    n.sca = new Vector3(n.scale[0], n.scale[1], n.scale[2]);
                    n.rot = (VBN.FromEulerAngles(n.rotation [2], n.rotation [1], n.rotation [0]));

                    d.Skip(24);

                    d.Seek(data + 0x5C);
                    d.Seek(d.ReadInt() + data + 12);
                    int parentid = 0x0FFFFFFF;
                    if (d.Pos() != data + 12)
                    {
                        parentid = d.ReadInt();
                    }
                    n.parentIndex = (int)parentid;

                    n.Text   = d.ReadString(nameOff, -1);
                    n.boneId = boneID;
                    boneID++;

                    v.bones.Add(n);
                }
                else
                {
                    bseccount++;
                }

                d.Seek(temp);
            }
            v.update();
            //v.updateChildren();
            v.boneCountPerType[0] = (uint)v.bones.Count;

            return(v);
        }
Пример #5
0
        public void NextFrame(VBN vbn, bool isChild = false)
        {
            if (frame >= frames.Count)
            {
                return;
            }

            if (frame == 0 && (!isChild || children.Count > 0))
            {
                vbn.reset();

                /*foreach (ModelContainer con in Runtime.ModelContainers)
                 * {
                 *  if (con.NUD != null && con.mta != null)
                 *  {
                 *      con.NUD.applyMTA(con.mta, 0);
                 *  }
                 * }*/
            }

            foreach (object child in children)
            {
                if (child is SkelAnimation)
                {
                    ((SkelAnimation)child).SetFrame(frame);
                    ((SkelAnimation)child).NextFrame(vbn, isChild: true);
                }
                if (child is MTA)
                {
                    /*foreach(ModelContainer con in Runtime.ModelContainers)
                     * {
                     *  if(con.NUD != null)
                     *  {
                     *      con.NUD.applyMTA(((MTA)child), frame);
                     *  }
                     * }*/
                }
            }

            KeyFrame key = frames[frame];

            foreach (KeyNode n in key.nodes)
            {
                //if (n.id == -1)
                //	continue;

                //if (n.hash == 0) {
                //continue;
                //n.hash = vbn.bones [n.id].boneId;
                //}

                int id = -1;

                foreach (Bone bo in vbn.bones)
                {
                    if (bo.boneId == n.hash)
                    {
                        id   = vbn.bones.IndexOf(bo);
                        n.id = id;
                        break;
                    }
                }

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

                Bone b = vbn.bones[id];

                if (n.tType != -1)// !b.isSwingBone)
                {
                    b.pos = n.t;
                }
                // We don't do the same swingBone check on rotation because as of yet
                // I have not seen an example of the rotation data being garbage, and it's
                // actually used properly in the animations - Struz
                if (n.rType != -1)
                {
                    if (b.Text.Equals("HeadN"))
                    {
                        //Console.WriteLine(b.transform.ExtractRotation().ToString());
                        //Console.WriteLine(VBN.FromEulerAngles(b.rotation[0], b.rotation[1], b.rotation[2]).ToString());
                        //Console.WriteLine(n.r.ToString() + " " + Math.Sqrt(n.r.X* n.r.X + n.r.Y* n.r.Y + n.r.Z* n.r.Z + n.r.W*n.r.W) + " " + n.r.Normalized().ToString());
                    }
                    //Console.WriteLine(new string(b.boneName) + " " + b.rot.ToString() + " " + n.r.ToString() + "\n" + (n.r.X + n.r.Y + n.r.X + n.r.W));
                    b.rot = n.r;
                }
                if (n.sType != -1)
                {
                    b.sca = n.s;
                }
                else
                {
                    b.sca = new Vector3(b.scale[0], b.scale[1], b.scale[2]);
                }
            }


            frame++;
            if (frame >= frames.Count)
            {
                frame = 0;
            }
            vbn.update();
        }