示例#1
0
        public VTX1(EndianBinaryReader reader, int offset, BMDInfo modelstats = null)
        {
            Attributes     = new VertexData();
            StorageFormats = new SortedDictionary <GXVertexAttribute, Tuple <GXDataType, byte> >();

            reader.BaseStream.Seek(offset, System.IO.SeekOrigin.Begin);

            reader.SkipInt32();
            int vtx1Size = reader.ReadInt32();
            int attributeHeaderOffset = reader.ReadInt32();

            if (modelstats != null)
            {
                modelstats.VTX1Size = vtx1Size;
            }

            int[] attribDataOffsets = new int[13];

            for (int i = 0; i < 13; i++)
            {
                attribDataOffsets[i] = reader.ReadInt32();
            }

            GXVertexAttribute attrib = (GXVertexAttribute)reader.ReadInt32();

            while (attrib != GXVertexAttribute.Null)
            {
                GXComponentCount componentCount     = (GXComponentCount)reader.ReadInt32();
                GXDataType       componentType      = (GXDataType)reader.ReadInt32();
                byte             fractionalBitCount = reader.ReadByte();
                StorageFormats.Add(attrib, new Tuple <GXDataType, byte>(componentType, fractionalBitCount));

                reader.Skip(3);
                long curPos = reader.BaseStream.Position;

                int attribDataSize = 0;
                int attribOffset   = GetAttributeDataOffset(attribDataOffsets, vtx1Size, attrib, out attribDataSize);
                int attribCount    = GetAttributeDataCount(attribDataSize, attrib, componentType, componentCount);
                Attributes.SetAttributeData(attrib, LoadAttributeData(reader, offset + attribOffset, attribCount, fractionalBitCount, attrib, componentType, componentCount));

                reader.BaseStream.Seek(curPos, System.IO.SeekOrigin.Begin);
                attrib = (GXVertexAttribute)reader.ReadInt32();
            }

            reader.BaseStream.Seek(offset + vtx1Size, System.IO.SeekOrigin.Begin);
        }
示例#2
0
        private int GetAttributeDataCount(int size, GXVertexAttribute attribute, GXDataType dataType, GXComponentCount compCount)
        {
            int compCnt    = 0;
            int compStride = 0;

            if (attribute == GXVertexAttribute.Color0 || attribute == GXVertexAttribute.Color1)
            {
                switch (dataType)
                {
                case GXDataType.RGB565:
                case GXDataType.RGBA4:
                    compCnt    = 1;
                    compStride = 2;
                    break;

                case GXDataType.RGB8:
                case GXDataType.RGBX8:
                case GXDataType.RGBA6:
                case GXDataType.RGBA8:
                    compCnt    = 4;
                    compStride = 1;
                    break;
                }
            }

            else
            {
                switch (dataType)
                {
                case GXDataType.Unsigned8:
                case GXDataType.Signed8:
                    compStride = 1;
                    break;

                case GXDataType.Unsigned16:
                case GXDataType.Signed16:
                    compStride = 2;
                    break;

                case GXDataType.Float32:
                    compStride = 4;
                    break;
                }

                switch (attribute)
                {
                case GXVertexAttribute.Position:
                    if (compCount == GXComponentCount.Position_XY)
                    {
                        compCnt = 2;
                    }
                    else if (compCount == GXComponentCount.Position_XYZ)
                    {
                        compCnt = 3;
                    }
                    break;

                case GXVertexAttribute.Normal:
                    if (compCount == GXComponentCount.Normal_XYZ)
                    {
                        compCnt = 3;
                    }
                    break;

                case GXVertexAttribute.Tex0:
                case GXVertexAttribute.Tex1:
                case GXVertexAttribute.Tex2:
                case GXVertexAttribute.Tex3:
                case GXVertexAttribute.Tex4:
                case GXVertexAttribute.Tex5:
                case GXVertexAttribute.Tex6:
                case GXVertexAttribute.Tex7:
                    if (compCount == GXComponentCount.TexCoord_S)
                    {
                        compCnt = 1;
                    }
                    else if (compCount == GXComponentCount.TexCoord_ST)
                    {
                        compCnt = 2;
                    }
                    break;
                }
            }

            return(size / (compCnt * compStride));
        }
示例#3
0
        private List <Color> LoadColorData(EndianBinaryReader reader, int count, GXDataType dataType)
        {
            List <Color> colorList = new List <Color>();

            for (int i = 0; i < count; i++)
            {
                switch (dataType)
                {
                case GXDataType.RGB565:
                    short colorShort = reader.ReadInt16();
                    int   r5         = (colorShort & 0xF800) >> 11;
                    int   g6         = (colorShort & 0x07E0) >> 5;
                    int   b5         = (colorShort & 0x001F);
                    colorList.Add(new Color((float)r5 / 255.0f, (float)g6 / 255.0f, (float)b5 / 255.0f));
                    break;

                case GXDataType.RGB8:
                    byte r8 = reader.ReadByte();
                    byte g8 = reader.ReadByte();
                    byte b8 = reader.ReadByte();
                    reader.SkipByte();
                    colorList.Add(new Color((float)r8 / 255.0f, (float)g8 / 255.0f, (float)b8 / 255.0f));
                    break;

                case GXDataType.RGBX8:
                    byte rx8 = reader.ReadByte();
                    byte gx8 = reader.ReadByte();
                    byte bx8 = reader.ReadByte();
                    reader.SkipByte();
                    colorList.Add(new Color((float)rx8 / 255.0f, (float)gx8 / 255.0f, (float)bx8 / 255.0f));
                    break;

                case GXDataType.RGBA4:
                    short colorShortA = reader.ReadInt16();
                    int   r4          = (colorShortA & 0xF000) >> 12;
                    int   g4          = (colorShortA & 0x0F00) >> 8;
                    int   b4          = (colorShortA & 0x00F0) >> 4;
                    int   a4          = (colorShortA & 0x000F);
                    colorList.Add(new Color((float)r4 / 255.0f, (float)g4 / 255.0f, (float)b4 / 255.0f, (float)a4 / 255.0f));
                    break;

                case GXDataType.RGBA6:
                    int colorInt = reader.ReadInt32();
                    int r6       = (colorInt & 0xFC0000) >> 18;
                    int ga6      = (colorInt & 0x03F000) >> 12;
                    int b6       = (colorInt & 0x000FC0) >> 6;
                    int a6       = (colorInt & 0x00003F);
                    colorList.Add(new Color((float)r6 / 255.0f, (float)ga6 / 255.0f, (float)b6 / 255.0f, (float)a6 / 255.0f));
                    break;

                case GXDataType.RGBA8:
                    byte ra8 = reader.ReadByte();
                    byte ga8 = reader.ReadByte();
                    byte ba8 = reader.ReadByte();
                    byte aa8 = reader.ReadByte();
                    colorList.Add(new Color((float)ra8 / 255.0f, (float)ga8 / 255.0f, (float)ba8 / 255.0f, (float)aa8 / 255.0f));
                    break;
                }
            }

            return(colorList);
        }
示例#4
0
        private List <Vector3> LoadVec3Data(EndianBinaryReader reader, byte frac, int count, GXDataType dataType)
        {
            List <Vector3> vec3List = new List <Vector3>();

            for (int i = 0; i < count; i++)
            {
                switch (dataType)
                {
                case GXDataType.Unsigned8:
                    byte  compu81      = reader.ReadByte();
                    byte  compu82      = reader.ReadByte();
                    byte  compu83      = reader.ReadByte();
                    float compu81Float = (float)compu81 / (float)(1 << frac);
                    float compu82Float = (float)compu82 / (float)(1 << frac);
                    float compu83Float = (float)compu83 / (float)(1 << frac);
                    vec3List.Add(new Vector3(compu81Float, compu82Float, compu83Float));
                    break;

                case GXDataType.Signed8:
                    sbyte comps81      = reader.ReadSByte();
                    sbyte comps82      = reader.ReadSByte();
                    sbyte comps83      = reader.ReadSByte();
                    float comps81Float = (float)comps81 / (float)(1 << frac);
                    float comps82Float = (float)comps82 / (float)(1 << frac);
                    float comps83Float = (float)comps83 / (float)(1 << frac);
                    vec3List.Add(new Vector3(comps81Float, comps82Float, comps83Float));
                    break;

                case GXDataType.Unsigned16:
                    ushort compu161      = reader.ReadUInt16();
                    ushort compu162      = reader.ReadUInt16();
                    ushort compu163      = reader.ReadUInt16();
                    float  compu161Float = (float)compu161 / (float)(1 << frac);
                    float  compu162Float = (float)compu162 / (float)(1 << frac);
                    float  compu163Float = (float)compu163 / (float)(1 << frac);
                    vec3List.Add(new Vector3(compu161Float, compu162Float, compu163Float));
                    break;

                case GXDataType.Signed16:
                    short comps161      = reader.ReadInt16();
                    short comps162      = reader.ReadInt16();
                    short comps163      = reader.ReadInt16();
                    float comps161Float = (float)comps161 / (float)(1 << frac);
                    float comps162Float = (float)comps162 / (float)(1 << frac);
                    float comps163Float = (float)comps163 / (float)(1 << frac);
                    vec3List.Add(new Vector3(comps161Float, comps162Float, comps163Float));
                    break;

                case GXDataType.Float32:
                    vec3List.Add(new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()));
                    break;
                }
            }

            return(vec3List);
        }
示例#5
0
        private List <float> LoadSingleFloat(EndianBinaryReader reader, byte frac, int count, GXDataType dataType)
        {
            List <float> floatList = new List <float>();

            for (int i = 0; i < count; i++)
            {
                switch (dataType)
                {
                case GXDataType.Unsigned8:
                    byte  compu81      = reader.ReadByte();
                    float compu81Float = (float)compu81 / (float)(1 << frac);
                    floatList.Add(compu81Float);
                    break;

                case GXDataType.Signed8:
                    sbyte comps81      = reader.ReadSByte();
                    float comps81Float = (float)comps81 / (float)(1 << frac);
                    floatList.Add(comps81Float);
                    break;

                case GXDataType.Unsigned16:
                    ushort compu161      = reader.ReadUInt16();
                    float  compu161Float = (float)compu161 / (float)(1 << frac);
                    floatList.Add(compu161Float);
                    break;

                case GXDataType.Signed16:
                    short comps161      = reader.ReadInt16();
                    float comps161Float = (float)comps161 / (float)(1 << frac);
                    floatList.Add(comps161Float);
                    break;

                case GXDataType.Float32:
                    floatList.Add(reader.ReadSingle());
                    break;
                }
            }

            return(floatList);
        }
示例#6
0
        public object LoadAttributeData(EndianBinaryReader reader, int offset, int count, byte frac, GXVertexAttribute attribute, GXDataType dataType, GXComponentCount compCount)
        {
            reader.BaseStream.Seek(offset, System.IO.SeekOrigin.Begin);
            object final = null;

            switch (attribute)
            {
            case GXVertexAttribute.Position:
                switch (compCount)
                {
                case GXComponentCount.Position_XY:
                    final = LoadVec2Data(reader, frac, count, dataType);
                    break;

                case GXComponentCount.Position_XYZ:
                    final = LoadVec3Data(reader, frac, count, dataType);
                    break;
                }
                break;

            case GXVertexAttribute.Normal:
                switch (compCount)
                {
                case GXComponentCount.Normal_XYZ:
                    final = LoadVec3Data(reader, frac, count, dataType);
                    break;

                case GXComponentCount.Normal_NBT:
                    break;

                case GXComponentCount.Normal_NBT3:
                    break;
                }
                break;

            case GXVertexAttribute.Color0:
            case GXVertexAttribute.Color1:
                final = LoadColorData(reader, count, dataType);
                break;

            case GXVertexAttribute.Tex0:
            case GXVertexAttribute.Tex1:
            case GXVertexAttribute.Tex2:
            case GXVertexAttribute.Tex3:
            case GXVertexAttribute.Tex4:
            case GXVertexAttribute.Tex5:
            case GXVertexAttribute.Tex6:
            case GXVertexAttribute.Tex7:
                switch (compCount)
                {
                case GXComponentCount.TexCoord_S:
                    final = LoadSingleFloat(reader, frac, count, dataType);
                    break;

                case GXComponentCount.TexCoord_ST:
                    final = LoadVec2Data(reader, frac, count, dataType);
                    break;
                }
                break;
            }

            return(final);
        }
示例#7
0
        public VTX1(Assimp.Scene scene, bool forceFloat32, GXDataType postype = GXDataType.Float32, byte fraction = 0)
        {
            Attributes     = new VertexData();
            StorageFormats = new SortedDictionary <GXVertexAttribute, Tuple <GXDataType, byte> >();

            int i = -1;

            foreach (Assimp.Mesh mesh in scene.Meshes)
            {
                i++;
                Console.Write(mesh.Name);

                if (mesh.HasVertices)
                {
                    SetAssimpPositionAttribute(mesh);
                    if (!StorageFormats.ContainsKey(GXVertexAttribute.Position))
                    {
                        StorageFormats.Add(GXVertexAttribute.Position, new Tuple <GXDataType, byte>(postype, fraction));
                    }
                }
                else
                {
                    throw new Exception($"Mesh \"{ mesh.Name }\" ({i}) has no vertices!");
                }

                if (mesh.HasNormals)
                {
                    SetAssimpNormalAttribute(mesh);
                    if (!StorageFormats.ContainsKey(GXVertexAttribute.Normal))
                    {
                        StorageFormats.Add(GXVertexAttribute.Normal, new Tuple <GXDataType, byte>(GXDataType.Signed16, 14));
                    }
                }
                else
                {
                    Console.WriteLine($"Mesh \"{ mesh.Name }\" ({i}) has no normals.");
                }

                if (mesh.HasVertexColors(0))
                {
                    //Console.WriteLine($"Mesh \"{ mesh.Name }\" ({i}) has vertex colors on channel 0.");
                    SetAssimpColorAttribute(0, GXVertexAttribute.Color0, mesh);
                    if (!StorageFormats.ContainsKey(GXVertexAttribute.Color0))
                    {
                        StorageFormats.Add(GXVertexAttribute.Color0, new Tuple <GXDataType, byte>(GXDataType.RGBA8, 0));
                    }
                }
                //else
                //    Console.WriteLine($"Mesh \"{ mesh.Name }\" has no colors on channel 0.");

                if (mesh.HasVertexColors(1))
                {
                    //Console.WriteLine($"Mesh \"{ mesh.Name }\" ({i}) has vertex colors on channel 1.");
                    SetAssimpColorAttribute(1, GXVertexAttribute.Color1, mesh);
                    if (!StorageFormats.ContainsKey(GXVertexAttribute.Color1))
                    {
                        StorageFormats.Add(GXVertexAttribute.Color1, new Tuple <GXDataType, byte>(GXDataType.RGBA8, 0));
                    }
                }
                //else
                //Console.WriteLine($"Mesh \"{ mesh.Name }\" has no colors on channel 1.");

                for (int texCoords = 0; texCoords < 8; texCoords++)
                {
                    if (mesh.HasTextureCoords(texCoords))
                    {
                        //Console.WriteLine($"Mesh \"{ mesh.Name }\" ({i}) has texture coordinates on channel { texCoords }.");
                        SetAssimpTexCoordAttribute(texCoords, GXVertexAttribute.Tex0 + texCoords, mesh);
                        if (!StorageFormats.ContainsKey(GXVertexAttribute.Tex0 + texCoords))
                        {
                            bool use_float = false;
                            if (forceFloat32)
                            {
                                use_float = true;
                            }
                            else
                            {
                                use_float = use_float_for_texcoords(mesh, texCoords);
                                if (use_float)
                                {
                                    Console.WriteLine($"Mesh \"{ mesh.Name }\" ({i}) has big texture coordinate values on channel { texCoords } and will use floats.");
                                }
                            }

                            if (use_float)
                            {
                                StorageFormats.Add(GXVertexAttribute.Tex0 + texCoords, new Tuple <GXDataType, byte>(GXDataType.Float32, 0));
                            }
                            else
                            {
                                StorageFormats.Add(GXVertexAttribute.Tex0 + texCoords, new Tuple <GXDataType, byte>(GXDataType.Signed16, 8));
                            }
                        }
                    }
                    //else
                    //    Console.WriteLine($"Mesh \"{ mesh.Name }\" has no texture coordinates on channel { texCoords }.");

                    Console.Write(".");
                }
                Console.Write("✓");
                Console.WriteLine();
            }
        }