public override TOutput Process(TInput input, ContentProcessorContext context) { MD5Bounds maximumBounds = input.Bounds[0]; for (int i = 1; i < input.Bounds.Length; i++) { MD5Bounds bound = input.Bounds[i]; bound.Minimum -= input.GetFrameSkeleton(i).RootPosition - input.GetFrameSkeleton(0).RootPosition; maximumBounds.Minimum.X = Math.Min(maximumBounds.Minimum.X, bound.Minimum.X); maximumBounds.Minimum.Y = Math.Min(maximumBounds.Minimum.Y, bound.Minimum.Y); maximumBounds.Minimum.Z = Math.Min(maximumBounds.Minimum.Z, bound.Minimum.Z); bound.Maximum -= input.GetFrameSkeleton(i).RootPosition - input.GetFrameSkeleton(0).RootPosition; maximumBounds.Maximum.X = Math.Max(maximumBounds.Maximum.X, bound.Maximum.X); maximumBounds.Maximum.Y = Math.Max(maximumBounds.Maximum.Y, bound.Maximum.Y); maximumBounds.Maximum.Z = Math.Max(maximumBounds.Maximum.Z, bound.Maximum.Z); } input.MaximumBounds = new BoundingBox(maximumBounds.Minimum, maximumBounds.Maximum); return(input); }
public void LoadAnimation(string filename) { int i, j; int version; string animFilename = filename; int numberOfFrames; int numberOfJoints; int numberOfAnimatedComponents; animFilename = filename; string line; string[] split; MD5Hierarchy[] hierarchy; MD5Bounds[] bounds; MD5Frame[] baseFrames; MD5Frame[] frames; if (!File.Exists(filename)) { throw new FileNotFoundException("File " + filename + " not found in directory " + Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "."); } FileStream fs = new FileStream(filename, FileMode.Open); StreamReader reader = new StreamReader(fs); #region LINE 1 - MD5Version line = MD5MeshContent.ReadLine(reader); if (!line.StartsWith("MD5Version")) { throw new Exception("File " + filename + "is not a valid .md5anim."); } version = int.Parse(line.Substring(10)); #endregion #region LINE 2 - commandline (discard) line = MD5MeshContent.ReadLine(reader); #endregion #region LINE 3 - Number Of Frames line = MD5MeshContent.LookForLine(reader, "numFrames"); numberOfFrames = int.Parse(line.Substring(10)); #endregion #region LINE 4 - Number Of Joints line = MD5MeshContent.LookForLine(reader, "numJoints"); numberOfJoints = int.Parse(line.Substring(10)); #endregion #region LINE 5 - Frames per Second line = MD5MeshContent.LookForLine(reader, "frameRate"); secondsPerFrame = 1.0f / int.Parse(line.Substring(10)); #endregion #region LINE 6 - Number Of AnimatedComponents line = MD5MeshContent.LookForLine(reader, "numAnimatedComponents"); numberOfAnimatedComponents = int.Parse(line.Substring(22)); #endregion #region CHUNK - Hierarchy line = MD5MeshContent.LookForLine(reader, "hierarchy"); hierarchy = new MD5Hierarchy[numberOfJoints]; flags = new int[numberOfJoints]; for (i = 0; i < numberOfJoints; i++) { MD5Hierarchy joint = new MD5Hierarchy(); line = MD5MeshContent.ReadLine(reader); if (line.StartsWith("}")) { throw new Exception("MD5Anim " + animFilename + " is invalid: Hierarchy chuck has missing joints."); } split = line.Split(new char[] { '"', ' ' }); for (j = 0; j < split.Length; j++) { split[j] = split[j].Trim(); } joint.Name = split[1]; joint.Parent = int.Parse(split[2]); joint.Flags = int.Parse(split[3]); joint.StartIndex = int.Parse(split[4]); hierarchy[i] = joint; flags[i] = joint.Flags; } #endregion #region CHUNK - Bounds line = MD5MeshContent.LookForLine(reader, "bounds"); bounds = new MD5Bounds[numberOfFrames]; for (i = 0; i < numberOfFrames; i++) { MD5Bounds bounding = new MD5Bounds(); line = MD5MeshContent.ReadLine(reader); if (line.StartsWith("}")) { throw new Exception("MD5Anim " + animFilename + " is invalid: Bounds chuck has missing frames."); } split = line.Split(new char[] { '(', ' ', ')' }); for (j = 0; j < split.Length; j++) { split[j] = split[j].Trim(); } bounding.Minimum = new Vector3(float.Parse(split[2]), float.Parse(split[4]), float.Parse(split[3])); bounding.Maximum = new Vector3(float.Parse(split[9]), float.Parse(split[11]), float.Parse(split[10])); bounds[i] = bounding; } this.Bounds = bounds; #endregion #region CHUNK - BaseFrame line = MD5MeshContent.LookForLine(reader, "baseframe"); baseFrames = new MD5Frame[numberOfJoints]; for (i = 0; i < numberOfJoints; i++) { MD5Frame baseFrame = new MD5Frame(); baseFrame.Data = new float[6]; line = MD5MeshContent.ReadLine(reader); if (line.StartsWith("}")) { throw new Exception("MD5Anim " + animFilename + " is invalid: Bounds chuck has missing frames."); } split = line.Split(new char[] { '(', ' ', ')' }); for (j = 0; j < split.Length; j++) { split[j] = split[j].Trim(); } baseFrame.Data[0] = float.Parse(split[2]); baseFrame.Data[1] = float.Parse(split[3]); baseFrame.Data[2] = float.Parse(split[4]); baseFrame.Data[3] = float.Parse(split[9]); baseFrame.Data[4] = float.Parse(split[10]); baseFrame.Data[5] = float.Parse(split[11]); baseFrames[i] = baseFrame; } #endregion #region CHUNKS - Frame Data frames = new MD5Frame[numberOfFrames]; for (i = 0; i < frames.Length; i++) { string chunk = ""; MD5Frame frame = new MD5Frame(); frame.Data = new float[numberOfAnimatedComponents]; line = MD5MeshContent.LookForLine(reader, "frame " + i.ToString() + " {"); while (!line.Contains("}")) { if (reader.EndOfStream) { throw new Exception("MD5Anim " + animFilename + " is invalid: Frame chunk " + i + " is malformed."); } line = MD5MeshContent.ReadLine(reader); if (!line.Contains("}")) { chunk += line + ' '; } else { chunk = chunk.Substring(0, chunk.Length - 1); } } StringReader sr = new StringReader(chunk); split = chunk.Split(new char[] { ' ' }); for (j = 0; j < frame.Data.Length; j++) { frame.Data[j] = float.Parse(split[j]); } frames[i] = frame; } #endregion reader.Dispose(); fs.Dispose(); // If every joint's flag field is set to 63, recalculate the flags, as the flags were probably improperly exported if (numberOfAnimatedComponents == hierarchy.Length * 6) { flags = RecalculateFlags(numberOfJoints, baseFrames, frames); } ComputeFrameSkeletons(hierarchy, baseFrames, frames); }