public Animation(Stream animStream, bool leaveOpen = true, bool alwaysAddBones = false) { Animations = new List <Keyframe>(); // Convert OW Animation to our Animation Type using (BinaryReader animReader = new BinaryReader(animStream, Encoding.Default, leaveOpen)) { Header = animReader.Read <AnimHeader>(); Duration = Header.duration; FramesPerSecond = Header.fps; InfoTableSize = (int)(Header.fps * Header.duration) + 1; ushort bonecount = Header.bonecount; animStream.Seek((long)Header.boneListOffset, SeekOrigin.Begin); for (uint i = 0; i < Header.bonecount; i++) { int boneID = animReader.ReadInt32(); BoneList.Add(boneID); } Vec3d[,] ScaleValues = new Vec3d[bonecount, InfoTableSize]; Vec3d[,] PositionValues = new Vec3d[bonecount, InfoTableSize]; Vec4d[,] RotationValues = new Vec4d[bonecount, InfoTableSize]; bool[,] hasScale = new bool[bonecount, InfoTableSize]; bool[,] hasPosition = new bool[bonecount, InfoTableSize]; bool[,] hasRotation = new bool[bonecount, InfoTableSize]; animStream.Seek((long)Header.infoTableOffset, SeekOrigin.Begin); for (int boneid = 0; boneid < Header.bonecount; boneid++) { long animStreamPos = animStream.Position; AnimInfoTable it = animReader.Read <AnimInfoTable>(); long SIO = (long)it.ScaleIndicesOffset * 4 + animStreamPos; long PIO = (long)it.PositionIndicesOffset * 4 + animStreamPos; long RIO = (long)it.RotationIndicesOffset * 4 + animStreamPos; long SDO = (long)it.ScaleDataOffset * 4 + animStreamPos; long PDO = (long)it.PositionDataOffset * 4 + animStreamPos; long RDO = (long)it.RotationDataOffset * 4 + animStreamPos; InfoTables.Add(it); // Read Indices List <int> ScaleIndexList = new List <int>(); animStream.Seek(SIO, SeekOrigin.Begin); for (int j = 0; j < it.ScaleCount; j++) { if (InfoTableSize <= 255) { ScaleIndexList.Add((int)animReader.ReadByte()); } else { ScaleIndexList.Add((int)animReader.ReadInt16()); } } List <int> PositonIndexList = new List <int>(); animStream.Seek(PIO, SeekOrigin.Begin); for (int j = 0; j < it.PositionCount; j++) { if (InfoTableSize <= 255) { PositonIndexList.Add((int)animReader.ReadByte()); } else { PositonIndexList.Add((int)animReader.ReadInt16()); } } List <int> RotationIndexList = new List <int>(); animStream.Seek(RIO, SeekOrigin.Begin); for (int j = 0; j < it.RotationCount; j++) { if (InfoTableSize <= 255) { RotationIndexList.Add((int)animReader.ReadByte()); } else { RotationIndexList.Add((int)animReader.ReadInt16()); } } // Read Data animStream.Seek(SDO, SeekOrigin.Begin); for (int j = 0; j < it.ScaleCount; j++) { int Index = Math.Abs(ScaleIndexList[j]) % InfoTableSize; hasScale[boneid, Index] = true; ushort x = animReader.ReadUInt16(); ushort y = animReader.ReadUInt16(); ushort z = animReader.ReadUInt16(); Vec3d values = UnpackScale(x, y, z); ScaleValues[boneid, Index] = values; } animStream.Seek(PDO, SeekOrigin.Begin); for (int j = 0; j < it.PositionCount; j++) { int Index = Math.Abs(PositonIndexList[j]) % InfoTableSize; hasPosition[boneid, Index] = true; float x = animReader.ReadSingle(); float y = animReader.ReadSingle(); float z = animReader.ReadSingle(); Vec3d values = new Vec3d(x, y, z); PositionValues[boneid, Index] = values; } animStream.Seek(RDO, SeekOrigin.Begin); for (int j = 0; j < it.RotationCount; j++) { int Index = Math.Abs(RotationIndexList[j]) % InfoTableSize; ushort x = animReader.ReadUInt16(); ushort y = animReader.ReadUInt16(); ushort z = animReader.ReadUInt16(); Vec4d values = UnpackRotation(x, y, z); hasRotation[boneid, Index] = true; RotationValues[boneid, Index] = values; } animStream.Seek(animStreamPos + 32L, SeekOrigin.Begin); } for (int frame = 0; frame < InfoTableSize; frame++) { Keyframe kf = new Keyframe(); kf.FramePosition = ((float)frame / FramesPerSecond); kf.FramePositionI = frame; kf.BoneFrames = new List <BoneAnimation>(); for (int bone = 0; bone < Header.bonecount; bone++) { // Build Value Data BoneAnimation ba = new BoneAnimation(); ba.BoneID = BoneList[bone]; ba.Values = new List <FrameValue>(); if (hasScale[bone, frame]) { Vec3d v = ScaleValues[bone, frame]; FrameValue fv = new FrameValue(AnimChannelID.SCALE, v); ba.Values.Add(fv); } if (hasPosition[bone, frame]) { Vec3d v = PositionValues[bone, frame]; FrameValue f = new FrameValue(AnimChannelID.POSITION, v); ba.Values.Add(f); } if (hasRotation[bone, frame]) { Vec4d v = RotationValues[bone, frame]; FrameValue f = new FrameValue(AnimChannelID.ROTATION, v); ba.Values.Add(f); } if (ba.Values.Count > 0 || alwaysAddBones) { kf.BoneFrames.Add(ba); } } if (kf.BoneFrames.Count > 0) { Animations.Add(kf); } } } }
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); }
/// <summary>Load animation from a stream</summary> public teAnimation(Stream stream, bool keepOpen = false) { using (BinaryReader reader = new BinaryReader(stream, Encoding.Default, keepOpen)) { Header = reader.Read <AnimHeader>(); InfoTableSize = (int)(Header.FPS * Header.Duration) + 1; reader.BaseStream.Position = Header.BoneListOffset; BoneList = reader.ReadArray <int>(Header.BoneCount); reader.BaseStream.Position = Header.InfoTableOffset; InfoTables = new InfoTable[Header.BoneCount]; BoneAnimations = new BoneAnimation[Header.BoneCount]; for (int boneIndex = 0; boneIndex < Header.BoneCount; boneIndex++) { long streamPos = reader.BaseStream.Position; InfoTable infoTable = reader.Read <InfoTable>(); long afterTablePos = reader.BaseStream.Position; InfoTables[boneIndex] = infoTable; long scaleIndicesPos = (long)infoTable.ScaleIndicesOffset * 4 + streamPos; long positionIndicesPos = (long)infoTable.PositionIndicesOffset * 4 + streamPos; long rotationIndicesPos = (long)infoTable.RotationIndicesOffset * 4 + streamPos; long scaleDataPos = (long)infoTable.ScaleDataOffset * 4 + streamPos; long positionDataPos = (long)infoTable.PositionDataOffset * 4 + streamPos; long rotationDataPos = (long)infoTable.RotationDataOffset * 4 + streamPos; reader.BaseStream.Position = scaleIndicesPos; int[] scaleIndices = ReadIndices(reader, infoTable.ScaleCount); reader.BaseStream.Position = positionIndicesPos; int[] positionIndices = ReadIndices(reader, infoTable.PositionCount); reader.BaseStream.Position = rotationIndicesPos; int[] rotationIndices = ReadIndices(reader, infoTable.RotationCount); BoneAnimation boneAnimation = new BoneAnimation(); BoneAnimations[boneIndex] = boneAnimation; reader.BaseStream.Position = scaleDataPos; for (int j = 0; j < infoTable.ScaleCount; j++) { int frame = System.Math.Abs(scaleIndices[j]) % InfoTableSize; boneAnimation.Scales[frame] = ReadScale(reader); } reader.BaseStream.Position = positionDataPos; for (int j = 0; j < infoTable.PositionCount; j++) { int frame = System.Math.Abs(positionIndices[j]) % InfoTableSize; boneAnimation.Positions[frame] = ReadPosition(reader); } reader.BaseStream.Position = rotationDataPos; for (int j = 0; j < infoTable.RotationCount; j++) { int frame = System.Math.Abs(rotationIndices[j]) % InfoTableSize; boneAnimation.Rotations[frame] = ReadRotation(reader); } reader.BaseStream.Position = afterTablePos; } } }
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("}"); } } else { file.WriteLine("anim " + b.Text + " 0 0 0;"); } } } }
public static void CreateANIM(string fname, Animation a, STSkeleton vbn) { System.Globalization.CultureInfo customCulture = (System.Globalization.CultureInfo)System.Threading.Thread.CurrentThread.CurrentCulture.Clone(); customCulture.NumberFormat.NumberDecimalSeparator = "."; 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, false, true); } a.NextFrame(vbn, false, true); //go on first frame int i = 0; // writing node attributes foreach (STBone 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", n.UseSegmentScaleCompensate); 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", n.UseSegmentScaleCompensate); 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", n.UseSegmentScaleCompensate); file.WriteLine("}"); } if (ac == 0) { file.WriteLine("anim " + b.Text + " 0 0 0;"); } } else { file.WriteLine("anim " + b.Text + " 0 0 0;"); } } } }