public static void process(FileData d, int type, int secOff, Animation.KeyNode node, String part, bool debug, Animation a) { int offset = d.ReadInt() + secOff; int temp = d.Pos(); d.Seek(offset); int max = 0; int fCount = -1; float scale = 0; float[] frame = null, step = null, tan = null; if (type == 0x1) { fCount = d.ReadUShort(); d.Skip(2); scale = d.ReadFloat(); float stepb = d.ReadFloat(); float base2 = d.ReadFloat(); frame = new float[fCount]; step = new float[fCount]; tan = new float[fCount]; for (int i = 0; i < fCount; i++) { frame[i] = d.ReadByte(); int th = d.ReadThree(); step[i] = base2 + ((th >> 12) & 0xfff) * stepb; tan[i] = (FileData.Sign12Bit(th & 0xfff) / 32f); if (frame[i] > max) { max = (int)frame[i]; } } } if (type == 0x2) { fCount = d.ReadUShort(); d.Skip(2); scale = d.ReadFloat(); float stepb = d.ReadFloat(); float base2 = d.ReadFloat(); frame = new float[fCount]; step = new float[fCount]; tan = new float[fCount]; for (int i = 0; i < fCount; i++) { frame[i] = d.ReadUShort() / 32f; step[i] = base2 + d.ReadUShort() * stepb; tan[i] = (d.ReadShort() / 256f); if (frame[i] > max) { max = (int)frame[i]; } } } if (type == 0x3) { //if(debug) //System.out.println(part + "\tInterpolated 12 " + Integer.toHexString(offset)); fCount = d.ReadUShort(); d.Skip(2); scale = d.ReadFloat(); frame = new float[fCount]; step = new float[fCount]; tan = new float[fCount]; for (int i = 0; i < fCount; i++) { frame[i] = d.ReadFloat(); step[i] = d.ReadFloat(); tan[i] = d.ReadFloat(); if (frame[i] > max) { max = (int)frame[i]; } } } //a.FrameCount = max; float degrad = (float)(Math.PI / 180f); if (frame != null) { for (int i = 0; i < fCount; i++) { Animation.KeyFrame f = new Animation.KeyFrame(); f.interType = Animation.InterpolationType.Hermite; f.Value = step[i]; f.Frame = frame[i]; f.In = tan[i]; switch (part) { case "RX": f.Value = step[i] * degrad; node.xrot.keys.Add(f); f.degrees = true; break; case "RY": f.Value = step[i] * degrad; node.yrot.keys.Add(f); f.degrees = true; break; case "RZ": f.Value = step[i] * degrad; node.zrot.keys.Add(f); f.degrees = true; break; case "X": node.xpos.keys.Add(f); break; case "Y": node.ypos.keys.Add(f); break; case "Z": node.zpos.keys.Add(f); break; case "SX": node.xsca.keys.Add(f); break; case "SY": node.ysca.keys.Add(f); break; case "SZ": node.zsca.keys.Add(f); break; } } } if (type == 0x4) { float stepb = d.ReadFloat(); float base2 = d.ReadFloat(); for (int i = 0; i < a.frameCount; i++) { float v = base2 + stepb * (d.ReadByte()); Animation.KeyFrame f = new Animation.KeyFrame(); f.interType = Animation.InterpolationType.Linear; f.Value = v; f.Frame = i; switch (part) { case "RX": f.Value = v * degrad; node.xrot.keys.Add(f); break; case "RY": f.Value = v * degrad; node.yrot.keys.Add(f); break; case "RZ": f.Value = v * degrad; node.zrot.keys.Add(f); break; case "X": node.xpos.keys.Add(f); break; case "Y": node.ypos.keys.Add(f); break; case "Z": node.zpos.keys.Add(f); break; case "SX": node.xsca.keys.Add(f); break; case "SY": node.ysca.keys.Add(f); break; case "SZ": node.zsca.keys.Add(f); break; } } } if (type == 0x6) { for (int i = 0; i < a.frameCount; i++) { float v = d.ReadFloat(); Animation.KeyFrame f = new Animation.KeyFrame(); f.interType = Animation.InterpolationType.Linear; f.Value = v; f.Frame = i; switch (part) { case "RX": f.Value = v * degrad; node.xrot.keys.Add(f); break; case "RY": f.Value = v * degrad; node.yrot.keys.Add(f); break; case "RZ": f.Value = v * degrad; node.zrot.keys.Add(f); break; case "X": node.xpos.keys.Add(f); break; case "Y": node.ypos.keys.Add(f); break; case "Z": node.zpos.keys.Add(f); break; case "SX": node.xsca.keys.Add(f); break; case "SY": node.ysca.keys.Add(f); break; case "SZ": node.zsca.keys.Add(f); break; } } } d.Seek(temp); }
private static void getAnimationKeyFrame(FileData input, Animation.KeyGroup group, out float endFrame) { float startFrame = input.ReadFloat(); endFrame = input.ReadFloat(); uint frameFlags = (uint)input.ReadInt(); //Debug.WriteLine(frameFlags.ToString("x")); //int preRepeat = (RenderBase.ORepeatMethod)(frameFlags & 0xf); //int postRepeat = (RenderBase.ORepeatMethod)((frameFlags >> 8) & 0xf); uint segmentFlags = (uint)input.ReadInt(); int interpolation = ((int)segmentFlags & 0xf); uint quantization = ((segmentFlags >> 8) & 0xff); uint entries = segmentFlags >> 16; float valueScale = input.ReadFloat(); float valueOffset = input.ReadFloat(); float frameScale = input.ReadFloat(); float frameOffset = input.ReadFloat(); uint offset = (uint)input.ReadInt(); if (offset < input.Size()) { input.Seek((int)offset); } for (int key = 0; key < entries; key++) { Animation.KeyFrame keyFrame = new Animation.KeyFrame(); //Console.WriteLine(quantization); switch (quantization) { /*case RenderBase.OSegmentQuantization.hermite128: * keyFrame.frame = input.ReadSingle(); * keyFrame.value = input.ReadSingle(); * keyFrame.inSlope = input.ReadSingle(); * keyFrame.outSlope = input.ReadSingle(); * break; * case RenderBase.OSegmentQuantization.hermite64: * uint h64Value = input.ReadUInt32(); * keyFrame.frame = h64Value & 0xfff; * keyFrame.value = h64Value >> 12; * keyFrame.inSlope = input.ReadInt16() / 256f; * keyFrame.outSlope = input.ReadInt16() / 256f; * break; * case RenderBase.OSegmentQuantization.hermite48: * keyFrame.frame = input.ReadByte(); * keyFrame.value = input.ReadUInt16(); * byte slope0 = input.ReadByte(); * byte slope1 = input.ReadByte(); * byte slope2 = input.ReadByte(); * keyFrame.inSlope = IOUtils.signExtend(slope0 | ((slope1 & 0xf) << 8), 12) / 32f; * keyFrame.outSlope = IOUtils.signExtend((slope1 >> 4) | (slope2 << 4), 12) / 32f; * break; * case RenderBase.OSegmentQuantization.unifiedHermite96: * keyFrame.frame = input.ReadSingle(); * keyFrame.value = input.ReadSingle(); * keyFrame.inSlope = input.ReadSingle(); * keyFrame.outSlope = keyFrame.inSlope; * break; * case RenderBase.OSegmentQuantization.unifiedHermite48: * keyFrame.frame = input.ReadUInt16() / 32f; * keyFrame.value = input.ReadUInt16(); * keyFrame.inSlope = input.ReadInt16() / 256f; * keyFrame.outSlope = keyFrame.inSlope; * break; * case RenderBase.OSegmentQuantization.unifiedHermite32: * keyFrame.frame = input.ReadByte(); * ushort uH32Value = input.ReadUInt16(); * keyFrame.value = uH32Value & 0xfff; * keyFrame.inSlope = IOUtils.signExtend((uH32Value >> 12) | (input.ReadByte() << 4), 12) / 32f; * keyFrame.outSlope = keyFrame.inSlope; * break; * case RenderBase.OSegmentQuantization.stepLinear64: * keyFrame.frame = input.ReadSingle(); * keyFrame.value = input.ReadSingle(); * break;*/ case 7: // RenderBase.OSegmentQuantization.stepLinear32: uint sL32Value = (uint)input.ReadInt(); keyFrame.Frame = sL32Value & 0xfff; keyFrame.Value = sL32Value >> 12; break; default: Console.WriteLine("Unknown type " + quantization); break; } keyFrame.Frame = (keyFrame.Frame * frameScale) + frameOffset; keyFrame.Value = (keyFrame.Value * valueScale) + valueOffset; group.keys.Add(keyFrame); } }
public static AnimationGroupNode Read(string filename) { bchHeader header = new bchHeader(); FileData f = new FileData(filename); f.endian = System.IO.Endianness.Little; f.Skip(4); header.backwardCompatibility = f.ReadByte(); header.forwardCompatibility = f.ReadByte(); header.version = f.ReadUShort(); header.mainHeaderOffset = f.ReadInt(); header.stringTableOffset = f.ReadInt(); header.gpuCommandsOffset = f.ReadInt(); header.dataOffset = f.ReadInt(); if (header.backwardCompatibility > 0x20) { header.dataExtendedOffset = f.ReadInt(); } header.relocationTableOffset = f.ReadInt(); header.mainHeaderLength = f.ReadInt(); header.stringTableLength = f.ReadInt(); header.gpuCommandsLength = f.ReadInt(); header.dataLength = f.ReadInt(); if (header.backwardCompatibility > 0x20) { header.dataExtendedLength = f.ReadInt(); } header.relocationTableLength = f.ReadInt(); header.uninitializedDataSectionLength = f.ReadInt(); header.uninitializedDescriptionSectionLength = f.ReadInt(); if (header.backwardCompatibility > 7) { header.flags = f.ReadUShort(); header.addressCount = f.ReadUShort(); } // Relocation table for (int i = 0; i < header.relocationTableLength; i += 4) { f.Seek(header.relocationTableOffset + i); int val = f.ReadInt(); int off = val & 0x1FFFFFF; byte flag = (byte)(val >> 25); switch (flag) { case 0: f.Seek((off * 4) + header.mainHeaderOffset); f.WriteInt((off * 4) + header.mainHeaderOffset, f.ReadInt() + header.mainHeaderOffset); break; case 1: f.Seek(off + header.mainHeaderOffset); f.WriteInt((off) + header.mainHeaderOffset, f.ReadInt() + header.stringTableOffset); break; case 2: f.Seek((off * 4) + header.mainHeaderOffset); f.WriteInt((off * 4) + header.mainHeaderOffset, f.ReadInt() + header.gpuCommandsOffset); break; case 0xc: f.Seek((off * 4) + header.mainHeaderOffset); f.WriteInt((off * 4) + header.mainHeaderOffset, f.ReadInt() + header.dataOffset); break; } } // Content Header f.Seek(header.mainHeaderOffset); bchContentHeader content = new bchContentHeader(); { content.modelsPointerTableOffset = f.ReadInt(); content.modelsPointerTableEntries = f.ReadInt(); content.modelsNameOffset = f.ReadInt(); content.materialsPointerTableOffset = f.ReadInt(); content.materialsPointerTableEntries = f.ReadInt(); content.materialsNameOffset = f.ReadInt(); content.shadersPointerTableOffset = f.ReadInt(); content.shadersPointerTableEntries = f.ReadInt(); content.shadersNameOffset = f.ReadInt(); content.texturesPointerTableOffset = f.ReadInt(); content.texturesPointerTableEntries = f.ReadInt(); content.texturesNameOffset = f.ReadInt(); content.materialsLUTPointerTableOffset = f.ReadInt(); content.materialsLUTPointerTableEntries = f.ReadInt(); content.materialsLUTNameOffset = f.ReadInt(); content.lightsPointerTableOffset = f.ReadInt(); content.lightsPointerTableEntries = f.ReadInt(); content.lightsNameOffset = f.ReadInt(); content.camerasPointerTableOffset = f.ReadInt(); content.camerasPointerTableEntries = f.ReadInt(); content.camerasNameOffset = f.ReadInt(); content.fogsPointerTableOffset = f.ReadInt(); content.fogsPointerTableEntries = f.ReadInt(); content.fogsNameOffset = f.ReadInt(); content.skeletalAnimationsPointerTableOffset = f.ReadInt(); content.skeletalAnimationsPointerTableEntries = f.ReadInt(); content.skeletalAnimationsNameOffset = f.ReadInt(); content.materialAnimationsPointerTableOffset = f.ReadInt(); content.materialAnimationsPointerTableEntries = f.ReadInt(); content.materialAnimationsNameOffset = f.ReadInt(); content.visibilityAnimationsPointerTableOffset = f.ReadInt(); content.visibilityAnimationsPointerTableEntries = f.ReadInt(); content.visibilityAnimationsNameOffset = f.ReadInt(); content.lightAnimationsPointerTableOffset = f.ReadInt(); content.lightAnimationsPointerTableEntries = f.ReadInt(); content.lightAnimationsNameOffset = f.ReadInt(); content.cameraAnimationsPointerTableOffset = f.ReadInt(); content.cameraAnimationsPointerTableEntries = f.ReadInt(); content.cameraAnimationsNameOffset = f.ReadInt(); content.fogAnimationsPointerTableOffset = f.ReadInt(); content.fogAnimationsPointerTableEntries = f.ReadInt(); content.fogAnimationsNameOffset = f.ReadInt(); content.scenePointerTableOffset = f.ReadInt(); content.scenePointerTableEntries = f.ReadInt(); content.sceneNameOffset = f.ReadInt(); } //Skeletal animation AnimationGroupNode ThisAnimation = new AnimationGroupNode() { Text = filename }; for (int index1 = 0; index1 < content.skeletalAnimationsPointerTableEntries; index1++)// { f.Seek(content.skeletalAnimationsPointerTableOffset + (index1 * 4)); int dataOffset = f.ReadInt(); f.Seek(dataOffset); string skeletalAnimationName = f.ReadString(f.ReadInt(), -1); int animationFlags = f.ReadInt(); //int skeletalAnimationloopMode = f.readByte(); //pas ça du tout float skeletalAnimationframeSize = f.ReadFloat(); int boneTableOffset = f.ReadInt(); int boneTableEntries = f.ReadInt(); int metaDataPointerOffset = f.ReadInt(); //Runtime.Animations.Add(skeletalAnimationName, a); //MainForm.animNode.Nodes.Add(skeletalAnimationName); Animation a = new Animation(skeletalAnimationName); ThisAnimation.Nodes.Add(a); for (int i = 0; i < boneTableEntries; i++) { f.Seek(boneTableOffset + (i * 4)); int offset = f.ReadInt(); Animation.KeyNode bone = new Animation.KeyNode(""); a.bones.Add(bone); f.Seek(offset); bone.Text = f.ReadString(f.ReadInt(), -1); //Console.WriteLine("Bone Name: " + bone.name); int animationTypeFlags = f.ReadInt(); uint flags = (uint)f.ReadInt(); OSegmentType segmentType = (OSegmentType)((animationTypeFlags >> 16) & 0xf); //Debug.WriteLine(bone.Text + " " + flags.ToString("x")); switch (segmentType) { case OSegmentType.transform: f.Seek(offset + 0xC); //Console.WriteLine(f.pos().ToString("x") + " " + flags.ToString("x")); uint notExistMask = 0x10000; uint constantMask = 0x40; for (int j = 0; j < 3; j++) { for (int axis = 0; axis < 3; axis++) { bool notExist = (flags & notExistMask) > 0; bool constant = (flags & constantMask) > 0; //Console.WriteLine(notExist + " " + constant); Animation.KeyGroup group = new Animation.KeyGroup(); //frame.exists = !notExist; if (!notExist) { if (constant) { Animation.KeyFrame frame = new Animation.KeyFrame(); frame.interType = Animation.InterpolationType.Linear; frame.Value = f.ReadFloat(); frame.Frame = 0; group.keys.Add(frame); } else { int frameOffset = f.ReadInt(); int position = f.Pos(); f.Seek(frameOffset); float c = 0; //Debug.WriteLine(j + " " + axis + " " + bone.Text); getAnimationKeyFrame(f, group, out c); if (c > a.frameCount) { a.frameCount = (int)c; } f.Seek(position); } } else { f.Seek(f.Pos() + 0x04); } bone.rotType = Animation.RotationType.Euler; if (j == 0) { switch (axis) { case 0: bone.xsca = group; break; case 1: bone.ysca = group; break; case 2: bone.zsca = group; break; } } else if (j == 1) { switch (axis) { case 0: bone.xrot = group; break; case 1: bone.yrot = group; break; case 2: bone.zrot = group; break; } } else if (j == 2) { switch (axis) { case 0: bone.xpos = group; break; case 1: bone.ypos = group; break; case 2: bone.zpos = group; break; } } notExistMask <<= 1; constantMask <<= 1; } if (j == 1) { constantMask <<= 1; } } break; /*case OSegmentType.transformQuaternion: * bone.isFrameFormat = true; * * int scaleOffset = f.readInt(); * int rotationOffset = f.readInt(); * int translationOffset = f.readInt(); * * if ((flags & 0x20) == 0) * { * bone.scale.exists = true; * f.seek(scaleOffset); * * if ((flags & 4) > 0) * { * bone.scale.vector.Add(new Vector4( * f.readFloat(), * f.readFloat(), * f.readFloat(), * 0)); * } * else * { * bone.scale.startFrame = f.readFloat(); * bone.scale.endFrame = f.readFloat(); * * int scaleFlags = f.readInt(); * int scaleDataOffset = f.readInt(); * int scaleEntries = f.readInt(); * * f.seek(scaleDataOffset); * for (int j = 0; j < scaleEntries; j++) * { * bone.scale.vector.Add(new Vector4( * f.readFloat(), * f.readFloat(), * f.readFloat(), * 0)); * } * } * } * * if ((flags & 0x10) == 0) * { * bone.rotationQuaternion.exists = true; * f.seek(rotationOffset); * * if ((flags & 2) > 0) * { * bone.rotationQuaternion.vector.Add(new Vector4( * f.readFloat(), * f.readFloat(), * f.readFloat(), * f.readFloat())); * } * else * { * bone.rotationQuaternion.startFrame = f.readFloat(); * bone.rotationQuaternion.endFrame = f.readFloat(); * * int rotationFlags = f.readInt(); * int rotationDataOffset = f.readInt(); * int rotationEntries = f.readInt(); * * f.seek(rotationDataOffset); * for (int j = 0; j < rotationEntries; j++) * { * bone.rotationQuaternion.vector.Add(new Vector4( * f.readFloat(), * f.readFloat(), * f.readFloat(), * f.readFloat())); * } * } * } * * if ((flags & 8) == 0) * { * bone.translation.exists = true; * f.seek(translationOffset); * * if ((flags & 1) > 0) * { * bone.translation.vector.Add(new Vector4( * f.readFloat(), * f.readFloat(), * f.readFloat(), * 0)); * } * else * { * bone.translation.startFrame = f.readFloat(); * bone.translation.endFrame = f.readFloat(); * * int translationFlags = f.readInt(); * int translationDataOffset = f.readInt(); * int translationEntries = f.readInt(); * * f.seek(translationDataOffset); * for (int j = 0; j < translationEntries; j++) * { * bone.translation.vector.Add(new Vector4( * f.readFloat(), * f.readFloat(), * f.readFloat(), * 0)); * } * } * } * * break; * case OSegmentType.transformMatrix: * bone.isFullBakedFormat = true; * * f.readInt(); * f.readInt(); * int matrixOffset = f.readInt(); * int entries = f.readInt(); * * f.seek(matrixOffset); * for (int j = 0; j < entries; j++) * { * OMatrix transform = new OMatrix(); * transform.M11 = f.readFloat(); * transform.M21 = f.readFloat(); * transform.M31 = f.readFloat(); * transform.M41 = f.readFloat(); * * transform.M12 = f.readFloat(); * transform.M22 = f.readFloat(); * transform.M32 = f.readFloat(); * transform.M42 = f.readFloat(); * * transform.M13 = f.readFloat(); * transform.M23 = f.readFloat(); * transform.M33 = f.readFloat(); * transform.M43 = f.readFloat(); * * bone.transform.Add(transform); * } * * break;*/ default: throw new Exception(string.Format("BCH: Unknow Segment Type {0} on Skeletal Animation bone {1}! STOP!", segmentType, bone.Text)); } //skeletalAnimation.bone.Add(bone); } } //return a; return(ThisAnimation); }
public static void Read(string fname, Animation a, VBN v) { StreamReader reader = File.OpenText(fname); string line; string current = ""; bool readBones = false; int frame = 0, prevframe = 0; KeyFrame k = new KeyFrame(); VBN vbn = v; if (v != null && v.bones.Count == 0) { readBones = true; } else { vbn = new VBN(); } 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 KeyFrame(); k.frame = frame; //a.addKeyframe(k); } continue; } if (current.Equals("nodes")) { Bone b = new Bone(vbn); b.Text = args[1].Replace("\"", ""); b.parentIndex = int.Parse(args[2]); //b.children = new System.Collections.Generic.List<int> (); vbn.totalBoneCount++; vbn.bones.Add(b); Animation.KeyNode node = new Animation.KeyNode(b.Text); a.bones.Add(node); } if (current.Equals("time")) { //Animation.KeyFrame n = new Animation.KeyFrame(); /*n.id = v.boneIndex(vbn.bones[int.Parse(args[0])].Text); * if (n.id == -1) * { * continue; * } * else * n.hash = v.bones[n.id].boneId;*/ // only if it finds the node //k.addNode(n); // reading the skeleton if this isn't an animation if (readBones && frame == 0) { Bone b = vbn.bones[int.Parse(args[0])]; b.position = new float[3]; b.rotation = new float[3]; b.scale = new float[3]; b.position[0] = float.Parse(args[1]); b.position[1] = float.Parse(args[2]); b.position[2] = float.Parse(args[3]); b.rotation[0] = float.Parse(args[4]); b.rotation[1] = float.Parse(args[5]); b.rotation[2] = float.Parse(args[6]); b.scale[0] = 1f; b.scale[1] = 1f; b.scale[2] = 1f; b.pos = new Vector3(float.Parse(args[1]), float.Parse(args[2]), float.Parse(args[3])); b.rot = VBN.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); } } } a.frameCount = frame; vbn.boneCountPerType[0] = (uint)vbn.bones.Count; vbn.update(); }
public void Read(ResFile TargetWiiUBFRES, AnimationGroupNode ThisAnimation, ResNSW.ResFile b) { Console.WriteLine("Reading Skeleton Animations ..."); if (b != null) { TreeNode SkeletonAnimation = new TreeNode() { Text = "Skeleton Animations" }; ThisAnimation.Nodes.Add(SkeletonAnimation); TreeNode dummy = new TreeNode() { Text = "Animation Set" }; int i = 0; foreach (ResNSW.SkeletalAnim ska in b.SkeletalAnims) { if (i == 0) { dummy = new TreeNode() { Text = "Animation Set " + "0 - 100" }; SkeletonAnimation.Nodes.Add(dummy); } if (i == 100) { dummy = new TreeNode() { Text = "Animation Set " + "100 - 200" }; SkeletonAnimation.Nodes.Add(dummy); } if (i == 200) { dummy = new TreeNode() { Text = "Animation Set " + "200 - 300" }; SkeletonAnimation.Nodes.Add(dummy); } if (i == 300) { dummy = new TreeNode() { Text = "Animation Set " + "300 - 400" }; SkeletonAnimation.Nodes.Add(dummy); } if (i == 400) { dummy = new TreeNode() { Text = "Animation Set " + "400 - 500" }; SkeletonAnimation.Nodes.Add(dummy); } if (i == 500) { dummy = new TreeNode() { Text = "Animation Set " + "500 - 600" }; SkeletonAnimation.Nodes.Add(dummy); } if (i == 600) { dummy = new TreeNode() { Text = "Animation Set " + "600 - 700" }; SkeletonAnimation.Nodes.Add(dummy); } if (i == 700) { dummy = new TreeNode() { Text = "Animation Set " + "700 - 800" }; SkeletonAnimation.Nodes.Add(dummy); } if (i == 800) { dummy = new TreeNode() { Text = "Animation Set " + "800 - 900" }; SkeletonAnimation.Nodes.Add(dummy); } if (i == 900) { dummy = new TreeNode() { Text = "Animation Set " + "900 - 1000" }; SkeletonAnimation.Nodes.Add(dummy); } if (i == 1000) { dummy = new TreeNode() { Text = "Animation Set " + "1000+" }; SkeletonAnimation.Nodes.Add(dummy); } Animation a = new Animation(ska.Name); SkeletonAnimations.Add(a); a.frameCount = ska.FrameCount; if (i >= 0 && i < 100) { SkeletonAnimation.Nodes[0].Nodes.Add(a); } if (i >= 100 && i < 200) { SkeletonAnimation.Nodes[1].Nodes.Add(a); } if (i >= 200 && i < 300) { SkeletonAnimation.Nodes[2].Nodes.Add(a); } if (i >= 300 && i < 400) { SkeletonAnimation.Nodes[3].Nodes.Add(a); } if (i >= 400 && i < 500) { SkeletonAnimation.Nodes[4].Nodes.Add(a); } if (i >= 500 && i < 600) { SkeletonAnimation.Nodes[5].Nodes.Add(a); } if (i >= 600 && i < 700) { SkeletonAnimation.Nodes[6].Nodes.Add(a); } if (i >= 700 && i < 800) { SkeletonAnimation.Nodes[7].Nodes.Add(a); } if (i >= 800 && i < 900) { SkeletonAnimation.Nodes[8].Nodes.Add(a); } if (i >= 900 && i < 1000) { SkeletonAnimation.Nodes[9].Nodes.Add(a); } i++; try { foreach (ResNSW.BoneAnim bn in ska.BoneAnims) { FSKANode bonean = new FSKANode(bn); Animation.KeyNode bone = new Animation.KeyNode(""); a.bones.Add(bone); if (ska.FlagsRotate == ResNSW.SkeletalAnimFlagsRotate.EulerXYZ) { bone.rotType = Animation.RotationType.Euler; } else { bone.rotType = Animation.RotationType.Quaternion; } bone.Text = bonean.Text; for (int Frame = 0; Frame < ska.FrameCount; Frame++) { //Set base/start values for bones. //Note. BOTW doesn't use base values as it uses havok engine. Need to add option to disable these if (Frame == 0) { if (bn.FlagsBase.HasFlag(ResNSW.BoneAnimFlagsBase.Scale)) { bone.xsca.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.sca.X }); bone.ysca.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.sca.Y }); bone.zsca.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.sca.Z }); } if (bn.FlagsBase.HasFlag(ResNSW.BoneAnimFlagsBase.Rotate)) { bone.xrot.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.rot.X }); bone.yrot.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.rot.Y }); bone.zrot.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.rot.Z }); bone.wrot.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.rot.W }); } if (bn.FlagsBase.HasFlag(ResNSW.BoneAnimFlagsBase.Translate)) { bone.xpos.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.pos.X }); bone.ypos.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.pos.Y }); bone.zpos.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.pos.Z }); } } foreach (FSKATrack track in bonean.tracks) { Animation.KeyFrame frame = new Animation.KeyFrame(); frame.interType = Animation.InterpolationType.Hermite; frame.Frame = Frame; FSKAKey left = track.GetLeft(Frame); FSKAKey right = track.GetRight(Frame); float value; value = Animation.Hermite(Frame, left.frame, right.frame, 0, 0, left.unk1, right.unk1); // interpolate the value and apply switch (track.flag) { case (int)TrackType.XPOS: frame.Value = value; bone.xpos.keys.Add(frame); break; case (int)TrackType.YPOS: frame.Value = value; bone.ypos.keys.Add(frame); break; case (int)TrackType.ZPOS: frame.Value = value; bone.zpos.keys.Add(frame); break; case (int)TrackType.XROT: frame.Value = value; bone.xrot.keys.Add(frame); break; case (int)TrackType.YROT: frame.Value = value; bone.yrot.keys.Add(frame); break; case (int)TrackType.ZROT: frame.Value = value; bone.zrot.keys.Add(frame); break; case (int)TrackType.XSCA: frame.Value = value; bone.xsca.keys.Add(frame); break; case (int)TrackType.YSCA: frame.Value = value; bone.ysca.keys.Add(frame); break; case (int)TrackType.ZSCA: frame.Value = value; bone.zsca.keys.Add(frame); break; } } } } } catch { } } } else { TreeNode SkeletonAnimation = new TreeNode() { Text = "Skeleton Animations" }; ThisAnimation.Nodes.Add(SkeletonAnimation); TreeNode dummy = new TreeNode() { Text = "Animation Set" }; int i = 0; foreach (SkeletalAnim ska in TargetWiiUBFRES.SkeletalAnims.Values) { if (i == 0) { dummy = new TreeNode() { Text = "Animation Set " + "0 - 100" }; SkeletonAnimation.Nodes.Add(dummy); } if (i == 100) { dummy = new TreeNode() { Text = "Animation Set " + "100 - 200" }; SkeletonAnimation.Nodes.Add(dummy); } if (i == 200) { dummy = new TreeNode() { Text = "Animation Set " + "200 - 300" }; SkeletonAnimation.Nodes.Add(dummy); } if (i == 300) { dummy = new TreeNode() { Text = "Animation Set " + "300 - 400" }; SkeletonAnimation.Nodes.Add(dummy); } if (i == 400) { dummy = new TreeNode() { Text = "Animation Set " + "400 - 500" }; SkeletonAnimation.Nodes.Add(dummy); } if (i == 500) { dummy = new TreeNode() { Text = "Animation Set " + "500 - 600" }; SkeletonAnimation.Nodes.Add(dummy); } if (i == 600) { dummy = new TreeNode() { Text = "Animation Set " + "600 - 700" }; SkeletonAnimation.Nodes.Add(dummy); } if (i == 700) { dummy = new TreeNode() { Text = "Animation Set " + "700 - 800" }; SkeletonAnimation.Nodes.Add(dummy); } if (i == 800) { dummy = new TreeNode() { Text = "Animation Set " + "800 - 900" }; SkeletonAnimation.Nodes.Add(dummy); } if (i == 900) { dummy = new TreeNode() { Text = "Animation Set " + "900 - 1000" }; SkeletonAnimation.Nodes.Add(dummy); } if (i == 1000) { dummy = new TreeNode() { Text = "Animation Set " + "1000+" }; SkeletonAnimation.Nodes.Add(dummy); } Animation a = new Animation(ska.Name); if (i >= 0 && i < 100) { SkeletonAnimation.Nodes[0].Nodes.Add(a); } if (i >= 100 && i < 200) { SkeletonAnimation.Nodes[1].Nodes.Add(a); } if (i >= 200 && i < 300) { SkeletonAnimation.Nodes[2].Nodes.Add(a); } if (i >= 300 && i < 400) { SkeletonAnimation.Nodes[3].Nodes.Add(a); } if (i >= 400 && i < 500) { SkeletonAnimation.Nodes[4].Nodes.Add(a); } if (i >= 500 && i < 600) { SkeletonAnimation.Nodes[5].Nodes.Add(a); } if (i >= 600 && i < 700) { SkeletonAnimation.Nodes[6].Nodes.Add(a); } if (i >= 700 && i < 800) { SkeletonAnimation.Nodes[7].Nodes.Add(a); } if (i >= 800 && i < 900) { SkeletonAnimation.Nodes[8].Nodes.Add(a); } if (i >= 900 && i < 1000) { SkeletonAnimation.Nodes[9].Nodes.Add(a); } a.frameCount = ska.FrameCount; i++; try { foreach (BoneAnim bn in ska.BoneAnims) { FSKANodeWiiU bonean = new FSKANodeWiiU(bn); Animation.KeyNode bone = new Animation.KeyNode(""); a.bones.Add(bone); if (ska.FlagsRotate == SkeletalAnimFlagsRotate.EulerXYZ) { bone.rotType = Animation.RotationType.Euler; } else { bone.rotType = Animation.RotationType.Quaternion; } bone.Text = bonean.Text; for (int Frame = 0; Frame < ska.FrameCount; Frame++) { //Set base/start values for bones. //Note. BOTW doesn't use base values as it uses havok engine. Need to add option to disable these if (Frame == 0) { if (bn.FlagsBase.HasFlag(BoneAnimFlagsBase.Scale)) { bone.xsca.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.sca.X }); bone.ysca.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.sca.Y }); bone.zsca.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.sca.Z }); } if (bn.FlagsBase.HasFlag(BoneAnimFlagsBase.Rotate)) { bone.xrot.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.rot.X }); bone.yrot.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.rot.Y }); bone.zrot.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.rot.Z }); bone.wrot.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.rot.W }); } if (bn.FlagsBase.HasFlag(BoneAnimFlagsBase.Translate)) { bone.xpos.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.pos.X }); bone.ypos.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.pos.Y }); bone.zpos.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.pos.Z }); } } foreach (FSKATrack track in bonean.tracks) { Animation.KeyFrame frame = new Animation.KeyFrame(); frame.interType = Animation.InterpolationType.Hermite; frame.Frame = Frame; FSKAKey left = track.GetLeft(Frame); FSKAKey right = track.GetRight(Frame); float value; value = Animation.Hermite(Frame, left.frame, right.frame, 0, 0, left.unk1, right.unk1); // interpolate the value and apply switch (track.flag) { case (int)TrackType.XPOS: frame.Value = value; bone.xpos.keys.Add(frame); break; case (int)TrackType.YPOS: frame.Value = value; bone.ypos.keys.Add(frame); break; case (int)TrackType.ZPOS: frame.Value = value; bone.zpos.keys.Add(frame); break; case (int)TrackType.XROT: frame.Value = value; bone.xrot.keys.Add(frame); break; case (int)TrackType.YROT: frame.Value = value; bone.yrot.keys.Add(frame); break; case (int)TrackType.ZROT: frame.Value = value; bone.zrot.keys.Add(frame); break; case (int)TrackType.XSCA: frame.Value = value; bone.xsca.keys.Add(frame); break; case (int)TrackType.YSCA: frame.Value = value; bone.ysca.keys.Add(frame); break; case (int)TrackType.ZSCA: frame.Value = value; bone.zsca.keys.Add(frame); break; } } } } } catch { } } } }
public void Read(ResFile targetWiiUbfres, AnimationGroupNode thisAnimation, ResNSW.ResFile b) { Console.WriteLine("Reading Skeleton Animations ..."); if (b != null) { TreeNode skeletonAnimationNode = new TreeNode { Text = "Skeleton Animations" }; thisAnimation.Nodes.Add(skeletonAnimationNode); // Split animation nodes into groups so they can all fit inside the view. // Make sure to add an additional set if the animations can't be divided evenly. int setCount = b.SkeletalAnims.Count / setSize; if (b.SkeletalAnims.Count % setSize != 0) { setCount += 1; } for (int i = 0; i < setCount; i++) { int start = i * setSize; int end = start + setSize - 1; skeletonAnimationNode.Nodes.Add(new TreeNode { Text = $"Animation Set {start} - {end}" }); } for (int i = 0; i < b.SkeletalAnims.Count; i++) { var ska = b.SkeletalAnims[i]; int setIndex = i / setSize; Animation a = new Animation(ska.Name); SkeletonAnimations.Add(a); a.frameCount = ska.FrameCount; skeletonAnimationNode.Nodes[setIndex].Nodes.Add(a); try { foreach (ResNSW.BoneAnim bn in ska.BoneAnims) { FSKANode bonean = new FSKANode(bn); Animation.KeyNode bone = new Animation.KeyNode(""); a.bones.Add(bone); if (ska.FlagsRotate == ResNSW.SkeletalAnimFlagsRotate.EulerXYZ) { bone.rotType = Animation.RotationType.Euler; } else { bone.rotType = Animation.RotationType.Quaternion; } bone.Text = bonean.Text; for (int frame = 0; frame < ska.FrameCount; frame++) { //Set base/start values for bones. //Note. BOTW doesn't use base values as it uses havok engine. Need to add option to disable these if (frame == 0) { if (bn.FlagsBase.HasFlag(ResNSW.BoneAnimFlagsBase.Scale)) { bone.xsca.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.sca.X }); bone.ysca.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.sca.Y }); bone.zsca.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.sca.Z }); } if (bn.FlagsBase.HasFlag(ResNSW.BoneAnimFlagsBase.Rotate)) { bone.xrot.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.rot.X }); bone.yrot.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.rot.Y }); bone.zrot.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.rot.Z }); bone.wrot.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.rot.W }); } if (bn.FlagsBase.HasFlag(ResNSW.BoneAnimFlagsBase.Translate)) { bone.xpos.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.pos.X }); bone.ypos.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.pos.Y }); bone.zpos.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.pos.Z }); } } foreach (FSKATrack track in bonean.tracks) { Animation.KeyFrame keyFrame = new Animation.KeyFrame(); keyFrame.interType = Animation.InterpolationType.Hermite; keyFrame.Frame = frame; FSKAKey left = track.GetLeft(frame); FSKAKey right = track.GetRight(frame); // interpolate the value and apply float value = Animation.Hermite(frame, left.frame, right.frame, 0, 0, left.unk1, right.unk1); switch (track.flag) { case (int)TrackType.XPOS: keyFrame.Value = value; bone.xpos.keys.Add(keyFrame); break; case (int)TrackType.YPOS: keyFrame.Value = value; bone.ypos.keys.Add(keyFrame); break; case (int)TrackType.ZPOS: keyFrame.Value = value; bone.zpos.keys.Add(keyFrame); break; case (int)TrackType.XROT: keyFrame.Value = value; bone.xrot.keys.Add(keyFrame); break; case (int)TrackType.YROT: keyFrame.Value = value; bone.yrot.keys.Add(keyFrame); break; case (int)TrackType.ZROT: keyFrame.Value = value; bone.zrot.keys.Add(keyFrame); break; case (int)TrackType.XSCA: keyFrame.Value = value; bone.xsca.keys.Add(keyFrame); break; case (int)TrackType.YSCA: keyFrame.Value = value; bone.ysca.keys.Add(keyFrame); break; case (int)TrackType.ZSCA: keyFrame.Value = value; bone.zsca.keys.Add(keyFrame); break; } } } } } catch { } } } else { TreeNode SkeletonAnimation = new TreeNode() { Text = "Skeleton Animations" }; thisAnimation.Nodes.Add(SkeletonAnimation); TreeNode dummy = new TreeNode() { Text = "Animation Set" }; int i = 0; foreach (SkeletalAnim ska in targetWiiUbfres.SkeletalAnims.Values) { if (i == 0) { dummy = new TreeNode() { Text = "Animation Set " + "0 - 100" }; SkeletonAnimation.Nodes.Add(dummy); } if (i == 100) { dummy = new TreeNode() { Text = "Animation Set " + "100 - 200" }; SkeletonAnimation.Nodes.Add(dummy); } if (i == 200) { dummy = new TreeNode() { Text = "Animation Set " + "200 - 300" }; SkeletonAnimation.Nodes.Add(dummy); } if (i == 300) { dummy = new TreeNode() { Text = "Animation Set " + "300 - 400" }; SkeletonAnimation.Nodes.Add(dummy); } if (i == 400) { dummy = new TreeNode() { Text = "Animation Set " + "400 - 500" }; SkeletonAnimation.Nodes.Add(dummy); } if (i == 500) { dummy = new TreeNode() { Text = "Animation Set " + "500 - 600" }; SkeletonAnimation.Nodes.Add(dummy); } if (i == 600) { dummy = new TreeNode() { Text = "Animation Set " + "600 - 700" }; SkeletonAnimation.Nodes.Add(dummy); } if (i == 700) { dummy = new TreeNode() { Text = "Animation Set " + "700 - 800" }; SkeletonAnimation.Nodes.Add(dummy); } if (i == 800) { dummy = new TreeNode() { Text = "Animation Set " + "800 - 900" }; SkeletonAnimation.Nodes.Add(dummy); } if (i == 900) { dummy = new TreeNode() { Text = "Animation Set " + "900 - 1000" }; SkeletonAnimation.Nodes.Add(dummy); } if (i == 1000) { dummy = new TreeNode() { Text = "Animation Set " + "1000+" }; SkeletonAnimation.Nodes.Add(dummy); } Animation a = new Animation(ska.Name); if (i >= 0 && i < 100) { SkeletonAnimation.Nodes[0].Nodes.Add(a); } if (i >= 100 && i < 200) { SkeletonAnimation.Nodes[1].Nodes.Add(a); } if (i >= 200 && i < 300) { SkeletonAnimation.Nodes[2].Nodes.Add(a); } if (i >= 300 && i < 400) { SkeletonAnimation.Nodes[3].Nodes.Add(a); } if (i >= 400 && i < 500) { SkeletonAnimation.Nodes[4].Nodes.Add(a); } if (i >= 500 && i < 600) { SkeletonAnimation.Nodes[5].Nodes.Add(a); } if (i >= 600 && i < 700) { SkeletonAnimation.Nodes[6].Nodes.Add(a); } if (i >= 700 && i < 800) { SkeletonAnimation.Nodes[7].Nodes.Add(a); } if (i >= 800 && i < 900) { SkeletonAnimation.Nodes[8].Nodes.Add(a); } if (i >= 900 && i < 1000) { SkeletonAnimation.Nodes[9].Nodes.Add(a); } a.frameCount = ska.FrameCount; i++; try { foreach (BoneAnim bn in ska.BoneAnims) { FSKANodeWiiU bonean = new FSKANodeWiiU(bn); Animation.KeyNode bone = new Animation.KeyNode(""); a.bones.Add(bone); if (ska.FlagsRotate == SkeletalAnimFlagsRotate.EulerXYZ) { bone.rotType = Animation.RotationType.Euler; } else { bone.rotType = Animation.RotationType.Quaternion; } bone.Text = bonean.Text; for (int Frame = 0; Frame < ska.FrameCount; Frame++) { //Set base/start values for bones. //Note. BOTW doesn't use base values as it uses havok engine. Need to add option to disable these if (Frame == 0) { if (bn.FlagsBase.HasFlag(BoneAnimFlagsBase.Scale)) { bone.xsca.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.sca.X }); bone.ysca.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.sca.Y }); bone.zsca.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.sca.Z }); } if (bn.FlagsBase.HasFlag(BoneAnimFlagsBase.Rotate)) { bone.xrot.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.rot.X }); bone.yrot.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.rot.Y }); bone.zrot.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.rot.Z }); bone.wrot.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.rot.W }); } if (bn.FlagsBase.HasFlag(BoneAnimFlagsBase.Translate)) { bone.xpos.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.pos.X }); bone.ypos.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.pos.Y }); bone.zpos.keys.Add(new Animation.KeyFrame() { Frame = 0, Value = bonean.pos.Z }); } } foreach (FSKATrack track in bonean.tracks) { Animation.KeyFrame frame = new Animation.KeyFrame(); frame.interType = Animation.InterpolationType.Hermite; frame.Frame = Frame; FSKAKey left = track.GetLeft(Frame); FSKAKey right = track.GetRight(Frame); float value; value = Animation.Hermite(Frame, left.frame, right.frame, 0, 0, left.unk1, right.unk1); // interpolate the value and apply switch (track.flag) { case (int)TrackType.XPOS: frame.Value = value; bone.xpos.keys.Add(frame); break; case (int)TrackType.YPOS: frame.Value = value; bone.ypos.keys.Add(frame); break; case (int)TrackType.ZPOS: frame.Value = value; bone.zpos.keys.Add(frame); break; case (int)TrackType.XROT: frame.Value = value; bone.xrot.keys.Add(frame); break; case (int)TrackType.YROT: frame.Value = value; bone.yrot.keys.Add(frame); break; case (int)TrackType.ZROT: frame.Value = value; bone.zrot.keys.Add(frame); break; case (int)TrackType.XSCA: frame.Value = value; bone.xsca.keys.Add(frame); break; case (int)TrackType.YSCA: frame.Value = value; bone.ysca.keys.Add(frame); break; case (int)TrackType.ZSCA: frame.Value = value; bone.zsca.keys.Add(frame); break; } } } } } catch { } } } }