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 static W3dAnimationChannel Parse(BinaryReader reader, W3dParseContext context) { return(ParseChunk(reader, context, header => { var startPosition = reader.BaseStream.Position; var result = new W3dAnimationChannel { FirstFrame = reader.ReadUInt16(), LastFrame = reader.ReadUInt16(), VectorLength = reader.ReadUInt16(), ChannelType = reader.ReadUInt16AsEnum <W3dAnimationChannelType>(), Pivot = reader.ReadUInt16(), Unknown = reader.ReadUInt16() }; ValidateChannelDataSize(result.ChannelType, result.VectorLength); var numElements = result.LastFrame - result.FirstFrame + 1; var data = new W3dAnimationChannelDatum[numElements]; for (var i = 0; i < numElements; i++) { data[i] = W3dAnimationChannelDatum.Parse(reader, result.ChannelType); } result.Data = data; result.NumPadBytes = (uint)(context.CurrentEndPosition - reader.BaseStream.Position); reader.BaseStream.Seek((int)result.NumPadBytes, SeekOrigin.Current); return result; })); }
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); }
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); }