public static EMA_Animation Read(byte[] rawBytes, List <byte> bytes, int offset, int index, EMA_File emaFile) { EMA_Animation animation = new EMA_Animation(); animation.Index = index; animation.I_00 = BitConverter.ToUInt16(rawBytes, offset + 0); animation.I_08 = (EmaType)BitConverter.ToUInt16(rawBytes, offset + 8); animation.I_10 = (ValueType)BitConverter.ToUInt16(rawBytes, offset + 10); animation.Commands = new ObservableCollection <EMA_Command>(); int commandCount = BitConverter.ToUInt16(rawBytes, offset + 2); int valueCount = BitConverter.ToInt32(rawBytes, offset + 4); int valueOffset = BitConverter.ToInt32(rawBytes, offset + 16) + offset; int nameOffset = (BitConverter.ToInt32(rawBytes, offset + 12) != 0) ? BitConverter.ToInt32(rawBytes, offset + 12) + offset : 0; //Name if (nameOffset > 0) { animation.Name = Utils.GetString(bytes, nameOffset + 11); } //Values float[] values = new float[valueCount]; for (int i = 0; i < valueCount; i++) { if (animation.I_10 == ValueType.Float16) { values[i] = Half.ToHalf(rawBytes, valueOffset + (i * 2)); } else if (animation.I_10 == ValueType.Float32 || animation.I_10 == ValueType.Float32_2) { values[i] = BitConverter.ToSingle(rawBytes, valueOffset + (i * 4)); } else { throw new InvalidDataException(String.Format("EMA_Animation: Unknown float type ({0}).", animation.I_10)); } //Console.WriteLine(string.Format("{1}: {0}", values[i], i)); } //Console.ReadLine(); //Commands for (int i = 0; i < commandCount; i++) { int commandOffset = BitConverter.ToInt32(rawBytes, offset + 20 + (i * 4)); if (commandOffset != 0) { animation.Commands.Add(EMA_Command.Read(rawBytes, commandOffset + offset, values, emaFile, animation.I_08)); } } return(animation); }
public void AddKeyframesFromCommand(EMA_Command anim) { foreach (var keyframe in anim.Keyframes) { var existing = GetKeyframe(keyframe.Time); if (existing == null) { var newKeyframe = new EMA_Keyframe() { Time = keyframe.Time, Value = GetValue(keyframe.Time) }; Keyframes.Add(newKeyframe); } } }
public static EMA_Command Read(byte[] rawBytes, int offset, float[] values, EMA_File emaFile, EmaType _emaType) { EMA_Command command = new EMA_Command(); command.emaType = _emaType; if (emaFile.HasSkeleton) { command.BoneName = emaFile.GetBoneName(BitConverter.ToUInt16(rawBytes, offset + 0)); } else { //This ema has no skeleton, thus no bones command.BoneName = null; } command.I_02 = rawBytes[offset + 2]; BitArray flags_b = new BitArray(new byte[1] { Int4Converter.ToInt4(rawBytes[offset + 3])[1] }); BitArray flags_a = new BitArray(new byte[1] { Int4Converter.ToInt4(rawBytes[offset + 3])[0] }); command.I_03_b1 = flags_b[0]; command.I_03_b2_Int16ForTime = flags_b[1]; command.I_03_b3_Int16ForValueIndex = flags_b[2]; command.I_03_b4 = flags_b[3]; command.I_03_a4 = flags_a[3]; flags_a[3] = false; command.I_03_a = Int4Converter.GetByte(Utils.ConvertToByte(flags_a), 0); command.Keyframes = new ObservableCollection <EMA_Keyframe>(); ushort keyframeCount = BitConverter.ToUInt16(rawBytes, offset + 4); ushort indexOffset = BitConverter.ToUInt16(rawBytes, offset + 6); for (int i = 0; i < keyframeCount; i++) { ushort time; float value; string value2 = null; string value3 = null; string value4 = null; KeyframeFlags flags; if (command.I_03_b2_Int16ForTime) { time = BitConverter.ToUInt16(rawBytes, offset + 8 + (i * 2)); } else { time = rawBytes[offset + 8 + i]; } if (command.I_03_b3_Int16ForValueIndex) { value = values[BitConverter.ToUInt16(rawBytes, offset + indexOffset + (i * 4))]; flags = (KeyframeFlags)BitConverter.ToUInt16(rawBytes, offset + indexOffset + 2 + (i * 4)); int extraOffset = 0; if (flags.HasFlag(KeyframeFlags.QuadraticBezier)) { ushort idx = (ushort)(BitConverter.ToUInt16(rawBytes, offset + indexOffset + (i * 4)) + 1); //idx might be out of range due to a bug with an older version of the parser... so in that case set it to value if (idx <= values.Length - 1) { value2 = values[idx].ToString(); } else { value2 = value.ToString(); } extraOffset++; } if (flags.HasFlag(KeyframeFlags.CubicBezier)) { ushort idx = (ushort)(BitConverter.ToUInt16(rawBytes, offset + indexOffset + (i * 4)) + 1 + extraOffset); //idx might be out of range due to a bug with an older version of the parser... so in that case set it to value if (idx + 1 <= values.Length - 1) { value3 = values[idx].ToString(); value4 = values[idx + 1].ToString(); } else { value3 = value.ToString(); value4 = value.ToString(); } extraOffset++; } } else { value = values[rawBytes[offset + indexOffset + (i * 2)]]; flags = (KeyframeFlags)rawBytes[offset + indexOffset + 1 + (i * 2)]; int extraOffset = 0; if (flags.HasFlag(KeyframeFlags.QuadraticBezier)) { byte idx = (byte)(rawBytes[offset + indexOffset + (i * 2)] + 1); if (idx <= values.Length - 1) { value2 = values[idx].ToString(); } else { value2 = value.ToString(); } } if (flags.HasFlag(KeyframeFlags.CubicBezier)) { byte idx = (byte)(rawBytes[offset + indexOffset + (i * 2)] + 1 + extraOffset); if (idx + 1 <= values.Length - 1) { value3 = values[idx].ToString(); value4 = values[idx + 1].ToString(); } else { value3 = value.ToString(); value4 = value.ToString(); } } } command.Keyframes.Add(new EMA_Keyframe() { Time = time, Value = value, Flags = flags, Value2 = value2, CubicBezier_1 = value3, CubicBezier_2 = value4 }); } return(command); }
/// <summary> /// Ensures that color components (R, G, B) are always in sync (e.x: R must exist at same frame as G, and so on) /// </summary> public void SyncColorCommands() { if (I_08 != EmaType.light) { throw new InvalidOperationException("EMA_Animation.SyncColorCommands: Method not valid for type = " + I_08); } var r_command = GetCommand("Color", "R"); var g_command = GetCommand("Color", "G"); var b_command = GetCommand("Color", "B"); //There is atleast one color component on this animation if (r_command != null || g_command != null || b_command != null) { //Now we need to add the components that dont exist if (r_command == null) { var newCommand = EMA_Command.GetNewLight(); newCommand.Component = "R"; newCommand.Keyframes.Add(new EMA_Keyframe() { Time = 0, Value = 0 }); //First keyframe newCommand.Keyframes.Add(new EMA_Keyframe() { Time = I_00, Value = 0 }); //Last keyframe Commands.Add(newCommand); } if (g_command == null) { var newCommand = EMA_Command.GetNewLight(); newCommand.Component = "G"; newCommand.Keyframes.Add(new EMA_Keyframe() { Time = 0, Value = 0 }); //First keyframe newCommand.Keyframes.Add(new EMA_Keyframe() { Time = I_00, Value = 0 }); //Last keyframe Commands.Add(newCommand); } if (b_command == null) { var newCommand = EMA_Command.GetNewLight(); newCommand.Component = "B"; newCommand.Keyframes.Add(new EMA_Keyframe() { Time = 0, Value = 0 }); //First keyframe newCommand.Keyframes.Add(new EMA_Keyframe() { Time = I_00, Value = 0 }); //Last keyframe Commands.Add(newCommand); } } //Reload the commands now that they are all added. r_command = GetCommand("Color", "R"); g_command = GetCommand("Color", "G"); b_command = GetCommand("Color", "B"); //Now sync the commands foreach (var anim in Commands) { foreach (var anim2 in Commands) { if (anim.I_02 == 2 && anim2.I_02 == 2 && anim.I_03_a != 3 && anim2.I_03_a != 3) { anim.AddKeyframesFromCommand(anim2); } } } }