public override object CustomDeserialize(BinaryReader reader, Type field, NMSAttribute settings, FieldInfo fieldInfo) { var fieldName = fieldInfo.Name; switch (fieldName) { case nameof(MeshDataStream): long listPosition = reader.BaseStream.Position; long listStartOffset = reader.ReadInt64(); int numEntries = reader.ReadInt32(); uint listMagic = reader.ReadUInt32(); if ((listMagic & 0xFF) != 1) { throw new InvalidListException(listMagic, reader.BaseStream.Position); } long listEndPosition = reader.BaseStream.Position; reader.BaseStream.Position = listPosition + listStartOffset; byte[] data = new byte[numEntries]; data = reader.ReadBytes(numEntries); reader.BaseStream.Position = listEndPosition; return(data); } return(null); }
public override object CustomDeserialize(BinaryReader reader, Type field, NMSAttribute settings, FieldInfo fieldInfo) { var fieldName = fieldInfo.Name; switch (fieldName) { case nameof(NameHash): ulong NEXT_GUID = 0xD5756F96B501B8A2; long returnPos = reader.BaseStream.Position; // Check to see if we are loading a pre-Beyond version: reader.BaseStream.Position = 0x10; ulong GUID = reader.ReadUInt64(); var byteName = Encoding.UTF8.GetBytes(this.Name.ToString()); var crc32 = new Crc32(); // Make sure we return the read position reader.BaseStream.Position = returnPos; if (GUID == NEXT_GUID) { return((UInt64)crc32.Get(byteName)); } else { // just deserialize as normal... return(null); } } return(null); }
public override bool CustomSerialize(BinaryWriter writer, Type field, object fieldData, NMSAttribute settings, FieldInfo fieldInfo, ref List<Tuple<long, object>> additionalData, ref int addtDataIndex) { if (field == null || fieldInfo == null) return false; var fieldName = fieldInfo.Name; switch (fieldName) { case nameof(CanCompress): //writer.Align(4, 0); writer.Write(0xFEFEFEFE); return true; } return false; }
public override bool CustomSerialize(BinaryWriter writer, Type field, object fieldData, NMSAttribute settings, FieldInfo fieldInfo, ref List <Tuple <long, object> > additionalData, ref int addtDataIndex) { if (field == null || fieldInfo == null) { return(false); } var fieldName = fieldInfo.Name; switch (fieldName) { case nameof(IndexBuffer): writer.Align(8, 0); // write empty list header long listPos = writer.BaseStream.Position; writer.Write((Int64)0); // listPosition writer.Write((Int32)0); // listCount writer.Write((UInt32)0xAAAAAA01); IList data = (IList)fieldData; if (Indices16Bit != 1) // if 32bit indices, we can just pass it directly { additionalData.Insert(addtDataIndex, new Tuple <long, object>(listPos, data)); } else { // otherwise we have to create 32bit indices from the 16bit ones var list32Bit = new List <uint>(); int effective_count = (data.Count / 2) * 2; for (int i = 0; i < effective_count; i += 2) { uint val32Bit = (uint)((int)data[i + 1] << 16 | (int)data[i]); list32Bit.Add(val32Bit); } //Handle odd cases if (data.Count % 2 == 1) { //uint val32Bit = (uint)((int)data[data.Count - 1] << 16); uint val32Bit = (uint)((int)data[data.Count - 1]); list32Bit.Add(val32Bit); } additionalData.Insert(addtDataIndex, new Tuple <long, object>(listPos, list32Bit)); } addtDataIndex++; return(true); case nameof(VertexStream): case nameof(SmallVertexStream): writer.Align(8, 0); // write empty list header long listPos2 = writer.BaseStream.Position; writer.Write((Int64)0); // listPosition writer.Write((Int32)0); // listCount writer.Write((UInt32)0xAAAAAA01); IList vertexData = (IList)fieldData; // list size field for VertexStream/SmallVertexSteam is the number of bytes, so we'll have to use a List<byte> in the additionalData byte[] streamData = null; using (var ms = new MemoryStream()) using (var writer2 = new BinaryWriter(ms)) { if (vertexData != null) { foreach (var vertex in vertexData) { var floatVertex = (float)vertex; var halfVertex = (Half)floatVertex; writer2.Write(halfVertex.value); } } streamData = ms.ToArray(); } var listBytes = new List <byte>(streamData); additionalData.Insert(addtDataIndex, new Tuple <long, object>(listPos2, listBytes)); addtDataIndex++; return(true); } return(false); }
public override object CustomDeserialize(BinaryReader reader, Type field, NMSAttribute settings, long templatePosition, FieldInfo fieldInfo) { var fieldName = fieldInfo.Name; switch (fieldName) { case nameof(IndexBuffer): reader.Align(8, 0); long listPosition = reader.BaseStream.Position; //Debug.WriteLine($"TkGeometryData.CustomDeserialize({fieldName}) start 0x{listPosition:X}"); long listStartOffset = reader.ReadInt64(); int numEntries = reader.ReadInt32() * ((Indices16Bit == 1) ? 2 : 1); // Adjust size uint listMagic = reader.ReadUInt32(); if ((listMagic & 0xFF) != 1) { throw new Exception($"Invalid list read, magic {listMagic:X8} expected xxxxxx01"); } long listEndPosition = reader.BaseStream.Position; reader.BaseStream.Position = listPosition + listStartOffset; var indices = new List <int>(); for (int i = 0; i < numEntries; i++) { if (Indices16Bit == 1) { indices.Add((int)reader.ReadUInt16()); } else { indices.Add((int)reader.ReadUInt32()); } } reader.BaseStream.Position = listEndPosition; reader.Align(0x8, 0); return(indices); case nameof(VertexStream): case nameof(SmallVertexStream): reader.Align(8, 0); listPosition = reader.BaseStream.Position; //Debug.WriteLine($"TkGeometryData.CustomDeserialize({fieldName}) start 0x{listPosition:X}"); listStartOffset = reader.ReadInt64(); numEntries = reader.ReadInt32(); listMagic = reader.ReadUInt32(); if ((listMagic & 0xFF) != 1) { throw new Exception($"Invalid list read, magic {listMagic:X8} expected xxxxxx01"); } listEndPosition = reader.BaseStream.Position; reader.BaseStream.Position = listPosition + listStartOffset; List <float> vertices = new List <float>(); while (reader.BaseStream.Position < (listPosition + listStartOffset + numEntries)) { ushort vertex = reader.ReadUInt16(); vertices.Add((float)Half.ToHalf(vertex)); } reader.BaseStream.Position = listEndPosition; reader.Align(0x8, 0); return(vertices); } return(null); }
public override bool CustomSerialize(BinaryWriter writer, Type field, object fieldData, NMSAttribute settings, FieldInfo fieldInfo, ref List <Tuple <long, object> > additionalData, ref int addtDataIndex) { var fieldName = fieldInfo.Name; switch (fieldName) { case nameof(MeshDataStream): writer.Align(8, fieldName); // write empty list header long listPos = writer.BaseStream.Position; writer.Write((Int64)0); // listPosition writer.Write((Int32)(MeshDataStream?.Length ?? 0)); // size of data chunk in bytes writer.Write((UInt32)0xFEFEFE01); additionalData.Insert(addtDataIndex, new Tuple <long, object>(listPos, fieldData)); addtDataIndex++; return(true); } return(false); }
///* 0x130 */ public List<float> VertexStream; // this is just here so that the code compiles ///* 0x140 */ public List<float> SmallVertexStream; // this is just here so that the code compiles public override bool CustomSerialize(BinaryWriter writer, Type field, object fieldData, NMSAttribute settings, FieldInfo fieldInfo, ref List <Tuple <long, object> > additionalData, ref int addtDataIndex) { if (field == null || fieldInfo == null) { return(false); } Dictionary <int, int> TypeMap = new Dictionary <int, int> { { 5131, 8 }, { 36255, 4 }, { 5121, 4 } }; var fieldName = fieldInfo.Name; switch (fieldName) { case nameof(IndexBuffer): writer.Align(8, 0); // write empty list header long listPos = writer.BaseStream.Position; writer.Write((Int64)0); // listPosition writer.Write((Int32)0); // listCount writer.Write((UInt32)0xAAAAAA01); IList data = (IList)fieldData; if (Indices16Bit != 1) // if 32bit indices, we can just pass it directly { additionalData.Insert(addtDataIndex, new Tuple <long, object>(listPos, data)); } else { // otherwise we have to create 32bit indices from the 16bit ones var list32Bit = new List <uint>(); int effective_count = (data.Count / 2) * 2; for (int i = 0; i < effective_count; i += 2) { uint val32Bit = (uint)((int)data[i + 1] << 16 | (int)data[i]); list32Bit.Add(val32Bit); } //Handle odd cases if (data.Count % 2 == 1) { //uint val32Bit = (uint)((int)data[data.Count - 1] << 16); uint val32Bit = (uint)((int)data[data.Count - 1]); list32Bit.Add(val32Bit); } additionalData.Insert(addtDataIndex, new Tuple <long, object>(listPos, list32Bit)); } addtDataIndex++; return(true); /* * case nameof(VertexStream): * case nameof(SmallVertexStream): * writer.Align(8, 0); * * List<int> LayoutTypes = new List<int>(); * TkVertexLayout layout; * * if (fieldName == nameof(VertexStream)) * layout = VertexLayout; * else * layout = SmallVertexLayout; * * foreach (TkVertexElement ve in layout.VertexElements) * { * int type = ve.Type; * LayoutTypes.Add(type); * } * int stride = 4 * LayoutTypes.Count; * * // write empty list header * long listPos2 = writer.BaseStream.Position; * writer.Write((Int64)0); // listPosition * writer.Write((Int32)0); // listCount * writer.Write((UInt32)0xAAAAAA01); * * IList vertexData = (IList)fieldData; * * // list size field for VertexStream/SmallVertexSteam is the number of bytes, so we'll have to use a List<byte> in the additionalData * byte[] streamData = null; * using (var ms = new MemoryStream()) * using (var writer2 = new BinaryWriter(ms)) * { * if (vertexData != null) * { * for (int v = 0; v < VertexCount; v++) * { * for (int i = 0; i < LayoutTypes.Count; i++) * { * if (LayoutTypes[i] == 5131) * { * // half-float * for (int j = 0; j < 4; j++) * { * var floatVertex = (float)vertexData[v * stride + 4 * i + j]; * var halfVertex = (Half)floatVertex; * writer2.Write(halfVertex.value); * } * } * else if (LayoutTypes[i] == 5121) * { * // Unsigned bytes * for (int j = 0; j < 4; j++) * { * byte ubyteVertex = (byte)vertexData[v * stride + 4 * i + j]; * writer2.Write(ubyteVertex); * } * } * else if (LayoutTypes[i] == 36255) * { * // INT_2_10_10_10_REV * float[] vertexes = new float[4] {(float)vertexData[v * stride + 4 * i], * (float)vertexData[v * stride + 4 * i + 1], * (float)vertexData[v * stride + 4 * i + 2], * (float)vertexData[v * stride + 4 * i + 3] }; * int val = INT_2_10_10_10_REV.FromVerts(vertexes); * writer2.Write((UInt32)val); * } * } * } * } * streamData = ms.ToArray(); * * } * * using (var ms = new MemoryStream()) * using (var writer2 = new BinaryWriter(ms)) * { * if(vertexData != null) * foreach (var vertex in vertexData) * { * var floatVertex = (float)vertex; * var halfVertex = (Half)floatVertex; * writer2.Write(halfVertex.value); * } * streamData = ms.ToArray(); * } * * var listBytes = new List<byte>(streamData); * additionalData.Insert(addtDataIndex, new Tuple<long, object>(listPos2, listBytes)); * addtDataIndex++; * * return true*/ } return(false); }
public override object CustomDeserialize(BinaryReader reader, Type field, NMSAttribute settings, long templatePosition, FieldInfo fieldInfo) { var fieldName = fieldInfo.Name; Dictionary <int, int> TypeMap = new Dictionary <int, int> { { 5131, 8 }, { 36255, 4 }, { 5121, 4 } }; switch (fieldName) { case nameof(IndexBuffer): reader.Align(8, 0); long listPosition = reader.BaseStream.Position; //DebugLog($"TkGeometryData.CustomDeserialize({fieldName}) start 0x{listPosition:X}"); long listStartOffset = reader.ReadInt64(); int numEntries = reader.ReadInt32() * ((Indices16Bit == 1) ? 2 : 1); // Adjust size uint listMagic = reader.ReadUInt32(); if ((listMagic & 0xFF) != 1) { throw new InvalidListException(listMagic); } long listEndPosition = reader.BaseStream.Position; reader.BaseStream.Position = listPosition + listStartOffset; var indices = new List <int>(); for (int i = 0; i < numEntries; i++) { if (Indices16Bit == 1) { indices.Add((int)reader.ReadUInt16()); } else { indices.Add((int)reader.ReadUInt32()); } } reader.BaseStream.Position = listEndPosition; reader.Align(0x8, 0); return(indices); /* * case nameof(VertexStream): * case nameof(SmallVertexStream): * * List<int> LayoutTypes = GetTypeLayouts(fieldName, reader); * int StreamBlockSize = 0; * foreach (int vert_type in LayoutTypes) * { * StreamBlockSize += TypeMap[vert_type]; * } * reader.Align(8, 0); * listPosition = reader.BaseStream.Position; * //DebugLog($"TkGeometryData.CustomDeserialize({fieldName}) start 0x{listPosition:X}"); * * listStartOffset = reader.ReadInt64(); * numEntries = reader.ReadInt32()/StreamBlockSize; // the number of blocks of data * listMagic = reader.ReadUInt32(); * if ((listMagic & 0xFF) != 1) * throw new Exception($"Invalid list read, magic {listMagic:X8} expected xxxxxx01"); * * listEndPosition = reader.BaseStream.Position; * * reader.BaseStream.Position = listPosition + listStartOffset; * List<float> vertices = new List<float>(); * int curr_block = 0; * while (curr_block < numEntries) * { * foreach (int ltype in LayoutTypes) * { * if (ltype == 5131) * // Half floats * { * // read in the half-float data * for (int i = 0; i < 4; i++) * { * ushort vertex = reader.ReadUInt16(); * vertices.Add((float)Half.ToHalf(vertex)); * } * } * else if (ltype == 5121) * // Unsigned bytes * { * for (int i = 0; i < 4; i++) * { * byte num = reader.ReadByte(); * vertices.Add((float)(int)num); * } * } * else if (ltype == 36255) * { * int vert_data = reader.ReadInt32(); * vertices.AddRange(INT_2_10_10_10_REV.FromBytes(vert_data)); * } * } * curr_block += 1; * } * /* * while (reader.BaseStream.Position < (listPosition + listStartOffset + numEntries)) * { * ushort vertex = reader.ReadUInt16(); * vertices.Add((float)Half.ToHalf(vertex)); * } * * reader.BaseStream.Position = listEndPosition; * reader.Align(0x8, 0); * * return vertices;*/ } return(null); }
public override object CustomDeserialize(BinaryReader reader, Type field, NMSAttribute settings, FieldInfo fieldInfo) { var fieldName = fieldInfo.Name; switch (fieldName) { case nameof(Rotations): // sort out reading of list long listPosition = reader.BaseStream.Position; long listStartOffset = reader.ReadInt64(); int numEntries = reader.ReadInt32() / 3; uint listMagic = reader.ReadUInt32(); if ((listMagic & 0xFF) != 1) { throw new InvalidListException(listMagic, reader.BaseStream.Position); } long listEndPosition = reader.BaseStream.Position; reader.BaseStream.Position = listPosition + listStartOffset; // output data List <Quaternion> data = new List <Quaternion>(); // worker values UInt16 c_x, c_y, c_z; UInt16 i_x, i_y; // a few normalisation/scaling values float norm = 1.0f / 0x3FFF; float scale = 1.0f / (float)Math.Sqrt(2.0f); // now, iterate over the input data. // We will read in the data in chunks of 6 bytes for (int i = 0; i < numEntries; i++) { // assign the variables c_x = reader.ReadUInt16(); c_y = reader.ReadUInt16(); c_z = reader.ReadUInt16(); // determine most significant bit (0 or 1) i_x = (UInt16)(c_x >> 0xF); i_y = (UInt16)(c_y >> 0xF); //i_z = (UInt16)(c_z >> 0xF); /* dropcomponent indicates which component of the quaternion has been dropped * 3 -> x * 2 -> y * 1 -> z * 0 -> w */ ushort dropcomponent = (ushort)(i_x << 1 | i_y << 0); //Mask Values (strip most significant bit) c_x = (UInt16)(c_x & 0x7FFF); c_y = (UInt16)(c_y & 0x7FFF); c_z = (UInt16)(c_z & 0x7FFF); Quaternion q = new Quaternion( ((float)(c_x - 0x3FFF)) * norm * scale, ((float)(c_y - 0x3FFF)) * norm * scale, ((float)(c_z - 0x3FFF)) * norm * scale, 0.0f); //I assume that W is positive by default q.w = (float)Math.Sqrt(Math.Max(1.0f - q.x * q.x - q.y * q.y - q.z * q.z, 0.0)); // output Quaternion Quaternion qo; switch (dropcomponent) { case 3: // qx was dropped qo = new Quaternion(q.w, q.x, q.y, q.z); break; case 2: // qy was dropped qo = new Quaternion(q.x, q.w, q.y, q.z); break; case 1: // qz was dropped qo = new Quaternion(q.x, q.y, q.w, q.z); break; case 0: // qw was dropped qo = new Quaternion(q.x, q.y, q.z, q.w); break; default: qo = new Quaternion(0.0f, 0.0f, 0.0f, 0.0f); // shouldn't ever get here break; } data.Add(qo); } // the padding bytes are just ignored... reader.BaseStream.Position = listEndPosition; return(data); } return(null); }
public override bool CustomSerialize(BinaryWriter writer, Type field, object fieldData, NMSAttribute settings, FieldInfo fieldInfo, ref List <Tuple <long, object> > additionalData, ref int addtDataIndex) { if (field == null || fieldInfo == null) { return(false); } var fieldName = fieldInfo.Name; switch (fieldName) { case nameof(Rotations): IList <Quaternion> data = (IList <Quaternion>)fieldData; List <UInt16> outputData = new List <UInt16>(); // write empty list header long listPos = writer.BaseStream.Position; writer.Write((Int64)0); // listPosition writer.Write((Int32)0); // listCount writer.Write((UInt32)0x00000001); if (data == null) { return(true); } foreach (Quaternion q in data) { List <UInt16> convertedQ = new List <UInt16> { ConvertQuat(q.x), ConvertQuat(q.y), ConvertQuat(q.z), ConvertQuat(q.w) }; int dropcomponent = (int)DetermineDropComponent(convertedQ); // remove the element we wish to discard convertedQ.RemoveAt(dropcomponent); dropcomponent = 3 - dropcomponent; // flip the number to correspond to the correct component int i_x = dropcomponent >> 1; int i_y = dropcomponent & 1; convertedQ[0] = (UInt16)((i_x << 0xF) + (int)convertedQ[0]); convertedQ[1] = (UInt16)((i_y << 0xF) + (int)convertedQ[1]); // extend the ouput data outputData.AddRange(convertedQ); } additionalData.Insert(addtDataIndex, new Tuple <long, object>(listPos, outputData)); addtDataIndex++; return(true); } return(false); }
public override object CustomDeserialize(BinaryReader reader, Type field, NMSAttribute settings, long templatePosition, FieldInfo fieldInfo) { var fieldName = fieldInfo.Name; switch (fieldName) { case nameof(Rotations): // sort out reading of list long listPosition = reader.BaseStream.Position; long listStartOffset = reader.ReadInt64(); int numEntries = reader.ReadInt32() / 3; uint listMagic = reader.ReadUInt32(); if ((listMagic & 0xFF) != 1) { throw new InvalidListException(listMagic); } long listEndPosition = reader.BaseStream.Position; reader.BaseStream.Position = listPosition + listStartOffset; // output data List <Quaternion> data = new List <Quaternion>(); // worker values UInt16 c_x, c_y, c_z; UInt16 i_x, i_y, i_z; // a few normalisation/scaling values float norm = 1.0f / 0x3FFF; float scale = 1.0f / (float)Math.Sqrt(2.0f); // now, iterate over the input data. // We will read in the data in chunks of 6 bytes for (int i = 0; i < numEntries; i++) { // assign the variables c_x = reader.ReadUInt16(); c_y = reader.ReadUInt16(); c_z = reader.ReadUInt16(); // make these things i_x = (UInt16)(c_x >> 15); i_y = (UInt16)(c_y >> 15); i_z = (UInt16)(c_z >> 15); ushort axisflag = (ushort)(i_x << 0 | i_y << 1 | i_z << 2); //Mask Values c_x = (UInt16)(c_x & 0x7FFF); c_y = (UInt16)(c_y & 0x7FFF); c_z = (UInt16)(c_z & 0x7FFF); Quaternion q = new Quaternion( ((float)(c_x - 0x3FFF)) * norm * scale, ((float)(c_y - 0x3FFF)) * norm * scale, ((float)(c_z - 0x3FFF)) * norm * scale, 0.0f); //I assume that W is positive by default q.w = (float)Math.Sqrt(Math.Max(1.0f - q.x * q.x - q.y * q.y - q.z * q.z, 0.0)); // output Quaternion Quaternion qo; switch (axisflag) { case 3: qo = new Quaternion(q.w, q.x, q.y, q.z); break; case 2: qo = new Quaternion(q.x, q.y, q.w, q.z); break; case 1: qo = new Quaternion(q.x, q.w, q.y, q.z); break; case 0: qo = new Quaternion(q.x, q.y, q.z, q.w); break; default: qo = new Quaternion(0.0f, 0.0f, 0.0f, 0.0f); // shouldn't ever get here break; } data.Add(qo); } // the padding bytes are just ignored... reader.BaseStream.Position = listEndPosition; return(data); } return(null); }
public override bool CustomSerialize(BinaryWriter writer, Type field, object fieldData, NMSAttribute settings, FieldInfo fieldInfo, ref List <Tuple <long, object> > additionalData) { if (field == null || fieldInfo == null) { return(false); } var fieldName = fieldInfo.Name; switch (fieldName) { case nameof(IndexBuffer): writer.Align(8, 0); // write empty list header long listPos = writer.BaseStream.Position; writer.Write((Int64)0); // listPosition writer.Write((Int32)0); // listCount writer.Write((UInt32)0xAAAAAA01); IList data = (IList)fieldData; if (Indices16Bit != 1) // if 32bit indices, we can just pass it directly { additionalData.Add(new Tuple <long, object>(listPos, data)); } else { // otherwise we have to create 32bit indices from the 16bit ones var list32Bit = new List <uint>(); for (int i = 0; i < data.Count; i += 2) { uint val32Bit = (uint)((int)data[i + 1] << 16 | (int)data[i]); list32Bit.Add(val32Bit); } additionalData.Add(new Tuple <long, object>(listPos, list32Bit)); } return(true); case nameof(VertexStream): case nameof(SmallVertexStream): writer.Align(8, 0); // write empty list header long listPos2 = writer.BaseStream.Position; writer.Write((Int64)0); // listPosition writer.Write((Int32)0); // listCount writer.Write((UInt32)0xAAAAAA01); IList vertexData = (IList)fieldData; // list size field for VertexStream/SmallVertexSteam is the number of bytes, so we'll have to use a List<byte> in the additionalData byte[] streamData = null; using (var ms = new MemoryStream()) using (var writer2 = new BinaryWriter(ms)) { foreach (var vertex in vertexData) { writer2.Write(Shared.HalfLittleToUInt16((float)vertex));//Shared.ToHalf((float)vertex)); // todo: why doesn't this get the original value? } streamData = ms.ToArray(); } var listBytes = new List <byte>(streamData); additionalData.Add(new Tuple <long, object>(listPos2, listBytes)); return(true); } return(false); }