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); }
/* * 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); } } }
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); }