예제 #1
0
 public static void effectiveScale(SkelAnimation anim, Matrix4 sca)
 {
     foreach (KeyFrame frame in anim.frames)
     {
         foreach (KeyNode node in frame.nodes)
         {
             if (node.t_type != -1)
             {
                 Vector3 pos = Vector3.TransformVector(node.t, sca);
                 if (node.t.X != -99)
                 {
                     node.t.X = pos.X;
                 }
                 if (node.t.Y != -99)
                 {
                     node.t.Y = pos.Y;
                 }
                 if (node.t.Z != -99)
                 {
                     node.t.Z = pos.Z;
                 }
             }
         }
     }
 }
예제 #2
0
        public SkelAnimation BakeToSkel(VBN skel)
        {
            SkelAnimation a = new SkelAnimation();

            for (int i = 1; i < anim.frameCount + 1; i++)
            {
                a.frames.Add(new KeyFrame());
            }

            for (int i = 0; i < anim.nodes.Count; i++)
            {
                Frame[] frames = Bake(i);

                int fr = 0;
                foreach (Frame f in frames)
                {
                    if (fr == 0)
                    {
                        fr++;
                        continue;
                    }
                    if (i >= skel.bones.Count)
                    {
                        continue;
                    }

                    KeyFrame frame = a.frames[fr - 1];
                    KeyNode  node  = new KeyNode();
                    frame.nodes.Add(node);

                    node.hash = skel.bones[i].boneId;

                    node.t_type = 1;
                    node.r_type = 1;
                    node.s_type = 1;

                    node.t.X = f.x != -99 ? f.x : skel.bones[i].position[0];
                    node.t.Y = f.y != -99 ? f.y : skel.bones[i].position[1];
                    node.t.Z = f.z != -99 ? f.z : skel.bones[i].position[2];

                    node.r.X = f.rx != -99 ? f.rx * (float)Math.PI / 180 : skel.bones[i].rotation[0];
                    node.r.Y = f.ry != -99 ? f.ry * (float)Math.PI / 180 : skel.bones[i].rotation[1];
                    node.r.Z = f.rz != -99 ? f.rz * (float)Math.PI / 180 : skel.bones[i].rotation[2];

                    node.s.X = f.sx != -99 ? f.sx : skel.bones[i].scale[0];
                    node.s.Y = f.sy != -99 ? f.sy : skel.bones[i].scale[1];
                    node.s.Z = f.sz != -99 ? f.sz : skel.bones[i].scale[2];

                    node.r = VBN.FromEulerAngles(node.r.Z, node.r.Y, node.r.X);

                    fr++;
                }
            }

            return(a);
        }
예제 #3
0
        // temp stuff
        public static Dictionary <string, SkelAnimation> LoadAJ(string fname, VBN vbn)
        {
            // a note, I know that the main player file has the offsets for
            // animations, this is just for viewing
            FileData f = new FileData(fname);

            f.Endian = System.IO.Endianness.Big;

            int pos = 0;

            Dictionary <string, SkelAnimation> animations = new Dictionary <string, SkelAnimation>();
            AnimationGroupNode group = new AnimationGroupNode()
            {
                Text = fname
            };

            MainForm.Instance.animList.treeView1.Nodes.Add(group);
            while (pos < f.size())
            {
                Console.WriteLine(pos.ToString("x"));
                int           len  = f.readInt();
                DAT_Animation anim = new DAT_Animation();
                anim.Read(new FileData(f.getSection(pos, len)));
                AnimTrack track = new AnimTrack(anim);

                if (pos == 0)
                {
                    //track.Show();
                }
                group.Nodes.Add(track.toAnimation(vbn));
                SkelAnimation sa = track.BakeToSkel(vbn);
                //sa.Tag = track;
                //Runtime.Animations.Add(anim.Name, sa);
                // MainForm.Instance.animList.treeView1.Nodes.Add(anim.Name);
                animations.Add(anim.Name, sa);

                if (pos != 0)
                {
                    track.Dispose();
                    track.Close();
                }

                f.skip(len - 4);
                f.align(32);
                pos = f.pos();
            }

            return(animations);
        }
예제 #4
0
파일: OMO.cs 프로젝트: StorMyu/Smash-Forge
        public static SkelAnimation read(FileData d)
        {
            d.Endian = Endianness.Big;

            d.skip(4); // header OMO
            d.skip(4); // two shorts, idk

            d.skip(4); //flags?

            d.skip(2);
            int numOfBones = d.readShort();
            int frameSize  = d.readShort();
            int frameStart = d.readShort();

            int offset1 = d.readInt();
            int offset2 = d.readInt();
            int offset3 = d.readInt();

            SkelAnimation anim = new SkelAnimation();

            anim.Tag = d;
            //anim.setModel(m);

            // base frames
            // These are linked to bones somehow, hash??
            d.seek(offset1); //
            int[]     framekey = new int[numOfBones];
            KeyNode[] baseNode = new KeyNode[numOfBones];

            for (int i = 0; i < numOfBones; i++)
            {
                int flags = d.readByte();
                int tFlag = d.readByte();
                int rFlag = d.readByte();
                int sFlag = d.readByte();
                int hash  = d.readInt(); // used to find the identifying bone
                int off1  = d.readInt() + offset2;
                framekey[i] = d.readInt();

                bool hasTrans = (flags & 0x01) == 0x01;
                bool hasScale = (flags & 0x04) == 0x04;
                bool hasRot   = (flags & 0x02) == 0x02;

                KeyNode node = new KeyNode();
                baseNode[i] = node;

                node.hash = (uint)hash;

                int temp = d.pos();
                d.seek(off1);

                if (hasTrans)
                {
                    if (tFlag == 0x8)
                    { // interpolated
                        node.t_type = KeyNode.INTERPOLATED;
                        node.t      = new Vector3(d.readFloat(), d.readFloat(), d.readFloat());
                        node.t2     = new Vector3(d.readFloat(), d.readFloat(), d.readFloat());
                    }
                    else if (tFlag == 0x20)
                    {
                        node.t_type = KeyNode.CONSTANT;
                        node.t      = new Vector3(d.readFloat(), d.readFloat(), d.readFloat());
                    }
                }
                if (hasRot)
                {
                    if ((rFlag & 0xF) != 0x50 && (rFlag & 0xF0) != 0x70 && (rFlag & 0xF0) != 0x60 && (rFlag & 0xF0) != 0xA0)
                    {
                        //Console.WriteLine(rFlag);
                    }

                    if ((rFlag & 0xF0) == 0xA0)
                    {
                        node.r_type = 3;
                    }

                    if ((rFlag & 0xF0) == 0x50)
                    { // interpolated
                        node.r_type = KeyNode.INTERPOLATED;
                        node.rv     = new Vector3(d.readFloat(), d.readFloat(), d.readFloat());
                        node.rv2    = new Vector3(d.readFloat(), d.readFloat(), d.readFloat());
                    }
                    if ((rFlag & 0xF0) == 0x70 || (rFlag & 0xF0) == 0x60)
                    { // constant
                        node.r_type = KeyNode.CONSTANT;
                        node.rv     = new Vector3(d.readFloat(), d.readFloat(), d.readFloat());
                        if ((rFlag & 0xF0) == 0x60)
                        {
                            d.skip(4);
                        }
                    }
                }

                if (hasScale)
                {
                    if ((sFlag & 0xF0) == 0x80)
                    { // interpolated
                        node.s_type = KeyNode.INTERPOLATED;
                        node.s      = new Vector3(d.readFloat(), d.readFloat(), d.readFloat());
                        node.s2     = new Vector3(d.readFloat(), d.readFloat(), d.readFloat());
                    }
                    if ((rFlag & 0x0F) == 0x02 || (rFlag & 0x0F) == 0x03)
                    { // constant
                        node.s_type = KeyNode.CONSTANT;
                        node.s      = new Vector3(d.readFloat(), d.readFloat(), d.readFloat());
                    }
                }
                d.seek(temp);
            }

            d.seek(offset3);
            for (int i = 0; i < frameSize; i++)
            {
                KeyFrame key = new KeyFrame();
                key.frame = i;

                int off = d.pos();

                for (int j = 0; j < numOfBones; j++)
                {
                    KeyNode node = new KeyNode();

                    node.t_type = baseNode[j].t_type;
                    node.r_type = baseNode[j].r_type;
                    node.s_type = baseNode[j].s_type;

                    node.id   = baseNode[j].id;
                    node.hash = baseNode[j].hash;

                    d.seek(off + framekey[j]);

                    if (baseNode[j].t_type == KeyNode.INTERPOLATED)
                    {
                        float i1 = ((float)d.readShort() / 0xffff);
                        float i2 = ((float)d.readShort() / 0xffff);
                        float i3 = ((float)d.readShort() / 0xffff);

                        float x = baseNode[j].t.X + (baseNode[j].t2.X * (i1));
                        float y = baseNode[j].t.Y + (baseNode[j].t2.Y * (i2));
                        float z = baseNode[j].t.Z + (baseNode[j].t2.Z * (i3));

                        node.t = new Vector3(x, y, z);
                    }
                    else
                    {
                        node.t = baseNode[j].t;
                    }

                    if (baseNode[j].r_type == 3)
                    {
                        float i1 = ((float)d.readShort() / (0xffff));
                        float i2 = ((float)d.readShort() / (0xffff));
                        float i3 = ((float)d.readShort() / (0xffff));
                        float i4 = ((float)d.readShort() / (0xffff));

                        node.r = new Quaternion(new Vector3(i1, i2, i3), i4);
                        //Console.WriteLine(node.r.ToString());
                        //node.r = VBN.FromEulerAngles(i4 * i1, i4 * i2, i4 * i3);
                        node.r_type = KeyNode.INTERPOLATED;
                        //node.r.Normalize();
                    }
                    else
                    if (baseNode[j].r_type == KeyNode.INTERPOLATED)
                    {
                        float i1 = ((float)d.readShort() / (0xffff));
                        float i2 = ((float)d.readShort() / (0xffff));
                        float i3 = ((float)d.readShort() / (0xffff));

                        float x = baseNode[j].rv.X + (baseNode[j].rv2.X * (i1));
                        float y = baseNode[j].rv.Y + (baseNode[j].rv2.Y * (i2));
                        float z = baseNode[j].rv.Z + (baseNode[j].rv2.Z * (i3));

                        float w = (float)Math.Sqrt(Math.Abs(1 - (x * x + y * y + z * z)));

                        node.r = new Quaternion(new Vector3(x, y, z), w);
                        node.r.Normalize();
                    }
                    else
                    {
                        float x = baseNode[j].rv.X;
                        float y = baseNode[j].rv.Y;
                        float z = baseNode[j].rv.Z;

                        float w = (float)Math.Sqrt(1 - (x * x + y * y + z * z));

                        node.r = new Quaternion(baseNode[j].rv, w);
                    }

                    if (baseNode[j].s_type == KeyNode.INTERPOLATED)
                    {
                        float i1 = ((float)d.readShort() / (0xffff));
                        float i2 = ((float)d.readShort() / (0xffff));
                        float i3 = ((float)d.readShort() / (0xffff));

                        float x = baseNode[j].s.X + (baseNode[j].s2.X * (i1));
                        float y = baseNode[j].s.Y + (baseNode[j].s2.Y * (i2));
                        float z = baseNode[j].s.Z + (baseNode[j].s2.Z * (i3));

                        node.s = new Vector3(x, y, z);
                    }
                    else
                    {
                        node.s = baseNode[j].s;
                    }

                    key.addNode(node);
                }
                d.seek(off + frameStart);

                anim.addKeyframe(key);
            }

            return(anim);
        }
예제 #5
0
파일: OMO.cs 프로젝트: StorMyu/Smash-Forge
 public static void createOMO(SkelAnimation a, VBN vbn, String fname)
 {
     File.WriteAllBytes(fname, createOMO(a, vbn));
 }
예제 #6
0
파일: OMO.cs 프로젝트: StorMyu/Smash-Forge
        public static byte[] createOMO(SkelAnimation a, VBN vbn)
        {
            List <int> nodeid = a.getNodes(true, vbn);

            int startNode = 0;
            int sizeNode  = nodeid.Count;

            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(sizeNode);       // numOfNodes

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

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

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


            // ASSESSMENT
            KeyNode[] minmax   = new KeyNode[sizeNode];
            bool[]    hasScale = new bool[sizeNode];
            bool[]    hasTrans = new bool[sizeNode];
            bool[]    hasRot   = new bool[sizeNode];

            bool[] conScale = new bool[sizeNode];
            bool[] conTrans = new bool[sizeNode];
            bool[] conRot   = new bool[sizeNode];

            a.setFrame(0);

            for (int i = 0; i < a.size(); i++)
            {
                a.nextFrame(vbn);

                for (int j = 0; j < nodeid.Count; j++)
                {
                    Bone node = getNodeId(vbn, nodeid[j]);

                    if (minmax[j] == null)
                    {
                        hasRot[j]   = false;
                        hasScale[j] = false;
                        hasTrans[j] = false;

                        KeyNode n = a.getFirstNode(nodeid[j]);
                        if (n != null)
                        {
                            if (n.r_type != -1)
                            {
                                hasRot[j] = true;
                            }
                            if (n.t_type != -1)
                            {
                                hasTrans[j] = true;
                            }
                            if (n.s_type != -1)
                            {
                                hasScale[j] = true;
                            }
                        }

                        minmax[j]    = new KeyNode();
                        minmax[j].t  = new Vector3(999f, 999f, 999f);
                        minmax[j].r  = new Quaternion(999f, 999f, 999f, 999f);
                        minmax[j].s  = new Vector3(999f, 999f, 999f);
                        minmax[j].t2 = new Vector3(-999f, -999f, -999f);
                        minmax[j].r2 = new Quaternion(-999f, -999f, -999f, -999f);
                        minmax[j].s2 = new Vector3(-999f, -999f, -999f);
                    }

                    if (node.pos.X < minmax[j].t.X)
                    {
                        minmax[j].t.X = node.pos.X;
                    }
                    if (node.pos.X > minmax[j].t2.X)
                    {
                        minmax[j].t2.X = node.pos.X;
                    }

                    if (node.pos.Y < minmax[j].t.Y)
                    {
                        minmax[j].t.Y = node.pos.Y;
                    }
                    if (node.pos.Y > minmax[j].t2.Y)
                    {
                        minmax[j].t2.Y = node.pos.Y;
                    }

                    if (node.pos.Z < minmax[j].t.Z)
                    {
                        minmax[j].t.Z = node.pos.Z;
                    }
                    if (node.pos.Z > minmax[j].t2.Z)
                    {
                        minmax[j].t2.Z = node.pos.Z;
                    }

                    //				float[] fix = Node.fix360(node.nrx, node.nry, node.nrz);
                    //float[] f = Bone.CalculateRotation(node.nrx, node.nry, node.nrz);
                    Quaternion r = node.rot;

                    if (r.X < minmax[j].r.X)
                    {
                        minmax[j].r.X = r.X;
                    }
                    if (r.X > minmax[j].r2.X)
                    {
                        minmax[j].r2.X = r.X;
                    }

                    if (r.Y < minmax[j].r.Y)
                    {
                        minmax[j].r.Y = r.Y;
                    }
                    if (r.Y > minmax[j].r2.Y)
                    {
                        minmax[j].r2.Y = r.Y;
                    }

                    if (r.Z < minmax[j].r.Z)
                    {
                        minmax[j].r.Z = r.Z;
                    }
                    if (r.Z > minmax[j].r2.Z)
                    {
                        minmax[j].r2.Z = r.Z;
                    }


                    if (node.sca.X < minmax[j].s.X)
                    {
                        minmax[j].s.X = node.sca.X;
                    }
                    if (node.sca.X > minmax[j].s2.X)
                    {
                        minmax[j].s2.X = node.sca.X;
                    }

                    if (node.sca.Y < minmax[j].s.Y)
                    {
                        minmax[j].s.Y = node.sca.Y;
                    }
                    if (node.sca.Y > minmax[j].s2.Y)
                    {
                        minmax[j].s2.Y = node.sca.Y;
                    }

                    if (node.sca.Z < minmax[j].s.Z)
                    {
                        minmax[j].s.Z = node.sca.Z;
                    }
                    if (node.sca.Z > minmax[j].s2.Z)
                    {
                        minmax[j].s2.Z = node.sca.Z;
                    }
                }
            }

            // NODE INFO

            int t2Size = 0;

            for (int i = 0; i < sizeNode; i++)
            {
                int flag = 0;

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

                // check for constant
                if (minmax[i].t.Equals(minmax[i].t2))
                {
                    conTrans[i] = true;
                }
                if (minmax[i].r.Equals(minmax[i].r2))
                {
                    conRot[i] = true;
                }
                if (minmax[i].s.Equals(minmax[i].s2))
                {
                    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;

                int hash = (int)getNodeId(vbn, nodeid[i]).boneId;
                //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(minmax[i].t.X);
                    t1.writeFloat(minmax[i].t.Y);
                    t1.writeFloat(minmax[i].t.Z);

                    if (!conTrans[i])
                    {
                        minmax[i].t2.X -= minmax[i].t.X;
                        minmax[i].t2.Y -= minmax[i].t.Y;
                        minmax[i].t2.Z -= minmax[i].t.Z;

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

                        t2Size += 6;
                    }
                }

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

                    if (!conRot[i])
                    {
                        minmax[i].r2.X -= minmax[i].r.X;
                        minmax[i].r2.Y -= minmax[i].r.Y;
                        minmax[i].r2.Z -= minmax[i].r.Z;

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

                        t2Size += 6;
                    }
                }

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

                    if (!conScale[i])
                    {
                        minmax[i].s2.X -= minmax[i].s.X;
                        minmax[i].s2.Y -= minmax[i].s.Y;
                        minmax[i].s2.Z -= minmax[i].s.Z;

                        t1.writeFloat(minmax[i].s2.X);
                        t1.writeFloat(minmax[i].s2.Y);
                        t1.writeFloat(minmax[i].s2.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.size(); i++)
            {
                a.nextFrame(vbn);
                for (int j = 0; j < nodeid.Count; j++)
                {
                    Bone node = getNodeId(vbn, nodeid[j]);

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

                    if (hasRot[j] && !conRot[j])
                    {
                        //					float[] fix = Node.fix360(node.nrx, node.nry, node.nrz);
                        //float[] f = CalculateRotation(node.nrx, node.nry, node.nrz);
                        Quaternion r = node.rot;

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

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

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

            o.writeOutput(t2);
            return(o.getBytes());
        }
예제 #7
0
파일: ANIM.cs 프로젝트: struz/Smash-Forge
        public static SkelAnimation read(string filename, VBN vbn)
        {
            StreamReader reader = File.OpenText(filename);
            string       line;

            bool isHeader = true;

            string          angularUnit, linearUnit, timeUnit;
            int             startTime = 0;
            int             endTime   = 0;
            List <AnimBone> bones     = new List <AnimBone>();
            AnimBone        current;
            AnimData        att    = new AnimData();
            bool            inKeys = false;

            while ((line = reader.ReadLine()) != null)
            {
                string[] args = line.Replace(";", "").TrimStart().Split(' ');

                if (isHeader)
                {
                    if (args [0].Equals("anim"))
                    {
                        isHeader = false;
                    }
                    else if (args [0].Equals("angularUnit"))
                    {
                        angularUnit = args [1];
                    }
                    else if (args [0].Equals("endTime"))
                    {
                        endTime = (int)Math.Ceiling(float.Parse(args [1]));
                    }
                    else if (args [0].Equals("startTime"))
                    {
                        startTime = (int)Math.Ceiling(float.Parse(args [1]));
                    }
                }

                if (!isHeader)
                {
                    if (inKeys)
                    {
                        if (args[0].Equals("}"))
                        {
                            inKeys = false;
                            continue;
                        }
                        AnimKey k = new AnimKey();
                        att.keys.Add(k);
                        k.input  = float.Parse(args [0]);
                        k.output = float.Parse(args [1]);
                        k.intan  = (args [2]);
                        k.outtan = (args [3]);
                        if (args.Length > 7 && att.weighted)
                        {
                            k.t1 = float.Parse(args[7]) * (float)(Math.PI / 180f);
                            k.w1 = float.Parse(args[8]);
                        }
                    }

                    if (args [0].Equals("anim"))
                    {
                        inKeys = false;
                        if (args.Length == 5)
                        {
                            //TODO: finish this type
                            // can be name of attribute
                        }
                        if (args.Length == 7)
                        {
                            // see of the bone of this attribute exists
                            current = null;
                            foreach (AnimBone b in bones)
                            {
                                if (b.name.Equals(args [3]))
                                {
                                    current = b;
                                    break;
                                }
                            }
                            if (current == null)
                            {
                                current = new AnimBone();
                                bones.Add(current);
                            }
                            current.name = args [3];

                            att      = new AnimData();
                            att.type = args [2];
                            current.atts.Add(att);

                            // row child attribute aren't needed here
                        }
                    }

                    if (args [0].Equals("input"))
                    {
                        att.input = args [1];
                    }
                    if (args [0].Equals("output"))
                    {
                        att.output = args [1];
                    }
                    if (args [0].Equals("weighted"))
                    {
                        att.weighted = args [1].Equals("1");
                    }
                    if (args [0].Equals("preInfinity"))
                    {
                        att.preInfinity = args [1];
                    }
                    if (args [0].Equals("postInfinity"))
                    {
                        att.postInfinity = args [1];
                    }

                    // begining keys section
                    if (args [0].Contains("keys"))
                    {
                        inKeys = true;
                    }
                }
            }

            SkelAnimation a = new SkelAnimation();

            for (int i = 0; i < endTime - startTime + 1; i++)
            {
                KeyFrame key = new KeyFrame();
                a.addKeyframe(key);

                foreach (AnimBone b in bones)
                {
                    KeyNode n = new KeyNode();
                    n.id = vbn.boneIndex(b.name);
                    if (n.id == -1)
                    {
                        continue;
                    }
                    else
                    {
                        n.hash = vbn.bones[n.id].boneId;
                    }
                    foreach (AnimData d in b.atts)
                    {
                        if (d.type.Contains("translate"))
                        {
                            n.t_type = KeyNode.INTERPOLATED;
                            if (d.type.Contains("X"))
                            {
                                n.t.X = d.getValue(i);
                            }
                            if (d.type.Contains("Y"))
                            {
                                n.t.Y = d.getValue(i);
                            }
                            if (d.type.Contains("Z"))
                            {
                                n.t.Z = d.getValue(i);
                            }
                        }
                        if (d.type.Contains("rotate"))
                        {
                            n.r_type = KeyNode.INTERPOLATED;
                            if (d.type.Contains("X"))
                            {
                                n.r.X = d.getValue(i) * (float)(Math.PI / 180f);
                            }
                            if (d.type.Contains("Y"))
                            {
                                n.r.Y = d.getValue(i) * (float)(Math.PI / 180f);
                            }
                            if (d.type.Contains("Z"))
                            {
                                n.r.Z = d.getValue(i) * (float)(Math.PI / 180f);
                            }
                        }
                        if (d.type.Contains("scale"))
                        {
                            n.s_type = KeyNode.INTERPOLATED;
                            if (d.type.Contains("X"))
                            {
                                n.s.X = d.getValue(i);
                            }
                            if (d.type.Contains("Y"))
                            {
                                n.s.Y = d.getValue(i);
                            }
                            if (d.type.Contains("Z"))
                            {
                                n.s.Z = d.getValue(i);
                            }
                        }
                    }
                    key.addNode(n);
                }
            }

            // keynode rotations need caluclation
            foreach (KeyFrame f in a.frames)
            {
                foreach (KeyNode n in f.nodes)
                {
                    n.r = VBN.FromEulerAngles(n.r.Z, n.r.Y, n.r.X);
                }
            }

            reader.Close();
            return(a);
        }
예제 #8
0
파일: ANIM.cs 프로젝트: struz/Smash-Forge
        private static void writeKey(StreamWriter file, SkelAnimation a, int i, string type, int tt)
        {
            file.WriteLine("animData {\n input time;\n output linear;\n weighted 1;\n preInfinity constant;\n postInfinity constant;\n keys {");

            int size = a.size();

            if (tt == KeyNode.CONSTANT)
            {
                size = 1;
            }

            for (int f = 0; f < size; f++)
            {
                KeyNode node = a.getNode(f, i);

                float v = 0;

                switch (type)
                {
                case "translateX":
                    v = node.t.X;
                    break;

                case "translateY":
                    v = node.t.Y;
                    break;

                case "translateZ":
                    v = node.t.Z;
                    break;

                case "rotateX":
                    v = quattoeul(node.r).X *(float)(180f / Math.PI);
                    break;

                case "rotateY":
                    v = quattoeul(node.r).Y *(float)(180f / Math.PI);
                    break;

                case "rotateZ":
                    v = quattoeul(node.r).Z *(float)(180f / Math.PI);
                    break;

                case "scaleX":
                    v = node.s.X;
                    break;

                case "scaleY":
                    v = node.s.Y;
                    break;

                case "scaleZ":
                    v = node.s.Z;
                    break;
                }

                file.WriteLine(" " + (f + 1) + " {0:N6} fixed fixed 1 1 0 0 1 0 1;", v);
            }

            file.WriteLine(" }");
        }
예제 #9
0
파일: ANIM.cs 프로젝트: struz/Smash-Forge
        public static void createANIM(string fname, SkelAnimation a, VBN vbn)
        {
            using (System.IO.StreamWriter file = new System.IO.StreamWriter(@fname))
            {
                file.WriteLine("animVersion 1.1;");
                file.WriteLine("mayaVersion 2014 x64;\ntimeUnit ntscf;\nlinearUnit cm;\nangularUnit deg;\nstartTime 1;\nendTime " + (a.size()) + ";");

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

                List <int> nodes = a.getNodes(true, vbn); //getting node indexes

                int i = 0;

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

                    if (nodes.Contains(i))
                    {
                        // write the bone attributes
                        // count the attributes
                        KeyNode n  = a.getNode(0, i);
                        int     ac = 0;
                        if (n.t_type != -1)
                        {
                            file.WriteLine("anim translate.translateX translateX " + b.Text + " 0 0 " + (ac++) + ";");
                            writeKey(file, a, i, "translateX", n.t_type);
                            file.WriteLine("}");
                            file.WriteLine("anim translate.translateY translateY " + b.Text + " 0 0 " + (ac++) + ";");
                            writeKey(file, a, i, "translateY", n.t_type);
                            file.WriteLine("}");
                            file.WriteLine("anim translate.translateZ translateZ " + b.Text + " 0 0 " + (ac++) + ";");
                            writeKey(file, a, i, "translateZ", n.t_type);
                            file.WriteLine("}");
                        }
                        if (n.r_type != -1)
                        {
                            file.WriteLine("anim rotate.rotateX rotateX " + b.Text + " 0 0 " + (ac++) + ";");
                            writeKey(file, a, i, "rotateX", n.r_type);
                            file.WriteLine("}");
                            file.WriteLine("anim rotate.rotateY rotateY " + b.Text + " 0 0 " + (ac++) + ";");
                            writeKey(file, a, i, "rotateY", n.r_type);
                            file.WriteLine("}");
                            file.WriteLine("anim rotate.rotateZ rotateZ " + b.Text + " 0 0 " + (ac++) + ";");
                            writeKey(file, a, i, "rotateZ", n.r_type);
                            file.WriteLine("}");
                        }
                        if (n.s_type != -1)
                        {
                            file.WriteLine("anim scale.scaleX scaleX " + b.Text + " 0 0 " + (ac++) + ";");
                            writeKey(file, a, i, "scaleX", n.s_type);
                            file.WriteLine("}");
                            file.WriteLine("anim scale.scaleY scaleY " + b.Text + " 0 0 " + (ac++) + ";");
                            writeKey(file, a, i, "scaleY", n.s_type);
                            file.WriteLine("}");
                            file.WriteLine("anim scale.scaleZ scaleZ " + b.Text + " 0 0 " + (ac++) + ";");
                            writeKey(file, a, i, "scaleZ", n.s_type);
                            file.WriteLine("}");
                        }
                    }
                    else
                    {
                        file.WriteLine("anim " + b.Text + " 0 0 0;");
                    }
                }
            }
        }
예제 #10
0
        public static void generateInter(SkelAnimation anim, int max, int nid, String part, float[] frame, float[] tan, float[] step, VBN vbn)
        {
            int in2  = 0;
            int out2 = 1;

            float degrad = (float)(Math.PI / 180f);

            for (int i = 0; i < max; i++)
            {
                KeyNode n = anim.getNode(i, nid);
                if (part.Contains("R"))
                {
                    n.r_type = 1;
                }
                else
                if (part.Contains("S"))
                {
                    n.s_type = 1;
                }
                else
                {
                    n.t_type = 1;
                }

                if (i > frame[out2])
                {
                    in2++;
                    out2++;
                }
                float inv    = frame[in2];
                float tanin  = tan[in2];
                float stepin = step[in2];

                if (frame[0] > i)
                {
                    inv    = 0;
                    tanin  = 0;
                    stepin = anim.getBaseNodeValue(nid, part, vbn);
                    out2   = 0;
                    in2    = 0;
                }

                if (frame[0] == i && out2 == 0)
                {
                    out2 = 1;
                    in2  = 0;
                }

                switch (part)
                {
                case "RX":
                    n.r.X = interHermite(i, inv, frame[out2], tanin, tan[out2], stepin, step[out2]) * degrad;
                    break;

                case "RY":
                    n.r.Y = interHermite(i, inv, frame[out2], tanin, tan[out2], stepin, step[out2]) * degrad;
                    break;

                case "RZ":
                    n.r.Z = interHermite(i, inv, frame[out2], tanin, tan[out2], stepin, step[out2]) * degrad;
                    break;

                case "X":
                    n.t.X = interHermite(i, inv, frame[out2], tanin, tan[out2], stepin, step[out2]);
                    break;

                case "Y":
                    n.t.Y = interHermite(i, inv, frame[out2], tanin, tan[out2], stepin, step[out2]);
                    break;

                case "Z":
                    n.t.Z = interHermite(i, inv, frame[out2], tanin, tan[out2], stepin, step[out2]);
                    break;

                case "SX":
                    n.s.X = interHermite(i, inv, frame[out2], tanin, tan[out2], stepin, step[out2]);
                    break;

                case "SY":
                    n.s.Y = interHermite(i, inv, frame[out2], tanin, tan[out2], stepin, step[out2]);
                    break;

                case "SZ":
                    n.s.Z = interHermite(i, inv, frame[out2], tanin, tan[out2], stepin, step[out2]);
                    break;
                }
            }
        }
예제 #11
0
파일: CHR0.cs 프로젝트: struz/Smash-Forge
        public static void process(FileData d, int type, int secOff, SkelAnimation anim, String part, int nid, bool debug, VBN vbn)
        {
            int offset = d.readInt() + secOff;
            int temp   = d.pos();

            d.seek(offset);
            //		System.out.println(d.pos());

            int   max    = 0;
            int   fCount = -1;
            float scale  = 0;

            float[] frame = null, step = null, tan = null;

            if (type == 0x1)
            {
                fCount = d.readShort();
                d.skip(2);
                scale = d.readFloat();
                float stepb = d.readFloat();
                float base2 = d.readFloat();

                frame = new float[fCount];
                step  = new float[fCount];
                tan   = new float[fCount];

                for (int i = 0; i < fCount; i++)
                {
                    frame[i] = d.readByte();
                    int th = d.readThree();
                    step[i] = base2 + ((th >> 12) & 0xfff) * stepb;
                    tan[i]  = (FileData.sign12Bit(th & 0xfff) / 32f);

                    if (frame[i] > max)
                    {
                        max = (int)frame[i];
                    }
                }
            }

            if (type == 0x2)
            {
                //if(debug)
                //System.out.println(part + "\tInterpolated 6\t" + Integer.toHexString(offset));

                fCount = d.readShort();
                d.skip(2);
                scale = d.readFloat();
                float stepb = d.readFloat();
                float base2 = d.readFloat();

                frame = new float[fCount];
                step  = new float[fCount];
                tan   = new float[fCount];

                for (int i = 0; i < fCount; i++)
                {
                    frame[i] = d.readShort() / 32f;
                    step[i]  = base2 + d.readShort() * stepb;
                    tan[i]   = ((short)d.readShort() / 256f);

                    if (frame[i] > max)
                    {
                        max = (int)frame[i];
                    }
                }
            }

            if (type == 0x3)
            {
                //if(debug)
                //System.out.println(part + "\tInterpolated 12 " + Integer.toHexString(offset));

                fCount = d.readShort();
                d.skip(2);
                scale = d.readFloat();

                frame = new float[fCount];
                step  = new float[fCount];
                tan   = new float[fCount];

                for (int i = 0; i < fCount; i++)
                {
                    frame[i] = d.readFloat();
                    step[i]  = d.readFloat();
                    tan[i]   = d.readFloat();

                    if (frame[i] > max)
                    {
                        max = (int)frame[i];
                    }
                }
            }

            if (frame != null)
            {
                generateInter(anim, max, nid, part, frame, tan, step, vbn);
            }

            if (type == 0x4)
            {
                //if(debug)
                //System.out.println(part + "\tLkin 1 " + Integer.toHexString(offset) + " " + anim.size());
                float stepb = d.readFloat();
                float base2 = d.readFloat();
                for (int i = 0; i < anim.size(); i++)
                {
                    KeyNode n = anim.getNode(i, nid);

                    if (part.Contains("R"))
                    {
                        n.r_type = 1;
                    }
                    else
                    if (part.Contains("S"))
                    {
                        n.s_type = 1;
                    }
                    else
                    {
                        n.t_type = 1;
                    }

                    float v = base2 + stepb * (d.readByte());
                    //				float f = d.readFloat();
                    //				System.out.println(stepb + " " + base + " " + (byte)d.readByte());

                    switch (part)
                    {
                    case "RX":
                        n.r.X = (float)(Math.PI / 180f) * (v);
                        break;

                    case "RY":
                        n.r.Y = (float)(Math.PI / 180f) * (v);
                        break;

                    case "RZ":
                        n.r.Z = (float)(Math.PI / 180f) * (v);
                        break;

                    case "X":
                        n.t.X = v;
                        break;

                    case "Y":
                        n.t.Y = v;
                        break;

                    case "Z":
                        n.t.Z = v;
                        break;

                    case "SX":
                        n.s.X = v;
                        break;

                    case "SY":
                        n.s.Y = v;
                        break;

                    case "SZ":
                        n.s.Z = v;
                        break;
                    }
                }

                //			System.out.println(d.pos());
            }

            if (type == 0x6)
            {
                //if(debug)
                //System.out.println(part + "\tLin 4");
                for (int i = 0; i < anim.size(); i++)
                {
                    KeyNode n = anim.getNode(i, nid);

                    if (part.Contains("R"))
                    {
                        n.r_type = 1;
                    }
                    else
                    if (part.Contains("S"))
                    {
                        n.s_type = 1;
                    }
                    else
                    {
                        n.t_type = 1;
                    }

                    float v = d.readFloat();

                    switch (part)
                    {
                    case "RX":
                        n.r.X = (float)(Math.PI / 180) * (v);
                        break;

                    case "RY":
                        n.r.Y = (float)(Math.PI / 180) * (v);
                        break;

                    case "RZ":
                        n.r.Z = (float)(Math.PI / 180) * (v);
                        break;

                    case "X":
                        n.t.X = v;
                        break;

                    case "Y":
                        n.t.Y = v;
                        break;

                    case "Z":
                        n.t.Z = v;
                        break;

                    case "SX":
                        n.s.X = v;
                        break;

                    case "SY":
                        n.s.Y = v;
                        break;

                    case "SZ":
                        n.s.Z = v;
                        break;
                    }
                }
            }

            d.seek(temp);
        }
예제 #12
0
파일: CHR0.cs 프로젝트: struz/Smash-Forge
        public static SkelAnimation readAnim(FileData d, VBN m)
        {
            int offset  = d.readInt();
            int nameoff = d.readInt();

            d.skip(4);
            int fCount        = d.readShort();
            int animDataCount = d.readShort();

            d.skip(8);

            SkelAnimation anim = new SkelAnimation();

            //anim.setModel(m);

            d.seek(offset);
            int sectionOffset = d.readInt() + offset;
            int size          = d.readInt();    // size again

            for (int i = 0; i < size; i++)
            {
                //			System.out.print(d.readShort()); // id
                d.skip(4);                 // id and unknown
                d.readShort();             //left
                d.readShort();             //right
                int nameOffset = d.readInt() + offset;
                int dataOffset = d.readInt() + offset;
                if (dataOffset == offset)
                {
                    i--;
                    continue;
                    //				d.skip(8);
                    //				nameOffset = d.readInt() + 4;
                    //				dataOffset = d.readInt() + offset;
                }


                int temp = d.pos();

                d.seek(dataOffset);

                int pos     = d.pos();
                int nameOff = d.readInt() + sectionOffset + (d.pos() - sectionOffset) - 4;
                int flags   = d.readInt();

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

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

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

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

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

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


                if (hasS == 1)
                {
                    if (Siso == 1)
                    {
                        //System.out.println("S is ISO");

                        int     nid  = anim.getNodeIndex(d.readString(nameOff, -1), m);
                        KeyNode node = anim.getNode(0, nid);
                        node.s_type = 1;
                        float iss = d.readFloat();
                        node.s = new OpenTK.Vector3(iss, iss, iss);
                    }
                    else
                    {
                        int     nid  = anim.getNodeIndex(d.readString(nameOff, -1), m);
                        KeyNode node = anim.getNode(0, nid);
                        node.s_type = 1;

                        //					System.out.println("Scale: " + SXfixed + " " + SYfixed + " " + SZfixed + " " + s_type);
                        node.s = new OpenTK.Vector3(-99, -99, -99);
                        if (SXfixed == 1)
                        {
                            node.s.X = d.readFloat();
                        }
                        else
                        {
                            process(d, s_type, pos, anim, "SX", nid, false, m);
                        }
                        if (SYfixed == 1)
                        {
                            node.s.Y = d.readFloat();
                        }
                        else
                        {
                            process(d, s_type, pos, anim, "SY", nid, false, m);
                        }
                        if (SZfixed == 1)
                        {
                            node.s.Z = d.readFloat();
                        }
                        else
                        {
                            process(d, s_type, pos, anim, "SZ", nid, false, m);
                        }
                    }
                }

                if (hasR == 1)
                {
                    if (Riso == 1)
                    {
                        //System.out.println("R is ISO");

                        int nid = anim.getNodeIndex(d.readString(nameOff, -1), m);
                        Console.WriteLine(nid.ToString("x"));
                        KeyNode node = anim.getNode(0, nid);
                        node.r_type = 1;
                        float iss = (float)((d.readFloat()) * Math.PI / 180f);
                        node.r = VBN.FromEulerAngles(iss, iss, iss);
                    }
                    else
                    {
                        int     nid  = anim.getNodeIndex(d.readString(nameOff, -1), m);
                        KeyNode node = anim.getNode(0, nid);

                        //				System.out.println("Rot: " + RXfixed + " " + RYfixed + " " + RZfixed);

                        node.r = new OpenTK.Quaternion(-99, -99, -99, 0);

                        if (RXfixed == 1)
                        {
                            node.r.X = (float)(Math.PI / 180f) * (d.readFloat());
                        }
                        else
                        {
                            process(d, r_type, pos, anim, "RX", nid, false, m);
                        }
                        if (RYfixed == 1)
                        {
                            node.r.Y = (float)(Math.PI / 180f) * (d.readFloat());
                        }
                        else
                        {
                            process(d, r_type, pos, anim, "RY", nid, false, m);
                        }
                        if (RZfixed == 1)
                        {
                            node.r.Z = (float)(Math.PI / 180f) * (d.readFloat());
                        }
                        else
                        {
                            process(d, r_type, pos, anim, "RZ", nid, false, m);
                        }
                    }
                }

                if (hasT == 1)
                {
                    if (Tiso == 1)
                    {
                        //System.out.println("T is ISO");

                        int     nid  = anim.getNodeIndex(d.readString(nameOff, -1), m);
                        KeyNode node = anim.getNode(0, nid);
                        node.t_type = 1;
                        float iss = d.readFloat();
                        node.t = new OpenTK.Vector3(iss, iss, iss);
                    }
                    else
                    {
                        int     nid  = anim.getNodeIndex(d.readString(nameOff, -1), m);
                        KeyNode node = anim.getNode(0, nid);
                        node.t_type = 1;

                        //					System.out.println("Trans: " + Xfixed + " " + Yfixed + " " + Zfixed);

                        node.t = new OpenTK.Vector3(-99, -99, -99);
                        if (Xfixed == 1)
                        {
                            node.t.X = d.readFloat();
                        }
                        else
                        {
                            process(d, t_type, pos, anim, "X", nid, false, m);
                        }
                        if (Yfixed == 1)
                        {
                            node.t.Y = d.readFloat();
                        }
                        else
                        {
                            process(d, t_type, pos, anim, "Y", nid, false, m);
                        }
                        if (Zfixed == 1)
                        {
                            node.t.Z = d.readFloat();
                        }
                        else
                        {
                            process(d, t_type, pos, anim, "Z", nid, false, m);
                        }
                    }
                }

                d.seek(temp);
            }

            // keynode rotations need caluclation
            foreach (KeyFrame f in anim.frames)
            {
                foreach (KeyNode n in f.nodes)
                {
                    n.r = VBN.FromEulerAngles(n.r.Z, n.r.Y, n.r.X);
                }
            }
            //anim.calcMax();

            return(anim);
        }
예제 #13
0
        public static Animation read(FileData d)
        {
            d.Endian = Endianness.Big;

            d.skip(4); // header OMO
            d.skip(4); // two shorts, idk

            d.skip(4); //flags?

            d.skip(2);
            int boneCount  = d.readShort();
            int frameCount = d.readShort();
            int frameSize  = d.readShort();

            int offset1 = d.readInt();  // nodeOffset
            int offset2 = d.readInt();  // interOffset
            int offset3 = d.readInt();  // keyOffset

            SkelAnimation anim = new SkelAnimation();

            anim.Tag = d;

            if (boneCount > offset2 / 0x10)
            {
                boneCount = offset2 / 0x10;
                anim.Tag  = null;
            }

            // base frames
            // These are linked to bones via hashes
            d.seek(offset1); //
            int[]     framekey = new int[boneCount];
            KeyNode[] baseNode = new KeyNode[boneCount];

            // Start positions for bones/nodes
            for (int i = 0; i < boneCount; i++)
            {
                flagsused = flagsused | d.readInt(); d.seek(d.pos() - 4);
                //Console.WriteLine(flagsused.ToString("x"));

                int flags = d.readByte();
                int tFlag = d.readByte();
                int rFlag = d.readByte();
                int sFlag = d.readByte();
                int hash  = d.readInt(); // used to find the identifying bone
                int off1  = d.readInt() + offset2;
                framekey[i] = d.readInt();

                bool hasTrans = (flags & 0x01) == 0x01;
                bool hasScale = (flags & 0x04) == 0x04;
                bool hasRot   = (flags & 0x02) == 0x02;

                KeyNode node = new KeyNode();
                baseNode[i] = node;

                node.hash = (uint)hash;

                int temp = d.pos();
                d.seek(off1);

                if (hasTrans)
                {
                    if (tFlag == 0x8)
                    { // interpolated
                        node.t_type = KeyNode.INTERPOLATED;
                        node.t      = new Vector3(d.readFloat(), d.readFloat(), d.readFloat());
                        node.t2     = new Vector3(d.readFloat(), d.readFloat(), d.readFloat());
                    }
                    else if (tFlag == 0x20)
                    {
                        node.t_type = KeyNode.CONSTANT;
                        node.t      = new Vector3(d.readFloat(), d.readFloat(), d.readFloat());
                    }
                    else if (tFlag == 0x4)
                    {
                        // entire Vector3 provided in keyframe data i.e. KEYFRAME type
                        node.t_type = KeyNode.KEYFRAME;
                    }
                }
                if (hasRot)
                {
                    if ((rFlag & 0xF0) != 0x50 && (rFlag & 0xF0) != 0x70 && (rFlag & 0xF0) != 0x60 && (rFlag & 0xF0) != 0xA0)
                    {
                        //Console.WriteLine(rFlag);
                    }

                    if ((rFlag & 0xF0) == 0xA0)
                    {
                        // All data is in the keyframe for this type
                        node.r_type = KeyNode.COMPRESSED;
                    }

                    if ((rFlag & 0xF0) == 0x50)
                    { // interpolated
                        node.r_type = KeyNode.INTERPOLATED;
                        node.rv     = new Vector3(d.readFloat(), d.readFloat(), d.readFloat());
                        node.rv2    = new Vector3(d.readFloat(), d.readFloat(), d.readFloat());
                    }

                    if ((rFlag & 0xF0) == 0x60)
                    {
                        node.r_type  = KeyNode.KEYFRAME;
                        node.rv      = new Vector3(d.readFloat(), d.readFloat(), d.readFloat());
                        node.r_extra = d.readFloat() / 65535;
                    }

                    if ((rFlag & 0xF0) == 0x70)
                    {
                        node.r_type = KeyNode.CONSTANT;
                        node.rv     = new Vector3(d.readFloat(), d.readFloat(), d.readFloat());
                    }
                }

                if (hasScale)
                {
                    if ((sFlag & 0xF0) == 0x80)
                    { // interpolated
                        node.s_type = KeyNode.INTERPOLATED;
                        node.s      = new Vector3(d.readFloat(), d.readFloat(), d.readFloat());
                        node.s2     = new Vector3(d.readFloat(), d.readFloat(), d.readFloat());
                    }
                    // TODO: investigate the difference between these
                    if ((rFlag & 0x0F) == 0x02 || (rFlag & 0x0F) == 0x03)
                    { // constant
                        node.s_type = KeyNode.CONSTANT;
                        node.s      = new Vector3(d.readFloat(), d.readFloat(), d.readFloat());
                    }
                }
                d.seek(temp);
            }

            // Interpolated type below here is always a set translation/rotation/scale
            // from the coords specified with the bone node above

            Animation a = new Animation("Anim");

            a.Tag        = anim.Tag;
            a.FrameCount = frameCount;

            d.seek(offset3);

            for (int j = 0; j < boneCount; j++)
            {
                string bid  = "";
                int    hash = -1;
                if (!MainForm.Hashes.ids.TryGetValue(baseNode[j].hash, out bid))
                {
                    hash = (int)baseNode[j].hash;
                }
                Animation.KeyNode n = new Animation.KeyNode(bid);
                n.Hash = hash;
                a.Bones.Add(n);
                n.Type = Animation.BoneType.NORMAL;

                /*foreach (ModelContainer con in Runtime.ModelContainers)
                 *  if (con.VBN != null)
                 *      bid = con.VBN.getBone(baseNode[j].hash) == null ? "" : con.VBN.getBone(baseNode[j].hash).Text;*/

                for (int i = 0; i < a.FrameCount; i++)
                {
                    d.seek(offset3 + frameSize * i + framekey[j]);

                    if (baseNode[j].t_type == KeyNode.INTERPOLATED)
                    {
                        float i1 = ((float)d.readShort() / 0xffff);
                        float i2 = ((float)d.readShort() / 0xffff);
                        float i3 = ((float)d.readShort() / 0xffff);

                        float x = baseNode[j].t.X + (baseNode[j].t2.X * (i1));
                        float y = baseNode[j].t.Y + (baseNode[j].t2.Y * (i2));
                        float z = baseNode[j].t.Z + (baseNode[j].t2.Z * (i3));

                        //node.t = new Vector3(x, y, z);  // Translation
                        n.XPOS.Keys.Add(new Animation.KeyFrame(x, i));
                        n.YPOS.Keys.Add(new Animation.KeyFrame(y, i));
                        n.ZPOS.Keys.Add(new Animation.KeyFrame(z, i));
                    }
                    else if (baseNode[j].t_type == KeyNode.CONSTANT)
                    {
                        //node.t = baseNode[j].t;
                        n.XPOS.Keys.Add(new Animation.KeyFrame(baseNode[j].t.X, i));
                        n.YPOS.Keys.Add(new Animation.KeyFrame(baseNode[j].t.Y, i));
                        n.ZPOS.Keys.Add(new Animation.KeyFrame(baseNode[j].t.Z, i));
                    }
                    else if (baseNode[j].t_type == 2)
                    {
                        float x = d.readFloat();
                        float y = d.readFloat();
                        float z = d.readFloat();

                        //node.t = new Vector3(x, y, z);
                        n.XPOS.Keys.Add(new Animation.KeyFrame(x, i));
                        n.YPOS.Keys.Add(new Animation.KeyFrame(y, i));
                        n.ZPOS.Keys.Add(new Animation.KeyFrame(z, i));
                    }

                    if (baseNode[j].r_type == KeyNode.COMPRESSED)
                    {
                        // There are 64 bits present for each node of this rot type
                        // The format is: 20bits * 3 of encoded floats, and 4 bits of flags
                        // The flags describe which 3 components of the quaternion are being presented
                        int b1 = d.readByte();
                        int b2 = d.readByte();
                        int b3 = d.readByte();
                        int b4 = d.readByte();
                        int b5 = d.readByte();
                        int b6 = d.readByte();
                        int b7 = d.readByte();
                        int b8 = d.readByte();

                        // Capture 20 bits at a time of the raw data
                        int f1    = (b1 << 12) | (b2 << 4) | ((b3 & 0xF0) >> 4);
                        int f2    = ((b3 & 0xF) << 16) | (b4 << 8) | b5;
                        int f3    = (b6 << 12) | (b7 << 4) | ((b8 & 0xF0) >> 4);
                        int flags = b8 & 0xF;

                        Quaternion r = new Quaternion();
                        switch (flags)
                        {
                        case 0:      // y, z, w provided
                            r.Y = encodedRot10ToQuaternionComponent(f1);
                            r.Z = encodedRot10ToQuaternionComponent(f2);
                            r.W = encodedRot10ToQuaternionComponent(f3);

                            r.X = (float)Math.Sqrt(Math.Abs(1 - (r.Y * r.Y + r.Z * r.Z + r.W * r.W)));
                            break;

                        case 1:      // x, z, w provided
                            r.X = encodedRot10ToQuaternionComponent(f1);
                            r.Z = encodedRot10ToQuaternionComponent(f2);
                            r.W = encodedRot10ToQuaternionComponent(f3);

                            r.Y = (float)Math.Sqrt(Math.Abs(1 - (r.X * r.X + r.Z * r.Z + r.W * r.W)));
                            break;

                        case 2:      // x, y, w provided
                            r.X = encodedRot10ToQuaternionComponent(f1);
                            r.Y = encodedRot10ToQuaternionComponent(f2);
                            r.W = encodedRot10ToQuaternionComponent(f3);

                            r.Z = (float)Math.Sqrt(Math.Abs(1 - (r.X * r.X + r.Y * r.Y + r.W * r.W)));
                            break;

                        case 3:      // x, y, z, provided
                            r.X = encodedRot10ToQuaternionComponent(f1);
                            r.Y = encodedRot10ToQuaternionComponent(f2);
                            r.Z = encodedRot10ToQuaternionComponent(f3);

                            r.W = (float)Math.Sqrt(Math.Abs(1 - (r.X * r.X + r.Y * r.Y + r.Z * r.Z)));
                            break;

                        default:
                            Console.WriteLine("Unknown rotation type3 flags: " + flags);
                            break;
                        }
                        n.RotType = Animation.RotationType.QUATERNION;
                        n.XROT.Keys.Add(new Animation.KeyFrame(r.X, i));
                        n.YROT.Keys.Add(new Animation.KeyFrame(r.Y, i));
                        n.ZROT.Keys.Add(new Animation.KeyFrame(r.Z, i));
                        n.WROT.Keys.Add(new Animation.KeyFrame(r.W, i));
                    }
                    else if (baseNode[j].r_type == KeyNode.INTERPOLATED)
                    {
                        float i1 = ((float)d.readShort() / (0xffff));
                        float i2 = ((float)d.readShort() / (0xffff));
                        float i3 = ((float)d.readShort() / (0xffff));

                        float x = baseNode[j].rv.X + (baseNode[j].rv2.X * (i1));
                        float y = baseNode[j].rv.Y + (baseNode[j].rv2.Y * (i2));
                        float z = baseNode[j].rv.Z + (baseNode[j].rv2.Z * (i3));

                        float w = (float)Math.Sqrt(Math.Abs(1 - (x * x + y * y + z * z)));

                        Quaternion r = new Quaternion(new Vector3(x, y, z), w);
                        r.Normalize();

                        n.RotType = Animation.RotationType.QUATERNION;
                        n.XROT.Keys.Add(new Animation.KeyFrame(r.X, i));
                        n.YROT.Keys.Add(new Animation.KeyFrame(r.Y, i));
                        n.ZROT.Keys.Add(new Animation.KeyFrame(r.Z, i));
                        n.WROT.Keys.Add(new Animation.KeyFrame(r.W, i));
                    }
                    else if (baseNode[j].r_type == KeyNode.KEYFRAME)
                    {
                        float scale = d.readShort() * baseNode[j].r_extra;
                        float x     = baseNode[j].rv.X;
                        float y     = baseNode[j].rv.Y;
                        float z     = baseNode[j].rv.Z + scale;
                        float w     = rot6CalculateW(x, y, z);

                        Quaternion r = new Quaternion(x, y, z, w);
                        n.RotType = Animation.RotationType.QUATERNION;
                        n.XROT.Keys.Add(new Animation.KeyFrame(r.X, i));
                        n.YROT.Keys.Add(new Animation.KeyFrame(r.Y, i));
                        n.ZROT.Keys.Add(new Animation.KeyFrame(r.Z, i));
                        n.WROT.Keys.Add(new Animation.KeyFrame(r.W, i));
                    }
                    else
                    {
                        float x = baseNode[j].rv.X;
                        float y = baseNode[j].rv.Y;
                        float z = baseNode[j].rv.Z;
                        float w = (float)Math.Sqrt(Math.Abs(1 - (x * x + y * y + z * z)));

                        Quaternion r = new Quaternion(baseNode[j].rv, w);
                        r.Normalize();
                        n.RotType = Animation.RotationType.QUATERNION;
                        n.XROT.Keys.Add(new Animation.KeyFrame(r.X, i));
                        n.YROT.Keys.Add(new Animation.KeyFrame(r.Y, i));
                        n.ZROT.Keys.Add(new Animation.KeyFrame(r.Z, i));
                        n.WROT.Keys.Add(new Animation.KeyFrame(r.W, i));
                    }

                    if (baseNode[j].s_type == KeyNode.INTERPOLATED)
                    {
                        float i1 = ((float)d.readShort() / (0xffff));
                        float i2 = ((float)d.readShort() / (0xffff));
                        float i3 = ((float)d.readShort() / (0xffff));

                        float x = baseNode[j].s.X + (baseNode[j].s2.X * (i1));
                        float y = baseNode[j].s.Y + (baseNode[j].s2.Y * (i2));
                        float z = baseNode[j].s.Z + (baseNode[j].s2.Z * (i3));

                        //node.s = new Vector3(x, y, z);
                        n.XSCA.Keys.Add(new Animation.KeyFrame(x, i));
                        n.YSCA.Keys.Add(new Animation.KeyFrame(y, i));
                        n.ZSCA.Keys.Add(new Animation.KeyFrame(z, i));
                    }
                    else
                    {
                        //node.s = baseNode[j].s;
                        n.XSCA.Keys.Add(new Animation.KeyFrame(baseNode[j].s.X, i));
                        n.YSCA.Keys.Add(new Animation.KeyFrame(baseNode[j].s.Y, i));
                        n.ZSCA.Keys.Add(new Animation.KeyFrame(baseNode[j].s.Z, i));
                    }
                }
            }

            return(a);
        }
예제 #14
0
        public static void read(string fname, SkelAnimation a, VBN v)
        {
            StreamReader reader = File.OpenText(fname);
            string       line;

            string   current = "";
            bool     readBones = false;
            int      frame = 0, prevframe = 0;
            KeyFrame k = new KeyFrame();

            VBN vbn = v;

            if (v.bones.Count == 0)
            {
                readBones = true;
            }
            else
            {
                vbn = new VBN();
            }

            while ((line = reader.ReadLine()) != null)
            {
                line = Regex.Replace(line, @"\s+", " ");
                string[] args = line.Replace(";", "").TrimStart().Split(' ');

                if (args[0].Equals("nodes") || args[0].Equals("skeleton") || args[0].Equals("end") || args[0].Equals("time"))
                {
                    current = args[0];
                    if (args.Length > 1)
                    {
                        prevframe = frame;
                        frame     = int.Parse(args[1]);

                        /*if (frame != prevframe + 1) {
                         *                              Console.WriteLine ("Needs interpolation " + frame);
                         *                      }*/

                        k       = new KeyFrame();
                        k.frame = frame;
                        a.addKeyframe(k);
                    }
                    continue;
                }

                if (current.Equals("nodes"))
                {
                    Bone b = new Bone(vbn);
                    b.Text        = args[1].Replace("\"", "");
                    b.parentIndex = int.Parse(args[2]);
                    //b.children = new System.Collections.Generic.List<int> ();
                    vbn.totalBoneCount++;
                    vbn.bones.Add(b);
                }

                if (current.Equals("time"))
                {
                    KeyNode n = new KeyNode();
                    n.id = v.boneIndex(vbn.bones[int.Parse(args[0])].Text);
                    if (n.id == -1)
                    {
                        continue;
                    }
                    else
                    {
                        n.hash = v.bones[n.id].boneId;
                    }

                    // only if it finds the node
                    k.addNode(n);

                    // reading the skeleton if this isn't an animation
                    if (readBones && frame == 0)
                    {
                        Bone b = vbn.bones[n.id];
                        b.position    = new float[3];
                        b.rotation    = new float[3];
                        b.scale       = new float[3];
                        b.position[0] = float.Parse(args[1]);
                        b.position[1] = float.Parse(args[2]);
                        b.position[2] = float.Parse(args[3]);
                        b.rotation[0] = float.Parse(args[4]);
                        b.rotation[1] = float.Parse(args[5]);
                        b.rotation[2] = float.Parse(args[6]);
                        b.scale[0]    = 1f;
                        b.scale[1]    = 1f;
                        b.scale[2]    = 1f;

                        b.pos = new Vector3(float.Parse(args[1]), float.Parse(args[2]), float.Parse(args[3]));
                        b.rot = VBN.FromEulerAngles(float.Parse(args[6]), float.Parse(args[5]), float.Parse(args[4]));

                        //if(b.parentIndex!=-1)
                        //	vbn.bones [b.parentIndex].children.Add (int.Parse(args[0]));
                    }

                    n.t_type = KeyNode.INTERPOLATED;
                    n.t      = new Vector3(float.Parse(args[1]), float.Parse(args[2]), float.Parse(args[3]));
                    n.r_type = KeyNode.INTERPOLATED;
                    n.r      = VBN.FromEulerAngles(float.Parse(args[6]), float.Parse(args[5]), float.Parse(args[4]));
                }
            }

            v.boneCountPerType[0] = (uint)vbn.bones.Count;
            v.update();
            a.bakeFramesLinear();
        }
예제 #15
0
        //<summary>
        //Open an animation based on filename
        //</summary>
        public void openAnimation(string filename)
        {
            //Runtime.Animations.Clear();
            if (filename.EndsWith(".mta"))
            {
                MTA mta = new MTA();
                try
                {
                    mta.Read(filename);
                    Runtime.MaterialAnimations.Add(filename, mta);
                    mtaNode.Nodes.Add(filename);
                    MainForm.Instance.viewports[0].loadMTA(mta);
                    Runtime.TargetMTAString = filename;
                }
                catch (EndOfStreamException)
                {
                    mta = null;
                }
            }
            else if (filename.EndsWith(".smd"))
            {
                var anim = new SkelAnimation();
                if (Runtime.TargetVBN == null)
                {
                    Runtime.TargetVBN = new VBN();
                }
                SMD.read(filename, anim, Runtime.TargetVBN);
                leftPanel.treeRefresh();
                Runtime.Animations.Add(filename, anim);
                animNode.Nodes.Add(filename);
            }
            else if (filename.EndsWith(".pac"))
            {
                PAC p = new PAC();
                p.Read(filename);

                foreach (var pair in p.Files)
                {
                    if (pair.Key.EndsWith(".omo"))
                    {
                        var    anim     = OMO.read(new FileData(pair.Value));
                        string AnimName = Regex.Match(pair.Key, @"([A-Z][0-9][0-9])(.*)").Groups[0].ToString();
                        //AnimName = pair.Key;
                        //AnimName = AnimName.Remove(AnimName.Length - 4);
                        //AnimName = AnimName.Insert(3, "_");
                        if (!string.IsNullOrEmpty(AnimName))
                        {
                            if (Runtime.Animations.ContainsKey(AnimName))
                            {
                                Runtime.Animations[AnimName].children.Add(anim);
                            }
                            else
                            {
                                animNode.Nodes.Add(AnimName);
                                Runtime.Animations.Add(AnimName, anim);
                            }
                        }
                        else
                        {
                            if (Runtime.Animations.ContainsKey(pair.Key))
                            {
                                Runtime.Animations[pair.Key].children.Add(anim);
                            }
                            else
                            {
                                animNode.Nodes.Add(pair.Key);
                                Runtime.Animations.Add(pair.Key, anim);
                            }
                        }
                    }
                    else if (pair.Key.EndsWith(".mta"))
                    {
                        MTA mta = new MTA();
                        try
                        {
                            if (!Runtime.MaterialAnimations.ContainsKey(pair.Key))
                            {
                                mta.read(new FileData(pair.Value));
                                Runtime.MaterialAnimations.Add(pair.Key, mta);
                                mtaNode.Nodes.Add(pair.Key);
                            }

                            // matching
                            string AnimName = Regex.Match(pair.Key, @"([A-Z][0-9][0-9])(.*)").Groups[0].ToString().Replace(".mta", ".omo");
                            if (Runtime.Animations.ContainsKey(AnimName))
                            {
                                Runtime.Animations[AnimName].children.Add(mta);
                            }
                        }
                        catch (EndOfStreamException)
                        {
                            mta = null;
                        }
                    }
                }
            }

            if (filename.EndsWith(".dat"))
            {
                if (!filename.EndsWith("AJ.dat"))
                {
                    MessageBox.Show("Not a DAT animation");
                }
                else
                {
                    if (Runtime.ModelContainers[0].dat_melee == null)
                    {
                        MessageBox.Show("Load a DAT model first");
                    }
                    else
                    {
                        DAT_Animation.LoadAJ(filename, Runtime.ModelContainers[0].dat_melee.bones);
                    }
                }
            }
            //if (Runtime.TargetVBN.bones.Count > 0)
            //{
            if (filename.EndsWith(".omo"))
            {
                Runtime.Animations.Add(filename, OMO.read(new FileData(filename)));
                animNode.Nodes.Add(filename);
            }
            if (filename.EndsWith(".chr0"))
            {
                Runtime.Animations.Add(filename, CHR0.read(new FileData(filename), Runtime.TargetVBN));
                animNode.Nodes.Add(filename);
            }
            if (filename.EndsWith(".anim"))
            {
                Runtime.Animations.Add(filename, ANIM.read(filename, Runtime.TargetVBN));
                animNode.Nodes.Add(filename);
            }
        }