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); }
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(); }
public static void read(string fname, Animation 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 != null && 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); Animation.KeyNode node = new Animation.KeyNode(b.Text); a.Bones.Add(node); } if (current.Equals("time")) { //Animation.KeyFrame n = new Animation.KeyFrame(); /*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[int.Parse(args[0])]; 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].Nodes.Add(b); } } Animation.KeyNode bone = a.GetBone(vbn.bones[int.Parse(args[0])].Text); bone.RotType = Animation.RotationType.EULER; Animation.KeyFrame n = new Animation.KeyFrame(); n.Value = float.Parse(args[1]); n.Frame = frame; bone.XPOS.Keys.Add(n); n = new Animation.KeyFrame(); n.Value = float.Parse(args[2]); n.Frame = frame; bone.YPOS.Keys.Add(n); n = new Animation.KeyFrame(); n.Value = float.Parse(args[3]); n.Frame = frame; bone.ZPOS.Keys.Add(n); n = new Animation.KeyFrame(); n.Value = float.Parse(args[4]); n.Frame = frame; bone.XROT.Keys.Add(n); n = new Animation.KeyFrame(); n.Value = float.Parse(args[5]); n.Frame = frame; bone.YROT.Keys.Add(n); n = new Animation.KeyFrame(); n.Value = float.Parse(args[6]); n.Frame = frame; bone.ZROT.Keys.Add(n); if (args.Length > 7) { n = new Animation.KeyFrame(); n.Value = float.Parse(args[7]); n.Frame = frame; bone.XSCA.Keys.Add(n); n = new Animation.KeyFrame(); n.Value = float.Parse(args[8]); n.Frame = frame; bone.YSCA.Keys.Add(n); n = new Animation.KeyFrame(); n.Value = float.Parse(args[9]); n.Frame = frame; bone.ZSCA.Keys.Add(n); } } } a.FrameCount = frame; vbn.boneCountPerType[0] = (uint)vbn.bones.Count; vbn.update(); }
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); }
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); }
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(); }
public static void toBFRES(string fname) { StreamReader reader = File.OpenText(fname); string line; string current = ""; bool readBones = false; int frame = 0, prevframe = 0; string Text = ""; readBones = true; 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]); } continue; } if (current.Equals("nodes")) { Text = args[1].Replace("\"", ""); } if (current.Equals("time")) { BFRES.NewBonePos bn = new BFRES.NewBonePos(); float positionX = float.Parse(args[1]); float positionY = float.Parse(args[2]); float positionZ = float.Parse(args[3]); float rotX = float.Parse(args[4]); float rotY = float.Parse(args[5]); float rotZ = float.Parse(args[6]); float scaleX = 1f; float scaleY = 1f; float scaleZ = 1f; bn.scale = new Vector3(1); bn.pos = new Vector3(float.Parse(args[1]), float.Parse(args[2]), float.Parse(args[3])); bn.rot = new Vector3(MathHelper.DegreesToRadians(rotX), MathHelper.DegreesToRadians(rotY), MathHelper.DegreesToRadians(rotZ)); Quaternion rot = VBN.FromEulerAngles(float.Parse(args[6]), float.Parse(args[5]), float.Parse(args[4])); bn.Name = Text; foreach (var defbn in BFRES.HackyBoneList) { if (defbn.Name == Text) { bn.pos.X = bn.pos.X + -defbn.pos.X; bn.pos.Y = bn.pos.Y + -defbn.pos.Y; bn.pos.Z = bn.pos.Z + -defbn.pos.Z; bn.rot.X = bn.rot.X + -defbn.rot.X; bn.rot.Y = bn.rot.Y + -defbn.rot.Y; bn.rot.Z = bn.rot.Z + -defbn.rot.Z; } } BFRES.HackyBoneDiffList.Add(bn); } } }
public VBN GetVBN(FileData d) { VBN v = new VBN(); d.Endian = Endianness.Big; d.seek(8); int ver = d.readInt(); d.skip(4); //outer offset to brres int boneHeader = 0x40; // for version 9 only int dlist = d.readInt(); int boneSec = d.readInt(); int vertSec = d.readInt(); int normSec = d.readInt(); int colrSec = d.readInt(); int texcSec = d.readInt(); d.skip(8); int polySec = d.readInt(); d.seek(0x40); d.skip(16); int vertCount = d.readInt(); int faceCount = d.readInt(); d.skip(4); int boneCount = d.readInt(); v.totalBoneCount = (uint)boneCount; for (int i = 0; i < 3; i++) { v.boneCountPerType[i + 1] = 0; } d.skip(4); int bonetableoff = d.readInt() + boneHeader; d.seek(bonetableoff); int bcount = d.readInt(); int[] nodeIndex = new int[bcount]; for (int i = 0; i < bcount; i++) { nodeIndex[i] = d.readInt(); } Random rng = new Random(); uint boneID = (uint)rng.Next(1, 0xFFFFFF); // BONES----------------------------------------------- d.seek(boneSec); d.skip(4); // length int bseccount = d.readInt(); for (int i = 0; i < bseccount; i++) { Debug.Write(i); d.skip(4); // entry id and unknown d.skip(4); // left and right index int name = d.readInt() + boneSec; int data = d.readInt() + boneSec; int temp = d.pos(); if (name != boneSec && data != boneSec) { // read bone data d.seek(data); d.skip(8); int nameOff = d.readInt() + data; int index = d.readInt(); // id d.skip(4); // index d.skip(8); // idk billboard settings and padding Bone n = new Bone(v); n.scale = new float[3]; n.position = new float[3]; n.rotation = new float[3]; d.skip(4); // index n.scale[0] = d.readFloat(); n.scale[1] = d.readFloat(); n.scale[2] = d.readFloat(); n.rotation[0] = toRadians(d.readFloat()); n.rotation[1] = toRadians(d.readFloat()); n.rotation[2] = toRadians(d.readFloat()); n.position[0] = d.readFloat(); n.position[1] = d.readFloat(); n.position[2] = d.readFloat(); n.pos = new Vector3(n.position[0], n.position[1], n.position[2]); n.sca = new Vector3(n.scale[0], n.scale[1], n.scale[2]); n.rot = (VBN.FromEulerAngles(n.rotation [2], n.rotation [1], n.rotation [0])); d.skip(24); d.seek(data + 0x5C); d.seek(d.readInt() + data + 12); int parentid = 0x0FFFFFFF; if (d.pos() != data + 12) { parentid = d.readInt(); } n.parentIndex = (int)parentid; n.boneName = d.readString(nameOff, -1).ToCharArray(); n.boneId = boneID; boneID++; v.bones.Add(n); } else { bseccount++; } d.seek(temp); } v.update(); //v.updateChildren(); v.boneCountPerType[0] = (uint)v.bones.Count; return(v); }
public static void DrawVBN(VBN vbn) { if (vbn != null && Runtime.renderBones) { foreach (Bone bone in vbn.bones) { // first calcuate the point and draw a point if (bone == BoneTreePanel.selectedBone) { GL.Color3(Color.Red); } else { GL.Color3(Color.GreenYellow); } Vector3 pos_c = Vector3.Transform(Vector3.Zero, bone.transform); RenderTools.drawCube(pos_c, .085f); // if swing bones then draw swing radius if (vbn.swingBones.bones.Count > 0 && Runtime.renderSwag) { SB.SBEntry sb = null; vbn.swingBones.TryGetEntry(bone.boneId, out sb); if (sb != null) { // draw if (bone.ParentBone != null) { int i = bone.parentIndex; float degtorad = (float)(Math.PI / 180); Vector3 pos_sb = Vector3.Transform(Vector3.Zero, Matrix4.CreateTranslation(new Vector3(3, 3, 3)) * Matrix4.CreateScale(bone.sca) * Matrix4.CreateFromQuaternion(VBN.FromEulerAngles(sb.rx1 * degtorad, sb.ry1 * degtorad, sb.rz1 * degtorad)) * Matrix4.CreateTranslation(bone.pos) * vbn.bones[i].transform); Vector3 pos_sb2 = Vector3.Transform(Vector3.Zero, Matrix4.CreateTranslation(new Vector3(3, 3, 3)) * Matrix4.CreateScale(bone.sca) * Matrix4.CreateFromQuaternion(VBN.FromEulerAngles(sb.rx2 * degtorad, sb.ry2 * degtorad, sb.rz2 * degtorad)) * Matrix4.CreateTranslation(bone.pos) * vbn.bones[i].transform); GL.Color3(Color.ForestGreen); GL.Begin(PrimitiveType.LineLoop); GL.Vertex3(pos_c); GL.Vertex3(pos_sb); GL.Vertex3(pos_sb2); GL.End(); } } } // now draw line between parent GL.Color3(Color.LightBlue); GL.LineWidth(2f); GL.Begin(PrimitiveType.Lines); if (bone.ParentBone != null) { Vector3 pos_p = Vector3.Transform(Vector3.Zero, bone.ParentBone.transform); GL.Vertex3(pos_c); GL.Color3(Color.Blue); GL.Vertex3(pos_p); } GL.End(); } } }
public void Read(string fname) { StreamReader reader = File.OpenText(fname); string line; string current = ""; Bones = new VBN(); Triangles = new List <SMDTriangle>(); Dictionary <int, Bone> BoneList = new Dictionary <int, Bone>(); int time = 0; while ((line = reader.ReadLine()) != null) { line = Regex.Replace(line, @"\s+", " "); string[] args = line.Replace(";", "").TrimStart().Split(' '); if (args[0].Equals("triangles") || args[0].Equals("end") || args[0].Equals("skeleton") || args[0].Equals("nodes")) { current = args[0]; continue; } if (current.Equals("nodes")) { int id = int.Parse(args[0]); Bone b = new Bone(Bones); b.Text = args[1].Replace('"', ' ').Trim(); int s = 2; while (args[s].Contains("\"")) { b.Text += args[s++]; } b.parentIndex = int.Parse(args[s]); BoneList.Add(id, b); } if (current.Equals("skeleton")) { if (args[0].Contains("time")) { time = int.Parse(args[1]); } else { if (time == 0) { Bone b = BoneList[int.Parse(args[0])]; 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])); Bones.bones.Add(b); if (b.parentIndex != -1) { b.parentIndex = Bones.bones.IndexOf(BoneList[b.parentIndex]); } } } } if (current.Equals("triangles")) { string meshName = args[0]; if (args[0].Equals("")) { continue; } SMDTriangle t = new SMDTriangle(); Triangles.Add(t); t.Material = meshName; for (int j = 0; j < 3; j++) { line = reader.ReadLine(); line = Regex.Replace(line, @"\s+", " "); args = line.Replace(";", "").TrimStart().Split(' '); int parent = int.Parse(args[0]); SMDVertex vert = new SMDVertex(); vert.P = new Vector3(float.Parse(args[1]), float.Parse(args[2]), float.Parse(args[3])); vert.N = new Vector3(float.Parse(args[4]), float.Parse(args[5]), float.Parse(args[6])); vert.UV = new Vector2(float.Parse(args[7]), float.Parse(args[8])); vert.Bones = new int[0]; vert.Weights = new float[0]; if (args.Length > 9) { int wCount = int.Parse(args[9]); int w = 10; vert.Bones = new int[wCount]; vert.Weights = new float[wCount]; for (int i = 0; i < wCount; i++) { vert.Bones[i] = (int.Parse(args[w++])); vert.Weights[i] = (float.Parse(args[w++])); } } switch (j) { case 0: t.v1 = vert; break; case 1: t.v2 = vert; break; case 2: t.v3 = vert; break; } } } } Bones.reset(); }
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 i4 = ((float)d.readShort() / (0xffff)); float i1 = ((float)d.readShort() / (0xffff)); float i2 = ((float)d.readShort() / (0xffff)); float i3 = ((float)d.readShort() / (0xffff)); node.r = new Quaternion(new Vector3(i1, i2, i3), i4); 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); }