public static void Write(DSBinaryWriter bin, FlverVertexStructMember val)
 {
     bin.Write(val.Unknown1);
     bin.Write(val.StructOffset);
     bin.Write((int)val.ValueType);
     bin.Write((int)val.Semantic);
     bin.Write(val.Index);
 }
        public static FlverVertexStructMember Read(DSBinaryReader bin)
        {
            var val = new FlverVertexStructMember();

            val.Unknown1     = bin.ReadInt32();
            val.StructOffset = bin.ReadInt32();
            val.ValueType    = (FlverVertexStructMemberValueType)bin.ReadInt32();
            val.Semantic     = (FlverVertexStructMemberSemantic)bin.ReadInt32();
            val.Index        = bin.ReadInt32();

            return(val);
        }
        public static FlverVertexStructLayout Read(DSBinaryReader bin)
        {
            var val = new FlverVertexStructLayout();

            int memberCount = bin.ReadInt32();

            val.Unknown1 = bin.ReadInt32();
            val.Unknown2 = bin.ReadInt32();

            int startOffset = bin.ReadInt32();

            bin.StepIn(startOffset);
            {
                val.Members = new List <FlverVertexStructMember>();
                for (int i = 0; i < memberCount; i++)
                {
                    val.Members.Add(FlverVertexStructMember.Read(bin));
                }
            }

            return(val);
        }
        public FlverVertexStructLayout BuildVertexStructLayout()
        {
            var structLayout  = new FlverVertexStructLayout();
            var currentOffset = 0;

            void _newMember(FlverVertexStructMemberSemantic s, FlverVertexStructMemberValueType v)
            {
                var newMember = new FlverVertexStructMember();

                newMember.Semantic     = s;
                newMember.ValueType    = v;
                newMember.StructOffset = currentOffset;

                switch (v)
                {
                case FlverVertexStructMemberValueType.BoneIndicesStruct:
                    currentOffset += 4;
                    break;

                case FlverVertexStructMemberValueType.BoneWeightsStruct:
                    currentOffset += sizeof(ushort) * 4;
                    break;

                case FlverVertexStructMemberValueType.UV:
                    currentOffset += sizeof(ushort) * 2;
                    break;

                case FlverVertexStructMemberValueType.UVPair:
                    currentOffset += (sizeof(ushort) * 2) * 2;
                    break;

                case FlverVertexStructMemberValueType.Vector3:
                    currentOffset += sizeof(float) * 3;
                    break;

                case FlverVertexStructMemberValueType.PackedVector4:
                    currentOffset += 4;
                    break;
                }

                structLayout.Members.Add(newMember);
            }

            var semanticsQueue = new Queue <FlverVertexStructMemberSemantic>(IncludedSemantics);

            while (semanticsQueue.Count > 0)
            {
                var semantic = semanticsQueue.Dequeue();
                switch (semantic)
                {
                case FlverVertexStructMemberSemantic.Position:
                    _newMember(FlverVertexStructMemberSemantic.Position,
                               FlverVertexStructMemberValueType.Vector3);
                    break;

                case FlverVertexStructMemberSemantic.BoneIndices:
                    _newMember(FlverVertexStructMemberSemantic.BoneIndices,
                               FlverVertexStructMemberValueType.BoneIndicesStruct);
                    break;

                case FlverVertexStructMemberSemantic.BoneWeights:
                    _newMember(FlverVertexStructMemberSemantic.BoneWeights,
                               FlverVertexStructMemberValueType.BoneWeightsStruct);
                    break;

                case FlverVertexStructMemberSemantic.Normal:
                    _newMember(FlverVertexStructMemberSemantic.Normal,
                               FlverVertexStructMemberValueType.PackedVector4);
                    break;

                case FlverVertexStructMemberSemantic.BiTangent:
                    _newMember(FlverVertexStructMemberSemantic.BiTangent,
                               FlverVertexStructMemberValueType.PackedVector4);
                    break;

                case FlverVertexStructMemberSemantic.VertexColor:
                    _newMember(FlverVertexStructMemberSemantic.VertexColor,
                               FlverVertexStructMemberValueType.PackedVector4);
                    break;

                case FlverVertexStructMemberSemantic.UV:
                    //If followed by another UV:
                    if (semanticsQueue.Count > 0 && semanticsQueue.Peek() == FlverVertexStructMemberSemantic.UV)
                    {
                        _newMember(FlverVertexStructMemberSemantic.UV,
                                   FlverVertexStructMemberValueType.UVPair);

                        //Consume the next UV along with the current one:
                        semanticsQueue.Dequeue();
                    }
                    else
                    {
                        _newMember(FlverVertexStructMemberSemantic.UV,
                                   FlverVertexStructMemberValueType.UV);
                    }
                    break;

                case FlverVertexStructMemberSemantic.UnknownVector4A:
                    _newMember(FlverVertexStructMemberSemantic.UnknownVector4A,
                               FlverVertexStructMemberValueType.PackedVector4);
                    break;
                }
            }

            return(structLayout);
        }