// I'm completely totally serious public static Nud Create(VBN vbn) { Dictionary <string, string> files = new Dictionary <string, string>(); ZipArchive zip = ZipFile.OpenRead("lib\\Skapon.zip"); Random random = new Random(); int randomNumber = random.Next(0, 0xFFFFFF); NUT nut = new NUT(); foreach (ZipArchiveEntry e in zip.Entries) { byte[] b; using (BinaryReader br = new BinaryReader(e.Open())) { b = br.ReadBytes((int)e.Length); } var stream = new StreamReader(new MemoryStream(b)); string s = stream.ReadToEnd(); files.Add(e.Name, s); if (e.Name.EndsWith(".dds")) { NutTexture tex = new Dds(new FileData(b)).ToNutTexture(); nut.Nodes.Add(tex); tex.HashId = 0x40000000 + randomNumber; nut.glTexByHashId.Add(tex.HashId, NUT.CreateTexture2D(tex)); } } Nud nud = new Nud(); Nud.Mesh head = new Nud.Mesh(); nud.Nodes.Add(head); head.Text = "Skapon"; head.Nodes.Add(setToBone(scale(readPoly(files["head.obj"]), 1, 1, 1), vbn.bones[vbn.boneIndex("HeadN")], vbn)); head.Nodes.Add(setToBone(scale(readPoly(files["body.obj"]), 1, 1, 1), vbn.bones[vbn.boneIndex("BustN")], vbn)); head.Nodes.Add(setToBone(scale(readPoly(files["hand.obj"]), 1, 1, 1), vbn.bones[vbn.boneIndex("RHandN")], vbn)); head.Nodes.Add(setToBone(scale(readPoly(files["hand.obj"]), -1, -1, 1), vbn.bones[vbn.boneIndex("LHandN")], vbn)); head.Nodes.Add(setToBone(scale(readPoly(files["foot.obj"]), 1, 1, 1), vbn.bones[vbn.boneIndex("RFootJ")], vbn)); head.Nodes.Add(setToBone(scale(readPoly(files["foot.obj"]), -1, -1, -1), vbn.bones[vbn.boneIndex("LFootJ")], vbn)); foreach (Nud.Polygon p in head.Nodes) { p.materials[0].textures[0].hash = 0x40000000 + randomNumber; } nud.UpdateRenderMeshes(); return(nud); }
public static Nud.Polygon setToBone(Nud.Polygon poly, Bone b, VBN vbn) { foreach (Nud.Vertex v in poly.vertices) { v.boneIds.Clear(); v.boneIds.Add(vbn.bones.IndexOf(b)); Vector3 newpos = Vector3.TransformVector(Vector3.Zero, b.transform); v.pos += newpos; } return(poly); }
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(); }
// temp stuff public static Dictionary <string, SkelAnimation> LoadAJ(string fname, VBN vbn) { // a note, I know that the main player file has the offsets for // animations, this is just for viewing FileData f = new FileData(fname); f.endian = System.IO.Endianness.Big; int pos = 0; Dictionary <string, SkelAnimation> animations = new Dictionary <string, SkelAnimation>(); AnimationGroupNode group = new AnimationGroupNode() { Text = fname }; MainForm.Instance.animList.treeView1.Nodes.Add(group); while (pos < f.Size()) { Console.WriteLine(pos.ToString("x")); int len = f.ReadInt(); DAT_Animation anim = new DAT_Animation(); anim.Read(new FileData(f.GetSection(pos, len))); AnimTrack track = new AnimTrack(anim); if (pos == 0) { //track.Show(); } group.Nodes.Add(track.ToAnimation(vbn)); SkelAnimation sa = track.BakeToSkel(vbn); //sa.Tag = track; //Runtime.Animations.Add(anim.Name, sa); // MainForm.Instance.animList.treeView1.Nodes.Add(anim.Name); animations.Add(anim.Name, sa); if (pos != 0) { track.Dispose(); track.Close(); } f.Skip(len - 4); f.Align(32); pos = f.Pos(); } return(animations); }
public static Animation read(FileData d, VBN m) { d.endian = Endianness.Big; d.Seek(0x8); int versionNum = d.ReadInt(); d.Seek(0x10); if (versionNum == 4) { return(readAnim(d, m)); } return(null); }
public bool essentialComparison(VBN compareTo) { // Because I don't want to override == just for a cursory bone comparison if (this.bones.Count != compareTo.bones.Count) { return(false); } for (int i = 0; i < this.bones.Count; i++) { if (this.bones[i].Name != compareTo.bones[i].Name) { return(false); } if (this.bones[i].pos != compareTo.bones[i].pos) { return(false); } } return(true); }
public float GetBaseNodeValue(int nid, String type, VBN vbn) { //UNSAFE: Hacky fix if (nid == -1) { return(0); } switch (type) { case "X": return(vbn.bones[nid].position[0]); case "Y": return(vbn.bones[nid].position[1]); case "Z": return(vbn.bones[nid].position[2]); case "RX": return(vbn.bones[nid].rotation[0]); case "RY": return(vbn.bones[nid].rotation[1]); case "RZ": return(vbn.bones[nid].rotation[2]); case "SX": return(vbn.bones[nid].scale[0]); case "SY": return(vbn.bones[nid].scale[1]); case "SZ": return(vbn.bones[nid].scale[2]); } return(0); }
public static void Save(Animation anim, VBN skeleton, String fname) { using (System.IO.StreamWriter file = new System.IO.StreamWriter(fname)) { file.WriteLine("version 1"); file.WriteLine("nodes"); foreach (Bone b in skeleton.bones) { file.WriteLine(skeleton.bones.IndexOf(b) + " \"" + b.Text + "\" " + b.parentIndex); } file.WriteLine("end"); file.WriteLine("skeleton"); anim.SetFrame(0); for (int i = 0; i <= anim.frameCount; i++) { anim.NextFrame(skeleton); file.WriteLine("time " + i); foreach (Animation.KeyNode sb in anim.bones) { Bone b = skeleton.getBone(sb.Text); if (b == null) { continue; } Vector3 eul = ANIM.quattoeul(b.rot); file.WriteLine(skeleton.bones.IndexOf(b) + " " + b.pos.X + " " + b.pos.Y + " " + b.pos.Z + " " + eul.X + " " + eul.Y + " " + eul.Z); } } file.WriteLine("end"); file.Close(); } }
public static void effectiveScale(Nud nud, VBN vbn, Matrix4 sca) { foreach (Bone b in vbn.bones) { Vector3 pos = Vector3.TransformVector(new Vector3(b.position[0], b.position[1], b.position[2]), sca); b.position[0] = pos.X; b.position[1] = pos.Y; b.position[2] = pos.Z; } vbn.reset(); foreach (Nud.Mesh mesh in nud.Nodes) { foreach (Nud.Polygon poly in mesh.Nodes) { foreach (Nud.Vertex v in poly.vertices) { v.pos = Vector3.TransformVector(v.pos, sca); } } } nud.UpdateRenderMeshes(); }
public FsklTreePanel(VBN vbn) : this() { this.vbn = vbn; TreeRefresh(); }
public static Animation read(string filename, VBN vbn) { Animation a = new Animation(filename); Animation.KeyNode current = null; Animation.KeyFrame att = new Animation.KeyFrame(); StreamReader reader = File.OpenText(filename); string line; AnimHeader header = new AnimHeader(); bool inHeader = true; bool inKeys = false; string type = ""; while ((line = reader.ReadLine()) != null) { string[] args = line.Replace(";", "").TrimStart().Split(' '); if (inHeader) { if (args[0].Equals("anim")) { inHeader = false; } else if (args[0].Equals("animVersion")) { header.animVersion = args[1]; } else if (args[0].Equals("mayaVersion")) { header.mayaVersion = args[1]; } else if (args[0].Equals("startTime")) { header.startTime = float.Parse(args[1]); } else if (args[0].Equals("endTime")) { header.endTime = float.Parse(args[1]); } else if (args[0].Equals("startUnitless")) { header.startUnitless = float.Parse(args[1]); } else if (args[0].Equals("endUnitless")) { header.endUnitless = float.Parse(args[1]); } else if (args[0].Equals("timeUnit")) { header.timeUnit = args[1]; } else if (args[0].Equals("linearUnit")) { header.linearUnit = args[1]; } else if (args[0].Equals("angularUnit")) { header.angularUnit = args[1]; } } if (!inHeader) { if (inKeys) { if (args[0].Equals("}")) { inKeys = false; continue; } Animation.KeyFrame k = new Animation.KeyFrame(); //att.keys.Add (k); if (type.Contains("translate")) { if (type.Contains("X")) { current.xpos.keys.Add(k); } if (type.Contains("Y")) { current.ypos.keys.Add(k); } if (type.Contains("Z")) { current.zpos.keys.Add(k); } } if (type.Contains("rotate")) { if (type.Contains("X")) { current.xrot.keys.Add(k); } if (type.Contains("Y")) { current.yrot.keys.Add(k); } if (type.Contains("Z")) { current.zrot.keys.Add(k); } } if (type.Contains("scale")) { if (type.Contains("X")) { current.xsca.keys.Add(k); } if (type.Contains("Y")) { current.ysca.keys.Add(k); } if (type.Contains("Z")) { current.zsca.keys.Add(k); } } k.Frame = float.Parse(args[0]) - 1; k.Value = float.Parse(args[1]); if (type.Contains("rotate")) { k.Value *= (float)(Math.PI / 180f); } //k.intan = (args [2]); //k.outtan = (args [3]); if (args.Length > 7 && att.weighted) { k.In = float.Parse(args[7]) * (float)(Math.PI / 180f); k.Out = float.Parse(args[8]) * (float)(Math.PI / 180f); } } 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 (Animation.KeyNode b in a.bones) { if (b.Text.Equals(args[3])) { current = b; break; } } if (current == null) { current = new Animation.KeyNode(args[3]); current.rotType = Animation.RotationType.Euler; a.bones.Add(current); } current.Text = args[3]; att = new Animation.KeyFrame(); att.interType = Animation.InterpolationType.Hermite; type = args[2]; //current.Nodes.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 ("preInfinity")) * att.preInfinity = args [1]; * if (args [0].Equals ("postInfinity")) * att.postInfinity = args [1];*/ if (args[0].Equals("weighted")) { att.weighted = args[1].Equals("1"); } // begining keys section if (args[0].Contains("keys")) { inKeys = true; } } } int startTime = (int)Math.Ceiling(header.startTime); int endTime = (int)Math.Ceiling(header.endTime); a.frameCount = (endTime + 1) - startTime; reader.Close(); return(a); }
public static void CreateANIM(string fname, Animation a, VBN vbn) { using (System.IO.StreamWriter file = new System.IO.StreamWriter(@fname)) { AnimHeader header = new AnimHeader(); file.WriteLine("animVersion " + header.animVersion + ";"); file.WriteLine("mayaVersion " + header.mayaVersion + ";"); file.WriteLine("timeUnit " + header.timeUnit + ";"); file.WriteLine("linearUnit " + header.linearUnit + ";"); file.WriteLine("angularUnit " + header.angularUnit + ";"); file.WriteLine("startTime " + 1 + ";"); file.WriteLine("endTime " + a.frameCount + ";"); a.SetFrame(a.frameCount - 1); //from last frame for (int li = 0; li < a.frameCount; ++li) //go through each frame with nextFrame { a.NextFrame(vbn); } a.NextFrame(vbn); //go on first frame int i = 0; // writing node attributes foreach (Bone b in vbn.getBoneTreeOrder()) { i = vbn.boneIndex(b.Text); if (a.HasBone(b.Text)) { // write the bone attributes // count the attributes Animation.KeyNode n = a.GetBone(b.Text); int ac = 0; if (n.xpos.HasAnimation()) { file.WriteLine("anim translate.translateX translateX " + b.Text + " 0 0 " + (ac++) + ";"); writeKey(file, n.xpos, n, a.Size(), "translateX"); file.WriteLine("}"); } if (n.ypos.HasAnimation()) { file.WriteLine("anim translate.translateY translateY " + b.Text + " 0 0 " + (ac++) + ";"); writeKey(file, n.ypos, n, a.Size(), "translateY"); file.WriteLine("}"); } if (n.zpos.HasAnimation()) { file.WriteLine("anim translate.translateZ translateZ " + b.Text + " 0 0 " + (ac++) + ";"); writeKey(file, n.zpos, n, a.Size(), "translateZ"); file.WriteLine("}"); } if (n.xrot.HasAnimation()) { file.WriteLine("anim rotate.rotateX rotateX " + b.Text + " 0 0 " + (ac++) + ";"); writeKey(file, n.xrot, n, a.Size(), "rotateX"); file.WriteLine("}"); } if (n.yrot.HasAnimation()) { file.WriteLine("anim rotate.rotateY rotateY " + b.Text + " 0 0 " + (ac++) + ";"); writeKey(file, n.yrot, n, a.Size(), "rotateY"); file.WriteLine("}"); } if (n.zrot.HasAnimation()) { file.WriteLine("anim rotate.rotateZ rotateZ " + b.Text + " 0 0 " + (ac++) + ";"); writeKey(file, n.zrot, n, a.Size(), "rotateZ"); file.WriteLine("}"); } if (n.xsca.HasAnimation()) { file.WriteLine("anim scale.scaleX scaleX " + b.Text + " 0 0 " + (ac++) + ";"); writeKey(file, n.xsca, n, a.Size(), "scaleX"); file.WriteLine("}"); } if (n.ysca.HasAnimation()) { file.WriteLine("anim scale.scaleY scaleY " + b.Text + " 0 0 " + (ac++) + ";"); writeKey(file, n.ysca, n, a.Size(), "scaleY"); file.WriteLine("}"); } if (n.zsca.HasAnimation()) { file.WriteLine("anim scale.scaleZ scaleZ " + b.Text + " 0 0 " + (ac++) + ";"); writeKey(file, n.zsca, n, a.Size(), "scaleZ"); file.WriteLine("}"); } if (ac == 0) { file.WriteLine("anim " + b.Text + " 0 0 0;"); } } else { file.WriteLine("anim " + b.Text + " 0 0 0;"); } } } }
public static byte[] CreateOMOFromAnimation(Animation a, VBN vbn) { if (vbn == null || a == null) { return new byte[] { } } ; // Test Actual Bones //------------------------- List <Animation.KeyNode> toRem = new List <Animation.KeyNode>(); for (int j = 0; j < a.bones.Count; j++) { Animation.KeyNode keynode = ((Animation.KeyNode)a.bones[j]); Bone b = vbn.getBone(keynode.Text); if (b == null) { toRem.Add(keynode); } } foreach (Animation.KeyNode r in toRem) { Console.WriteLine("Removing " + r.Text); a.bones.Remove(r); } //------------------------- 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(a.bones.Count); // numOfNodes o.WriteShort(a.frameCount); // frame size o.WriteShort(0); // frame start ?? o.WriteInt(0); o.WriteInt(0); o.WriteInt(0); o.WriteIntAt(o.Size(), 0x14); // ASSESSMENT Vector3[] maxT = new Vector3[a.bones.Count], minT = new Vector3[a.bones.Count]; Vector4[] maxR = new Vector4[a.bones.Count], minR = new Vector4[a.bones.Count]; Vector3[] maxS = new Vector3[a.bones.Count], minS = new Vector3[a.bones.Count]; bool[] hasScale = new bool[a.bones.Count]; bool[] hasTrans = new bool[a.bones.Count]; bool[] hasRot = new bool[a.bones.Count]; bool[] conScale = new bool[a.bones.Count]; bool[] conTrans = new bool[a.bones.Count]; bool[] conRot = new bool[a.bones.Count]; a.SetFrame(0); List <List <Bone> > Frames = new List <List <Bone> >(); { for (int j = 0; j < a.bones.Count; j++) { Animation.KeyNode keynode = ((Animation.KeyNode)a.bones[j]); if (keynode.xpos.HasAnimation() || keynode.ypos.HasAnimation() || keynode.zpos.HasAnimation()) { hasTrans[j] = true; } if (keynode.xrot.HasAnimation()) { hasRot[j] = true; } if (keynode.xsca.HasAnimation() || keynode.ysca.HasAnimation() || keynode.zsca.HasAnimation()) { hasScale[j] = true; } maxT[j] = new Vector3(-999f, -999f, -999f); minT[j] = new Vector3(999f, 999f, 999f); maxS[j] = new Vector3(-999f, -999f, -999f); minS[j] = new Vector3(999f, 999f, 999f); maxR[j] = new Vector4(-999f, -999f, -999f, -999f); minR[j] = new Vector4(999f, 999f, 999f, 999f); foreach (Animation.KeyFrame key in keynode.xpos.keys) { maxT[j].X = Math.Max(maxT[j].X, key.Value); minT[j].X = Math.Min(minT[j].X, key.Value); } foreach (Animation.KeyFrame key in keynode.ypos.keys) { maxT[j].Y = Math.Max(maxT[j].Y, key.Value); minT[j].Y = Math.Min(minT[j].Y, key.Value); } foreach (Animation.KeyFrame key in keynode.zpos.keys) { maxT[j].Z = Math.Max(maxT[j].Z, key.Value); minT[j].Z = Math.Min(minT[j].Z, key.Value); } foreach (Animation.KeyFrame key in keynode.xsca.keys) { maxS[j].X = Math.Max(maxS[j].X, key.Value); minS[j].X = Math.Min(minS[j].X, key.Value); } foreach (Animation.KeyFrame key in keynode.ysca.keys) { maxS[j].Y = Math.Max(maxS[j].Y, key.Value); minS[j].Y = Math.Min(minS[j].Y, key.Value); } foreach (Animation.KeyFrame key in keynode.zsca.keys) { maxS[j].Z = Math.Max(maxS[j].Z, key.Value); minS[j].Z = Math.Min(minS[j].Z, key.Value); } Bone b = vbn.getBone(keynode.Text); for (int i = 0; i < a.frameCount; i++) { Quaternion r = new Quaternion(); if (keynode.rotType == Animation.RotationType.Quaternion) { Animation.KeyFrame[] x = keynode.xrot.GetFrame(i); Animation.KeyFrame[] y = keynode.yrot.GetFrame(i); Animation.KeyFrame[] z = keynode.zrot.GetFrame(i); Animation.KeyFrame[] w = keynode.wrot.GetFrame(i); 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 == i) { r = q1; } else if (x[1].Frame == i) { r = q2; } else { r = Quaternion.Slerp(q1, q2, (i - x[0].Frame) / (x[1].Frame - x[0].Frame)); } } else if (keynode.rotType == Animation.RotationType.Euler) { float x = keynode.xrot.HasAnimation() ? keynode.xrot.GetValue(i) : b.rotation[0]; float y = keynode.yrot.HasAnimation() ? keynode.yrot.GetValue(i) : b.rotation[1]; float z = keynode.zrot.HasAnimation() ? keynode.zrot.GetValue(i) : b.rotation[2]; r = Animation.EulerToQuat(z, y, x); } r.Normalize(); maxR[j].X = Math.Max(maxR[j].X, r.X); minR[j].X = Math.Min(minR[j].X, r.X); maxR[j].Y = Math.Max(maxR[j].Y, r.Y); minR[j].Y = Math.Min(minR[j].Y, r.Y); maxR[j].Z = Math.Max(maxR[j].Z, r.Z); minR[j].Z = Math.Min(minR[j].Z, r.Z); } //if (b == null)continue; if (b != null) { if (maxT[j].X == -999) { maxT[j].X = b.position[0]; } if (maxT[j].Y == -999) { maxT[j].Y = b.position[1]; } if (maxT[j].Z == -999) { maxT[j].Z = b.position[2]; } if (minT[j].X == -999) { minT[j].X = b.position[0]; } if (minT[j].Y == -999) { minT[j].Y = b.position[1]; } if (minT[j].Z == -999) { minT[j].Z = b.position[2]; } if (maxS[j].X == -999) { maxS[j].X = b.scale[0]; } if (maxS[j].Y == -999) { maxS[j].Y = b.scale[1]; } if (maxS[j].Z == -999) { maxS[j].Z = b.scale[2]; } if (minS[j].X == -999) { minS[j].X = b.scale[0]; } if (minS[j].Y == -999) { minS[j].Y = b.scale[1]; } if (minS[j].Z == -999) { minS[j].Z = b.scale[2]; } } } } //TODO: Euler Rotation Values /*VBN tempvbn = new VBN(); * a.SetFrame(0); * for (int i = 0; i < a.FrameCount; i++) * { * //Frames.Add(new List<Bone>()); * for (int j = 0; j < a.Bones.Count; j++) * { * Animation.KeyNode keynode = a.Bones[j]; * Bone b = vbn.getBone(keynode.Text); * //if(b == null) continue; * maxR[j].X = Math.Max(maxR[j].X, b.rot.X); * minR[j].X = Math.Min(minR[j].X, b.rot.X); * maxR[j].Y = Math.Max(maxR[j].Y, b.rot.Y); * minR[j].Y = Math.Min(minR[j].Y, b.rot.Y); * maxR[j].Z = Math.Max(maxR[j].Z, b.rot.Z); * minR[j].Z = Math.Min(minR[j].Z, b.rot.Z); * * Bone f1 = new Bone(tempvbn); * f1.pos = b.pos; * f1.rot = b.rot; * f1.sca = b.sca; * //Frames[i].Add(f1); * } * a.NextFrame(vbn); * }*/ // NODE INFO int t2Size = 0; for (int i = 0; i < a.bones.Count; i++) { int flag = 0; conRot[i] = false; conScale[i] = false; conTrans[i] = false; // check for constant if (maxT[i].Equals(minT[i])) { conTrans[i] = true; } if (maxR[i].Equals(minR[i])) { conRot[i] = true; } if (maxS[i].Equals(minS[i])) { 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; //uint id = 999; Bone b = vbn.getBone(a.bones[i].Text); int hash = -1; if (MainForm.hashes.names.ContainsKey(a.bones[i].Text)) { hash = (int)MainForm.hashes.names[a.bones[i].Text]; } else { if (b != null) { hash = (int)b.boneId; } else { continue; } } //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(minT[i].X); t1.WriteFloat(minT[i].Y); t1.WriteFloat(minT[i].Z); if (!conTrans[i]) { maxT[i].X -= minT[i].X; maxT[i].Y -= minT[i].Y; maxT[i].Z -= minT[i].Z; t1.WriteFloat(maxT[i].X); t1.WriteFloat(maxT[i].Y); t1.WriteFloat(maxT[i].Z); t2Size += 6; } } if (hasRot[i]) { t1.WriteFloat(minR[i].X); t1.WriteFloat(minR[i].Y); t1.WriteFloat(minR[i].Z); if (!conRot[i]) { maxR[i].X -= minR[i].X; maxR[i].Y -= minR[i].Y; maxR[i].Z -= minR[i].Z; t1.WriteFloat(maxR[i].X); t1.WriteFloat(maxR[i].Y); t1.WriteFloat(maxR[i].Z); t2Size += 6; } } if (hasScale[i]) { t1.WriteFloat(minS[i].X); t1.WriteFloat(minS[i].Y); t1.WriteFloat(minS[i].Z); if (!conScale[i]) { maxS[i].X -= minS[i].X; maxS[i].Y -= minS[i].Y; maxS[i].Z -= minS[i].Z; t1.WriteFloat(maxS[i].X); t1.WriteFloat(maxS[i].Y); t1.WriteFloat(maxS[i].Z); t2Size += 6; } } } o.WriteIntAt(o.Size(), 0x18); o.WriteOutput(t1); o.WriteIntAt(o.Size(), 0x1C); // INTERPOLATION a.SetFrame(0); bool go = true; for (int i = 0; i < a.frameCount; i++) { //a.NextFrame(vbn); for (int j = 0; j < a.bones.Count; j++) { Bone node = vbn.getBone(a.bones[j].Text); Animation.KeyNode anode = a.bones[j]; //if (node == null) continue; if (hasTrans[j] && !conTrans[j]) { t2.WriteShort((int)(((anode.xpos.GetValue(i) - minT[j].X) / maxT[j].X) * 0xFFFF)); t2.WriteShort((int)(((anode.ypos.GetValue(i) - minT[j].Y) / maxT[j].Y) * 0xFFFF)); t2.WriteShort((int)(((anode.zpos.GetValue(i) - minT[j].Z) / maxT[j].Z) * 0xFFFF)); } if (hasRot[j] && !conRot[j]) { Quaternion r = new Quaternion(); if (anode.rotType == Animation.RotationType.Quaternion) { Animation.KeyFrame[] x = anode.xrot.GetFrame(i); Animation.KeyFrame[] y = anode.yrot.GetFrame(i); Animation.KeyFrame[] z = anode.zrot.GetFrame(i); Animation.KeyFrame[] w = anode.wrot.GetFrame(i); 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 == i) { r = q1; } else if (x[1].Frame == i) { r = q2; } else { r = Quaternion.Slerp(q1, q2, (i - x[0].Frame) / (x[1].Frame - x[0].Frame)); } } else if (anode.rotType == Animation.RotationType.Euler) { float x = anode.xrot.HasAnimation() ? anode.xrot.GetValue(i) : node.rotation[0]; float y = anode.yrot.HasAnimation() ? anode.yrot.GetValue(i) : node.rotation[1]; float z = anode.zrot.HasAnimation() ? anode.zrot.GetValue(i) : node.rotation[2]; r = Animation.EulerToQuat(z, y, x); } r.Normalize(); t2.WriteShort((int)(((r.X - minR[j].X) / maxR[j].X) * 0xFFFF)); t2.WriteShort((int)(((r.Y - minR[j].Y) / maxR[j].Y) * 0xFFFF)); t2.WriteShort((int)(((r.Z - minR[j].Z) / maxR[j].Z) * 0xFFFF)); } if (hasScale[j] && !conScale[j]) { t2.WriteShort((int)(((anode.xsca.GetValue(i) - minS[j].X) / maxS[j].X) * 0xFFFF)); t2.WriteShort((int)(((anode.ysca.GetValue(i) - minS[j].Y) / maxS[j].Y) * 0xFFFF)); t2.WriteShort((int)(((anode.zsca.GetValue(i) - minS[j].Z) / maxS[j].Z) * 0xFFFF)); } } if (go) { o.WriteShortAt(t2.Size(), 0x12); go = false; } } o.WriteOutput(t2); return(o.GetBytes()); } }
public override string ToString() { return(VBN.BoneNameFromHash(hash)); }
public AddBone(Bone parentBone = null, VBN vbn = null) { InitializeComponent(); this.vbn = vbn; this.parent = parentBone; }
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.Text = d.ReadString(nameOff, -1); 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 Smd() { bones = new VBN(); triangles = new List <SmdTriangle>(); }
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 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.rType = 1; } else if (part.Contains("S")) { n.sType = 1; } else { n.tType = 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; } } }
public static Animation readAnim(FileData d, VBN m) { int offset = d.ReadInt(); int nameoff = d.ReadInt(); d.Skip(4); int fCount = d.ReadUShort(); int animDataCount = d.ReadUShort(); d.Skip(8); Animation anim = new Animation(d.ReadString(nameoff, -1)); anim.frameCount = fCount; //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.ReadUShort(); //left d.ReadUShort(); //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; Animation.KeyNode node = new Animation.KeyNode(d.ReadString(nameOff, -1)); anim.bones.Add(node); node.rotType = Animation.RotationType.Euler; if (hasS == 1) { if (Siso == 1) { float iss = d.ReadFloat(); node.xsca.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = iss }); node.ysca.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = iss }); node.zsca.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = iss }); } else { if (SXfixed == 1) { node.xsca.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = d.ReadFloat() }); } else { process(d, s_type, pos, node, "SX", false, anim); } if (SYfixed == 1) { node.ysca.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = d.ReadFloat() }); } else { process(d, s_type, pos, node, "SY", false, anim); } if (SZfixed == 1) { node.zsca.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = d.ReadFloat() }); } else { process(d, s_type, pos, node, "SZ", false, anim); } } } if (hasR == 1) { if (Riso == 1) { float iss = (float)((d.ReadFloat()) * Math.PI / 180f); node.xrot.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = iss }); node.yrot.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = iss }); node.zrot.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = iss }); } else { if (RXfixed == 1) { node.xrot.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = (float)(Math.PI / 180f) * (d.ReadFloat()) }); } else { process(d, r_type, pos, node, "RX", false, anim); } if (RYfixed == 1) { node.yrot.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = (float)(Math.PI / 180f) * (d.ReadFloat()) }); } else { process(d, r_type, pos, node, "RY", false, anim); } if (RZfixed == 1) { node.zrot.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = (float)(Math.PI / 180f) * (d.ReadFloat()) }); } else { process(d, r_type, pos, node, "RZ", false, anim); } } } if (hasT == 1) { if (Tiso == 1) { float iss = d.ReadFloat(); node.xpos.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = iss }); node.ypos.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = iss }); node.zpos.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = iss }); } else { if (Xfixed == 1) { node.xpos.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = d.ReadFloat() }); } else { process(d, t_type, pos, node, "X", false, anim); } if (Yfixed == 1) { node.ypos.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = d.ReadFloat() }); } else { process(d, t_type, pos, node, "Y", false, anim); } if (Zfixed == 1) { node.zpos.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = d.ReadFloat() }); } else { process(d, t_type, pos, node, "Z", false, anim); } } } d.Seek(temp); } return(anim); }
public Bone(VBN v) { vbnParent = v; ImageKey = "bone"; SelectedImageKey = "bone"; }
public Animation ToAnimation(VBN vbn) { Animation animation = new Animation(anim.Name); animation.frameCount = anim.frameCount; int i = 0; foreach (Bone b in vbn.bones) { i = vbn.boneIndex(b.Text); if (i < anim.nodes.Count) { List <DAT_Animation.DATAnimTrack> tracks = anim.nodes[i]; Animation.KeyNode node = new Animation.KeyNode(b.Text); node.rotType = Animation.RotationType.Euler; foreach (DAT_Animation.DATAnimTrack track in tracks) { switch (track.type) { case DAT_Animation.AnimType.XPOS: node.xpos = CreateKeyGroup(i, track, false); break; case DAT_Animation.AnimType.YPOS: node.ypos = CreateKeyGroup(i, track, false); break; case DAT_Animation.AnimType.ZPOS: node.zpos = CreateKeyGroup(i, track, false); break; case DAT_Animation.AnimType.XROT: node.xrot = CreateKeyGroup(i, track, false); break; case DAT_Animation.AnimType.YROT: node.yrot = CreateKeyGroup(i, track, false); break; case DAT_Animation.AnimType.ZROT: node.zrot = CreateKeyGroup(i, track, false); break; case DAT_Animation.AnimType.XSCA: node.xsca = CreateKeyGroup(i, track, false); break; case DAT_Animation.AnimType.YSCA: node.ysca = CreateKeyGroup(i, track, false); break; case DAT_Animation.AnimType.ZSCA: node.zsca = CreateKeyGroup(i, track, false); break; } } if (node.xsca.HasAnimation() || node.ysca.HasAnimation() || node.zsca.HasAnimation() || node.xpos.HasAnimation() || node.ypos.HasAnimation() || node.zpos.HasAnimation() || node.xrot.HasAnimation() || node.yrot.HasAnimation() || node.zrot.HasAnimation()) { animation.bones.Add(node); } } } return(animation); }
public void CreateAnim(string fname, 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 " + (anim.frameCount + 1) + ";"); int i = 0; // writing node attributes foreach (Bone b in vbn.getBoneTreeOrder()) { i = vbn.boneIndex(b.Text); if (i < anim.nodes.Count) { // write the bone attributes // count the attributes List <DAT_Animation.DATAnimTrack> tracks = anim.nodes[i]; int tracknum = 0; if (tracks.Count == 0) { file.WriteLine("anim " + b.Text + " 0 0 0;"); } foreach (DAT_Animation.DATAnimTrack track in tracks) { switch (track.type) { case DAT_Animation.AnimType.XPOS: file.WriteLine("anim translate.translateX translateX " + b.Text + " 0 0 " + (tracknum++) + ";"); WriteAnimKey(file, i, track, false); break; case DAT_Animation.AnimType.YPOS: file.WriteLine("anim translate.translateY translateY " + b.Text + " 0 0 " + (tracknum++) + ";"); WriteAnimKey(file, i, track, false); break; case DAT_Animation.AnimType.ZPOS: file.WriteLine("anim translate.translateZ translateZ " + b.Text + " 0 0 " + (tracknum++) + ";"); WriteAnimKey(file, i, track, false); break; case DAT_Animation.AnimType.XROT: file.WriteLine("anim rotate.rotateX rotateX " + b.Text + " 0 0 " + (tracknum++) + ";"); WriteAnimKey(file, i, track, true); break; case DAT_Animation.AnimType.YROT: file.WriteLine("anim rotate.rotateY rotateY " + b.Text + " 0 0 " + (tracknum++) + ";"); WriteAnimKey(file, i, track, true); break; case DAT_Animation.AnimType.ZROT: file.WriteLine("anim rotate.rotateZ rotateZ " + b.Text + " 0 0 " + (tracknum++) + ";"); WriteAnimKey(file, i, track, true); break; case DAT_Animation.AnimType.XSCA: file.WriteLine("anim scale.scaleX scaleX " + b.Text + " 0 0 " + (tracknum++) + ";"); WriteAnimKey(file, i, track, false); break; case DAT_Animation.AnimType.YSCA: file.WriteLine("anim scale.scaleY scaleY " + b.Text + " 0 0 " + (tracknum++) + ";"); WriteAnimKey(file, i, track, false); break; case DAT_Animation.AnimType.ZSCA: file.WriteLine("anim scale.scaleZ scaleZ " + b.Text + " 0 0 " + (tracknum++) + ";"); WriteAnimKey(file, i, track, false); break; } } } else { file.WriteLine("anim " + b.Text + " 0 0 0;"); } } } }
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 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 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); List <List <Bone> > Frames = new List <List <Bone> >(); VBN tempvbn = new VBN(); for (int i = 0; i < a.Size(); i++) { a.NextFrame(vbn, true); List <Bone> bonelist = new List <Bone>(); for (int j = 0; j < nodeid.Count; j++) { Bone node = getNodeId(vbn, nodeid[j]); Bone f1 = new Bone(tempvbn); f1.pos = node.pos; f1.rot = node.rot; f1.sca = node.sca; bonelist.Add(f1); if (minmax[j] == null) { hasRot[j] = false; hasScale[j] = false; hasTrans[j] = false; KeyNode n = a.GetFirstNode(nodeid[j]); if (n != null) { if (n.rType != -1) { hasRot[j] = true; } if (n.tType != -1) { hasTrans[j] = true; } if (n.sType != -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 = -1; if (MainForm.hashes.names.ContainsKey(getNodeId(vbn, nodeid[i]).Text)) { hash = (int)MainForm.hashes.names[getNodeId(vbn, nodeid[i]).Text]; } //else hash = (int)FileData.crc12(getNodeId(vbn, nodeid[i]).Text); 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); bool go = false; foreach (List <Bone> bonelist in Frames) { //a.nextFrame(vbn); int j = 0; foreach (Bone node in bonelist) { //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)); } j++; } if (!go) { o.WriteShortAt(t2.Size(), 0x12); go = true; } } o.WriteOutput(t2); return(o.GetBytes()); }
public void RenderHurtboxes(float frame, int scriptId, ForgeAcmdScript acmdScript, VBN vbn) { if (Hurtboxes.Count > 0) { GL.Enable(EnableCap.DepthTest); GL.Enable(EnableCap.Blend); if (acmdScript != null) { if (acmdScript.BodyIntangible) { return; } } if (scriptId != -1) { if (frame + 1 >= MovesData[scriptId].IntangibilityStart && frame + 1 < MovesData[scriptId].IntangibilityEnd) { return; } } foreach (var pair in Hurtboxes) { var h = pair.Value; if (!h.Visible) { continue; } var va = new Vector3(h.X, h.Y, h.Z); Bone b = ForgeAcmdScript.GetBone(h.Bone, vbn); if (b == null) { continue; } if (acmdScript != null) { if (acmdScript.IntangibleBones.Contains(h.Bone)) { continue; } } //va = Vector3.Transform(va, b.transform); GL.Color4(Color.FromArgb(Runtime.hurtboxAlpha, Runtime.hurtboxColor)); if (Runtime.renderHurtboxesZone) { switch (h.Zone) { case Hurtbox.LwZone: GL.Color4(Color.FromArgb(Runtime.hurtboxAlpha, Runtime.hurtboxColorLow)); break; case Hurtbox.NZone: GL.Color4(Color.FromArgb(Runtime.hurtboxAlpha, Runtime.hurtboxColorMed)); break; case Hurtbox.HiZone: GL.Color4(Color.FromArgb(Runtime.hurtboxAlpha, Runtime.hurtboxColorHi)); break; } } if (acmdScript != null) { if (acmdScript.SuperArmor) { GL.Color4(Color.FromArgb(Runtime.hurtboxAlpha, 0x73, 0x0a, 0x43)); } if (acmdScript.BodyInvincible) { GL.Color4(Color.FromArgb(Runtime.hurtboxAlpha, Color.White)); } if (acmdScript.InvincibleBones.Contains(h.Bone)) { GL.Color4(Color.FromArgb(Runtime.hurtboxAlpha, Color.White)); } } var va2 = new Vector3(h.X2, h.Y2, h.Z2); //if (h.Bone != -1)va2 = Vector3.Transform(va2, b.transform); if (h.IsSphere) { Rendering.ShapeDrawing.DrawSphereTransformedVisible(va, h.Size, 30, b.transform); } else { Rendering.ShapeDrawing.DrawReducedCylinderTransformed(va, va2, h.Size, b.transform); } if (Runtime.SelectedHurtboxId == h.Id) { GL.Color4(Color.FromArgb(Runtime.hurtboxAlpha, Runtime.hurtboxColorSelected)); if (h.IsSphere) { Rendering.ShapeDrawing.DrawWireframeSphereTransformedVisible(va, h.Size, 20, b.transform); } else { Rendering.ShapeDrawing.DrawWireframeCylinderTransformed(va, va2, h.Size, b.transform); } } } GL.Disable(EnableCap.Blend); GL.Disable(EnableCap.DepthTest); } }
public static void createOMO(Animation a, VBN vbn, String fname) { File.WriteAllBytes(fname, CreateOMOFromAnimation(a, vbn)); }
public static Bone getNodeId(VBN vbn, int node) { return(vbn.bones[node]); }
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.tType != -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.rType != -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.sType != -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(); }