public void NewBone() { CHR0EntryNode node = ((CHR0Node)_resource).CreateEntry(); BaseWrapper res = this.FindResource(node, false); res.EnsureVisible(); res.TreeView.SelectedNode = res; }
public DialogResult ShowDialog(IWin32Window owner, KeyFrameMode type, CHR0EntryNode target) { _target = target; _type = type; comboBox1.Items.Add("Add"); comboBox1.Items.Add("Subtract"); comboBox1.SelectedIndex = 0; return(base.ShowDialog(owner)); }
private void ReloadIcons() { if (miscdata80 == null) { return; } CHR0Node chr0 = miscdata80.FindChild("AnmChr(NW4R)/MenSelmapPos_TopN__" + (MyMusic ? "1" : "0"), false) as CHR0Node; if (chr0 == null) { return; } icons = new Tuple <Image, RectangleF> [_numIcons + 1]; CHR0EntryNode entry = chr0.FindChild("MenSelmapPos_TopN", false) as CHR0EntryNode; Vector3 offset = entry.GetAnimFrame(_numIcons + OFFSET).Translation; for (int i = 1; i <= _numIcons; i++) { entry = chr0.FindChild("pos" + i.ToString("D2"), false) as CHR0EntryNode; CHRAnimationFrame frame = entry.GetAnimFrame(_numIcons + OFFSET, true); float x = (BRAWLWIDTH / 2 + frame.Translation._x + offset._x) / BRAWLWIDTH; float y = (BRAWLHEIGHT / 2 - frame.Translation._y - offset._y) / BRAWLHEIGHT; float w = 6.4f * (frame.Scale._x) / BRAWLWIDTH; float h = 5.6f * (frame.Scale._y) / BRAWLHEIGHT; RectangleF r = new RectangleF(x, y, w, h); TextureContainer tc = new TextureContainer(miscdata80, IconOrder != null && i <= IconOrder.Length ? IconOrder[i - 1] : 100); if (tc.icon.tex0 == null) { continue; } Image image = tc.icon.tex0.GetImage(0); icons[i] = new Tuple <Image, RectangleF>(image, r); } var nexttex0 = miscdata80.FindChild("Textures(NW4R)/MenSelmapIcon_Change.1", false) as TEX0Node; if (nexttex0 != null) { float NEXTOFFSET = 10.8f; entry = chr0.FindChild("pos" + (_numIcons + 1).ToString("D2"), false) as CHR0EntryNode; CHRAnimationFrame frame2 = entry.GetAnimFrame(_numIcons + OFFSET, true); float x2 = (BRAWLWIDTH / 2 + frame2.Translation._x - NEXTOFFSET) / BRAWLWIDTH; float y2 = (BRAWLHEIGHT / 2 - frame2.Translation._y) / BRAWLHEIGHT; float w2 = 14.4f * (frame2.Scale._x) / BRAWLWIDTH; float h2 = 4.8f * (frame2.Scale._y) / BRAWLHEIGHT; RectangleF r2 = new RectangleF(x2, y2, w2, h2); Image image2 = nexttex0.GetImage(0); icons[0] = new Tuple <Image, RectangleF>(image2, r2); //pos00 is not used anyway, so let's overwrite it } this.Invalidate(); }
public void AddToNode(CHR0EntryNode node) { for (int i = 0; i < 9; i++) { if (_transformations[i].HasValue) { node.SetKeyframe(i, Frame, _transformations[i].Value, false, true); } } }
private static BoneAnim Chr0Entry2BoneAnim(CHR0EntryNode entry) { BoneAnim boneAnim = new BoneAnim(); boneAnim.Name = entry.Name; if (entry.UseModelTranslate) { boneAnim.FlagsBase |= BoneAnimFlagsBase.Translate; } if (entry.UseModelRotate) { boneAnim.FlagsBase |= BoneAnimFlagsBase.Rotate; } if (entry.UseModelScale) { boneAnim.FlagsBase |= BoneAnimFlagsBase.Scale; } var baseData = new BoneAnimData(); baseData.Translate = new Vector3F(); baseData.Rotate = new Vector4F(); baseData.Scale = new Vector3F(); baseData.Flags = 0; boneAnim.BaseData = baseData; boneAnim.BeginBaseTranslate = 0; boneAnim.BeginRotate = 0; boneAnim.BeginTranslate = 0; boneAnim.FlagsTransform = 0; KeyframeCollection c = entry.Keyframes; for (int index = 0; index < 9; index++) { } if (entry.UseModelTranslate) { boneAnim.FlagsCurve |= BoneAnimFlagsCurve.TranslateX; } if (entry.UseModelRotate) { boneAnim.FlagsBase |= BoneAnimFlagsBase.Rotate; } if (entry.UseModelScale) { boneAnim.FlagsBase |= BoneAnimFlagsBase.Scale; } return(boneAnim); }
public void AddToNode(CHR0Node parentNode) { CHR0EntryNode entryNode = new CHR0EntryNode(); parentNode.AddChild(entryNode); entryNode.SetSize(parentNode.FrameCount, parentNode.Loop); entryNode.Name = Name; foreach (Keyframe keyframe in Keyframes) { keyframe.AddToNode(entryNode); } //entryNode.Keyframes.Clean(); }
private void toolStripMenuItem3_Click(object sender, EventArgs e) { if (SelectedAnimation == null || type == 0) { return; } KeyframeEntry kfe; CHR0EntryNode _target = SelectedAnimation.FindChild(TargetTexRef.Parent.Name, false) as CHR0EntryNode; for (int x = 0; x < _target.FrameCount; x++) //Loop thru each frame { if ((kfe = _target.GetKeyframe((KeyFrameMode)type, x)) != null) //Check for a keyframe { kfe._value += 180; } } ResetBox(type - 0x10); _mainWindow.UpdateModel(); }
public void ChangeScale(string name, ResourceNode parent, Vector3 scale) { int numFrames; CHR0EntryNode entry; foreach (ResourceNode r in parent.Children) { if (r is CHR0Node) { if (r.FindChild(name, false) == null) { CHR0EntryNode c = new CHR0EntryNode(); c._numFrames = (r as CHR0Node).FrameCount; c.Name = name; r.Children.Add(c); } } if (r.Name == name) { if (r is CHR0EntryNode) { entry = r as CHR0EntryNode; numFrames = entry.FrameCount; for (int x = 0; x < numFrames; x++) { for (int i = 0x10; i < 0x13; i++) { if (entry.GetKeyframe((KeyFrameMode)i, x) != null) { entry.RemoveKeyframe((KeyFrameMode)i, x); } } } entry.SetKeyframeOnlyScale(0, scale); } } ChangeScale(name, r, scale); } }
public static CHR0Node Read(string input) { CHR0Node node = new CHR0Node { _name = Path.GetFileNameWithoutExtension(input) }; using (StreamReader file = new StreamReader(input)) { float start = 0.0f; float end = 0.0f; string line; while (true) { line = file.ReadLine(); if (line == null) { break; } int i = line.IndexOf(' '); string tag = line.Substring(0, i); if (tag == "anim") { break; } string val = line.Substring(i + 1, line.IndexOf(';') - i - 1); switch (tag) { case "startTime": case "startUnitless": float.TryParse(val, out start); break; case "endTime": case "endUnitless": float.TryParse(val, out end); break; case "animVersion": case "mayaVersion": case "timeUnit": case "linearUnit": case "angularUnit": default: break; } } int frameCount = (int)(end - start + 1.5f); node.FrameCount = frameCount; while (true) { if (line == null) { break; } string[] anim = line.Split(' '); if (anim.Length != 7) { while ((line = file.ReadLine()) != null && !line.StartsWith("anim ")) { ; } continue; } string t = anim[2]; string bone = anim[3]; int mode = -1; if (t.StartsWith("scale")) { if (t.EndsWith("X")) { mode = 0; } else if (t.EndsWith("Y")) { mode = 1; } else if (t.EndsWith("Z")) { mode = 2; } } else if (t.StartsWith("rotate")) { if (t.EndsWith("X")) { mode = 3; } else if (t.EndsWith("Y")) { mode = 4; } else if (t.EndsWith("Z")) { mode = 5; } } else if (t.StartsWith("translate")) { if (t.EndsWith("X")) { mode = 6; } else if (t.EndsWith("Y")) { mode = 7; } else if (t.EndsWith("Z")) { mode = 8; } } if (mode == -1) { while ((line = file.ReadLine()) != null && !line.StartsWith("anim ")) { ; } continue; } line = file.ReadLine(); if (line.StartsWith("animData")) { CHR0EntryNode e; if ((e = node.FindChild(bone, false) as CHR0EntryNode) == null) { e = new CHR0EntryNode { _name = bone }; node.AddChild(e); } while (true) { line = file.ReadLine().TrimStart(); int i = line.IndexOf(' '); if (i < 0) { break; } string tag = line.Substring(0, i); if (tag == "keys") { List <KeyframeEntry> l = new List <KeyframeEntry>(); while (true) { line = file.ReadLine().TrimStart(); if (line == "}") { break; } string[] s = line.Split(' '); for (int si = 0; si < s.Length; si++) { s[si] = s[si].Trim('\n', ';', ' '); } float.TryParse(s[0], NumberStyles.Number, CultureInfo.InvariantCulture, out float inVal); float.TryParse(s[1], NumberStyles.Number, CultureInfo.InvariantCulture, out float outVal); float weight1 = 0; float weight2 = 0; float angle1 = 0; float angle2 = 0; bool firstFixed = false; bool secondFixed = false; switch (s[2]) { case "linear": case "spline": case "auto": break; case "fixed": firstFixed = true; float.TryParse(s[7], NumberStyles.Number, CultureInfo.InvariantCulture, out angle1); float.TryParse(s[8], NumberStyles.Number, CultureInfo.InvariantCulture, out weight1); break; } switch (s[3]) { case "linear": case "spline": case "auto": break; case "fixed": secondFixed = true; if (firstFixed) { float.TryParse(s[9], NumberStyles.Number, CultureInfo.InvariantCulture, out angle2); float.TryParse(s[10], NumberStyles.Number, CultureInfo.InvariantCulture, out weight2); } else { float.TryParse(s[7], NumberStyles.Number, CultureInfo.InvariantCulture, out angle2); float.TryParse(s[8], NumberStyles.Number, CultureInfo.InvariantCulture, out weight2); } break; } bool anyFixed = secondFixed || firstFixed; bool bothFixed = secondFixed && firstFixed; KeyframeEntry x = e.SetKeyframe(mode, (int)(inVal - 0.5f), outVal, true); if (!anyFixed) { l.Add(x); } else { if (bothFixed) { x._tangent = (float)Math.Tan((angle1 + angle2) / 2 * Maths._deg2radf) * ((weight1 + weight2) / 2); } else if (firstFixed) { x._tangent = (float)Math.Tan(angle1 * Maths._deg2radf) * weight1; } else { x._tangent = (float)Math.Tan(angle2 * Maths._deg2radf) * weight2; } } } foreach (KeyframeEntry w in l) { w.GenerateTangent(); } } else { int z = line.IndexOf(';') - i - 1; if (z < 0) { continue; } string val = line.Substring(i + 1, z); switch (tag) { case "input": break; case "output": break; case "weighted": break; case "inputUnit": break; case "outputUnit": break; case "preInfinity": case "postInfinity": default: break; } } } } line = file.ReadLine(); } } return(node); }
public static void Serialize(CHR0Node node, string output, MDL0Node model) { model.Populate(); using (StreamWriter file = new StreamWriter(output)) { file.WriteLine("animVersion 1.1;"); file.WriteLine("mayaVersion 2015;"); file.WriteLine("timeUnit ntscf;"); file.WriteLine("linearUnit cm;"); file.WriteLine("angularUnit deg;"); file.WriteLine("startTime 0;"); file.WriteLine($"endTime {node.FrameCount - 1};"); foreach (MDL0BoneNode b in model.AllBones) { CHR0EntryNode e = node.FindChild(b.Name, true) as CHR0EntryNode; if (e == null) { file.WriteLine($"anim {b.Name} 0 {b.Children.Count} 0;"); continue; } KeyframeCollection c = e.Keyframes; int counter = 0; for (int index = 0; index < 9; index++) { KeyframeArray array = c._keyArrays[index]; if (array._keyCount <= 0) { continue; } file.WriteLine("anim {0}.{0}{1} {0}{1} {2} {3} {4} {5};", types[index / 3], axes[index % 3], e.Name, 0, b.Children.Count, counter); file.WriteLine("animData {"); file.WriteLine(" input time;"); file.WriteLine($" output {(index > 2 && index < 6 ? "angular" : "linear")};"); file.WriteLine(" weighted 1;"); file.WriteLine(" preInfinity constant;"); file.WriteLine(" postInfinity constant;"); file.WriteLine(" keys {"); for (KeyframeEntry entry = array._keyRoot._next; entry != array._keyRoot; entry = entry._next) { float angle = (float)Math.Atan(entry._tangent) * Maths._rad2degf; file.WriteLine(" {0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10};", entry._index, entry._value.ToString(CultureInfo.InvariantCulture.NumberFormat), "fixed", "fixed", "1", "1", "0", angle.ToString(CultureInfo.InvariantCulture.NumberFormat), "1", angle.ToString(CultureInfo.InvariantCulture.NumberFormat), "1"); } file.WriteLine(" }"); file.WriteLine("}"); counter++; } } } }
public static CHR0Node Convert(string input) { try { CHR0Node chr0 = new CHR0Node { Name = Path.GetFileNameWithoutExtension(input), Loop = false, Version = 4 }; for (TextReader reader = new StreamReader(input); reader.Peek() != -1;) { string line = reader.ReadLine(); if (line.CompareTo("Animation Keyframe Data Frames") == 0) { line = reader.ReadLine(); //Remove any non-digit characters string justNumbers = new string(line.Where(char.IsDigit).ToArray()); int keyFrameCount = int.Parse(justNumbers); chr0.FrameCount = keyFrameCount; for (line = reader.ReadLine(); line != null && line.CompareTo("End Of Animation Data") != 0; line = reader.ReadLine()) { if (line.CompareTo("Keyframe Data") == 0) { CHR0EntryNode node = new CHR0EntryNode(); chr0.AddChild(node); node.Name = reader.ReadLine(); node.SetSize(keyFrameCount, chr0.Loop); Coords translation = new Coords(); Coords rotation = new Coords(); Coords scale = new Coords(); for (line = reader.ReadLine(); line != null && line.CompareTo("End of Keyframe Data") != 0; line = reader.ReadLine()) { //Use goto to retry the loop without advancing the reader, when it returns from getCoords it will have the next line we need from it. retry: if (line.CompareTo("Translation") == 0) { reader.ReadLine(); //Skip first blank line translation = getCoords(reader, out line); goto retry; } else if (line.CompareTo("Rotation") == 0) { reader.ReadLine(); //Skip first blank line rotation = getCoords(reader, out line); goto retry; } else if (line.CompareTo("Scale") == 0) { reader.ReadLine(); //Skip first blank line scale = getCoords(reader, out line); goto retry; } else if (line.CompareTo("End of Keyframe Data") == 0 ) //If line equals this now it's time to break { break; } } //Add frames to node for (int frameCount = 0; translation.highestCount > frameCount || rotation.highestCount > frameCount || scale.highestCount > frameCount; frameCount++) { if (translation.highestCount > frameCount) { if (translation.x.Count != 0 && frameCount < translation.x.Count) { node.SetKeyframe(6, frameCount, translation.x[frameCount]); } if (translation.y.Count != 0 && frameCount < translation.y.Count) { node.SetKeyframe(7, frameCount, translation.y[frameCount]); } if (translation.z.Count != 0 && frameCount < translation.z.Count) { node.SetKeyframe(8, frameCount, translation.z[frameCount]); } } if (rotation.highestCount > frameCount) { if (rotation.x.Count != 0 && frameCount < rotation.x.Count) { node.SetKeyframe(3, frameCount, rotation.x[frameCount]); } if (rotation.y.Count != 0 && frameCount < rotation.y.Count) { node.SetKeyframe(4, frameCount, rotation.y[frameCount]); } if (rotation.z.Count != 0 && frameCount < rotation.z.Count) { node.SetKeyframe(5, frameCount, rotation.z[frameCount]); } } if (scale.highestCount > frameCount) { if (scale.x.Count != 0 && frameCount < scale.x.Count) { node.SetKeyframe(0, frameCount, scale.x[frameCount]); } if (scale.y.Count != 0 && frameCount < scale.y.Count) { node.SetKeyframe(1, frameCount, scale.y[frameCount]); } if (scale.z.Count != 0 && frameCount < scale.z.Count) { node.SetKeyframe(2, frameCount, scale.z[frameCount]); } } } } } } else { MessageBox.Show("Not a valid CHR0 text file."); return(null); } } return(chr0); } catch (Exception e) { MessageBox.Show("There was a problem importing keyframes.\n\nError:\n" + e.ToString()); return(null); } }
public unsafe void ChangeNode(string _name, ResourceNode parent, Vector3 scale, Vector3 rot, Vector3 trans, MDL0Node _targetModel, MDL0Node model, bool disLoop) { int numFrames; float * v; bool hasKeyframe = false; CHR0EntryNode entry; KeyframeEntry kfe; AnimationFrame anim = new AnimationFrame(); foreach (ResourceNode r in parent.Children) { if (r is CHR0Node) { if (Port.Checked && _targetModel != null && model != null) { ((CHR0Node)r).Port(_targetModel, model); } if (Version.Enabled) { if (Version.SelectedIndex == 0) { ((CHR0Node)r).Version = 4; } else if (Version.SelectedIndex == 1) { ((CHR0Node)r).Version = 5; } } if (disLoop) { ((CHR0Node)r).Loop = false; } _copyNode = r.FindChild(textBox1.Text, false) as CHR0EntryNode; if (r.FindChild(_name, false) == null) { if (_name != null && _name != String.Empty) { CHR0EntryNode c = new CHR0EntryNode(); c._numFrames = (r as CHR0Node).FrameCount; c.Name = _name; if (_copyNode != null) { for (int x = 0; x < _copyNode._numFrames; x++) { for (int i = 0x10; i < 0x19; i++) { if ((kfe = _copyNode.GetKeyframe((KeyFrameMode)i, x)) != null) { c.SetKeyframe((KeyFrameMode)i, x, kfe._value); } } } } r.Children.Add(c); r._changed = true; } } } if (r.Name == _name) { if (r is CHR0EntryNode) { entry = r as CHR0EntryNode; numFrames = entry.FrameCount; if (ReplaceScale.Checked) { for (int x = 0; x < numFrames; x++) { for (int i = 0x10; i < 0x13; i++) { if (entry.GetKeyframe((KeyFrameMode)i, x) != null) { entry.RemoveKeyframe((KeyFrameMode)i, x); } } } entry.SetKeyframeOnlyScale(0, scale); } if (ReplaceRot.Checked) { for (int x = 0; x < numFrames; x++) { for (int i = 0x13; i < 0x16; i++) { if (entry.GetKeyframe((KeyFrameMode)i, x) != null) { entry.RemoveKeyframe((KeyFrameMode)i, x); } } } entry.SetKeyframeOnlyRot(0, rot); } if (ReplaceTrans.Checked) { for (int x = 0; x < numFrames; x++) { for (int i = 0x16; i < 0x19; i++) { if (entry.GetKeyframe((KeyFrameMode)i, x) != null) { entry.RemoveKeyframe((KeyFrameMode)i, x); } } } entry.SetKeyframeOnlyTrans(0, trans); } hasKeyframe = false; if (AddScale.Checked) { for (int x = 0; x < numFrames; x++) { for (int i = 0x10; i < 0x13; i++) { if ((kfe = entry.GetKeyframe((KeyFrameMode)i, x)) != null) { switch (i) { case 0x10: kfe._value += scale._x; break; case 0x11: kfe._value += scale._y; break; case 0x12: kfe._value += scale._z; break; } hasKeyframe = true; } } } if (!hasKeyframe) { anim = entry.GetAnimFrame(0); Vector3 newScale = anim.Scale; scale._x += newScale._x; scale._y += newScale._y; scale._z += newScale._z; entry.SetKeyframeOnlyScale(0, scale); } } hasKeyframe = false; if (AddRot.Checked) { for (int x = 0; x < numFrames; x++) { for (int i = 0x13; i < 0x16; i++) { if ((kfe = entry.GetKeyframe((KeyFrameMode)i, x)) != null) { switch (i) { case 0x13: kfe._value += rot._x; break; case 0x14: kfe._value += rot._y; break; case 0x15: kfe._value += rot._z; break; } hasKeyframe = true; } } } if (!hasKeyframe) { anim = entry.GetAnimFrame(0); Vector3 newRot = anim.Rotation; rot._x += newRot._x; rot._y += newRot._y; rot._z += newRot._z; entry.SetKeyframeOnlyRot(0, rot); } } hasKeyframe = false; if (AddTrans.Checked) { for (int x = 0; x < numFrames; x++) { for (int i = 0x16; i < 0x19; i++) { if ((kfe = entry.GetKeyframe((KeyFrameMode)i, x)) != null) { switch (i) { case 0x16: kfe._value += trans._x; break; case 0x17: kfe._value += trans._y; break; case 0x18: kfe._value += trans._z; break; } hasKeyframe = true; } } } if (!hasKeyframe) { anim = entry.GetAnimFrame(0); Vector3 newTrans = anim.Translation; trans._x += newTrans._x; trans._y += newTrans._y; trans._z += newTrans._z; entry.SetKeyframeOnlyTrans(0, trans); } } hasKeyframe = false; if (SubtractScale.Checked) { for (int x = 0; x < numFrames; x++) { for (int i = 0x10; i < 0x13; i++) { if ((kfe = entry.GetKeyframe((KeyFrameMode)i, x)) != null) { switch (i) { case 0x10: kfe._value -= scale._x; break; case 0x11: kfe._value -= scale._y; break; case 0x12: kfe._value -= scale._z; break; } hasKeyframe = true; } } } if (!hasKeyframe) { anim = entry.GetAnimFrame(0); Vector3 newScale = anim.Scale; scale._x = newScale._x - scale._x; scale._y = newScale._y - scale._y; scale._z = newScale._z - scale._z; entry.SetKeyframeOnlyScale(0, scale); } } hasKeyframe = false; if (SubtractRot.Checked) { for (int x = 0; x < numFrames; x++) { for (int i = 0x13; i < 0x16; i++) { if ((kfe = entry.GetKeyframe((KeyFrameMode)i, x)) != null) { switch (i) { case 0x13: kfe._value -= rot._x; break; case 0x14: kfe._value -= rot._y; break; case 0x15: kfe._value -= rot._z; break; } hasKeyframe = true; } } } if (!hasKeyframe) { anim = entry.GetAnimFrame(0); Vector3 newRot = anim.Rotation; rot._x = newRot._x - rot._x; rot._y = newRot._y - rot._y; rot._z = newRot._z - rot._z; entry.SetKeyframeOnlyRot(0, rot); } } hasKeyframe = false; if (SubtractTrans.Checked) { for (int x = 0; x < numFrames; x++) { for (int i = 0x16; i < 0x19; i++) { if ((kfe = entry.GetKeyframe((KeyFrameMode)i, x)) != null) { switch (i) { case 0x16: kfe._value -= trans._x; break; case 0x17: kfe._value -= trans._y; break; case 0x18: kfe._value -= trans._z; break; } hasKeyframe = true; } } } if (!hasKeyframe) { anim = entry.GetAnimFrame(0); Vector3 newTrans = anim.Translation; trans._x = newTrans._x - trans._x; trans._y = newTrans._y - trans._y; trans._z = newTrans._z - trans._z; entry.SetKeyframeOnlyTrans(0, trans); } } } r._changed = true; } ChangeNode(_name, r, scale, rot, trans, _targetModel, model, disLoop); } }
public void RootChanged() { ResourceNode node = _targetNode; if (node is ISCN0KeyframeHolder) { if (node is SCN0LightNode) { SCN0LightNode n = node as SCN0LightNode; interpolationViewer.FrameLimit = n.FrameCount; interpolationViewer.KeyRoot = n.GetKeys(SelectedMode)._keyRoot; } else if (node is SCN0FogNode) { SCN0FogNode n = node as SCN0FogNode; interpolationViewer.FrameLimit = n.FrameCount; interpolationViewer.KeyRoot = n.GetKeys(SelectedMode)._keyRoot; } else if (node is SCN0CameraNode) { SCN0CameraNode n = node as SCN0CameraNode; interpolationViewer.FrameLimit = n.FrameCount; interpolationViewer.KeyRoot = n.GetKeys(SelectedMode)._keyRoot; } } else if (node is IKeyframeHolder) { if (node is CHR0EntryNode) { CHR0EntryNode n = node as CHR0EntryNode; interpolationViewer.FrameLimit = n._keyframes._frameCount; interpolationViewer.KeyRoot = n._keyframes._keyRoots[SelectedMode]; } else if (node is SRT0TextureNode) { SRT0TextureNode n = node as SRT0TextureNode; interpolationViewer.FrameLimit = n._keyframes._frameCount; int i = SelectedMode; if (i == 2) { i = 3; } else if (i > 2) { i += 3; } interpolationViewer.KeyRoot = n._keyframes._keyRoots[i]; } } else if (node is IKeyframeArrayHolder) { comboBox1.Enabled = false; if (node is SHP0VertexSetNode) { SHP0VertexSetNode n = node as SHP0VertexSetNode; interpolationViewer.FrameLimit = n._keyframes._frameLimit; interpolationViewer.KeyRoot = n._keyframes._keyRoot; } } }
private static BoneAnim Chr0Entry2BoneAnim(CHR0EntryNode entry) { BoneAnim boneAnim = new BoneAnim(); boneAnim.Name = entry.Name; // boneAnim.Name = NameConverterMkWii2Mk8(boneAnim.Name); if (entry.UseModelTranslate) { boneAnim.FlagsBase |= BoneAnimFlagsBase.Translate; } if (entry.UseModelRotate) { boneAnim.FlagsBase |= BoneAnimFlagsBase.Rotate; } if (entry.UseModelScale) { boneAnim.FlagsBase |= BoneAnimFlagsBase.Scale; } var baseData = new BoneAnimData(); var FirstFrame = entry.GetAnimFrame(0); if (FirstFrame.HasKeys) { float xRadian = FirstFrame.Rotation._x * Deg2Rad; float yRadian = FirstFrame.Rotation._y * Deg2Rad; float zRadian = FirstFrame.Rotation._z * Deg2Rad; baseData.Translate = new Vector3F(FirstFrame.Translation._x, FirstFrame.Translation._y, FirstFrame.Translation._z); baseData.Rotate = new Vector4F(xRadian, yRadian, zRadian, 1); baseData.Scale = new Vector3F(FirstFrame.Scale._x, FirstFrame.Scale._y, FirstFrame.Scale._z); baseData.Flags = 0; boneAnim.BaseData = baseData; } else { baseData.Translate = new Vector3F(0, 0, 0); baseData.Rotate = new Vector4F(0, 0, 0, 1); baseData.Scale = new Vector3F(1, 1, 1); baseData.Flags = 0; boneAnim.BaseData = baseData; } boneAnim.FlagsBase |= BoneAnimFlagsBase.Translate; boneAnim.FlagsBase |= BoneAnimFlagsBase.Scale; boneAnim.FlagsBase |= BoneAnimFlagsBase.Rotate; if (baseData.Rotate == new Vector4F(0, 0, 0, 1)) { boneAnim.FlagsTransform |= BoneAnimFlagsTransform.RotateZero; } if (baseData.Translate == new Vector3F(0, 0, 0)) { boneAnim.FlagsTransform |= BoneAnimFlagsTransform.TranslateZero; } if (baseData.Scale == new Vector3F(1, 1, 1)) { boneAnim.FlagsTransform |= BoneAnimFlagsTransform.ScaleOne; } if (IsUniform(baseData.Scale)) { boneAnim.FlagsTransform |= BoneAnimFlagsTransform.ScaleUniform; } if (!IsRoot(boneAnim)) { boneAnim.FlagsTransform |= BoneAnimFlagsTransform.SegmentScaleCompensate; } boneAnim.BeginTranslate = 6; boneAnim.BeginRotate = 3; if (FirstFrame.HasKeys) { var AnimFrame = entry.GetAnimFrame(0); if (AnimFrame.hasTx) { boneAnim.FlagsCurve |= BoneAnimFlagsCurve.TranslateX; var curve = GenerateCurve(0x10, entry); if (curve != null) { boneAnim.Curves.Add(curve); } } if (AnimFrame.hasTy) { boneAnim.FlagsCurve |= BoneAnimFlagsCurve.TranslateY; var curve = GenerateCurve(0x14, entry); if (curve != null) { boneAnim.Curves.Add(curve); } } if (AnimFrame.hasTz) { boneAnim.FlagsCurve |= BoneAnimFlagsCurve.TranslateZ; var curve = GenerateCurve(0x18, entry); if (curve != null) { boneAnim.Curves.Add(curve); } } if (AnimFrame.hasRx) { boneAnim.FlagsCurve |= BoneAnimFlagsCurve.RotateX; var curve = GenerateCurve(0x20, entry); if (curve != null) { boneAnim.Curves.Add(curve); } } if (AnimFrame.hasRy) { boneAnim.FlagsCurve |= BoneAnimFlagsCurve.RotateY; var curve = GenerateCurve(0x24, entry); if (curve != null) { boneAnim.Curves.Add(curve); } } if (AnimFrame.hasRz) { boneAnim.FlagsCurve |= BoneAnimFlagsCurve.RotateZ; var curve = GenerateCurve(0x28, entry); if (curve != null) { boneAnim.Curves.Add(curve); } } if (AnimFrame.hasSx) { boneAnim.FlagsCurve |= BoneAnimFlagsCurve.ScaleX; var curve = GenerateCurve(0x4, entry); if (curve != null) { boneAnim.Curves.Add(curve); } } if (AnimFrame.hasSy) { boneAnim.FlagsCurve |= BoneAnimFlagsCurve.ScaleY; var curve = GenerateCurve(0x8, entry); if (curve != null) { boneAnim.Curves.Add(curve); } } if (AnimFrame.hasSz) { boneAnim.FlagsCurve |= BoneAnimFlagsCurve.ScaleZ; var curve = GenerateCurve(0xC, entry); if (curve != null) { boneAnim.Curves.Add(curve); } } } return(boneAnim); }
private static AnimCurve GenerateCurve(uint AnimOffset, CHR0EntryNode entry) { AnimCurve curve = new AnimCurve(); curve.AnimDataOffset = AnimOffset; curve.StartFrame = 0; curve.Offset = 0; curve.Scale = 1; curve.FrameType = AnimCurveFrameType.Single; curve.KeyType = AnimCurveKeyType.Single; curve.CurveType = AnimCurveType.Linear; List <float> Frames = new List <float>(); List <float> Keys = new List <float>(); CHRAnimationFrame ain, aout; for (int frame = 0; frame < entry.FrameCount; frame++) { //Max of 4 values. Cubic using 4, linear using 2, and step using 1 float[] KeyValues = new float[4]; //Set the main values to the curve based on offset for encoding later if ((ain = entry.GetAnimFrame(frame)).HasKeys) { aout = entry.GetAnimFrame(frame, true); FillKeyList(aout, frame, curve.AnimDataOffset, Frames, Keys); if (!ain.Equals(aout)) { FillKeyList(aout, frame, curve.AnimDataOffset, Frames, Keys); } } } if (Frames.Count <= 0) { return(null); } // Console.WriteLine($"AnimOffset {AnimOffset} Keys {Keys.Count}"); //Max value in frames is our end frame curve.EndFrame = Frames.Max(); curve.Frames = Frames.ToArray(); //If a curve only has one frame we don't need to interpolate or add keys to a curve as it's constant if (curve.Frames.Length <= 1) { return(null); } switch (curve.CurveType) { case AnimCurveType.Cubic: curve.Keys = new float[Keys.Count, 4]; for (int frame = 0; frame < Keys.Count; frame++) { float Delta = 0; if (frame < Keys.Count - 1) { Delta = Keys[frame + 1] - Keys[frame]; } float value = Keys[frame]; float Slope = 0; float Slope2 = 0; curve.Keys[frame, 0] = value; curve.Keys[frame, 1] = Slope; curve.Keys[frame, 2] = Slope2; curve.Keys[frame, 3] = Delta; } break; case AnimCurveType.StepInt: //Step requires no interpolation curve.Keys = new float[Keys.Count, 1]; for (int frame = 0; frame < Keys.Count; frame++) { curve.Keys[frame, 0] = Keys[frame]; } break; case AnimCurveType.Linear: curve.Keys = new float[Keys.Count, 2]; for (int frame = 0; frame < Keys.Count; frame++) { //Delta for second value used in linear curves float time = curve.Frames[frame]; float Delta = 0; if (frame < Keys.Count - 1) { Delta = Keys[frame + 1] - Keys[frame]; } curve.Keys[frame, 0] = Keys[frame]; curve.Keys[frame, 1] = Delta; } break; } QuantizeCurveData(curve); return(curve); }
public static void BoneAnim2Chr0Entry(BoneAnim boneAnim, CHR0Node chr0) { CHR0EntryNode chr0Entry = chr0.CreateEntry(boneAnim.Name); chr0Entry.UseModelRotate = false; chr0Entry.UseModelScale = false; chr0Entry.UseModelTranslate = false; chr0Entry.ScaleCompensateApply = boneAnim.ApplySegmentScaleCompensate; //Float for time/frame Dictionary <float, FSKAKeyNode> TranslateX = new Dictionary <float, FSKAKeyNode>(); Dictionary <float, FSKAKeyNode> TranslateY = new Dictionary <float, FSKAKeyNode>(); Dictionary <float, FSKAKeyNode> TranslateZ = new Dictionary <float, FSKAKeyNode>(); Dictionary <float, FSKAKeyNode> RotateX = new Dictionary <float, FSKAKeyNode>(); Dictionary <float, FSKAKeyNode> RotateY = new Dictionary <float, FSKAKeyNode>(); Dictionary <float, FSKAKeyNode> RotateZ = new Dictionary <float, FSKAKeyNode>(); Dictionary <float, FSKAKeyNode> ScaleX = new Dictionary <float, FSKAKeyNode>(); Dictionary <float, FSKAKeyNode> ScaleY = new Dictionary <float, FSKAKeyNode>(); Dictionary <float, FSKAKeyNode> ScaleZ = new Dictionary <float, FSKAKeyNode>(); if (boneAnim.FlagsBase.HasFlag(BoneAnimFlagsBase.Translate)) { TranslateX.Add(0, new FSKAKeyNode() { Value = boneAnim.BaseData.Translate.X, }); TranslateY.Add(0, new FSKAKeyNode() { Value = boneAnim.BaseData.Translate.Y, }); TranslateZ.Add(0, new FSKAKeyNode() { Value = boneAnim.BaseData.Translate.Z, }); } if (boneAnim.FlagsBase.HasFlag(BoneAnimFlagsBase.Rotate)) { RotateX.Add(0, new FSKAKeyNode() { Value = boneAnim.BaseData.Rotate.X, }); RotateY.Add(0, new FSKAKeyNode() { Value = boneAnim.BaseData.Rotate.Y, }); RotateZ.Add(0, new FSKAKeyNode() { Value = boneAnim.BaseData.Rotate.Z, }); } if (boneAnim.FlagsBase.HasFlag(BoneAnimFlagsBase.Scale)) { ScaleX.Add(0, new FSKAKeyNode() { Value = boneAnim.BaseData.Scale.X, }); ScaleY.Add(0, new FSKAKeyNode() { Value = boneAnim.BaseData.Scale.Y, }); ScaleZ.Add(0, new FSKAKeyNode() { Value = boneAnim.BaseData.Scale.Z, }); } else { ScaleX.Add(0, new FSKAKeyNode() { Value = 1 }); ScaleY.Add(0, new FSKAKeyNode() { Value = 1 }); ScaleZ.Add(0, new FSKAKeyNode() { Value = 1 }); } foreach (var curve in boneAnim.Curves) { for (int frame = 0; frame < curve.Frames.Length; frame++) { float time = curve.Frames[frame]; float value = 0; float slope = 0; float slope2 = 0; float delta = 0; float scale = curve.Scale; if (scale <= 0) { scale = 1; } if (curve.CurveType == AnimCurveType.Cubic) { value = curve.Offset + curve.Keys[frame, 0] * scale; slope = curve.Offset + curve.Keys[frame, 1] * scale; slope2 = curve.Offset + curve.Keys[frame, 2] * scale; delta = curve.Offset + curve.Keys[frame, 3] * scale; } if (curve.CurveType == AnimCurveType.Linear) { value = curve.Offset + curve.Keys[frame, 0] * scale; delta = curve.Offset + curve.Keys[frame, 1] * scale; } if (curve.CurveType == AnimCurveType.StepInt) { value = curve.Offset + curve.Keys[frame, 0] * scale; } switch (curve.AnimDataOffset) { case 0x10: if (TranslateX.Count > 0 && frame == 0) { TranslateX.Remove(0); } TranslateX.Add(time, new FSKAKeyNode() { Value = value, Slope = slope, Slope2 = slope2, Delta = delta, Frame = time, }); break; case 0x14: if (TranslateY.Count > 0 && frame == 0) { TranslateY.Remove(0); } TranslateY.Add(time, new FSKAKeyNode() { Value = value, Slope = slope, Slope2 = slope2, Delta = delta, Frame = time, }); break; case 0x18: if (TranslateZ.Count > 0 && frame == 0) { TranslateZ.Remove(0); } TranslateZ.Add(time, new FSKAKeyNode() { Value = value, Slope = slope, Slope2 = slope2, Delta = delta, Frame = time, }); break; case 0x20: if (RotateX.Count > 0 && frame == 0) { RotateX.Remove(0); } RotateX.Add(time, new FSKAKeyNode() { Value = value, Slope = slope, Slope2 = slope2, Delta = delta, Frame = time, }); break; case 0x24: if (RotateY.Count > 0 && frame == 0) { RotateY.Remove(0); } RotateY.Add(time, new FSKAKeyNode() { Value = value, Slope = slope, Slope2 = slope2, Delta = delta, Frame = time, }); break; case 0x28: if (RotateZ.Count > 0 && frame == 0) { RotateZ.Remove(0); } RotateZ.Add(time, new FSKAKeyNode() { Value = value, Slope = slope, Slope2 = slope2, Delta = delta, Frame = time, }); break; case 0x04: if (ScaleX.Count > 0 && frame == 0) { ScaleX.Remove(0); } ScaleX.Add(time, new FSKAKeyNode() { Value = value, Slope = slope, Slope2 = slope2, Delta = delta, Frame = time, }); break; case 0x08: if (ScaleY.Count > 0 && frame == 0) { ScaleY.Remove(0); } ScaleY.Add(time, new FSKAKeyNode() { Value = value, Slope = slope, Slope2 = slope2, Delta = delta, Frame = time, }); break; case 0x0C: if (ScaleZ.Count > 0 && frame == 0) { ScaleZ.Remove(0); } ScaleZ.Add(time, new FSKAKeyNode() { Value = value, Slope = slope, Slope2 = slope2, Delta = delta, Frame = time, }); break; } } } for (int frame = 0; frame < chr0.FrameCount; frame++) { if (TranslateX.ContainsKey(frame)) { chr0Entry.SetKeyframe(6, frame, TranslateX[frame].Value); } if (TranslateY.ContainsKey(frame)) { chr0Entry.SetKeyframe(7, frame, TranslateY[frame].Value); } if (TranslateZ.ContainsKey(frame)) { chr0Entry.SetKeyframe(8, frame, TranslateZ[frame].Value); } if (RotateX.ContainsKey(frame)) { chr0Entry.SetKeyframe(3, frame, RotateX[frame].Value * Rad2Deg); } if (RotateY.ContainsKey(frame)) { chr0Entry.SetKeyframe(4, frame, RotateY[frame].Value * Rad2Deg); } if (RotateZ.ContainsKey(frame)) { chr0Entry.SetKeyframe(5, frame, RotateZ[frame].Value * Rad2Deg); } if (ScaleX.ContainsKey(frame)) { chr0Entry.SetKeyframe(0, frame, ScaleX[frame].Value); } if (ScaleY.ContainsKey(frame)) { chr0Entry.SetKeyframe(1, frame, ScaleY[frame].Value); } if (ScaleZ.ContainsKey(frame)) { chr0Entry.SetKeyframe(2, frame, ScaleZ[frame].Value); } } }
private void keyframes_Paint(object sender, PaintEventArgs e) { //Nonstop paint? //if (_mainWindow == null) return; KeyframeEntry kfe; CHR0EntryNode entry = null; int cellDims = 0, keyDims = 0; Pen pen = new Pen(Color.LightBlue, 1); if (lstBones.Items.Count > 0) { cellDims = lstBones.PreferredHeight / lstBones.Items.Count; keyDims = cellDims - 2; } int rectX = -(keyDims / 2), rectY = -2; //Keyframes lie on column lines, but in between row lines if (SelectedCHR0 != null && TargetModel != null && lstBones.Items.Count != 0) { bgLayer.Width = SelectedCHR0.FrameCount * cellDims; //For frames e.Graphics.DrawRectangle(pen, 0, 0, bgLayer.Width, 20); //Columns for (int frame = 0; frame < SelectedCHR0.FrameCount; frame++) { } int x = 0, y = 0; //Rows foreach (MDL0BoneNode b in lstBones.Items) { //Get line color if (TargetBone != null && TargetBone.Name == b.Name) { pen.Color = Color.Green; //Selected bone } else if (SelectedCHR0 != null && (entry = SelectedCHR0.FindChild(b.Name, false) as CHR0EntryNode) != null) { if (b._render) { pen.Color = Color.Blue; //Rendered bone has keyframe } else { pen.Color = Color.Red; //Unrendered bone has keyframe } } else { pen.Color = Color.Orange; //Bone doesn't have keyframe regardless } //Draw Line e.Graphics.DrawLine(pen, new Point(0, y), new Point(bgLayer.Width, y)); //Change pen back to black for keyframes pen.Color = Color.Black; int offset = cellDims; e.Graphics.RotateTransform(45); //Mark keyframe spots if (entry != null) { for (int frame = 0; frame < SelectedCHR0.FrameCount; frame++, offset += cellDims, x++) { for (int i = 0x10; i < 0x19; i++) { if ((kfe = entry.GetKeyframe((KeyFrameMode)i, frame)) != null) { e.Graphics.DrawRectangle(pen, x + rectX, y + rectY, keyDims, keyDims); break; //Only one keyframe needs to be marked } } } } e.Graphics.RotateTransform(-45); entry = null; y += cellDims; x = 0; } } }
public static CHR0Node Convert(string input) { try { CHR0Node chr0 = new CHR0Node { Name = Path.GetFileNameWithoutExtension(input), Loop = false, Version = 4 }; List<string> boneNames = new List<string>(); List<int> boneIDs = new List<int>(); int lineNumber = 0; bool isReadingBones = false; bool isReadingFrames = false; int currentFrameID = new int(); float radianFloat = 57.29579143313326f; //Angles are given in radians. To convert them into degrees, multiply them by this float. List<SMDFrame> allFrames = new List<SMDFrame>(); for (TextReader reader = new StreamReader(input); reader.Peek() != -1;) //Writing data into Lists { string line = reader.ReadLine(); if (line.CompareTo("end") == 0) //When reaching this line, we stop reading what we were reading { isReadingBones = false; isReadingFrames = false; } if (isReadingBones) { string[] splitLine = line.Split('\"'); int boneID = int.Parse(splitLine[0].Split(' ')[0]); string boneName = splitLine[1]; boneIDs.Add(boneID); boneNames.Add(boneName); } if(isReadingFrames) { SMDFrame currentFrame = new SMDFrame(); if(line.Contains("time ")) { currentFrameID = int.Parse(line.Split(' ')[1]); line = reader.ReadLine(); lineNumber++; } string[] frameNumbers = line.Split(' '); int boneID = int.Parse(frameNumbers[0], CultureInfo.InvariantCulture.NumberFormat); float posX = float.Parse(frameNumbers[2], CultureInfo.InvariantCulture.NumberFormat); float posY = float.Parse(frameNumbers[3], CultureInfo.InvariantCulture.NumberFormat); float posZ = float.Parse(frameNumbers[4], CultureInfo.InvariantCulture.NumberFormat); float rotX = float.Parse(frameNumbers[6], CultureInfo.InvariantCulture.NumberFormat) * radianFloat; float rotY = float.Parse(frameNumbers[7], CultureInfo.InvariantCulture.NumberFormat) * radianFloat; float rotZ = float.Parse(frameNumbers[8], CultureInfo.InvariantCulture.NumberFormat) * radianFloat; currentFrame = new SMDFrame(currentFrameID, boneID, posX, posY, posZ, rotX, rotY, rotZ); allFrames.Add(currentFrame); } if (lineNumber == 0) //First Line { if (line.CompareTo("version 1") != 0) //The first line contains the version number. It needs to be 1. { MessageBox.Show("Unsupported SMD Version. Please use SMD Version 1."); //I don't even know if there's versions >1 but let's not take risks return null; } } if (line.CompareTo("nodes") == 0) //When reaching this line, we start reading bones names { isReadingBones = true; } if (line.CompareTo("skeleton") == 0) //When reaching this line, we start reading frames { isReadingFrames = true; } lineNumber++; } foreach (int thisBone in boneIDs) { CHR0EntryNode node = new CHR0EntryNode(); chr0.AddChild(node); node.Name = boneNames[thisBone]; node.SetSize(currentFrameID + 1, true); int keynum = 0; foreach (SMDFrame currentFrame in allFrames) { //Keyframe Array documentation: // --------------------- // | | X | Y | Z | // | Scale | 0 | 1 | 2 | // | Rot | 3 | 4 | 5 | // | Pos | 6 | 7 | 8 | // --------------------- if (currentFrame.boneID == thisBone) { node.SetKeyframe(3, currentFrame.id, currentFrame.rotx); node.SetKeyframe(4, currentFrame.id, currentFrame.roty); node.SetKeyframe(5, currentFrame.id, currentFrame.rotz); node.SetKeyframe(6, currentFrame.id, currentFrame.posx); node.SetKeyframe(7, currentFrame.id, currentFrame.posy); node.SetKeyframe(8, currentFrame.id, currentFrame.posz); keynum++; } } chr0.FrameCount = keynum; chr0.Loop = true; } return chr0; } catch (Exception e) { MessageBox.Show("There was a problem importing keyframes.\n\nError:\n" + e); return null; } }
internal unsafe void BoxChanged(object sender, EventArgs e) { if (_transformObject == null) { return; } NumericInputBox box = sender as NumericInputBox; int index = (int)box.Tag; if (_transformObject is MDL0BoneNode) { MDL0BoneNode bone = _transformObject as MDL0BoneNode; if ((_selectedAnim != null) && (_animFrame > 0)) { //Find bone anim and change transform CHR0EntryNode entry = _selectedAnim.FindChild(bone.Name, false) as CHR0EntryNode; if (entry == null) //Create new bone animation { if (!float.IsNaN(box.Value)) { entry = _selectedAnim.CreateEntry(); entry._name = bone.Name; //Set initial values FrameState state = bone._bindState; float * p = (float *)&state; for (int i = 0; i < 3; i++) { if (p[i] != 1.0f) { entry.SetKeyframe(KeyFrameMode.ScaleX + i, 0, p[i]); } } for (int i = 3; i < 9; i++) { if (p[i] != 0.0f) { entry.SetKeyframe(KeyFrameMode.ScaleX + i, 0, p[i]); } } entry.SetKeyframe(KeyFrameMode.ScaleX + index, _animFrame - 1, box.Value); } } else //Set existing { if (float.IsNaN(box.Value)) { entry.RemoveKeyframe(KeyFrameMode.ScaleX + index, _animFrame - 1); } else { entry.SetKeyframe(KeyFrameMode.ScaleX + index, _animFrame - 1, box.Value); } } } else { //Change base transform FrameState state = bone._bindState; float * p = (float *)&state; p[index] = float.IsNaN(box.Value) ? (index > 2 ? 0.0f : 1.0f) : box.Value; state.CalcTransforms(); bone._bindState = state; bone.RecalcBindState(); bone.SignalPropertyChange(); } _targetModel.ApplyCHR(_selectedAnim, _animFrame); ResetBox(index); if (RenderStateChanged != null) { RenderStateChanged(this, null); } } }