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(); }
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 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 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; } }