コード例 #1
0
        public static IColor GetColorFromRGBA(IRGB c, int a)
        {
            var hsv = rgb2hsv(c.r, c.g, c.b);

            var hex = rgb2hex(c.r, c.g, c.b);

            var color = new Color
            {
                a   = a,
                b   = c.b,
                g   = c.g,
                h   = hsv.h,
                hex = hex,
                r   = c.r,
                s   = hsv.s,
                str = a == 100 ? $"#{hex}" : $"rgba(${c.r}, ${c.g}, ${c.b}, ${a / 100})",
                v   = hsv.v
            };

            return(color);
        }
コード例 #2
0
        private static IRGB hsl(string str)
        {
            if (!str.StartsWith("hsl("))
            {
                return(null);
            }

            var parts = parser.Match(str)
                        .Value
                        .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                        .Select(v => Convert.ToSingle(v))
                        .ToArray();

            int h = Convert.ToInt32(parts[0]);
            int s = Convert.ToInt32(parts[1]);
            int l = Convert.ToInt32(parts[2]);

            IRGB rgba = hsl2rgb(h, s, l);

            rgba.a = 100;

            return(rgba);
        }
コード例 #3
0
        public static IColor getColorFromString(string inputColor)
        {
            IRGB color = cssColor(inputColor);

            if (color == null)
            {
                return(null);
            }

            IHSV hsv = rgb2hsv(color.r, color.g, color.b);

            return(new Color
            {
                a = color.a,
                b = color.b,
                g = color.g,
                h = hsv.h,
                hex = rgb2hex(color.r, color.g, color.b),
                r = color.r,
                s = hsv.s,
                str = inputColor,
                v = hsv.v
            });
        }
コード例 #4
0
        public override void Read(BinaryReader r)
        {
            base.Read(r);
            Flags2 = r.ReadUInt32(); // another filler
            var tmpdataStreamType = r.ReadUInt32();

            DataStreamType = (DataStreamTypeEnum)Enum.ToObject(typeof(DataStreamTypeEnum), tmpdataStreamType);
            NumElements    = r.ReadUInt32(); // number of elements in this chunk
            if (_model.FileVersion == FileVersionEnum.CryTek_3_5 || _model.FileVersion == FileVersionEnum.CryTek_3_4)
            {
                BytesPerElement = r.ReadUInt32(); // bytes per element
            }
            if (_model.FileVersion == FileVersionEnum.CryTek_3_6)
            {
                BytesPerElement = (uint)r.ReadInt16();        // Star Citizen 2.0 is using an int16 here now.
                r.ReadInt16();                                // unknown value.   Doesn't look like padding though.
            }
            SkipBytes(r, 8);

            // Now do loops to read for each of the different Data Stream Types.  If vertices, need to populate Vector3s for example.
            switch (DataStreamType)
            {
            case DataStreamTypeEnum.VERTICES:      // Ref is 0x00000000
                Vertices = new Vector3[NumElements];
                switch (BytesPerElement)
                {
                case 12:
                    for (var i = 0; i < NumElements; i++)
                    {
                        Vertices[i].x = r.ReadSingle();
                        Vertices[i].y = r.ReadSingle();
                        Vertices[i].z = r.ReadSingle();
                    }
                    break;

                case 8:          // Prey files, and old Star Citizen files
                    for (var i = 0; i < NumElements; i++)
                    {
                        // 2 byte floats.  Use the Half structure from TK.Math
                        //Vertices[i].x = Byte4HexToFloat(r.ReadUInt16().ToString("X8"));
                        //Vertices[i].y = Byte4HexToFloat(r.ReadUInt16().ToString("X8")); r.ReadUInt16();
                        //Vertices[i].z = Byte4HexToFloat(r.ReadUInt16().ToString("X8"));
                        //Vertices[i].w = Byte4HexToFloat(r.ReadUInt16().ToString("X8"));
                        Vertices[i].x = new Half {
                            bits = r.ReadUInt16()
                        }.ToSingle();
                        Vertices[i].y = new Half {
                            bits = r.ReadUInt16()
                        }.ToSingle();
                        Vertices[i].z = new Half {
                            bits = r.ReadUInt16()
                        }.ToSingle();
                        r.ReadUInt16();
                    }
                    break;

                case 16:
                    //Console.WriteLine("method: (3)");
                    for (var i = 0; i < NumElements; i++)
                    {
                        Vertices[i].x = r.ReadSingle();
                        Vertices[i].y = r.ReadSingle();
                        Vertices[i].z = r.ReadSingle();
                        Vertices[i].w = r.ReadSingle();         // TODO:  Sometimes there's a W to these structures.  Will investigate.
                    }
                    break;
                }
                break;

            case DataStreamTypeEnum.INDICES:      // Ref is
                Indices = new uint[NumElements];
                if (BytesPerElement == 2)
                {
                    for (var i = 0; i < NumElements; i++)
                    {
                        Indices[i] = (uint)r.ReadUInt16();     //Console.WriteLine(R"Indices {i}: {Indices[i]}");
                    }
                }
                if (BytesPerElement == 4)
                {
                    for (var i = 0; i < NumElements; i++)
                    {
                        Indices[i] = r.ReadUInt32();
                    }
                }
                //Log($"Offset is {r.BaseStream.Position:X}");
                break;

            case DataStreamTypeEnum.NORMALS:
                Normals = new Vector3[NumElements];
                for (var i = 0; i < NumElements; i++)
                {
                    Normals[i].x = r.ReadSingle();
                    Normals[i].y = r.ReadSingle();
                    Normals[i].z = r.ReadSingle();
                }
                //Log($"Offset is {r.BaseStream.Position:X}");
                break;

            case DataStreamTypeEnum.UVS:
                UVs = new UV[NumElements];
                for (var i = 0; i < NumElements; i++)
                {
                    UVs[i].U = r.ReadSingle();
                    UVs[i].V = r.ReadSingle();
                }
                //Log($"Offset is {r..BaseStream.Position:X}");
                break;

            case DataStreamTypeEnum.TANGENTS:
                Tangents = new Tangent[NumElements, 2];
                Normals  = new Vector3[NumElements];
                for (var i = 0; i < NumElements; i++)
                {
                    switch (BytesPerElement)
                    {
                    case 0x10:
                        // These have to be divided by 32767 to be used properly (value between 0 and 1)
                        Tangents[i, 0].x = r.ReadInt16();
                        Tangents[i, 0].y = r.ReadInt16();
                        Tangents[i, 0].z = r.ReadInt16();
                        Tangents[i, 0].w = r.ReadInt16();
                        //
                        Tangents[i, 1].x = r.ReadInt16();
                        Tangents[i, 1].y = r.ReadInt16();
                        Tangents[i, 1].z = r.ReadInt16();
                        Tangents[i, 1].w = r.ReadInt16();
                        break;

                    case 0x08:
                        // These have to be divided by 127 to be used properly (value between 0 and 1)
                        // Tangent
                        Tangents[i, 0].w = r.ReadSByte() / 127.0f;
                        Tangents[i, 0].x = r.ReadSByte() / 127.0f;
                        Tangents[i, 0].y = r.ReadSByte() / 127.0f;
                        Tangents[i, 0].z = r.ReadSByte() / 127.0f;
                        // Binormal
                        Tangents[i, 1].w = r.ReadSByte() / 127.0f;
                        Tangents[i, 1].x = r.ReadSByte() / 127.0f;
                        Tangents[i, 1].y = r.ReadSByte() / 127.0f;
                        Tangents[i, 1].z = r.ReadSByte() / 127.0f;
                        // Calculate the normal based on the cross product of the tangents.
                        //Normals[i].x = (Tangents[i,0].y * Tangents[i,1].z - Tangents[i,0].z * Tangents[i,1].y);
                        //Normals[i].y = 0 - (Tangents[i,0].x * Tangents[i,1].z - Tangents[i,0].z * Tangents[i,1].x);
                        //Normals[i].z = (Tangents[i,0].x * Tangents[i,1].y - Tangents[i,0].y * Tangents[i,1].x);
                        //Console.WriteLine("Tangent: {0:F6} {1:F6} {2:F6}", Tangents[i,0].x, Tangents[i, 0].y, Tangents[i, 0].z);
                        //Console.WriteLine("Binormal: {0:F6} {1:F6} {2:F6}", Tangents[i, 1].x, Tangents[i, 1].y, Tangents[i, 1].z);
                        //Console.WriteLine("Normal: {0:F6} {1:F6} {2:F6}", Normals[i].x, Normals[i].y, Normals[i].z);
                        break;

                    default: throw new Exception("Need to add new Tangent Size");
                    }
                }
                //Log($"Offset is {r.BaseStream.Position:X}");
                break;

            case DataStreamTypeEnum.COLORS:
                switch (BytesPerElement)
                {
                case 3:
                    RGBColors = new IRGB[NumElements];
                    for (var i = 0; i < NumElements; i++)
                    {
                        RGBColors[i].r = r.ReadByte();
                        RGBColors[i].g = r.ReadByte();
                        RGBColors[i].b = r.ReadByte();
                    }
                    break;

                case 4:
                    RGBAColors = new IRGBA[NumElements];
                    for (var i = 0; i < NumElements; i++)
                    {
                        RGBAColors[i].r = r.ReadByte();
                        RGBAColors[i].g = r.ReadByte();
                        RGBAColors[i].b = r.ReadByte();
                        RGBAColors[i].a = r.ReadByte();
                    }
                    break;

                default:
                    Log("Unknown Color Depth");
                    for (var i = 0; i < NumElements; i++)
                    {
                        SkipBytes(r, BytesPerElement);
                    }
                    break;
                }
                break;

            case DataStreamTypeEnum.VERTSUVS:      // 3 half floats for verts, 3 half floats for normals, 2 half floats for UVs
                Vertices  = new Vector3[NumElements];
                Normals   = new Vector3[NumElements];
                RGBColors = new IRGB[NumElements];
                UVs       = new UV[NumElements];
                switch (BytesPerElement) // new Star Citizen files
                {
                case 20:                 // Dymek wrote this.  Used in 2.6 skin files.  3 floats for vertex position, 4 bytes for normals, 2 halfs for UVs.  Normals are calculated from Tangents
                    for (var i = 0; i < NumElements; i++)
                    {
                        Vertices[i].x = r.ReadSingle();
                        Vertices[i].y = r.ReadSingle();
                        Vertices[i].z = r.ReadSingle();         // For some reason, skins are an extra 1 meter in the z direction.
                        // Normals are stored in a signed byte, prob div by 127.
                        Normals[i].x = (float)r.ReadSByte() / 127;
                        Normals[i].y = (float)r.ReadSByte() / 127;
                        Normals[i].z = (float)r.ReadSByte() / 127;
                        r.ReadSByte();         // Should be FF.
                        UVs[i].U = new Half {
                            bits = r.ReadUInt16()
                        }.ToSingle();
                        UVs[i].V = new Half {
                            bits = r.ReadUInt16()
                        }.ToSingle();
                        //UVs[i].U = Byte4HexToFloat(r.ReadUInt16().ToString("X8"));
                        //UVs[i].V = Byte4HexToFloat(r.ReadUInt16().ToString("X8"));
                    }
                    break;

                case 16:           // Dymek updated this.
                                   //Console.WriteLine("method: (5), 3 half floats for verts, 3 colors, 2 half floats for UVs");
                    for (var i = 0; i < NumElements; i++)
                    {
                        ushort bver = 0;
                        var    ver  = 0F;
                        Vertices[i].x = Byte2HexIntFracToFloat2(r.ReadUInt16().ToString("X4")) / 127f;
                        Vertices[i].y = Byte2HexIntFracToFloat2(r.ReadUInt16().ToString("X4")) / 127f;
                        Vertices[i].z = Byte2HexIntFracToFloat2(r.ReadUInt16().ToString("X4")) / 127f;
                        Vertices[i].w = Byte2HexIntFracToFloat2(r.ReadUInt16().ToString("X4")) / 127f;         // Almost always 1
                        // Next structure is Colors, not normals.  For 16 byte elements, normals are calculated from Tangent data.
                        //RGBColors[i].r = r.ReadByte();
                        //RGBColors[i].g = r.ReadByte();
                        //RGBColors[i].b = r.ReadByte();
                        //r.ReadByte();           // additional byte.
                        //
                        //Normals[i].x = (r.ReadByte() - 128.0f) / 127.5f;
                        //Normals[i].y = (r.ReadByte() - 128.0f) / 127.5f;
                        //Normals[i].z = (r.ReadByte() - 128.0f) / 127.5f;
                        //r.ReadByte();           // additional byte.
                        // Read a Quat, convert it to vector3
                        var quat = new Vector4
                        {
                            x = (r.ReadByte() - 128.0f) / 127.5f,
                            y = (r.ReadByte() - 128.0f) / 127.5f,
                            z = (r.ReadByte() - 128.0f) / 127.5f,
                            w = (r.ReadByte() - 128.0f) / 127.5f
                        };
                        Normals[i].x = (2 * (quat.x * quat.z + quat.y * quat.w));
                        Normals[i].y = (2 * (quat.y * quat.z - quat.x * quat.w));
                        Normals[i].z = (2 * (quat.z * quat.z + quat.w * quat.w)) - 1;

                        // UVs ABSOLUTELY should use the Half structures.
                        UVs[i].U = new Half {
                            bits = r.ReadUInt16()
                        }.ToSingle();
                        UVs[i].V = new Half {
                            bits = r.ReadUInt16()
                        }.ToSingle();

                        //Vertices[i].x = new Half { bits = r.ReadUInt16() }.ToSingle();
                        //Vertices[i].y = new Half { bits = r.ReadUInt16() }.ToSingle();
                        //Vertices[i].z = new Half { bits = r.ReadUInt16() }.ToSingle();
                        //Normals[i].x = new Half { bits = r.ReadUInt16() }.ToSingle();
                        //Normals[i].y = new Half { bits = r.ReadUInt16() }.ToSingle();
                        //Normals[i].z = new Half { bits = r.ReadUInt16() }.ToSingle();
                        //UVs[i].U = new Half { bits = r.ReadUInt16() }.ToSingle();
                        //UVs[i].V = new Half { bits = r.ReadUInt16() }.ToSingle();
                    }
                    break;

                default:
                    Log("Unknown VertUV structure");
                    SkipBytes(r, NumElements * BytesPerElement);
                    break;
                }
                break;

            case DataStreamTypeEnum.BONEMAP:
                var skin = GetSkinningInfo();
                skin.HasBoneMapDatastream = true;
                skin.BoneMapping          = new List <MeshBoneMapping>();
                // Bones should have 4 bone IDs (index) and 4 weights.
                for (var i = 0; i < NumElements; i++)
                {
                    var tmpMap = new MeshBoneMapping();
                    switch (BytesPerElement)
                    {
                    case 8:
                        tmpMap.BoneIndex = new int[4];
                        tmpMap.Weight    = new int[4];
                        for (var j = 0; j < 4; j++)                 // read the 4 bone indexes first
                        {
                            tmpMap.BoneIndex[j] = r.ReadByte();
                        }
                        for (var j = 0; j < 4; j++)                   // read the weights.
                        {
                            tmpMap.Weight[j] = r.ReadByte();
                        }
                        skin.BoneMapping.Add(tmpMap);
                        break;

                    case 12:
                        tmpMap.BoneIndex = new int[4];
                        tmpMap.Weight    = new int[4];
                        for (var j = 0; j < 4; j++)                 // read the 4 bone indexes first
                        {
                            tmpMap.BoneIndex[j] = r.ReadUInt16();
                        }
                        for (var j = 0; j < 4; j++)                   // read the weights.
                        {
                            tmpMap.Weight[j] = r.ReadByte();
                        }
                        skin.BoneMapping.Add(tmpMap);
                        break;

                    default: Log("Unknown BoneMapping structure"); break;
                    }
                }
                break;

            case DataStreamTypeEnum.UNKNOWN1:
                Tangents = new Tangent[NumElements, 2];
                Normals  = new Vector3[NumElements];
                for (var i = 0; i < NumElements; i++)
                {
                    Tangents[i, 0].w = r.ReadSByte() / 127.0f;
                    Tangents[i, 0].x = r.ReadSByte() / 127.0f;
                    Tangents[i, 0].y = r.ReadSByte() / 127.0f;
                    Tangents[i, 0].z = r.ReadSByte() / 127.0f;
                    // Binormal
                    Tangents[i, 1].w = r.ReadSByte() / 127.0f;
                    Tangents[i, 1].x = r.ReadSByte() / 127.0f;
                    Tangents[i, 1].y = r.ReadSByte() / 127.0f;
                    Tangents[i, 1].z = r.ReadSByte() / 127.0f;
                    // Calculate the normal based on the cross product of the tangents.
                    Normals[i].x = (Tangents[i, 0].y * Tangents[i, 1].z - Tangents[i, 0].z * Tangents[i, 1].y);
                    Normals[i].y = 0 - (Tangents[i, 0].x * Tangents[i, 1].z - Tangents[i, 0].z * Tangents[i, 1].x);
                    Normals[i].z = (Tangents[i, 0].x * Tangents[i, 1].y - Tangents[i, 0].y * Tangents[i, 1].x);
                }
                break;

            default: Log("***** Unknown DataStream Type *****"); break;
            }
        }
コード例 #5
0
        public static string hsv2hex(float h, float s, float v)
        {
            IRGB rgb = hsv2rgb(h, s, v);

            return(rgb2hex(rgb.r, rgb.g, rgb.b));
        }
コード例 #6
0
        public override void Read(BinaryReader b)
        {
            base.Read(b);

            Flags2 = b.ReadUInt32(); // another filler
            uint tmpdataStreamType = b.ReadUInt32();

            DataStreamType = (DataStreamTypeEnum)Enum.ToObject(typeof(DataStreamTypeEnum), tmpdataStreamType);
            NumElements    = b.ReadUInt32(); // number of elements in this chunk

            if (_model.FileVersion == FileVersionEnum.CryTek_3_5 || _model.FileVersion == FileVersionEnum.CryTek_3_4)
            {
                BytesPerElement = b.ReadUInt32();
            }
            if (_model.FileVersion == FileVersionEnum.CryTek_3_6)
            {
                BytesPerElement = (uint)b.ReadInt16();        // Star Citizen 2.0 is using an int16 here now.
                b.ReadInt16();                                // unknown value.   Doesn't look like padding though.
            }

            SkipBytes(b, 8);

            // Now do loops to read for each of the different Data Stream Types.  If vertices, need to populate Vector3s for example.
            switch (DataStreamType)
            {
                #region case DataStreamTypeEnum.VERTICES:

            case DataStreamTypeEnum.VERTICES:      // Ref is 0x00000000
                Vertices = new Vector3[NumElements];

                switch (BytesPerElement)
                {
                case 12:
                    for (int i = 0; i < NumElements; i++)
                    {
                        Vertices[i].x = b.ReadSingle();
                        Vertices[i].y = b.ReadSingle();
                        Vertices[i].z = b.ReadSingle();
                    }
                    break;

                case 8:          // Prey files, and old Star Citizen files
                    for (int i = 0; i < NumElements; i++)
                    {
                        //uint bver = 0;
                        //float ver = 0;

                        // 2 byte floats.  Use the Half structure from TK.Math
                        //bver = b.ReadUInt16();
                        //ver = Byte4HexToFloat(bver.ToString("X8"));
                        //Vertices[i].x = ver;

                        //bver = b.ReadUInt16();
                        //ver = Byte4HexToFloat(bver.ToString("X8"));
                        //Vertices[i].y = ver; bver = b.ReadUInt16();

                        //bver = b.ReadUInt16();
                        //ver = Byte4HexToFloat(bver.ToString("X8"));
                        //Vertices[i].z = ver;

                        //bver = b.ReadUInt16();
                        //ver = Byte4HexToFloat(bver.ToString("X8"));
                        //Vertices[i].w = ver;
                        Half xshort = new Half();
                        xshort.bits   = b.ReadUInt16();
                        Vertices[i].x = xshort.ToSingle();

                        Half yshort = new Half();
                        yshort.bits   = b.ReadUInt16();
                        Vertices[i].y = yshort.ToSingle();

                        Half zshort = new Half();
                        zshort.bits   = b.ReadUInt16();
                        Vertices[i].z = zshort.ToSingle();
                        b.ReadUInt16();
                    }
                    break;

                case 16:
                    for (int i = 0; i < NumElements; i++)
                    {
                        Vertices[i].x = b.ReadSingle();
                        Vertices[i].y = b.ReadSingle();
                        Vertices[i].z = b.ReadSingle();
                        Vertices[i].w = b.ReadSingle();         // TODO:  Sometimes there's a W to these structures.  Will investigate.
                    }
                    break;
                }
                break;

                #endregion
                #region case DataStreamTypeEnum.INDICES:

            case DataStreamTypeEnum.INDICES:      // Ref is
                Indices = new uint[NumElements];

                if (BytesPerElement == 2)
                {
                    for (int i = 0; i < NumElements; i++)
                    {
                        Indices[i] = (uint)b.ReadUInt16();
                        //Console.WriteLine("Indices {0}: {1}", i, Indices[i]);
                    }
                }
                if (BytesPerElement == 4)
                {
                    for (int i = 0; i < NumElements; i++)
                    {
                        Indices[i] = b.ReadUInt32();
                    }
                }
                //Utils.Log(LogLevelEnum.Debug, "Offset is {0:X}", b.BaseStream.Position);
                break;

                #endregion
                #region case DataStreamTypeEnum.NORMALS:

            case DataStreamTypeEnum.NORMALS:
                Normals = new Vector3[NumElements];
                for (int i = 0; i < NumElements; i++)
                {
                    Normals[i].x = b.ReadSingle();
                    Normals[i].y = b.ReadSingle();
                    Normals[i].z = b.ReadSingle();
                }
                break;

                #endregion
                #region case DataStreamTypeEnum.UVS:

            case DataStreamTypeEnum.UVS:
                UVs = new UV[NumElements];
                for (Int32 i = 0; i < NumElements; i++)
                {
                    UVs[i].U = b.ReadSingle();
                    UVs[i].V = b.ReadSingle();
                }
                //Utils.Log(LogLevelEnum.Debug, "Offset is {0:X}", b.BaseStream.Position);
                break;

                #endregion
                #region case DataStreamTypeEnum.TANGENTS:

            case DataStreamTypeEnum.TANGENTS:
                Tangents = new Tangent[NumElements, 2];
                Normals  = new Vector3[NumElements];
                for (int i = 0; i < NumElements; i++)
                {
                    switch (BytesPerElement)
                    {
                    case 0x10:
                        // These have to be divided by 32767 to be used properly (value between 0 and 1)
                        Tangents[i, 0].x = b.ReadInt16();
                        Tangents[i, 0].y = b.ReadInt16();
                        Tangents[i, 0].z = b.ReadInt16();
                        Tangents[i, 0].w = b.ReadInt16();

                        Tangents[i, 1].x = b.ReadInt16();
                        Tangents[i, 1].y = b.ReadInt16();
                        Tangents[i, 1].z = b.ReadInt16();
                        Tangents[i, 1].w = b.ReadInt16();

                        break;

                    case 0x08:
                        // These have to be divided by 127 to be used properly (value between 0 and 1)
                        // Tangent
                        Tangents[i, 0].w = b.ReadSByte() / 127.0;
                        Tangents[i, 0].x = b.ReadSByte() / 127.0;
                        Tangents[i, 0].y = b.ReadSByte() / 127.0;
                        Tangents[i, 0].z = b.ReadSByte() / 127.0;

                        // Binormal
                        Tangents[i, 1].w = b.ReadSByte() / 127.0;
                        Tangents[i, 1].x = b.ReadSByte() / 127.0;
                        Tangents[i, 1].y = b.ReadSByte() / 127.0;
                        Tangents[i, 1].z = b.ReadSByte() / 127.0;

                        // Calculate the normal based on the cross product of the tangents.
                        //Normals[i].x = (Tangents[i,0].y * Tangents[i,1].z - Tangents[i,0].z * Tangents[i,1].y);
                        //Normals[i].y = 0 - (Tangents[i,0].x * Tangents[i,1].z - Tangents[i,0].z * Tangents[i,1].x);
                        //Normals[i].z = (Tangents[i,0].x * Tangents[i,1].y - Tangents[i,0].y * Tangents[i,1].x);
                        //Console.WriteLine("Tangent: {0:F6} {1:F6} {2:F6}", Tangents[i,0].x, Tangents[i, 0].y, Tangents[i, 0].z);
                        //Console.WriteLine("Binormal: {0:F6} {1:F6} {2:F6}", Tangents[i, 1].x, Tangents[i, 1].y, Tangents[i, 1].z);
                        //Console.WriteLine("Normal: {0:F6} {1:F6} {2:F6}", Normals[i].x, Normals[i].y, Normals[i].z);
                        break;

                    default:
                        throw new Exception("Need to add new Tangent Size");
                    }
                }
                // Utils.Log(LogLevelEnum.Debug, "Offset is {0:X}", b.BaseStream.Position);
                break;

                #endregion
                #region case DataStreamTypeEnum.COLORS:

            case DataStreamTypeEnum.COLORS:
                switch (BytesPerElement)
                {
                case 3:
                    RGBColors = new IRGB[NumElements];
                    for (int i = 0; i < NumElements; i++)
                    {
                        RGBColors[i].r = b.ReadByte();
                        RGBColors[i].g = b.ReadByte();
                        RGBColors[i].b = b.ReadByte();
                    }
                    break;

                case 4:
                    RGBAColors = new IRGBA[NumElements];
                    for (int i = 0; i < NumElements; i++)
                    {
                        RGBAColors[i].r = b.ReadByte();
                        RGBAColors[i].g = b.ReadByte();
                        RGBAColors[i].b = b.ReadByte();
                        RGBAColors[i].a = b.ReadByte();
                    }
                    break;

                default:
                    Utils.Log("Unknown Color Depth");
                    for (int i = 0; i < NumElements; i++)
                    {
                        SkipBytes(b, BytesPerElement);
                    }
                    break;
                }
                break;

                #endregion
                #region case DataStreamTypeEnum.VERTSUVS:

            case DataStreamTypeEnum.VERTSUVS:      // 3 half floats for verts, 3 half floats for normals, 2 half floats for UVs
                // Utils.Log(LogLevelEnum.Debug, "In VertsUVs...");
                Vertices  = new Vector3[NumElements];
                Normals   = new Vector3[NumElements];
                RGBColors = new IRGB[NumElements];
                UVs       = new UV[NumElements];
                switch (BytesPerElement) // new Star Citizen files
                {
                case 20:                 // Dymek wrote   Used in 2.6 skin files.  3 floats for vertex position, 4 bytes for normals, 2 halfs for UVs.  Normals are calculated from Tangents
                    for (int i = 0; i < NumElements; i++)
                    {
                        Vertices[i].x = b.ReadSingle();
                        Vertices[i].y = b.ReadSingle();
                        Vertices[i].z = b.ReadSingle();                          // For some reason, skins are an extra 1 meter in the z direction.

                        // Normals are stored in a signed byte, prob div by 127.
                        Normals[i].x = (float)b.ReadSByte() / 127;
                        Normals[i].y = (float)b.ReadSByte() / 127;
                        Normals[i].z = (float)b.ReadSByte() / 127;
                        b.ReadSByte();         // Should be FF.

                        Half uvu = new Half();
                        uvu.bits = b.ReadUInt16();
                        UVs[i].U = uvu.ToSingle();

                        Half uvv = new Half();
                        uvv.bits = b.ReadUInt16();
                        UVs[i].V = uvv.ToSingle();

                        //bver = b.ReadUInt16();
                        //ver = Byte4HexToFloat(bver.ToString("X8"));
                        //UVs[i].U = ver;

                        //bver = b.ReadUInt16();
                        //ver = Byte4HexToFloat(bver.ToString("X8"));
                        //UVs[i].V = ver;
                    }
                    break;

                case 16:           // Dymek updated
                    //Console.WriteLine("method: (5), 3 half floats for verts, 3 colors, 2 half floats for UVs");
                    for (Int32 i = 0; i < NumElements; i++)
                    {
                        ushort bver = 0;
                        float  ver  = 0;

                        bver          = b.ReadUInt16();
                        ver           = Byte2HexIntFracToFloat2(bver.ToString("X4")) / 127;
                        Vertices[i].x = ver;

                        bver          = b.ReadUInt16();
                        ver           = Byte2HexIntFracToFloat2(bver.ToString("X4")) / 127;
                        Vertices[i].y = ver;

                        bver          = b.ReadUInt16();
                        ver           = Byte2HexIntFracToFloat2(bver.ToString("X4")) / 127;
                        Vertices[i].z = ver;

                        bver          = b.ReadUInt16();
                        ver           = Byte2HexIntFracToFloat2(bver.ToString("X4")) / 127;
                        Vertices[i].w = ver;               // Almost always 1

                        // Next structure is Colors, not normals.  For 16 byte elements, normals are calculated from Tangent data.
                        //RGBAColors[i].r = b.ReadByte();
                        //RGBAColors[i].g = b.ReadByte();
                        //RGBAColors[i].b = b.ReadByte();
                        //RGBAColors[i].a = b.ReadByte();

                        //Normals[i].x = (b.ReadByte() - 128.0f) / 127.5f;
                        //Normals[i].y = (b.ReadByte() - 128.0f) / 127.5f;
                        //Normals[i].z = (b.ReadByte() - 128.0f) / 127.5f;
                        //b.ReadByte();           // additional byte.

                        // Read a Quat, convert it to vector3
                        Vector4 quat = new Vector4();
                        quat.x       = (b.ReadByte() - 128.0f) / 127.5f;
                        quat.y       = (b.ReadByte() - 128.0f) / 127.5f;
                        quat.z       = (b.ReadByte() - 128.0f) / 127.5f;
                        quat.w       = (b.ReadByte() - 128.0f) / 127.5f;
                        Normals[i].x = (2 * (quat.x * quat.z + quat.y * quat.w));
                        Normals[i].y = (2 * (quat.y * quat.z - quat.x * quat.w));
                        Normals[i].z = (2 * (quat.z * quat.z + quat.w * quat.w)) - 1;


                        // UVs ABSOLUTELY should use the Half structures.
                        Half uvu = new Half();
                        uvu.bits = b.ReadUInt16();
                        UVs[i].U = uvu.ToSingle();

                        Half uvv = new Half();
                        uvv.bits = b.ReadUInt16();
                        UVs[i].V = uvv.ToSingle();

                        #region Legacy version using Halfs
                        //Half xshort = new Half();
                        //xshort.bits = b.ReadUInt16();
                        //Vertices[i].x = xshort.ToSingle();

                        //Half yshort = new Half();
                        //yshort.bits = b.ReadUInt16();
                        //Vertices[i].y = yshort.ToSingle();

                        //Half zshort = new Half();
                        //zshort.bits = b.ReadUInt16();
                        //Vertices[i].z = zshort.ToSingle();

                        //Half xnorm = new Half();
                        //xnorm.bits = b.ReadUInt16();
                        //Normals[i].x = xnorm.ToSingle();

                        //Half ynorm = new Half();
                        //ynorm.bits = b.ReadUInt16();
                        //Normals[i].y = ynorm.ToSingle();

                        //Half znorm = new Half();
                        //znorm.bits = b.ReadUInt16();
                        //Normals[i].z = znorm.ToSingle();

                        //Half uvu = new Half();
                        //uvu.bits = b.ReadUInt16();
                        //UVs[i].U = uvu.ToSingle();

                        //Half uvv = new Half();
                        //uvv.bits = b.ReadUInt16();
                        //UVs[i].V = uvv.ToSingle();
                        #endregion
                    }
                    break;

                default:
                    Utils.Log("Unknown VertUV structure");
                    for (Int32 i = 0; i < NumElements; i++)
                    {
                        SkipBytes(b, BytesPerElement);
                    }
                    break;
                }
                break;

                #endregion
                #region case DataStreamTypeEnum.BONEMAP:
            case DataStreamTypeEnum.BONEMAP:
                SkinningInfo skin = GetSkinningInfo();
                skin.HasBoneMapDatastream = true;

                skin.BoneMapping = new List <MeshBoneMapping>();

                // Bones should have 4 bone IDs (index) and 4 weights.
                for (int i = 0; i < NumElements; i++)
                {
                    MeshBoneMapping tmpMap = new MeshBoneMapping();
                    switch (BytesPerElement)
                    {
                    case 8:
                        tmpMap.BoneIndex = new int[4];
                        tmpMap.Weight    = new int[4];

                        for (int j = 0; j < 4; j++)                 // read the 4 bone indexes first
                        {
                            tmpMap.BoneIndex[j] = b.ReadByte();
                        }
                        for (int j = 0; j < 4; j++)                   // read the weights.
                        {
                            tmpMap.Weight[j] = b.ReadByte();
                        }
                        skin.BoneMapping.Add(tmpMap);
                        break;

                    case 12:
                        tmpMap.BoneIndex = new int[4];
                        tmpMap.Weight    = new int[4];

                        for (int j = 0; j < 4; j++)                 // read the 4 bone indexes first
                        {
                            tmpMap.BoneIndex[j] = b.ReadUInt16();
                        }
                        for (int j = 0; j < 4; j++)                   // read the weights.
                        {
                            tmpMap.Weight[j] = b.ReadByte();
                        }
                        skin.BoneMapping.Add(tmpMap);

                        break;

                    default:
                        Utils.Log("Unknown BoneMapping structure");
                        break;
                    }
                }

                break;

                #endregion
                #region DataStreamTypeEnum.Unknown1
            case DataStreamTypeEnum.UNKNOWN1:
                Tangents = new Tangent[NumElements, 2];
                Normals  = new Vector3[NumElements];
                for (int i = 0; i < NumElements; i++)
                {
                    Tangents[i, 0].w = b.ReadSByte() / 127.0;
                    Tangents[i, 0].x = b.ReadSByte() / 127.0;
                    Tangents[i, 0].y = b.ReadSByte() / 127.0;
                    Tangents[i, 0].z = b.ReadSByte() / 127.0;

                    // Binormal
                    Tangents[i, 1].w = b.ReadSByte() / 127.0;
                    Tangents[i, 1].x = b.ReadSByte() / 127.0;
                    Tangents[i, 1].y = b.ReadSByte() / 127.0;
                    Tangents[i, 1].z = b.ReadSByte() / 127.0;

                    // Calculate the normal based on the cross product of the tangents.
                    Normals[i].x = (Tangents[i, 0].y * Tangents[i, 1].z - Tangents[i, 0].z * Tangents[i, 1].y);
                    Normals[i].y = 0 - (Tangents[i, 0].x * Tangents[i, 1].z - Tangents[i, 0].z * Tangents[i, 1].x);
                    Normals[i].z = (Tangents[i, 0].x * Tangents[i, 1].y - Tangents[i, 0].y * Tangents[i, 1].x);
                }
                break;
                #endregion // Prey normals?
                #region default:

            default:
                Utils.Log(LogLevelEnum.Debug, "***** Unknown DataStream Type *****");
                break;

                #endregion
            }
        }