private void ReadTransformAnimations(ANIM animFile, AnimGroup animGroup, SBAnimation animation) { var decoder = new SSBHAnimTrackDecoder(animFile); foreach (AnimNode animNode in animGroup.Nodes) { SBTransformAnimation tfrmAnim = new SBTransformAnimation() { Name = animNode.Name }; foreach (AnimTrack track in animNode.Tracks) { object[] Transform = decoder.ReadTrack(track); if (track.Name.Equals("Transform")) { for (int i = 0; i < Transform.Length; i++) { AnimTrackTransform t = (AnimTrackTransform)Transform[i]; tfrmAnim.Transform.Keys.Add(new SBAnimKey <Matrix4>() { Frame = i, Value = GetMatrix((AnimTrackTransform)Transform[i]), }); } } } animation.TransformNodes.Add(tfrmAnim); } }
private void UpdateSBSkeleton(SBSkeleton skeleton, Dictionary <String, SBTransformAnimation> transformNodes, int frame) { foreach (var nodeName in transformNodes.Keys) { SBTransformAnimation a = transformNodes[nodeName]; SBBone bone = skeleton[nodeName]; bone.AnimatedTransform = a.GetTransformAt(frame, bone); } }
public SBAnimation ImportSBAnimation(string FileName, SBSkeleton skeleton) { IO_MayaANIM anim = new IO_MayaANIM(); anim.Open(FileName); var animation = new SBAnimation(); animation.Name = Path.GetFileNameWithoutExtension(FileName); animation.FrameCount = anim.header.endTime - 1; foreach (var node in anim.Bones) { SBTransformAnimation a = new SBTransformAnimation(); a.Name = node.name; animation.TransformNodes.Add(a); foreach (var att in node.atts) { if (!trackTypeConversion.ContainsKey(att.type)) { continue; } SBTransformTrack track = new SBTransformTrack(trackTypeConversion[att.type]); a.Tracks.Add(track); foreach (var key in att.keys) { InterpolationType itype = InterpolationType.Linear; float intan = 0; float outtan = 0; if (key.intan == "fixed") { itype = InterpolationType.Hermite; intan = key.t1; } if (key.outtan == "fixed") { itype = InterpolationType.Hermite; outtan = key.t2; } track.AddKey(key.input - header.startTime, GetOutputValue(anim, att, key.output), itype, intan , outtan); } } } return(animation); }
public static void ExportIOAnimationAsANIM(string fname, SBAnimation animation, SBSkeleton Skeleton, bool ordinal = false) { IO_MayaANIM anim = new IO_MayaANIM(); anim.header.endTime = animation.FrameCount + 1; // get bone order List <SBBone> BonesInOrder = getBoneTreeOrder(Skeleton); if (ordinal) { BonesInOrder = BonesInOrder.OrderBy(f => f.Name, StringComparer.Ordinal).ToList(); } foreach (SBBone b in BonesInOrder) { AnimBone animBone = new AnimBone() { name = b.Name }; anim.Bones.Add(animBone); // Add Tracks SBTransformAnimation node = null; foreach (var animNode in animation.TransformNodes) { if (animNode.Name.Equals(b.Name)) { node = animNode; break; } } if (node == null) { continue; } AddAnimData(animBone, node.Transform, ControlType.translate, TrackType.translateX); AddAnimData(animBone, node.Transform, ControlType.translate, TrackType.translateY); AddAnimData(animBone, node.Transform, ControlType.translate, TrackType.translateZ); AddAnimData(animBone, node.Transform, ControlType.rotate, TrackType.rotateX); AddAnimData(animBone, node.Transform, ControlType.rotate, TrackType.rotateY); AddAnimData(animBone, node.Transform, ControlType.rotate, TrackType.rotateZ); AddAnimData(animBone, node.Transform, ControlType.scale, TrackType.scaleX); AddAnimData(animBone, node.Transform, ControlType.scale, TrackType.scaleY); AddAnimData(animBone, node.Transform, ControlType.scale, TrackType.scaleZ); } anim.Save(fname); }
private void ReadTransformAnimations(Anim animFile, AnimGroup animGroup, SBAnimation animation) { var decoder = new SsbhAnimTrackDecoder(animFile); foreach (AnimNode animNode in animGroup.Nodes) { SBTransformAnimation tfrmAnim = new SBTransformAnimation() { Name = animNode.Name }; SBTransformTrack X = new SBTransformTrack(SBTrackType.TranslateX); SBTransformTrack Y = new SBTransformTrack(SBTrackType.TranslateY); SBTransformTrack Z = new SBTransformTrack(SBTrackType.TranslateZ); SBTransformTrack RX = new SBTransformTrack(SBTrackType.RotateX); SBTransformTrack RY = new SBTransformTrack(SBTrackType.RotateY); SBTransformTrack RZ = new SBTransformTrack(SBTrackType.RotateZ); SBTransformTrack SX = new SBTransformTrack(SBTrackType.ScaleX); SBTransformTrack SY = new SBTransformTrack(SBTrackType.ScaleY); SBTransformTrack SZ = new SBTransformTrack(SBTrackType.ScaleZ); SBTransformTrack CompensateScale = new SBTransformTrack(SBTrackType.CompensateScale); tfrmAnim.Tracks.AddRange(new SBTransformTrack[] { X, Y, Z, RX, RY, RZ, SX, SY, SZ, CompensateScale }); foreach (AnimTrack track in animNode.Tracks) { object[] Transform = decoder.ReadTrack(track); if (track.Name.Equals("Transform")) { for (int i = 0; i < Transform.Length; i++) { AnimTrackTransform t = (AnimTrackTransform)Transform[i]; SBBone transform = new SBBone(); transform.Transform = GetMatrix((AnimTrackTransform)Transform[i]); X.AddKey(i, transform.X); Y.AddKey(i, transform.Y); Z.AddKey(i, transform.Z); RX.AddKey(i, transform.RX); RY.AddKey(i, transform.RY); RZ.AddKey(i, transform.RZ); SX.AddKey(i, transform.SX); SY.AddKey(i, transform.SY); SZ.AddKey(i, transform.SZ); CompensateScale.AddKey(i, t.CompensateScale); } } } animation.TransformNodes.Add(tfrmAnim); } }
public SBAnimation ImportSBAnimation(string FileName, SBSkeleton skeleton) { SMD smd = new SMD(); smd.Open(FileName); SBAnimation animation = new SBAnimation(); animation.Name = Path.GetFileNameWithoutExtension(FileName); Dictionary <int, SBTransformAnimation> idToAnim = new Dictionary <int, SBTransformAnimation>(); foreach (var node in smd.nodes) { var nodeAnim = new SBTransformAnimation() { Name = node.Name }; idToAnim.Add(node.ID, nodeAnim); animation.TransformNodes.Add(nodeAnim); } var frameCount = 0; foreach (var v in smd.skeleton) { frameCount = Math.Max(v.time, frameCount); foreach (var node in v.skeletons) { var animNode = idToAnim[node.BoneID]; animNode.AddKey(v.time, node.Position.X, SBTrackType.TranslateX); animNode.AddKey(v.time, node.Position.Y, SBTrackType.TranslateY); animNode.AddKey(v.time, node.Position.Z, SBTrackType.TranslateZ); animNode.AddKey(v.time, node.Rotation.X, SBTrackType.RotateX); animNode.AddKey(v.time, node.Rotation.Y, SBTrackType.RotateY); animNode.AddKey(v.time, node.Rotation.Z, SBTrackType.RotateZ); } } animation.FrameCount = frameCount; return(animation); }
/// <summary> /// /// </summary> /// <param name="FileName"></param> /// <param name="skeleton"></param> /// <returns></returns> public SBAnimation ImportSBAnimation(string FileName, SBSkeleton skeleton) { SEAnim anim = SEAnim.Read(FileName); var sbAnim = new SBAnimation(); sbAnim.FrameCount = anim.FrameCount; sbAnim.Name = anim.DeltaTagName; Dictionary <string, SBTransformAnimation> nameToAnim = new Dictionary <string, SBTransformAnimation>(); foreach (var v in anim.AnimationPositionKeys) { if (!nameToAnim.ContainsKey(v.Key)) { SBTransformAnimation an = new SBTransformAnimation(); an.Name = v.Key; nameToAnim.Add(v.Key, an); sbAnim.TransformNodes.Add(an); } var a = nameToAnim[v.Key]; foreach (var k in v.Value) { if (k.Data is SELib.Utilities.Vector2 vc) { a.AddKey(k.Frame, (float)vc.X, SBTrackType.TranslateX, InterpolationType.Linear); a.AddKey(k.Frame, (float)vc.Y, SBTrackType.TranslateY, InterpolationType.Linear); } if (k.Data is SELib.Utilities.Vector3 vc3) { a.AddKey(k.Frame, (float)vc3.X, SBTrackType.TranslateX, InterpolationType.Linear); a.AddKey(k.Frame, (float)vc3.Y, SBTrackType.TranslateY, InterpolationType.Linear); a.AddKey(k.Frame, (float)vc3.Z, SBTrackType.TranslateZ, InterpolationType.Linear); } } } foreach (var v in anim.AnimationRotationKeys) { if (!nameToAnim.ContainsKey(v.Key)) { SBTransformAnimation an = new SBTransformAnimation(); an.Name = v.Key; nameToAnim.Add(v.Key, an); sbAnim.TransformNodes.Add(an); } var a = nameToAnim[v.Key]; foreach (var k in v.Value) { if (k.Data is SELib.Utilities.Quaternion q) { var euler = Tools.CrossMath.ToEulerAngles(new OpenTK.Quaternion((float)q.X, (float)q.Y, (float)q.Z, (float)q.W).Inverted()); a.AddKey(k.Frame, (float)q.X, SBTrackType.RotateX, InterpolationType.Linear); a.AddKey(k.Frame, (float)q.Y, SBTrackType.RotateY, InterpolationType.Linear); a.AddKey(k.Frame, (float)q.Z, SBTrackType.RotateZ, InterpolationType.Linear); a.AddKey(k.Frame, (float)q.W, SBTrackType.RotateW, InterpolationType.Linear); } if (k.Data is SELib.Utilities.Vector3 vc) { a.AddKey(k.Frame, (float)vc.X, SBTrackType.RotateX, InterpolationType.Linear); a.AddKey(k.Frame, (float)vc.Y, SBTrackType.RotateY, InterpolationType.Linear); a.AddKey(k.Frame, (float)vc.Z, SBTrackType.RotateZ, InterpolationType.Linear); } } } foreach (var v in anim.AnimationScaleKeys) { if (!nameToAnim.ContainsKey(v.Key)) { SBTransformAnimation an = new SBTransformAnimation(); an.Name = v.Key; nameToAnim.Add(v.Key, an); sbAnim.TransformNodes.Add(an); } var a = nameToAnim[v.Key]; foreach (var k in v.Value) { if (k.Data is SELib.Utilities.Vector3 vc3) { a.AddKey(k.Frame, (float)vc3.X, SBTrackType.ScaleX, InterpolationType.Linear); a.AddKey(k.Frame, (float)vc3.Y, SBTrackType.ScaleY, InterpolationType.Linear); a.AddKey(k.Frame, (float)vc3.Z, SBTrackType.ScaleZ, InterpolationType.Linear); } } } return(sbAnim); }
public static void ExportIOAnimationAsANIM(string fname, SBAnimation animation, SBSkeleton Skeleton) { IO_MayaANIM anim = new IO_MayaANIM(); anim.header.endTime = animation.FrameCount + 1; if (!MayaSettings.UseRadians) { anim.header.angularUnit = "deg"; } // get bone order List <SBBone> BonesInOrder = getBoneTreeOrder(Skeleton); if (MayaSettings.Maya2015) { BonesInOrder = BonesInOrder.OrderBy(f => f.Name, StringComparer.Ordinal).ToList(); } if (MayaSettings.RemoveRedundantFrames) { animation.Optimize(); } foreach (SBBone b in BonesInOrder) { AnimBone animBone = new AnimBone() { name = b.Name }; anim.Bones.Add(animBone); // Add Tracks SBTransformAnimation node = null; foreach (var animNode in animation.TransformNodes) { if (animNode.Name.Equals(b.Name)) { node = animNode; break; } } if (node == null) { continue; } //TODO: bake scale for compensate scale... foreach (var track in node.Tracks) { switch (track.Type) { case SBTrackType.TranslateX: AddAnimData(animBone, track.Keys, ControlType.translate, TrackType.translateX); break; case SBTrackType.TranslateY: AddAnimData(animBone, track.Keys, ControlType.translate, TrackType.translateY); break; case SBTrackType.TranslateZ: AddAnimData(animBone, track.Keys, ControlType.translate, TrackType.translateZ); break; case SBTrackType.RotateX: AddAnimData(animBone, track.Keys, ControlType.rotate, TrackType.rotateX); break; case SBTrackType.RotateY: AddAnimData(animBone, track.Keys, ControlType.rotate, TrackType.rotateY); break; case SBTrackType.RotateZ: AddAnimData(animBone, track.Keys, ControlType.rotate, TrackType.rotateZ); break; case SBTrackType.ScaleX: AddAnimData(animBone, track.Keys, ControlType.scale, TrackType.scaleX); break; case SBTrackType.ScaleY: AddAnimData(animBone, track.Keys, ControlType.scale, TrackType.scaleY); break; case SBTrackType.ScaleZ: AddAnimData(animBone, track.Keys, ControlType.scale, TrackType.scaleZ); break; } } } anim.Save(fname); }
public SBAnimation ImportSBAnimation(string FileName, SBSkeleton skeleton, string jvcPath) { var sbAnim = new SBAnimation(); var jointTable = GetJointTable(jvcPath); var anim = new Anim(); using (BinaryReaderExt r = new BinaryReaderExt(new FileStream(FileName, FileMode.Open))) anim.Parse(r); float scale = Settings.FrameScale; sbAnim.FrameCount = (float)(scale * anim.EndTime); foreach (var j in anim.Joints) { if (j.BoneID == -1) { continue; } if (j.BoneID >= jointTable.Length || jointTable[j.BoneID] == -1 || jointTable[j.BoneID] >= skeleton.Bones.Length) { continue; } var bone = skeleton.Bones[jointTable[j.BoneID]]; SBTransformAnimation node = sbAnim.TransformNodes.Find(e => e.Name == bone.Name); if (node == null) { node = new SBTransformAnimation(); node.Name = bone.Name; sbAnim.TransformNodes.Add(node); } //Console.WriteLine(bone.Name); if (j.Flag3 == 0x21) { foreach (var k in j.Keys) { //Console.WriteLine($"\t{k.Time} {k.X} {k.Y} {k.Z} {k.W}"); node.AddKey((float)Math.Ceiling(k.Time * scale), bone.X + k.X, SBTrackType.TranslateX); node.AddKey((float)Math.Ceiling(k.Time * scale), bone.Y + k.Y, SBTrackType.TranslateY); node.AddKey((float)Math.Ceiling(k.Time * scale), bone.Z + k.Z, SBTrackType.TranslateZ); } } else if (j.Flag3 == 0x28) { var eul0 = ToQuat(bone.RotationQuaternion, j.Keys[0].W, new Vector3(j.Keys[0].X, j.Keys[0].Y, j.Keys[0].Z)); node.AddKey(0, eul0.X, SBTrackType.RotateX, InterpolationType.Step); node.AddKey(0, eul0.Y, SBTrackType.RotateY, InterpolationType.Step); node.AddKey(0, eul0.Z, SBTrackType.RotateZ, InterpolationType.Step); node.AddKey(0, eul0.W, SBTrackType.RotateW, InterpolationType.Step); foreach (var k in j.Keys) { var eul = ToQuat(bone.RotationQuaternion, k.W, new Vector3(k.X, k.Y, k.Z)); node.AddKey((float)Math.Ceiling(k.Time * scale), eul.X, SBTrackType.RotateX); node.AddKey((float)Math.Ceiling(k.Time * scale), eul.Y, SBTrackType.RotateY); node.AddKey((float)Math.Ceiling(k.Time * scale), eul.Z, SBTrackType.RotateZ); node.AddKey((float)Math.Ceiling(k.Time * scale), eul.W, SBTrackType.RotateW); } } else { SBConsole.WriteLine("Unknown MOT Track Type " + j.Flag3.ToString("X")); } } sbAnim.ConvertRotationKeysToEuler(); return(sbAnim); }
public SBAnimation ImportSBAnimation(string FileName, SBSkeleton skeleton) { SBAnimation anim = new SBAnimation(); HSDRawFile f = new HSDRawFile(FileName); foreach (var root in f.Roots) { if (root == null || root.Data == null) { continue; } anim.Name = root.Name; if (root.Data is HSD_AnimJoint joint) { var joints = joint.BreathFirstList; int nodeIndex = -1; foreach (var j in joints) { nodeIndex++; if (j.AOBJ == null || j.AOBJ.FObjDesc == null) { continue; } SBConsole.WriteLine(nodeIndex + " " + j.Flags.ToString("X8") + " " + j.AOBJ.Flags.ToString()); SBTransformAnimation a = new SBTransformAnimation(); if (nodeIndex < skeleton.Bones.Length) { a.Name = skeleton.Bones[nodeIndex].Name; } else { a.Name = "JOBJ_" + nodeIndex; } anim.TransformNodes.Add(a); anim.FrameCount = Math.Max(anim.FrameCount, j.AOBJ.EndFrame); foreach (var fobj in j.AOBJ.FObjDesc.List) { a.Tracks.Add(DecodeFOBJ(fobj.ToFOBJ())); } } } if (root.Data is HSD_FigaTree tree) { anim.FrameCount = tree.FrameCount; int nodeIndex = 0; foreach (var node in tree.Nodes) { SBTransformAnimation a = new SBTransformAnimation(); a.Name = skeleton.Bones[nodeIndex++].Name; anim.TransformNodes.Add(a); foreach (var att in node.Tracks) { if (att.FOBJ == null) { continue; } a.Tracks.Add(DecodeFOBJ(att.FOBJ)); } } } if (root.Data is HSD_MatAnimJoint matjoint) { var joints = matjoint.BreathFirstList; anim.FrameCount = 0; int nodeIndex = -1; foreach (var j in joints) { if (j.MaterialAnimation == null) { continue; } var matAnims = j.MaterialAnimation.List; foreach (var manim in matAnims) { nodeIndex++; var aobj = manim.AnimationObject; if (aobj != null) { anim.FrameCount = Math.Max(anim.FrameCount, aobj.EndFrame); } var texanim = manim.TextureAnimation; if (texanim == null) { continue; } var texAOBJ = texanim.AnimationObject; if (texAOBJ == null || texAOBJ.FObjDesc == null) { continue; } anim.FrameCount = Math.Max(anim.FrameCount, texAOBJ.EndFrame); //TODO: tex anim is a list if (texanim != null) { SBTextureAnimation textureAnim = new SBTextureAnimation(); anim.TextureNodes.Add(textureAnim); textureAnim.MeshName = "DOBJ_" + nodeIndex; textureAnim.TextureAttibute = texanim.GXTexMapID.ToString(); textureAnim.Keys = DecodeFOBJ(texAOBJ.FObjDesc.ToFOBJ()).Keys; for (int i = 0; i < texanim.ImageCount; i++) { HSD_TOBJ tobj = new HSD_TOBJ(); tobj.ImageData = texanim.ImageBuffers.Array[i].Data; if (texanim.TlutCount > i) { tobj.TlutData = texanim.TlutBuffers.Array[i].Data; } var surface = new SBSurface(); surface.Arrays.Add(new MipArray() { Mipmaps = new List <byte[]>() { tobj.GetDecodedImageData() } }); surface.Width = tobj.ImageData.Width; surface.Height = tobj.ImageData.Height; surface.PixelFormat = PixelFormat.Bgra; surface.PixelType = PixelType.UnsignedByte; surface.InternalFormat = InternalFormat.Rgba; textureAnim.Surfaces.Add(surface); } } } } SBConsole.WriteLine(nodeIndex); } } return(anim); }