Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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;
        }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
        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);
        }
Esempio n. 6
0
        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);
        }
Esempio n. 7
0
        ///* 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);
        }
Esempio n. 8
0
        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);
        }
Esempio n. 11
0
        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);
        }
Esempio n. 12
0
        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);
        }