public void Apply(VBN vbn, int frame) { if (frame == 0) { vbn.reset(); } OMOFrame keys = Frames[frame]; foreach (OMONode node in Nodes) { foreach (Bone b in vbn.bones) { if (b.boneId == node.hash) { // apply interpolation frames Console.WriteLine(b.Text); node.Apply(b, keys); break; } } } vbn.update(); }
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 void NextFrame(VBN skeleton, bool isChild = false) { if (Frame >= FrameCount) { return; } if (Frame == 0 && !isChild) { skeleton.reset(); } foreach (object child in Children) { if (child is Animation) { ((Animation)child).SetFrame(Frame); ((Animation)child).NextFrame(skeleton, isChild: true); } if (child is MTA) { //foreach (ModelContainer con in Runtime.ModelContainers) { if (((ModelContainer)skeleton.Parent).NUD != null) { ((ModelContainer)skeleton.Parent).NUD.ApplyMta(((MTA)child), (int)Frame); } } } if (child is BFRES.MTA) //For BFRES { { if (((ModelContainer)skeleton.Parent).BFRES != null) { ((ModelContainer)skeleton.Parent).BFRES.ApplyMta(((BFRES.MTA)child), (int)Frame); } } } } bool Updated = false; // no need to update skeleton of animations that didn't change foreach (KeyNode node in Bones) { // Get Skeleton Node Bone b = null; if (node.Hash == -1) { b = skeleton.getBone(node.Text); } else { b = skeleton.GetBone((uint)node.Hash); } if (b == null) { continue; } Updated = true; if (node.XPOS.HasAnimation() && b.boneType != 3) { b.pos.X = node.XPOS.GetValue(Frame); } if (node.YPOS.HasAnimation() && b.boneType != 3) { b.pos.Y = node.YPOS.GetValue(Frame); } if (node.ZPOS.HasAnimation() && b.boneType != 3) { b.pos.Z = node.ZPOS.GetValue(Frame); } if (node.XSCA.HasAnimation()) { b.sca.X = node.XSCA.GetValue(Frame); } else { b.sca.X = 1; } if (node.YSCA.HasAnimation()) { b.sca.Y = node.YSCA.GetValue(Frame); } else { b.sca.Y = 1; } if (node.ZSCA.HasAnimation()) { b.sca.Z = node.ZSCA.GetValue(Frame); } else { b.sca.Z = 1; } if (node.XROT.HasAnimation() || node.YROT.HasAnimation() || node.ZROT.HasAnimation()) { if (node.RotType == RotationType.QUATERNION) { KeyFrame[] x = node.XROT.GetFrame(Frame); KeyFrame[] y = node.YROT.GetFrame(Frame); KeyFrame[] z = node.ZROT.GetFrame(Frame); KeyFrame[] w = node.WROT.GetFrame(Frame); Quaternion q1 = new Quaternion(x[0].Value, y[0].Value, z[0].Value, w[0].Value); Quaternion q2 = new Quaternion(x[1].Value, y[1].Value, z[1].Value, w[1].Value); if (x[0].Frame == Frame) { b.rot = q1; } else if (x[1].Frame == Frame) { b.rot = q2; } else { b.rot = Quaternion.Slerp(q1, q2, (Frame - x[0].Frame) / (x[1].Frame - x[0].Frame)); } } else if (node.RotType == RotationType.EULER) { float x = node.XROT.HasAnimation() ? node.XROT.GetValue(Frame) : b.rotation[0]; float y = node.YROT.HasAnimation() ? node.YROT.GetValue(Frame) : b.rotation[1]; float z = node.ZROT.HasAnimation() ? node.ZROT.GetValue(Frame) : b.rotation[2]; b.rot = EulerToQuat(z, y, x); } } } Frame += 1f; if (Frame >= FrameCount) { Frame = 0; } if (!isChild && Updated) { skeleton.update(); } }
public void nextFrame(VBN vbn) { if (frame >= frames.Count) { return; } if (frame == 0 && Main) { vbn.reset(); foreach (ModelContainer con in Runtime.ModelContainers) { if (con.nud != null && con.mta != null) { con.nud.applyMTA(con.mta, 0); } } } if (children.Count > 0) { Main = true; } foreach (object child in children) { if (child is SkelAnimation) { ((SkelAnimation)child).setFrame(frame); ((SkelAnimation)child).nextFrame(vbn); } if (child is MTA) { foreach (ModelContainer con in Runtime.ModelContainers) { if (con.nud != null) { con.nud.applyMTA(((MTA)child), frame); } } } } KeyFrame key = frames[frame]; foreach (KeyNode n in key.nodes) { //if (n.id == -1) // continue; //if (n.hash == 0) { //continue; //n.hash = vbn.bones [n.id].boneId; //} int id = -1; foreach (Bone bo in vbn.bones) { if (bo.boneId == n.hash) { id = vbn.bones.IndexOf(bo); n.id = id; break; } } if (id == -1) { continue; } Bone b = vbn.bones[id]; if (n.t_type != -1) { b.pos = n.t; } if (n.r_type != -1) { //if(new string(b.boneName).Equals("HeadN")) // Console.WriteLine(n.r.ToString() + (n.r.X + n.r.Y + n.r.X + n.r.W)); //Console.WriteLine(new string(b.boneName) + " " + b.rot.ToString() + " " + n.r.ToString() + "\n" + (n.r.X + n.r.Y + n.r.X + n.r.W)); b.rot = n.r; } if (n.s_type != -1) { b.sca = n.s; } else { b.sca = new Vector3(b.scale[0], b.scale[1], b.scale[2]); } } frame++; if (frame >= frames.Count) { frame = 0; } vbn.update(); }
public void nextFrame(VBN vbn, bool isChild = false) { if (frame >= frames.Count) { return; } if (frame == 0 && (!isChild || children.Count > 0)) { vbn.reset(); foreach (ModelContainer con in Runtime.ModelContainers) { if (con.nud != null && con.mta != null) { con.nud.applyMTA(con.mta, 0); } } } foreach (object child in children) { if (child is SkelAnimation) { ((SkelAnimation)child).setFrame(frame); ((SkelAnimation)child).nextFrame(vbn, isChild: true); } if (child is MTA) { foreach (ModelContainer con in Runtime.ModelContainers) { if (con.nud != null) { con.nud.applyMTA(((MTA)child), frame); } } } } KeyFrame key = frames[frame]; foreach (KeyNode n in key.nodes) { //if (n.id == -1) // continue; //if (n.hash == 0) { //continue; //n.hash = vbn.bones [n.id].boneId; //} int id = -1; foreach (Bone bo in vbn.bones) { if (bo.boneId == n.hash) { id = vbn.bones.IndexOf(bo); n.id = id; break; } } if (id == -1) { continue; } Bone b = vbn.bones[id]; if (n.t_type != -1)// !b.isSwingBone) { b.pos = n.t; } // We don't do the same swingBone check on rotation because as of yet // I have not seen an example of the rotation data being garbage, and it's // actually used properly in the animations - Struz if (n.r_type != -1) { if (b.Text.Equals("HeadN")) { //Console.WriteLine(b.transform.ExtractRotation().ToString()); //Console.WriteLine(VBN.FromEulerAngles(b.rotation[0], b.rotation[1], b.rotation[2]).ToString()); //Console.WriteLine(n.r.ToString() + " " + Math.Sqrt(n.r.X* n.r.X + n.r.Y* n.r.Y + n.r.Z* n.r.Z + n.r.W*n.r.W) + " " + n.r.Normalized().ToString()); } //Console.WriteLine(new string(b.boneName) + " " + b.rot.ToString() + " " + n.r.ToString() + "\n" + (n.r.X + n.r.Y + n.r.X + n.r.W)); b.rot = n.r; } if (n.s_type != -1) { b.sca = n.s; } else { b.sca = new Vector3(b.scale[0], b.scale[1], b.scale[2]); } } frame++; if (frame >= frames.Count) { frame = 0; } vbn.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.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); } } a.FrameCount = frame; v.boneCountPerType[0] = (uint)vbn.bones.Count; v.update(); }
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 void NextFrame(VBN skeleton, bool isChild = false) { if (Frame == 0 && !isChild) { skeleton.reset(); } foreach (object child in Children) { if (child is Animation) { ((Animation)child).SetFrame(Frame); ((Animation)child).NextFrame(skeleton, isChild: true); } if (child is MTA) { foreach (ModelContainer con in Runtime.ModelContainers) { if (con.nud != null) { con.nud.applyMTA(((MTA)child), (int)Frame); } } } } foreach (KeyNode node in Bones) { // Get Skeleton Node Bone b = skeleton.getBone(node.Text); if (b == null) { continue; } if (node.XPOS.HasAnimation()) { b.pos.X = node.XPOS.GetValue(Frame); } if (node.YPOS.HasAnimation()) { b.pos.Y = node.YPOS.GetValue(Frame); } if (node.ZPOS.HasAnimation()) { b.pos.Z = node.ZPOS.GetValue(Frame); } if (node.XSCA.HasAnimation()) { b.sca.X = node.XSCA.GetValue(Frame); } else { b.sca.X = 1; } if (node.YSCA.HasAnimation()) { b.sca.Y = node.YSCA.GetValue(Frame); } else { b.sca.Y = 1; } if (node.ZSCA.HasAnimation()) { b.sca.Z = node.ZSCA.GetValue(Frame); } else { b.sca.Z = 1; } if (node.XROT.HasAnimation()) { if (node.RotType == RotationType.QUATERNION) { KeyFrame[] x = node.XROT.GetFrame(Frame); KeyFrame[] y = node.YROT.GetFrame(Frame); KeyFrame[] z = node.ZROT.GetFrame(Frame); KeyFrame[] w = node.WROT.GetFrame(Frame); Quaternion q1 = new Quaternion(x[0].Value, y[0].Value, z[0].Value, w[0].Value); Quaternion q2 = new Quaternion(x[1].Value, y[1].Value, z[1].Value, w[1].Value); if (x[0].Frame == Frame) { b.rot = q1; } else if (x[1].Frame == Frame) { b.rot = q2; } else { b.rot = Quaternion.Slerp(q1, q2, (Frame - x[0].Frame) / (x[1].Frame - x[0].Frame)); } } else if (node.RotType == RotationType.EULER) { float x = node.XROT.HasAnimation() ? node.XROT.GetValue(Frame) : b.rotation[0]; float y = node.YROT.HasAnimation() ? node.YROT.GetValue(Frame) : b.rotation[1]; float z = node.ZROT.HasAnimation() ? node.ZROT.GetValue(Frame) : b.rotation[2]; b.rot = EulerToQuat(z, y, x); } } } Frame += 1f; if (Frame >= FrameCount) { Frame = 0; } skeleton.update(); }
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); }