Beispiel #1
0
        public static void Save(Animation anim, VBN Skeleton, String Fname)
        {
            using (System.IO.StreamWriter file = new System.IO.StreamWriter(@Fname))
            {
                file.WriteLine("version 1");

                file.WriteLine("nodes");
                foreach(Bone b in Skeleton.bones)
                {
                    file.WriteLine(Skeleton.bones.IndexOf(b) + " \"" + b.Text + "\" " + b.parentIndex);
                }
                file.WriteLine("end");
                
                file.WriteLine("skeleton");
                anim.SetFrame(0);
                for(int i = 0; i <= anim.FrameCount; i++)
                {
                    anim.NextFrame(Skeleton);
                    
                    file.WriteLine("time " + i);

                    foreach (Animation.KeyNode sb in anim.Bones)
                    {
                        Bone b = Skeleton.getBone(sb.Text);
                        if (b == null) continue;
                        Vector3 eul = ANIM.quattoeul(b.rot);
                        file.WriteLine(Skeleton.bones.IndexOf(b) + " " + b.pos.X + " " + b.pos.Y + " " + b.pos.Z + " " + eul.X + " " + eul.Y + " " + eul.Z);
                    }

                }
                file.WriteLine("end");

                file.Close();
            }
        }
Beispiel #2
0
        public static void CreateANIM(string fname, Animation a, VBN vbn)
        {
            using (System.IO.StreamWriter file = new System.IO.StreamWriter(@fname))
            {
                AnimHeader header = new AnimHeader();
                file.WriteLine("animVersion " + header.animVersion + ";");
                file.WriteLine("mayaVersion " + header.mayaVersion + ";");
                file.WriteLine("timeUnit " + header.timeUnit + ";");
                file.WriteLine("linearUnit " + header.linearUnit + ";");
                file.WriteLine("angularUnit " + header.angularUnit + ";");
                file.WriteLine("startTime " + 1 + ";");
                file.WriteLine("endTime " + a.FrameCount + ";");

                a.SetFrame(a.FrameCount - 1);             //from last frame
                for (int li = 0; li < a.FrameCount; ++li) //go through each frame with nextFrame
                {
                    a.NextFrame(vbn);
                }
                a.NextFrame(vbn);  //go on first frame

                int i = 0;

                // writing node attributes
                foreach (Bone b in vbn.getBoneTreeOrder())
                {
                    i = vbn.boneIndex(b.Text);

                    if (a.HasBone(b.Text))
                    {
                        // write the bone attributes
                        // count the attributes
                        Animation.KeyNode n = a.GetBone(b.Text);
                        int ac = 0;


                        if (n.XPOS.HasAnimation())
                        {
                            file.WriteLine("anim translate.translateX translateX " + b.Text + " 0 0 " + (ac++) + ";");
                            writeKey(file, n.XPOS, n, a.Size(), "translateX");
                            file.WriteLine("}");
                        }
                        if (n.YPOS.HasAnimation())
                        {
                            file.WriteLine("anim translate.translateY translateY " + b.Text + " 0 0 " + (ac++) + ";");
                            writeKey(file, n.YPOS, n, a.Size(), "translateY");
                            file.WriteLine("}");
                        }
                        if (n.ZPOS.HasAnimation())
                        {
                            file.WriteLine("anim translate.translateZ translateZ " + b.Text + " 0 0 " + (ac++) + ";");
                            writeKey(file, n.ZPOS, n, a.Size(), "translateZ");
                            file.WriteLine("}");
                        }
                        if (n.XROT.HasAnimation())
                        {
                            file.WriteLine("anim rotate.rotateX rotateX " + b.Text + " 0 0 " + (ac++) + ";");
                            writeKey(file, n.XROT, n, a.Size(), "rotateX");
                            file.WriteLine("}");
                        }
                        if (n.YROT.HasAnimation())
                        {
                            file.WriteLine("anim rotate.rotateY rotateY " + b.Text + " 0 0 " + (ac++) + ";");
                            writeKey(file, n.YROT, n, a.Size(), "rotateY");
                            file.WriteLine("}");
                        }
                        if (n.ZROT.HasAnimation())
                        {
                            file.WriteLine("anim rotate.rotateZ rotateZ " + b.Text + " 0 0 " + (ac++) + ";");
                            writeKey(file, n.ZROT, n, a.Size(), "rotateZ");
                            file.WriteLine("}");
                        }

                        if (n.XSCA.HasAnimation())
                        {
                            file.WriteLine("anim scale.scaleX scaleX " + b.Text + " 0 0 " + (ac++) + ";");
                            writeKey(file, n.XSCA, n, a.Size(), "scaleX");
                            file.WriteLine("}");
                        }
                        if (n.YSCA.HasAnimation())
                        {
                            file.WriteLine("anim scale.scaleY scaleY " + b.Text + " 0 0 " + (ac++) + ";");
                            writeKey(file, n.YSCA, n, a.Size(), "scaleY");
                            file.WriteLine("}");
                        }
                        if (n.ZSCA.HasAnimation())
                        {
                            file.WriteLine("anim scale.scaleZ scaleZ " + b.Text + " 0 0 " + (ac++) + ";");
                            writeKey(file, n.ZSCA, n, a.Size(), "scaleZ");
                            file.WriteLine("}");
                        }
                    }
                    else
                    {
                        file.WriteLine("anim " + b.Text + " 0 0 0;");
                    }
                }
            }
        }
Beispiel #3
0
        public static byte[] CreateOMOFromAnimation(Animation a, VBN vbn)
        {
            FileOutput o = new FileOutput();

            o.Endian = Endianness.Big;

            FileOutput t1 = new FileOutput();

            t1.Endian = Endianness.Big;

            FileOutput t2 = new FileOutput();

            t2.Endian = Endianness.Big;

            o.writeString("OMO ");
            o.writeShort(1);        //idk
            o.writeShort(3);        //idk

            o.writeInt(0x091E100C); //flags??


            o.writeShort(0);             //padding
            o.writeShort(a.Bones.Count); // numOfNodes

            o.writeShort(a.FrameCount);  // frame size
            o.writeShort(0);             // frame start ??

            o.writeInt(0);
            o.writeInt(0);
            o.writeInt(0);

            o.writeIntAt(o.size(), 0x14);

            // ASSESSMENT
            Vector3[] maxT     = new Vector3[a.Bones.Count], minT = new Vector3[a.Bones.Count];
            Vector4[] maxR     = new Vector4[a.Bones.Count], minR = new Vector4[a.Bones.Count];
            Vector3[] maxS     = new Vector3[a.Bones.Count], minS = new Vector3[a.Bones.Count];
            bool[]    hasScale = new bool[a.Bones.Count];
            bool[]    hasTrans = new bool[a.Bones.Count];
            bool[]    hasRot   = new bool[a.Bones.Count];

            bool[] conScale = new bool[a.Bones.Count];
            bool[] conTrans = new bool[a.Bones.Count];
            bool[] conRot   = new bool[a.Bones.Count];

            a.SetFrame(0);

            //for (int i = 0; i < a.FrameCount; i++)
            {
                //a.NextFrame(vbn);

                for (int j = 0; j < a.Bones.Count; j++)
                {
                    Animation.KeyNode keynode = ((Animation.KeyNode)a.Bones[j]);
                    if (keynode.XPOS.HasAnimation() || keynode.YPOS.HasAnimation() || keynode.ZPOS.HasAnimation())
                    {
                        hasTrans[j] = true;
                    }
                    if (keynode.XROT.HasAnimation())
                    {
                        hasRot[j] = true;
                    }
                    if (keynode.XSCA.HasAnimation() || keynode.YSCA.HasAnimation() || keynode.ZSCA.HasAnimation())
                    {
                        hasScale[j] = true;
                    }

                    maxT[j] = new Vector3(-999f, -999f, -999f);
                    minT[j] = new Vector3(999f, 999f, 999f);
                    maxS[j] = new Vector3(-999f, -999f, -999f);
                    minS[j] = new Vector3(999f, 999f, 999f);
                    maxR[j] = new Vector4(-999f, -999f, -999f, -999f);
                    minR[j] = new Vector4(999f, 999f, 999f, 999f);

                    foreach (Animation.KeyFrame key in keynode.XPOS.Keys)
                    {
                        maxT[j].X = Math.Max(maxT[j].X, key.Value);
                        minT[j].X = Math.Min(minT[j].X, key.Value);
                    }
                    foreach (Animation.KeyFrame key in keynode.YPOS.Keys)
                    {
                        maxT[j].Y = Math.Max(maxT[j].Y, key.Value);
                        minT[j].Y = Math.Min(minT[j].Y, key.Value);
                    }
                    foreach (Animation.KeyFrame key in keynode.ZPOS.Keys)
                    {
                        maxT[j].Z = Math.Max(maxT[j].Z, key.Value);
                        minT[j].Z = Math.Min(minT[j].Z, key.Value);
                    }
                    foreach (Animation.KeyFrame key in keynode.XSCA.Keys)
                    {
                        maxS[j].X = Math.Max(maxS[j].X, key.Value);
                        minS[j].X = Math.Min(minS[j].X, key.Value);
                    }
                    foreach (Animation.KeyFrame key in keynode.YSCA.Keys)
                    {
                        maxS[j].Y = Math.Max(maxS[j].Y, key.Value);
                        minS[j].Y = Math.Min(minS[j].Y, key.Value);
                    }
                    foreach (Animation.KeyFrame key in keynode.ZSCA.Keys)
                    {
                        maxS[j].Z = Math.Max(maxS[j].Z, key.Value);
                        minS[j].Z = Math.Min(minS[j].Z, key.Value);
                    }
                    //TODO: Euler Rotation Values
                    a.SetFrame(0);
                    Bone b = vbn.getBone(keynode.Text);
                    if (b == null)
                    {
                        continue;
                    }
                    for (int i = 0; i < a.FrameCount; i++)
                    {
                        maxR[j].X = Math.Max(maxR[j].X, b.rot.X);
                        minR[j].X = Math.Min(minR[j].X, b.rot.X);
                        maxR[j].Y = Math.Max(maxR[j].Y, b.rot.Y);
                        minR[j].Y = Math.Min(minR[j].Y, b.rot.Y);
                        maxR[j].Z = Math.Max(maxR[j].Z, b.rot.Z);
                        minR[j].Z = Math.Min(minR[j].Z, b.rot.Z);
                        a.NextFrame(vbn);
                    }

                    if (b != null)
                    {
                        if (maxT[j].X == -999)
                        {
                            maxT[j].X = b.position[0];
                        }
                        if (maxT[j].Y == -999)
                        {
                            maxT[j].Y = b.position[1];
                        }
                        if (maxT[j].Z == -999)
                        {
                            maxT[j].Z = b.position[2];
                        }
                        if (minT[j].X == -999)
                        {
                            minT[j].X = b.position[0];
                        }
                        if (minT[j].Y == -999)
                        {
                            minT[j].Y = b.position[1];
                        }
                        if (minT[j].Z == -999)
                        {
                            minT[j].Z = b.position[2];
                        }

                        if (maxS[j].X == -999)
                        {
                            maxS[j].X = b.scale[0];
                        }
                        if (maxS[j].Y == -999)
                        {
                            maxS[j].Y = b.scale[1];
                        }
                        if (maxS[j].Z == -999)
                        {
                            maxS[j].Z = b.scale[2];
                        }
                        if (minS[j].X == -999)
                        {
                            minS[j].X = b.scale[0];
                        }
                        if (minS[j].Y == -999)
                        {
                            minS[j].Y = b.scale[1];
                        }
                        if (minS[j].Z == -999)
                        {
                            minS[j].Z = b.scale[2];
                        }
                    }
                }
            }

            // NODE INFO

            int t2Size = 0;

            for (int i = 0; i < a.Bones.Count; i++)
            {
                int flag = 0;

                conRot[i]   = false;
                conScale[i] = false;
                conTrans[i] = false;

                // check for constant
                if (maxT[i].Equals(minT[i]))
                {
                    conTrans[i] = true;
                }
                if (maxR[i].Equals(minR[i]))
                {
                    conRot[i] = true;
                }
                if (maxS[i].Equals(minS[i]))
                {
                    conScale[i] = true;
                }

                if (hasTrans[i])
                {
                    flag |= 0x01000000;
                }
                if (hasRot[i])
                {
                    flag |= 0x02000000;
                }
                if (hasScale[i])
                {
                    flag |= 0x04000000;
                }

                if (conTrans[i] && hasTrans[i])
                {
                    flag |= 0x00200000;
                }
                else
                {
                    flag |= 0x00080000;
                }

                if (conRot[i] && hasRot[i])
                {
                    flag |= 0x00007000;
                }
                else
                {
                    flag |= 0x00005000;
                }

                if (conScale[i] && hasScale[i])
                {
                    flag |= 0x00000200;
                }
                else
                {
                    flag |= 0x00000080;
                }

                flag |= 0x00000001;

                //uint id = 999;
                Bone b    = vbn.getBone(a.Bones[i].Text);
                int  hash = -1;
                if (b != null)
                {
                    hash = (int)b.boneId;
                }
                else
                {
                    continue;
                }
                //if(hash == -1)
                //hash = (int)FileData.crc32(getNodeId(nodeid.get(i)).name);
                o.writeInt(flag);      // flags...
                o.writeInt(hash);      //hash
                o.writeInt(t1.size()); // Offset in 1 table
                o.writeInt(t2Size);    // Offset in 2 table

                // calculate size needed
                if (hasTrans[i])
                {
                    t1.writeFloat(minT[i].X);
                    t1.writeFloat(minT[i].Y);
                    t1.writeFloat(minT[i].Z);

                    if (!conTrans[i])
                    {
                        maxT[i].X -= minT[i].X;
                        maxT[i].Y -= minT[i].Y;
                        maxT[i].Z -= minT[i].Z;

                        t1.writeFloat(maxT[i].X);
                        t1.writeFloat(maxT[i].Y);
                        t1.writeFloat(maxT[i].Z);

                        t2Size += 6;
                    }
                }

                if (hasRot[i])
                {
                    t1.writeFloat(minR[i].X);
                    t1.writeFloat(minR[i].Y);
                    t1.writeFloat(minR[i].Z);

                    if (!conRot[i])
                    {
                        maxR[i].X -= minR[i].X;
                        maxR[i].Y -= minR[i].Y;
                        maxR[i].Z -= minR[i].Z;

                        t1.writeFloat(maxR[i].X);
                        t1.writeFloat(maxR[i].Y);
                        t1.writeFloat(maxR[i].Z);

                        t2Size += 6;
                    }
                }

                if (hasScale[i])
                {
                    t1.writeFloat(minS[i].X);
                    t1.writeFloat(minS[i].Y);
                    t1.writeFloat(minS[i].Z);

                    if (!conScale[i])
                    {
                        maxS[i].X -= minS[i].X;
                        maxS[i].Y -= minS[i].Y;
                        maxS[i].Z -= minS[i].Z;

                        t1.writeFloat(maxS[i].X);
                        t1.writeFloat(maxS[i].Y);
                        t1.writeFloat(maxS[i].Z);

                        t2Size += 6;
                    }
                }
            }

            o.writeIntAt(o.size(), 0x18);

            o.writeOutput(t1);

            o.writeIntAt(o.size(), 0x1C);

            // INTERPOLATION

            a.SetFrame(0);

            for (int i = 0; i < a.FrameCount; i++)
            {
                //Console.WriteLine("Workin on" + i);
                a.NextFrame(vbn);
                for (int j = 0; j < a.Bones.Count; j++)
                {
                    Bone node = vbn.getBone(a.Bones[j].Text);
                    if (node == null)
                    {
                        continue;
                    }

                    if (hasTrans[j] && !conTrans[j])
                    {
                        t2.writeShort((int)(((node.pos.X - minT[j].X) / maxT[j].X) * 0xFFFF));
                        t2.writeShort((int)(((node.pos.Y - minT[j].Y) / maxT[j].Y) * 0xFFFF));
                        t2.writeShort((int)(((node.pos.Z - minT[j].Z) / maxT[j].Z) * 0xFFFF));
                    }

                    if (hasRot[j] && !conRot[j])
                    {
                        Quaternion r = node.rot;

                        t2.writeShort((int)(((r.X - minR[j].X) / maxR[j].X) * 0xFFFF));
                        t2.writeShort((int)(((r.Y - minR[j].Y) / maxR[j].Y) * 0xFFFF));
                        t2.writeShort((int)(((r.Z - minR[j].Z) / maxR[j].Z) * 0xFFFF));
                    }

                    if (hasScale[j] && !conScale[j])
                    {
                        t2.writeShort((int)(((node.sca.X - minS[j].X) / maxS[j].X) * 0xFFFF));
                        t2.writeShort((int)(((node.sca.Y - minS[j].Y) / maxS[j].Y) * 0xFFFF));
                        t2.writeShort((int)(((node.sca.Z - minS[j].Z) / maxS[j].Z) * 0xFFFF));
                    }
                }

                if (i == 0)
                {
                    o.writeShortAt(t2.size(), 0x12);
                }
            }

            //Console.WriteLine("Saving");
            o.writeOutput(t2);
            return(o.getBytes());
        }
Beispiel #4
0
        public static byte[] CreateOMOFromAnimation(Animation a, VBN vbn)
        {
            if (vbn == null || a == null)
            {
                return new byte[] { }
            }
            ;

            // Test Actual Bones
            //-------------------------

            List <Animation.KeyNode> toRem = new List <Animation.KeyNode>();

            for (int j = 0; j < a.Bones.Count; j++)
            {
                Animation.KeyNode keynode = ((Animation.KeyNode)a.Bones[j]);
                Bone b = vbn.getBone(keynode.Text);

                if (b == null)
                {
                    toRem.Add(keynode);
                }
            }
            foreach (Animation.KeyNode r in toRem)
            {
                Console.WriteLine("Removing " + r.Text);
                a.Bones.Remove(r);
            }

            //-------------------------

            FileOutput o = new FileOutput();

            o.Endian = Endianness.Big;

            FileOutput t1 = new FileOutput();

            t1.Endian = Endianness.Big;

            FileOutput t2 = new FileOutput();

            t2.Endian = Endianness.Big;

            o.writeString("OMO ");
            o.writeShort(1);        //idk
            o.writeShort(3);        //idk

            o.writeInt(0x091E100C); //flags??


            o.writeShort(0);             //padding
            o.writeShort(a.Bones.Count); // numOfNodes

            o.writeShort(a.FrameCount);  // frame size
            o.writeShort(0);             // frame start ??

            o.writeInt(0);
            o.writeInt(0);
            o.writeInt(0);

            o.writeIntAt(o.size(), 0x14);

            // ASSESSMENT
            Vector3[] maxT     = new Vector3[a.Bones.Count], minT = new Vector3[a.Bones.Count];
            Vector4[] maxR     = new Vector4[a.Bones.Count], minR = new Vector4[a.Bones.Count];
            Vector3[] maxS     = new Vector3[a.Bones.Count], minS = new Vector3[a.Bones.Count];
            bool[]    hasScale = new bool[a.Bones.Count];
            bool[]    hasTrans = new bool[a.Bones.Count];
            bool[]    hasRot   = new bool[a.Bones.Count];

            bool[] conScale = new bool[a.Bones.Count];
            bool[] conTrans = new bool[a.Bones.Count];
            bool[] conRot   = new bool[a.Bones.Count];

            a.SetFrame(0);

            List <List <Bone> > Frames = new List <List <Bone> >();

            {
                for (int j = 0; j < a.Bones.Count; j++)
                {
                    Animation.KeyNode keynode = ((Animation.KeyNode)a.Bones[j]);
                    if (keynode.XPOS.HasAnimation() || keynode.YPOS.HasAnimation() || keynode.ZPOS.HasAnimation())
                    {
                        hasTrans[j] = true;
                    }
                    if (keynode.XROT.HasAnimation())
                    {
                        hasRot[j] = true;
                    }
                    if (keynode.XSCA.HasAnimation() || keynode.YSCA.HasAnimation() || keynode.ZSCA.HasAnimation())
                    {
                        hasScale[j] = true;
                    }

                    maxT[j] = new Vector3(-999f, -999f, -999f);
                    minT[j] = new Vector3(999f, 999f, 999f);
                    maxS[j] = new Vector3(-999f, -999f, -999f);
                    minS[j] = new Vector3(999f, 999f, 999f);
                    maxR[j] = new Vector4(-999f, -999f, -999f, -999f);
                    minR[j] = new Vector4(999f, 999f, 999f, 999f);

                    foreach (Animation.KeyFrame key in keynode.XPOS.Keys)
                    {
                        maxT[j].X = Math.Max(maxT[j].X, key.Value);
                        minT[j].X = Math.Min(minT[j].X, key.Value);
                    }
                    foreach (Animation.KeyFrame key in keynode.YPOS.Keys)
                    {
                        maxT[j].Y = Math.Max(maxT[j].Y, key.Value);
                        minT[j].Y = Math.Min(minT[j].Y, key.Value);
                    }
                    foreach (Animation.KeyFrame key in keynode.ZPOS.Keys)
                    {
                        maxT[j].Z = Math.Max(maxT[j].Z, key.Value);
                        minT[j].Z = Math.Min(minT[j].Z, key.Value);
                    }
                    foreach (Animation.KeyFrame key in keynode.XSCA.Keys)
                    {
                        maxS[j].X = Math.Max(maxS[j].X, key.Value);
                        minS[j].X = Math.Min(minS[j].X, key.Value);
                    }
                    foreach (Animation.KeyFrame key in keynode.YSCA.Keys)
                    {
                        maxS[j].Y = Math.Max(maxS[j].Y, key.Value);
                        minS[j].Y = Math.Min(minS[j].Y, key.Value);
                    }
                    foreach (Animation.KeyFrame key in keynode.ZSCA.Keys)
                    {
                        maxS[j].Z = Math.Max(maxS[j].Z, key.Value);
                        minS[j].Z = Math.Min(minS[j].Z, key.Value);
                    }

                    Bone b = vbn.getBone(keynode.Text);
                    for (int i = 0; i < a.FrameCount; i++)
                    {
                        Quaternion r = new Quaternion();
                        if (keynode.RotType == Animation.RotationType.QUATERNION)
                        {
                            Animation.KeyFrame[] x  = keynode.XROT.GetFrame(i);
                            Animation.KeyFrame[] y  = keynode.YROT.GetFrame(i);
                            Animation.KeyFrame[] z  = keynode.ZROT.GetFrame(i);
                            Animation.KeyFrame[] w  = keynode.WROT.GetFrame(i);
                            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 == i)
                            {
                                r = q1;
                            }
                            else
                            if (x[1].Frame == i)
                            {
                                r = q2;
                            }
                            else
                            {
                                r = Quaternion.Slerp(q1, q2, (i - x[0].Frame) / (x[1].Frame - x[0].Frame));
                            }
                        }
                        else
                        if (keynode.RotType == Animation.RotationType.EULER)
                        {
                            float x = keynode.XROT.HasAnimation() ? keynode.XROT.GetValue(i) : b.rotation[0];
                            float y = keynode.YROT.HasAnimation() ? keynode.YROT.GetValue(i) : b.rotation[1];
                            float z = keynode.ZROT.HasAnimation() ? keynode.ZROT.GetValue(i) : b.rotation[2];
                            r = Animation.EulerToQuat(z, y, x);
                        }
                        r.Normalize();

                        maxR[j].X = Math.Max(maxR[j].X, r.X);
                        minR[j].X = Math.Min(minR[j].X, r.X);
                        maxR[j].Y = Math.Max(maxR[j].Y, r.Y);
                        minR[j].Y = Math.Min(minR[j].Y, r.Y);
                        maxR[j].Z = Math.Max(maxR[j].Z, r.Z);
                        minR[j].Z = Math.Min(minR[j].Z, r.Z);
                    }

                    //if (b == null)continue;
                    if (b != null)
                    {
                        if (maxT[j].X == -999)
                        {
                            maxT[j].X = b.position[0];
                        }
                        if (maxT[j].Y == -999)
                        {
                            maxT[j].Y = b.position[1];
                        }
                        if (maxT[j].Z == -999)
                        {
                            maxT[j].Z = b.position[2];
                        }
                        if (minT[j].X == -999)
                        {
                            minT[j].X = b.position[0];
                        }
                        if (minT[j].Y == -999)
                        {
                            minT[j].Y = b.position[1];
                        }
                        if (minT[j].Z == -999)
                        {
                            minT[j].Z = b.position[2];
                        }

                        if (maxS[j].X == -999)
                        {
                            maxS[j].X = b.scale[0];
                        }
                        if (maxS[j].Y == -999)
                        {
                            maxS[j].Y = b.scale[1];
                        }
                        if (maxS[j].Z == -999)
                        {
                            maxS[j].Z = b.scale[2];
                        }
                        if (minS[j].X == -999)
                        {
                            minS[j].X = b.scale[0];
                        }
                        if (minS[j].Y == -999)
                        {
                            minS[j].Y = b.scale[1];
                        }
                        if (minS[j].Z == -999)
                        {
                            minS[j].Z = b.scale[2];
                        }
                    }
                }
            }

            //TODO: Euler Rotation Values

            /*VBN tempvbn = new VBN();
             * a.SetFrame(0);
             * for (int i = 0; i < a.FrameCount; i++)
             * {
             *  //Frames.Add(new List<Bone>());
             *  for (int j = 0; j < a.Bones.Count; j++)
             *  {
             *      Animation.KeyNode keynode = a.Bones[j];
             *      Bone b = vbn.getBone(keynode.Text);
             *      //if(b == null) continue;
             *      maxR[j].X = Math.Max(maxR[j].X, b.rot.X);
             *      minR[j].X = Math.Min(minR[j].X, b.rot.X);
             *      maxR[j].Y = Math.Max(maxR[j].Y, b.rot.Y);
             *      minR[j].Y = Math.Min(minR[j].Y, b.rot.Y);
             *      maxR[j].Z = Math.Max(maxR[j].Z, b.rot.Z);
             *      minR[j].Z = Math.Min(minR[j].Z, b.rot.Z);
             *
             *      Bone f1 = new Bone(tempvbn);
             *      f1.pos = b.pos;
             *      f1.rot = b.rot;
             *      f1.sca = b.sca;
             *      //Frames[i].Add(f1);
             *  }
             *  a.NextFrame(vbn);
             * }*/

            // NODE INFO

            int t2Size = 0;

            for (int i = 0; i < a.Bones.Count; i++)
            {
                int flag = 0;

                conRot[i]   = false;
                conScale[i] = false;
                conTrans[i] = false;

                // check for constant
                if (maxT[i].Equals(minT[i]))
                {
                    conTrans[i] = true;
                }
                if (maxR[i].Equals(minR[i]))
                {
                    conRot[i] = true;
                }
                if (maxS[i].Equals(minS[i]))
                {
                    conScale[i] = true;
                }

                if (hasTrans[i])
                {
                    flag |= 0x01000000;
                }
                if (hasRot[i])
                {
                    flag |= 0x02000000;
                }
                if (hasScale[i])
                {
                    flag |= 0x04000000;
                }

                if (conTrans[i] && hasTrans[i])
                {
                    flag |= 0x00200000;
                }
                else
                {
                    flag |= 0x00080000;
                }

                if (conRot[i] && hasRot[i])
                {
                    flag |= 0x00007000;
                }
                else
                {
                    flag |= 0x00005000;
                }

                if (conScale[i] && hasScale[i])
                {
                    flag |= 0x00000200;
                }
                else
                {
                    flag |= 0x00000080;
                }

                flag |= 0x00000001;

                //uint id = 999;

                Bone b    = vbn.getBone(a.Bones[i].Text);
                int  hash = -1;
                if (MainForm.Hashes.names.ContainsKey(a.Bones[i].Text))
                {
                    hash = (int)MainForm.Hashes.names[a.Bones[i].Text];
                }
                else
                {
                    if (b != null)
                    {
                        hash = (int)b.boneId;
                    }
                    else
                    {
                        continue;
                    }
                }
                //if(hash == -1)
                //hash = (int)FileData.crc32(getNodeId(nodeid.get(i)).name);
                o.writeInt(flag);      // flags...
                o.writeInt(hash);      //hash
                o.writeInt(t1.size()); // Offset in 1 table
                o.writeInt(t2Size);    // Offset in 2 table

                // calculate size needed
                if (hasTrans[i])
                {
                    t1.writeFloat(minT[i].X);
                    t1.writeFloat(minT[i].Y);
                    t1.writeFloat(minT[i].Z);

                    if (!conTrans[i])
                    {
                        maxT[i].X -= minT[i].X;
                        maxT[i].Y -= minT[i].Y;
                        maxT[i].Z -= minT[i].Z;

                        t1.writeFloat(maxT[i].X);
                        t1.writeFloat(maxT[i].Y);
                        t1.writeFloat(maxT[i].Z);

                        t2Size += 6;
                    }
                }

                if (hasRot[i])
                {
                    t1.writeFloat(minR[i].X);
                    t1.writeFloat(minR[i].Y);
                    t1.writeFloat(minR[i].Z);

                    if (!conRot[i])
                    {
                        maxR[i].X -= minR[i].X;
                        maxR[i].Y -= minR[i].Y;
                        maxR[i].Z -= minR[i].Z;

                        t1.writeFloat(maxR[i].X);
                        t1.writeFloat(maxR[i].Y);
                        t1.writeFloat(maxR[i].Z);

                        t2Size += 6;
                    }
                }

                if (hasScale[i])
                {
                    t1.writeFloat(minS[i].X);
                    t1.writeFloat(minS[i].Y);
                    t1.writeFloat(minS[i].Z);

                    if (!conScale[i])
                    {
                        maxS[i].X -= minS[i].X;
                        maxS[i].Y -= minS[i].Y;
                        maxS[i].Z -= minS[i].Z;

                        t1.writeFloat(maxS[i].X);
                        t1.writeFloat(maxS[i].Y);
                        t1.writeFloat(maxS[i].Z);

                        t2Size += 6;
                    }
                }
            }

            o.writeIntAt(o.size(), 0x18);

            o.writeOutput(t1);

            o.writeIntAt(o.size(), 0x1C);

            // INTERPOLATION

            a.SetFrame(0);

            bool go = true;

            for (int i = 0; i < a.FrameCount; i++)
            {
                //a.NextFrame(vbn);
                for (int j = 0; j < a.Bones.Count; j++)
                {
                    Bone node = vbn.getBone(a.Bones[j].Text);

                    Animation.KeyNode anode = a.Bones[j];
                    //if (node == null) continue;

                    if (hasTrans[j] && !conTrans[j])
                    {
                        t2.writeShort((int)(((anode.XPOS.GetValue(i) - minT[j].X) / maxT[j].X) * 0xFFFF));
                        t2.writeShort((int)(((anode.YPOS.GetValue(i) - minT[j].Y) / maxT[j].Y) * 0xFFFF));
                        t2.writeShort((int)(((anode.ZPOS.GetValue(i) - minT[j].Z) / maxT[j].Z) * 0xFFFF));
                    }

                    if (hasRot[j] && !conRot[j])
                    {
                        Quaternion r = new Quaternion();
                        if (anode.RotType == Animation.RotationType.QUATERNION)
                        {
                            Animation.KeyFrame[] x  = anode.XROT.GetFrame(i);
                            Animation.KeyFrame[] y  = anode.YROT.GetFrame(i);
                            Animation.KeyFrame[] z  = anode.ZROT.GetFrame(i);
                            Animation.KeyFrame[] w  = anode.WROT.GetFrame(i);
                            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 == i)
                            {
                                r = q1;
                            }
                            else
                            if (x[1].Frame == i)
                            {
                                r = q2;
                            }
                            else
                            {
                                r = Quaternion.Slerp(q1, q2, (i - x[0].Frame) / (x[1].Frame - x[0].Frame));
                            }
                        }
                        else
                        if (anode.RotType == Animation.RotationType.EULER)
                        {
                            float x = anode.XROT.HasAnimation() ? anode.XROT.GetValue(i) : node.rotation[0];
                            float y = anode.YROT.HasAnimation() ? anode.YROT.GetValue(i) : node.rotation[1];
                            float z = anode.ZROT.HasAnimation() ? anode.ZROT.GetValue(i) : node.rotation[2];
                            r = Animation.EulerToQuat(z, y, x);
                        }
                        r.Normalize();
                        t2.writeShort((int)(((r.X - minR[j].X) / maxR[j].X) * 0xFFFF));
                        t2.writeShort((int)(((r.Y - minR[j].Y) / maxR[j].Y) * 0xFFFF));
                        t2.writeShort((int)(((r.Z - minR[j].Z) / maxR[j].Z) * 0xFFFF));
                    }

                    if (hasScale[j] && !conScale[j])
                    {
                        t2.writeShort((int)(((anode.XSCA.GetValue(i) - minS[j].X) / maxS[j].X) * 0xFFFF));
                        t2.writeShort((int)(((anode.YSCA.GetValue(i) - minS[j].Y) / maxS[j].Y) * 0xFFFF));
                        t2.writeShort((int)(((anode.ZSCA.GetValue(i) - minS[j].Z) / maxS[j].Z) * 0xFFFF));
                    }
                }

                if (go)
                {
                    o.writeShortAt(t2.size(), 0x12);
                    go = false;
                }
            }

            o.writeOutput(t2);
            return(o.getBytes());
        }
    }
Beispiel #5
0
        private void animationTrackBar_ValueChanged(object sender, EventArgs e)
        {
            if (animationTrackBar.Value > totalFrame.Value)
            {
                animationTrackBar.Value = 0;
            }
            if (animationTrackBar.Value < 0)
            {
                animationTrackBar.Value = (int)totalFrame.Value;
            }
            currentFrame.Value = animationTrackBar.Value;


            int frameNum = animationTrackBar.Value;

            if (MaterialAnimation != null)
            {
                foreach (TreeNode node in MeshList.treeView1.Nodes)
                {
                    if (!(node is ModelContainer))
                    {
                        continue;
                    }
                    ModelContainer m = (ModelContainer)node;
                    m.NUD.applyMTA(MaterialAnimation, frameNum);
                }
            }

            if (Animation == null)
            {
                return;
            }

            // Process script first in case we have to speed up the animation
            if (ACMDScript != null)
            {
                ACMDScript.processToFrame(frameNum);
            }

            float animFrameNum = frameNum;

            if (ACMDScript != null && Runtime.useFrameDuration)
            {
                animFrameNum = ACMDScript.animationFrame;// - 1;
            }
            foreach (TreeNode node in MeshList.treeView1.Nodes)
            {
                if (!(node is ModelContainer))
                {
                    continue;
                }
                ModelContainer m = (ModelContainer)node;
                Animation.SetFrame(animFrameNum);
                if (m.VBN != null)
                {
                    Animation.NextFrame(m.VBN);
                }

                // Deliberately do not ever use ACMD/animFrame to modify these other types of model
                if (m.dat_melee != null)
                {
                    Animation.SetFrame(frameNum);
                    Animation.NextFrame(m.dat_melee.bones);
                }
                if (m.BCH != null)
                {
                    foreach (BCH_Model mod in m.BCH.Models.Nodes)
                    {
                        if (mod.skeleton != null)
                        {
                            Animation.SetFrame(animFrameNum);
                            Animation.NextFrame(mod.skeleton);
                        }
                    }
                }
            }

            //Frame = (int)animFrameNum;
        }