Esempio n. 1
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);
        }
Esempio n. 2
0
        public void Apply(VBN bone)
        {
            for (int i = 0; i < nodes.Count; i++)
            {
                List <AnimType> used = new List <AnimType>();

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

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

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

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

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

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

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

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

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

            bone.update();
        }
Esempio n. 3
0
        public KeyNode getNode(int i)
        {
            for (int j = 0; j < nodes.Count; j++)
            {
                if (nodes[j].id == i)
                {
                    return(nodes[j]);
                }
            }

            KeyNode ne = new KeyNode();

            ne.id = i;

            addNode(ne);

            return(ne);
        }
Esempio n. 4
0
        /*
         * TODO: Fix this
         * the key frame needs to check if it occurs within a time frame AND
         * it has the node it is looking for
         */
        public void bakeFramesLinear()
        {
            List <int>      nodeids     = getNodes(false);
            List <KeyFrame> base_frames = frames;

            frames = new List <KeyFrame>();
            int fCount = 0;

            foreach (KeyFrame k in base_frames)
            {
                if (k.frame > fCount)
                {
                    fCount = k.frame;
                }
            }


            for (int i = 0; i < fCount; i++)
            {
                KeyFrame k = new KeyFrame();
                k.frame = i;
                frames.Add(k);

                // add all the nodes at this frame
                foreach (int id in nodeids)
                {
                    KeyFrame f1 = base_frames[0], f2 = base_frames[0];

                    if (base_frames.Count > 1)
                    {
                        for (int j = 0; j < base_frames.Count - 1; j++)
                        {
                            if (base_frames[j].frame <= i && base_frames[j + 1].frame >= i &&
                                base_frames[j].contains(id) && base_frames[j + 1].contains(id))
                            {
                                f1 = base_frames[j];
                                f2 = base_frames[j + 1];
                                break;
                            }
                        }
                    }

                    // interpolate the values
                    KeyNode n = new KeyNode();
                    n.id = id;

                    KeyNode k1 = f1.getNodeid(id), k2 = f2.getNodeid(id);
                    n.hash = k1.hash;

                    n.t_type = k1.t_type;
                    n.r_type = k1.r_type;
                    n.s_type = k1.s_type;

                    n.t.X = lerp(k1.t.X, k2.t.X, f1.frame, f2.frame, i);
                    n.t.Y = lerp(k1.t.Y, k2.t.Y, f1.frame, f2.frame, i);
                    n.t.Z = lerp(k1.t.Z, k2.t.Z, f1.frame, f2.frame, i);

                    n.r.X = lerp(k1.r.X, k2.r.X, f1.frame, f2.frame, i);
                    n.r.Y = lerp(k1.r.Y, k2.r.Y, f1.frame, f2.frame, i);
                    n.r.Z = lerp(k1.r.Z, k2.r.Z, f1.frame, f2.frame, i);
                    n.r.W = lerp(k1.r.W, k2.r.W, f1.frame, f2.frame, i);

                    //n.s.X = lerp (k1.s.X, k2.s.X, f1.frame, f2.frame, i);
                    //n.s.Y = lerp (k1.s.Y, k2.s.Y, f1.frame, f2.frame, i);
                    //n.s.Z = lerp (k1.s.Z, k2.s.Z, f1.frame, f2.frame, i);


                    k.addNode(n);
                }
            }
        }
Esempio n. 5
0
 public void addNode(KeyNode n)
 {
     nodes.Add(n);
 }
Esempio n. 6
0
        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);
        }
Esempio n. 7
0
        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());
        }
Esempio n. 8
0
        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);
        }
Esempio n. 9
0
        public void readKeyFrame(FileData d, int length, int dataoff, int valueFormat, int tanFormat, int keyframeCount, int boneId, int trackType)
        {
            int temp = d.pos();

            d.seek(dataoff);

            if (Debug)
            {
                Console.WriteLine("Start 0x" + d.pos() + " " + keyframeCount);
            }

            DATAnimTrack track = new DATAnimTrack();

            track.type = (AnimType)trackType;
            nodes[boneId].Add(track);

            while (d.pos() < dataoff + length)
            {
                int type = readExtendedByte(d);

                int interpolation = ((type) & 0x0F);
                int numOfKey      = ((type >> 4) & 0xFF) + 1;

                if (Debug)
                {
                    Console.WriteLine("Interpolation type: " + (InterpolationType)interpolation + "\tnumofkey: " + numOfKey);
                }

                for (int i = 0; i < numOfKey; i++)
                {
                    double value = -99, tan = -99;
                    int    time = 0;
                    if (interpolation == 1)
                    { // step
                        value = readVal(d, valueFormat);
                        time  = readExtendedByte(d);
                        if (Debug)
                        {
                            Console.WriteLine("\t" + value + "\t" + time);
                        }
                    }
                    if (interpolation == 2)
                    { // linear
                        value = readVal(d, valueFormat);
                        time  = readExtendedByte(d);
                        //Console.WriteLine("\t" + value + "\t" + time);
                    }
                    if (interpolation == 3)
                    { // hermite
                        value = readVal(d, valueFormat);
                        tan   = 0;
                        time  = readExtendedByte(d);
                        if (Debug)
                        {
                            Console.WriteLine("\t" + value + "\t" + time);
                        }
                    }
                    if (interpolation == 4)
                    { // hermite
                        value = readVal(d, valueFormat);
                        tan   = readVal(d, tanFormat);
                        time  = readExtendedByte(d);
                        if (Debug)
                        {
                            Console.WriteLine("\t" + value + "\t" + tan + "\t" + time);
                        }
                    }
                    if (interpolation == 5)
                    { // hermite
                        tan = readVal(d, tanFormat);
                        if (Debug)
                        {
                            Console.WriteLine("\t" + "Tan" + tan);
                        }
                    }
                    if (interpolation == 6)
                    { // constant
                        value = readVal(d, valueFormat);
                        time  = readExtendedByte(d);
                        //Console.WriteLine("\t" + value + "\t" + time);
                    }

                    KeyNode node = new KeyNode();
                    node.value             = (float)value;
                    node.frame             = time;
                    node.tan               = (float)tan;
                    node.interpolationType = (InterpolationType)interpolation;
                    track.keys.Add(node);
                    //node.boneID = boneId;
                }
                d.Endian = System.IO.Endianness.Big;
            }
            //Console.WriteLine("Ends at: " + (d.pos() + 8 - (d.pos() % 8)).ToString("x"));

            d.seek(temp);
        }
Esempio n. 10
0
        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;");
                    }
                }
            }
        }
Esempio n. 11
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;
                }
            }
        }
Esempio n. 12
0
        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);
        }
Esempio n. 13
0
        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);
        }
Esempio n. 14
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);
        }
Esempio n. 15
0
        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(" }");
        }
Esempio n. 16
0
        public static void MakePichu(string path = "C:\\Pichu\\")
        {
            if (!path.EndsWith("\\"))
            {
                path += "\\";
            }
            DAT dat = new DAT();

            dat.Read(new FileData(path + "PlPcNr.dat"));
            dat.PreRender();

            dat.ExportTextures(path, 0x401B1000);

            BoneNameFix(dat.bones);

            // model--------------------------------------------------------
            ModelContainer converted = dat.wrapToNUD();
            NUD            nud       = converted.NUD;
            float          sca       = 0.6f;


            removeLowPolyNr(nud);
            nud.UpdateRenderMeshes();

            //Runtime.ModelContainers.Add(converted);
            //-------------------------------------------------

            Runtime.TargetVBN = converted.VBN;

            MainForm.HashMatch();

            Dictionary <string, SkelAnimation> anims = DAT_Animation.LoadAJ(path + "PlPcAJ.dat", converted.VBN);

            //ArrangeBones(converted.vbn, converted.nud);

            // note bone 40 - 51 is disabled for pika

            foreach (string an in anims.Keys)
            {
                effectiveScale(anims[an], Matrix4.CreateTranslation(0, 0, 0) * Matrix4.CreateScale(sca, sca, sca));
            }
            effectiveScale(converted.NUD, converted.VBN, Matrix4.CreateTranslation(0, 0, 0) * Matrix4.CreateScale(sca, sca, sca));

            Directory.CreateDirectory(path + "build\\model\\body\\c00\\");
            nud.Save(path + "build\\model\\body\\c00\\model.nud");
            converted.VBN.Endian = Endianness.Little;
            converted.VBN.Save(path + "build\\model\\body\\c00\\model.vbn");


            PAC org  = new PAC();
            PAC npac = new PAC();

            org.Read(path + "main.pac");
            foreach (string key in org.Files.Keys)
            {
                byte[] d = org.Files[key];

                foreach (string an in anims.Keys)
                {
                    string name = an.Replace("PlyPichu5K_Share_ACTION_", "").Replace("_figatree", "");
                    if (key.Contains(name))
                    {
                        Console.WriteLine("Matched " + name + " with " + key);

                        if (!anims[an].getNodes(true).Contains(0) && !key.Contains("Cliff"))
                        {
                            KeyNode node = anims[an].getNode(0, 0);
                            node.t_type = 1;
                        }
                        d = OMOOld.createOMO(anims[an], converted.VBN);
                        break;
                    }
                }

                npac.Files.Add(key, d);
            }
            Directory.CreateDirectory(path + "build\\motion\\");
            npac.Save(path + "build\\motion\\main.pac");

            /*FileOutput omo = new FileOutput();
             * converted.vbn.reset();
             * converted.vbn.totalBoneCount = (uint)converted.vbn.bones.Count;
             * omo.writeBytes(OMO.createOMO(anims["PlyPichu5K_Share_ACTION_Wait1_figatree"], converted.vbn));
             * omo.save(path + "PlyPichu5K_Share_ACTION_Wait1_figatree.omo");*/
        }
Esempio n. 17
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();
        }