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()); }
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;"); } } } }
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(" }"); }
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); }