internal static void ValidateChannelDataSize(W3dAnimationChannelType channelType, int vectorLength) { switch (channelType) { case W3dAnimationChannelType.Quaternion: if (vectorLength != 4) { throw new InvalidDataException(); } break; case W3dAnimationChannelType.TranslationX: case W3dAnimationChannelType.TranslationY: case W3dAnimationChannelType.TranslationZ: if (vectorLength != 1) { throw new InvalidDataException(); } break; case W3dAnimationChannelType.UnknownBfme: if (vectorLength != 1) { throw new InvalidDataException(); } break; default: throw new InvalidDataException(); } }
public static W3dAnimationChannelDatum Parse(BinaryReader reader, W3dAnimationChannelType channelType) { switch (channelType) { case W3dAnimationChannelType.Quaternion: return(new W3dAnimationChannelDatum { Quaternion = reader.ReadQuaternion() }); case W3dAnimationChannelType.TranslationX: case W3dAnimationChannelType.TranslationY: case W3dAnimationChannelType.TranslationZ: return(new W3dAnimationChannelDatum { FloatValue = reader.ReadSingle() }); case W3dAnimationChannelType.UnknownBfme: return(new W3dAnimationChannelDatum { FloatValue = reader.ReadSingle() }); default: throw new InvalidDataException(); } }
internal void WriteTo(BinaryWriter writer, W3dAnimationChannelType channelType) { InitialDatum.WriteTo(writer, channelType); for (var i = 0; i < DeltaBlocks.Length; i++) { DeltaBlocks[i].WriteTo(writer); } }
internal void WriteTo(BinaryWriter writer, W3dAnimationChannelType channelType) { var timeCode = TimeCode; if (NonInterpolatedMovement) { timeCode |= (1u << 31); } writer.Write(timeCode); Value.WriteTo(writer, channelType); }
internal override void WriteTo(BinaryWriter writer, W3dAnimationChannelType channelType) { for (var i = 0; i < TimeCodes.Length; i++) { writer.Write(TimeCodes[i]); } if (TimeCodes.Length % 2 != 0) { // Align to 4-byte boundary. writer.Write((ushort)0); } for (var i = 0; i < Values.Length; i++) { Values[i].WriteTo(writer, channelType); } }
internal static W3dMotionChannelAdaptiveDeltaData Parse( BinaryReader reader, uint numTimeCodes, W3dAnimationChannelType channelType, int vectorLen, W3dAdaptiveDeltaBitCount bitCount) { return(new W3dMotionChannelAdaptiveDeltaData { Scale = reader.ReadSingle(), Data = W3dAdaptiveDeltaData.Parse( reader, numTimeCodes, channelType, vectorLen, bitCount) }); }
internal static W3dTimeCodedDatum Parse(BinaryReader reader, W3dAnimationChannelType channelType) { var result = new W3dTimeCodedDatum(); result.TimeCode = reader.ReadUInt32(); // MSB is used to indicate a binary (non interpolated) movement if ((result.TimeCode >> 31) == 1) { result.NonInterpolatedMovement = true; // TODO: non-interpolated movement. result.TimeCode &= ~(1 << 31); } result.Value = W3dAnimationChannelDatum.Parse(reader, channelType); return(result); }
private static float GetValue(W3dAnimationChannelDatum datum, W3dAnimationChannelType type, int i = 0) { if (i > 0 && type != W3dAnimationChannelType.Quaternion) { throw new InvalidDataException(); } switch (type) { case W3dAnimationChannelType.TranslationX: case W3dAnimationChannelType.TranslationY: case W3dAnimationChannelType.TranslationZ: case W3dAnimationChannelType.XR: case W3dAnimationChannelType.YR: case W3dAnimationChannelType.ZR: case W3dAnimationChannelType.UnknownBfme: return(datum.FloatValue); case W3dAnimationChannelType.Quaternion: switch (i) { case 0: return(datum.Quaternion.X); case 1: return(datum.Quaternion.Y); case 2: return(datum.Quaternion.Z); case 3: return(datum.Quaternion.W); default: throw new InvalidOperationException(); } break; default: throw new NotImplementedException(); } }
private static Keyframe CreateKeyframe(W3dAnimationChannelType channelType, TimeSpan time, ref W3dAnimationChannelDatum datum) { switch (channelType) { case W3dAnimationChannelType.Quaternion: return(new QuaternionKeyframe(time, datum.Quaternion)); case W3dAnimationChannelType.TranslationX: return(new TranslationXKeyframe(time, datum.FloatValue)); case W3dAnimationChannelType.TranslationY: return(new TranslationYKeyframe(time, datum.FloatValue)); case W3dAnimationChannelType.TranslationZ: return(new TranslationZKeyframe(time, datum.FloatValue)); default: throw new NotImplementedException(); } }
private static KeyframeValue CreateKeyframeValue(W3dAnimationChannelType channelType, ref W3dAnimationChannelDatum datum) { switch (channelType) { case W3dAnimationChannelType.Quaternion: return(new KeyframeValue { Quaternion = datum.Quaternion }); case W3dAnimationChannelType.TranslationX: case W3dAnimationChannelType.TranslationY: case W3dAnimationChannelType.TranslationZ: return(new KeyframeValue { FloatValue = datum.FloatValue }); default: throw new NotImplementedException(); } }
public static AnimationClipType ToAnimationClipType(this W3dAnimationChannelType value) { switch (value) { case W3dAnimationChannelType.TranslationX: return(AnimationClipType.TranslationX); case W3dAnimationChannelType.TranslationY: return(AnimationClipType.TranslationY); case W3dAnimationChannelType.TranslationZ: return(AnimationClipType.TranslationZ); case W3dAnimationChannelType.Quaternion: return(AnimationClipType.Quaternion); default: throw new ArgumentOutOfRangeException(nameof(value)); } }
internal static W3dAdaptiveDeltaData Parse( BinaryReader reader, uint numFrames, W3dAnimationChannelType type, int vectorLength, W3dAdaptiveDeltaBitCount bitCount) { var count = (numFrames + 15) >> 4; // First read all initial values var result = new W3dAdaptiveDeltaData { BitCount = bitCount, VectorLength = vectorLength, InitialDatum = W3dAnimationChannelDatum.Parse(reader, type) }; var numBits = (int)bitCount; // Then read the interleaved delta blocks var deltaBlocks = new W3dAdaptiveDeltaBlock[count * vectorLength]; for (var i = 0; i < count; i++) { for (var j = 0; j < vectorLength; j++) { deltaBlocks[(i * vectorLength) + j] = W3dAdaptiveDeltaBlock.Parse( reader, j, numBits); } } result.DeltaBlocks = deltaBlocks; return(result); }
private static void UpdateDatum(ref W3dAnimationChannelDatum datum, float value, W3dAnimationChannelType type, int i = 0) { if (i > 0 && type != W3dAnimationChannelType.Quaternion) { throw new InvalidDataException(); } switch (type) { case W3dAnimationChannelType.TranslationX: case W3dAnimationChannelType.TranslationY: case W3dAnimationChannelType.TranslationZ: case W3dAnimationChannelType.XR: case W3dAnimationChannelType.YR: case W3dAnimationChannelType.ZR: case W3dAnimationChannelType.UnknownBfme: datum.FloatValue = value; break; case W3dAnimationChannelType.Quaternion: switch (i) { case 0: datum.Quaternion.X = value; break; case 1: datum.Quaternion.Y = value; break; case 2: datum.Quaternion.Z = value; break; case 3: datum.Quaternion.W = value; break; } break; } }
private static Keyframe CreateKeyframe(W3dAnimationChannelType channelType, TimeSpan time, ref W3dAnimationChannelDatum datum) { return(new Keyframe(time, CreateKeyframeValue(channelType, ref datum))); }
internal override void WriteTo(BinaryWriter writer, W3dAnimationChannelType channelType) { writer.Write(Scale); Data.WriteTo(writer, channelType); }
public static W3dMotionChannelTimeCodedData Parse(BinaryReader reader, ushort numTimeCodes, W3dAnimationChannelType channelType) { var keyframes = new ushort[numTimeCodes]; for (var i = 0; i < numTimeCodes; i++) { keyframes[i] = reader.ReadUInt16(); } if (numTimeCodes % 2 != 0) { // Align to 4-byte boundary. reader.ReadUInt16(); } var data = new W3dAnimationChannelDatum[numTimeCodes]; for (var i = 0; i < numTimeCodes; i++) { data[i] = W3dAnimationChannelDatum.Parse(reader, channelType); } return(new W3dMotionChannelTimeCodedData { TimeCodes = keyframes, Values = data }); }
internal abstract void WriteTo(BinaryWriter writer, W3dAnimationChannelType channelType);
private static Keyframe CreateKeyframe(W3dAnimationChannelType channelType, TimeSpan time, in W3dAnimationChannelDatum datum)
public static W3dMotionChannelAdaptiveDeltaData Parse(BinaryReader reader, uint numTimeCodes, W3dAnimationChannelType channelType, int vectorLen, int nBits) { float scale = reader.ReadSingle(); var data = W3dAdaptiveDelta.ReadAdaptiveDelta(reader, numTimeCodes, channelType, vectorLen, scale, nBits); var keyframes = new ushort[numTimeCodes]; for (ushort i = 0; i < numTimeCodes; i++) { keyframes[i] = i; } return(new W3dMotionChannelAdaptiveDeltaData { TimeCodes = keyframes, Values = data }); }
public static W3dAnimationChannelDatum[] ReadAdaptiveDelta(BinaryReader reader, uint numFrames, W3dAnimationChannelType type, int vectorLen, float scale, int nBits) { float scaleFactor = 1.0f; switch (nBits) { //When deltas are 8 bits large we need to scale them to the range [-16;16] case 8: scaleFactor = 1 / 16.0f; break; //Do nothing for 4 bit deltas since they already map to [-16;16] case 4: break; default: throw new InvalidOperationException("Adaptive delta only supported 4 bit & 8 bit!"); } uint count = (numFrames + 15) >> 4; var data = new W3dAnimationChannelDatum[numFrames]; //First read all initial values for (int k = 0; k < vectorLen; ++k) { var initial = reader.ReadSingle(); UpdateDatum(ref data[0], initial, type, k); } //Then read the interleaved delta blocks for (int i = 0; i < count; ++i) { for (int k = 0; k < vectorLen; ++k) { var blockIndex = reader.ReadByte(); var blockScale = Table[blockIndex]; var deltaScale = blockScale * scale * scaleFactor; //read deltas for the next var deltas = ReadDeltaBlock(reader, nBits); for (int j = 0; j < deltas.Length; ++j) { int idx = i * 16 + j + 1; if (idx >= numFrames) { break; } var value = GetValue(data[idx - 1], type, k) + deltaScale * deltas[j]; UpdateDatum(ref data[idx], value, type, k); } } } return(data); }