public static Animation Read(string fname, STSkeleton v) { Animation a = new Animation(); StreamReader reader = File.OpenText(fname); string line; string current = ""; bool readBones = false; int frame = 0, prevframe = 0; Animation.KeyFrame k = new Animation.KeyFrame(); STSkeleton vbn = v; if (v != null && v.bones.Count == 0) { readBones = true; } else { vbn = new STSkeleton(); } 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 Animation.KeyFrame(); k.Frame = frame; //a.addKeyframe(k); } continue; } if (current.Equals("nodes")) { STBone b = new STBone(vbn); b.Text = args[1].Replace("\"", ""); b.parentIndex = int.Parse(args[2]); //b.children = new System.Collections.Generic.List<int> (); vbn.bones.Add(b); Animation.KeyNode node = new Animation.KeyNode(b.Text); a.Bones.Add(node); } if (current.Equals("time")) { // reading the skeleton if this isn't an animation if (readBones && frame == 0) { STBone b = vbn.bones[int.Parse(args[0])]; b.Position = new Vector3( float.Parse(args[1]), float.Parse(args[2]), float.Parse(args[3])); b.EulerRotation = new Vector3( float.Parse(args[4]), float.Parse(args[5]), float.Parse(args[6])); b.Scale = Vector3.One; b.pos = new Vector3(float.Parse(args[1]), float.Parse(args[2]), float.Parse(args[3])); b.rot = STSkeleton.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); } else { bone.XSCA.Keys.Add(new Animation.KeyFrame() { Value = 1.0f, Frame = frame, }); bone.YSCA.Keys.Add(new Animation.KeyFrame() { Value = 1.0f, Frame = frame, }); bone.ZSCA.Keys.Add(new Animation.KeyFrame() { Value = 1.0f, Frame = frame, }); } } } a.FrameCount = frame; vbn.update(); return(a); }
public static Animations.Animation CreateGenericAnimation(Assimp.Animation animation) { Animations.Animation STanim = new Animations.Animation(); STanim.Text = animation.Name; float TicksPerSecond = animation.TicksPerSecond != 0 ? (float)animation.TicksPerSecond : 25.0f; float Duriation = (float)animation.DurationInTicks; STanim.FrameCount = (int)(Duriation * 30); //Load node animations if (animation.HasNodeAnimations) { var _channels = new NodeAnimationChannel[animation.NodeAnimationChannelCount]; for (int i = 0; i < _channels.Length; i++) { _channels[i] = new NodeAnimationChannel(); var boneAnim = new Animations.Animation.KeyNode(_channels[i].NodeName); boneAnim.RotType = Animations.Animation.RotationType.EULER; STanim.Bones.Add(boneAnim); STConsole.WriteLine($"Creating Bone Anims {boneAnim.Text} "); for (int frame = 0; frame < STanim.FrameCount; i++) { if (_channels[i].HasPositionKeys) { for (int key = 0; key < _channels[i].PositionKeyCount; key++) { if (frame == _channels[i].PositionKeys[key].Time) { boneAnim.XPOS.Keys.Add(new Animations.Animation.KeyFrame() { Value = _channels[i].PositionKeys[key].Value.X, Frame = frame, }); boneAnim.YPOS.Keys.Add(new Animations.Animation.KeyFrame() { Value = _channels[i].PositionKeys[key].Value.Y, Frame = frame, }); boneAnim.ZPOS.Keys.Add(new Animations.Animation.KeyFrame() { Value = _channels[i].PositionKeys[key].Value.Z, Frame = frame, }); } } } if (_channels[i].HasRotationKeys) { for (int key = 0; key < _channels[i].RotationKeyCount; key++) { if (frame == _channels[i].RotationKeys[key].Time) { var quat = _channels[i].RotationKeys[key].Value; var euler = STMath.ToEulerAngles(quat.X, quat.Y, quat.Z, quat.W); boneAnim.XROT.Keys.Add(new Animations.Animation.KeyFrame() { Value = euler.X, Frame = frame, }); boneAnim.YROT.Keys.Add(new Animations.Animation.KeyFrame() { Value = euler.Y, Frame = frame, }); boneAnim.ZROT.Keys.Add(new Animations.Animation.KeyFrame() { Value = euler.Z, Frame = frame, }); boneAnim.WROT.Keys.Add(new Animations.Animation.KeyFrame() { Value = 1, Frame = frame, }); } } } if (_channels[i].HasScalingKeys) { for (int key = 0; key < _channels[i].ScalingKeyCount; key++) { if (frame == _channels[i].ScalingKeys[key].Time) { boneAnim.XSCA.Keys.Add(new Animations.Animation.KeyFrame() { Value = _channels[i].ScalingKeys[key].Value.X, Frame = frame, }); boneAnim.YSCA.Keys.Add(new Animations.Animation.KeyFrame() { Value = _channels[i].ScalingKeys[key].Value.Y, Frame = frame, }); boneAnim.ZSCA.Keys.Add(new Animations.Animation.KeyFrame() { Value = _channels[i].ScalingKeys[key].Value.Z, Frame = frame, }); } } } } } } //Load mesh animations if (animation.HasMeshAnimations) { var _meshChannels = new MeshAnimationChannel[animation.MeshAnimationChannelCount]; for (int i = 0; i < _meshChannels.Length; i++) { _meshChannels[i] = new MeshAnimationChannel(); } } return(STanim); }
public static Animation Read(string FileName, STSkeleton skeleton) { Animation anim = new Animation(); var seanim = SEAnim.Read(FileName); anim.FrameCount = seanim.FrameCount; anim.CanLoop = seanim.Looping; foreach (var bone in seanim.Bones) { STBone genericBone = skeleton.GetBone(bone); if (genericBone != null) { var boneAnim = new Animation.KeyNode(bone); boneAnim.RotType = Animation.RotationType.EULER; boneAnim.UseSegmentScaleCompensate = false; anim.Bones.Add(boneAnim); float PositionX = 0; float PositionY = 0; float PositionZ = 0; float RotationX = 0; float RotationY = 0; float RotationZ = 0; float ScaleX = 0; float ScaleY = 0; float ScaleZ = 0; if (seanim.AnimType == AnimationType.Relative) { PositionX = genericBone.Position.X; PositionY = genericBone.Position.Y; PositionZ = genericBone.Position.Z; RotationX = genericBone.EulerRotation.X; RotationY = genericBone.EulerRotation.Y; RotationZ = genericBone.EulerRotation.Z; ScaleX = genericBone.Scale.X; ScaleY = genericBone.Scale.Y; ScaleZ = genericBone.Scale.Z; } System.Console.WriteLine(bone); if (seanim.AnimationPositionKeys.ContainsKey(bone)) { var translationKeys = seanim.AnimationPositionKeys[bone]; foreach (SEAnimFrame animFrame in translationKeys) { System.Console.WriteLine(animFrame.Frame + " T " + ((SELib.Utilities.Vector3)animFrame.Data).X); System.Console.WriteLine(animFrame.Frame + " T " + ((SELib.Utilities.Vector3)animFrame.Data).Y); System.Console.WriteLine(animFrame.Frame + " T " + ((SELib.Utilities.Vector3)animFrame.Data).Z); boneAnim.XPOS.Keys.Add(new Animation.KeyFrame() { Value = (float)((SELib.Utilities.Vector3)animFrame.Data).X + PositionX, Frame = animFrame.Frame, }); boneAnim.YPOS.Keys.Add(new Animation.KeyFrame() { Value = (float)((SELib.Utilities.Vector3)animFrame.Data).Y + PositionY, Frame = animFrame.Frame, }); boneAnim.ZPOS.Keys.Add(new Animation.KeyFrame() { Value = (float)((SELib.Utilities.Vector3)animFrame.Data).Z + PositionZ, Frame = animFrame.Frame, }); } } if (seanim.AnimationRotationKeys.ContainsKey(bone)) { var rotationnKeys = seanim.AnimationRotationKeys[bone]; foreach (SEAnimFrame animFrame in rotationnKeys) { var quat = ((SELib.Utilities.Quaternion)animFrame.Data); var euler = STMath.ToEulerAngles(quat.X, quat.Y, quat.Z, quat.W); System.Console.WriteLine(animFrame.Frame + " R " + euler.X); System.Console.WriteLine(animFrame.Frame + " R " + euler.Y); System.Console.WriteLine(animFrame.Frame + " R " + euler.Z); boneAnim.XROT.Keys.Add(new Animation.KeyFrame() { Value = euler.X + RotationX, Frame = animFrame.Frame, }); boneAnim.YROT.Keys.Add(new Animation.KeyFrame() { Value = euler.Y + RotationY, Frame = animFrame.Frame, }); boneAnim.ZROT.Keys.Add(new Animation.KeyFrame() { Value = euler.Z + RotationZ, Frame = animFrame.Frame, }); } } if (seanim.AnimationScaleKeys.ContainsKey(bone)) { var scaleKeys = seanim.AnimationScaleKeys[bone]; foreach (SEAnimFrame animFrame in scaleKeys) { System.Console.WriteLine(animFrame.Frame + " S " + ((SELib.Utilities.Vector3)animFrame.Data).X); System.Console.WriteLine(animFrame.Frame + " S " + ((SELib.Utilities.Vector3)animFrame.Data).Y); System.Console.WriteLine(animFrame.Frame + " S " + ((SELib.Utilities.Vector3)animFrame.Data).Z); boneAnim.XSCA.Keys.Add(new Animation.KeyFrame() { Value = (float)((SELib.Utilities.Vector3)animFrame.Data).X + ScaleX, Frame = animFrame.Frame, }); boneAnim.YSCA.Keys.Add(new Animation.KeyFrame() { Value = (float)((SELib.Utilities.Vector3)animFrame.Data).Y + ScaleY, Frame = animFrame.Frame, }); boneAnim.ZSCA.Keys.Add(new Animation.KeyFrame() { Value = (float)((SELib.Utilities.Vector3)animFrame.Data).Z + ScaleZ, Frame = animFrame.Frame, }); } } else { boneAnim.XSCA.Keys.Add(new Animation.KeyFrame() { Value = 1, Frame = 0, }); boneAnim.YSCA.Keys.Add(new Animation.KeyFrame() { Value = 1, Frame = 0, }); boneAnim.ZSCA.Keys.Add(new Animation.KeyFrame() { Value = 1, Frame = 0, }); } } } return(anim); }
public static void SaveAnimation(string FileName, Animation anim, STSkeleton skeleton) { anim.SetFrame(anim.FrameCount - 1); //from last frame for (int f = 0; f < anim.FrameCount; ++f) //go through each frame with nextFrame { anim.NextFrame(skeleton); } anim.NextFrame(skeleton); //go on first frame foreach (STBone b in skeleton.getBoneTreeOrder()) { if (anim.HasBone(b.Text)) { Animation.KeyNode n = anim.GetBone(b.Text); if (n.XPOS.HasAnimation()) { WriteKey(n.XPOS); } if (n.YPOS.HasAnimation()) { WriteKey(n.YPOS); } if (n.ZPOS.HasAnimation()) { WriteKey(n.ZPOS); } if (n.XROT.HasAnimation()) { WriteKey(n.XROT); } if (n.YROT.HasAnimation()) { WriteKey(n.YROT); } if (n.ZROT.HasAnimation()) { WriteKey(n.ZROT); } if (n.XSCA.HasAnimation()) { WriteKey(n.XSCA); } if (n.YSCA.HasAnimation()) { WriteKey(n.YSCA); } if (n.ZSCA.HasAnimation()) { WriteKey(n.ZSCA); } } } SEAnim seAnim = new SEAnim(); seAnim.Looping = anim.CanLoop; seAnim.AnimType = AnimationType.Absolute; //Reset active animation to 0 anim.SetFrame(0); for (int frame = 0; frame < anim.FrameCount; frame++) { anim.NextFrame(skeleton, false, true); foreach (Animation.KeyNode boneAnim in anim.Bones) { if (boneAnim.HasKeyedFrames(frame)) { STBone bone = skeleton.GetBone(boneAnim.Text); if (bone == null) { continue; } Vector3 position = bone.GetPosition(); Quaternion rotation = bone.GetRotation(); Vector3 scale = bone.GetScale(); //Exporting at specific keys doesn't work atm //Todo bool IsTranlationKeyed = (boneAnim.XPOS.GetKeyFrame(frame).IsKeyed || boneAnim.YPOS.GetKeyFrame(frame).IsKeyed || boneAnim.ZPOS.GetKeyFrame(frame).IsKeyed); bool IsRotationKeyed = (boneAnim.XROT.GetKeyFrame(frame).IsKeyed || boneAnim.YROT.GetKeyFrame(frame).IsKeyed || boneAnim.ZROT.GetKeyFrame(frame).IsKeyed); bool IsScaleKeyed = (boneAnim.XSCA.GetKeyFrame(frame).IsKeyed || boneAnim.YSCA.GetKeyFrame(frame).IsKeyed || boneAnim.ZSCA.GetKeyFrame(frame).IsKeyed); seAnim.AddTranslationKey(boneAnim.Text, frame, position.X, position.Y, position.Z); seAnim.AddRotationKey(boneAnim.Text, frame, rotation.X, rotation.Y, rotation.Z, rotation.W); seAnim.AddScaleKey(boneAnim.Text, frame, scale.X, scale.Y, scale.Z); } } } seAnim.Write(FileName); }
public static Animation read(string filename, STSkeleton vbn) { StreamReader reader = File.OpenText(filename); string line; bool isHeader = true; string angularUnit, linearUnit, timeUnit; int startTime = 0; int endTime = 0; List <AnimBone> bones = new List <AnimBone>(); Animation.KeyNode current = null; Animation.KeyFrame att = new Animation.KeyFrame(); bool inKeys = false; string type = ""; Animation a = new Animation(filename); while ((line = reader.ReadLine()) != null) { string[] args = line.Replace(";", "").TrimStart().Split(' '); if (isHeader) { if (args [0].Equals("anim")) { isHeader = false; } else if (args [0].Equals("angularUnit")) { angularUnit = args [1]; } else if (args [0].Equals("endTime")) { endTime = (int)Math.Ceiling(float.Parse(args [1])); } else if (args [0].Equals("startTime")) { startTime = (int)Math.Ceiling(float.Parse(args [1])); } } if (!isHeader) { 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 *= Deg2Rad; } //k.intan = (args [2]); //k.outtan = (args [3]); if (args.Length > 7 && att.Weighted) { k.In = float.Parse(args[7]) * Deg2Rad; k.Out = float.Parse(args[8]) * Deg2Rad; } } 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 = 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; } } } a.FrameCount = endTime - 1; reader.Close(); return(a); }
private static void writeKey(StreamWriter file, Animation.KeyGroup keys, Animation.KeyNode rt, int size, string type, bool useSegmentCompenseateScale = false) { bool isAngular = type == "rotateX" || type == "rotateY" || type == "rotateZ"; // string interp = isAngular ? "angular" : "linear"; string interp = "linear"; file.WriteLine("animData {"); file.WriteLine(" input time;"); file.WriteLine($" output {interp};"); file.WriteLine(" weighted 1;"); file.WriteLine(" preInfinity constant;"); file.WriteLine(" postInfinity constant;"); file.WriteLine(" keys {"); if (((Animation.KeyFrame)keys.Keys[0]).InterType == InterpolationType.CONSTANT) { size = 1; } int f = 1; foreach (Animation.KeyFrame key in keys.Keys) { float v = 0; switch (type) { case "translateX": case "translateY": case "translateZ": v = key.Value; break; case "rotateX": if (rt.RotType == Animation.RotationType.EULER) { v = key.Value * Rad2Deg; } if (rt.RotType == Animation.RotationType.QUATERNION) { Quaternion q = new Quaternion(rt.XROT.GetValue(key.Frame), rt.YROT.GetValue(key.Frame), rt.ZROT.GetValue(key.Frame), rt.WROT.GetValue(key.Frame)); v = quattoeul(q).X *Rad2Deg; } break; case "rotateY": if (rt.RotType == Animation.RotationType.EULER) { v = key.Value * Rad2Deg; } if (rt.RotType == Animation.RotationType.QUATERNION) { Quaternion q = new Quaternion(rt.XROT.GetValue(key.Frame), rt.YROT.GetValue(key.Frame), rt.ZROT.GetValue(key.Frame), rt.WROT.GetValue(key.Frame)); v = quattoeul(q).Y *Rad2Deg; } break; case "rotateZ": if (rt.RotType == Animation.RotationType.EULER) { v = key.Value * Rad2Deg; } if (rt.RotType == Animation.RotationType.QUATERNION) { Quaternion q = new Quaternion(rt.XROT.GetValue(key.Frame), rt.YROT.GetValue(key.Frame), rt.ZROT.GetValue(key.Frame), rt.WROT.GetValue(key.Frame)); v = quattoeul(q).Z *Rad2Deg; } break; case "scaleX": case "scaleY": case "scaleZ": if (useSegmentCompenseateScale) { v = 1f / key.Value; } else { v = key.Value; } break; } file.WriteLine(" " + (key.Frame + 1) + " {0:N6} fixed fixed 1 1 0 0 1 0 1;", v); } file.WriteLine(" }"); }
public static void CreateANIM(string fname, Animation a, STSkeleton 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, 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;"); } } } }