Exemple #1
0
        void ReadMaterial()
        {
            if (clyt.Materials.Count > 0)
            {
                throw new FormatException("Expecting just one mat1 section");
            }

            long baseOffset   = reader.Stream.Position - 8;
            int  numMaterials = reader.ReadInt32();

            while (numMaterials > 0)
            {
                // Read from table and jump to material
                long offset = baseOffset + reader.ReadUInt32();
                reader.Stream.PushToPosition(offset);

                var material = new Material();
                material.Name = reader.ReadString(0x14).Replace("\0", string.Empty);

                for (int i = 0; i < material.TevConstantColors.Length; i++)
                {
                    // TODO: Convert to RGBA
                    material.TevConstantColors[i] = reader.ReadUInt32();
                }

                uint flags           = reader.ReadUInt32();
                uint numTexMap       = flags & 0x3;
                uint numTexMatrix    = (flags >> 2) & 0x3;
                uint numTexCoordGen  = (flags >> 4) & 0x3;
                uint numTevStage     = (flags >> 6) & 0x7;
                bool hasAlphaCompare = ((flags >> 9) & 0x01) == 1;
                bool hasBlendMode    = ((flags >> 10) & 0x01) == 1;
                material.UseTextureOnly = ((flags >> 11) & 0x01) == 1;
                bool separateBlendMode  = ((flags >> 12) & 0x01) == 1;
                bool hasIndirectParam   = ((flags >> 13) & 0x01) == 1;
                uint numProjTexGenParam = (flags >> 14) & 0x03;
                bool hasFontShadowParam = ((flags >> 16) & 0x01) == 1;

                for (int i = 0; i < numTexMap; i++)
                {
                    var entry = new TextureMapEntry();
                    entry.Index = reader.ReadUInt16();

                    byte flag1 = reader.ReadByte();
                    byte flag2 = reader.ReadByte();
                    entry.WrapS     = (WrapMode)(flag1 & 0x3);
                    entry.WrapT     = (WrapMode)(flag2 & 0x3);
                    entry.MinFilter = (TextureFilter)((flag1 >> 2) & 0x3);
                    entry.MagFilter = (TextureFilter)((flag2 >> 2) & 0x3);

                    material.TexMapEntries.Add(entry);
                }

                for (int i = 0; i < numTexMatrix; i++)
                {
                    var entry = new TextureMatrixEntry();
                    entry.Translation = new Vector2(reader.ReadSingle(), reader.ReadSingle());
                    entry.Rotation    = reader.ReadSingle();
                    entry.Scale       = new Vector2(reader.ReadSingle(), reader.ReadSingle());

                    material.TexMatrixEntries.Add(entry);
                }

                for (int i = 0; i < numTexCoordGen; i++)
                {
                    material.TextureCoordGen.Add(reader.ReadSingle());
                }

                for (int i = 0; i < numTevStage; i++)
                {
                    var stage = new TevStage();
                    stage.Param1 = reader.ReadUInt32();
                    stage.Param2 = reader.ReadUInt32();
                    stage.Param3 = reader.ReadUInt32();
                    material.TevStages.Add(stage);
                }

                if (hasAlphaCompare)
                {
                    material.AlphaCompare = new AlphaCompare {
                        Function  = reader.ReadUInt32(),
                        Reference = reader.ReadSingle(),
                    };
                }

                if (hasBlendMode)
                {
                    material.ColorBlendMode = new BlendMode {
                        BlendOperator     = reader.ReadByte(),
                        SourceFactor      = reader.ReadByte(),
                        DestinationFactor = reader.ReadByte(),
                        LogicOperator     = reader.ReadByte(),
                    };
                }

                if (separateBlendMode)
                {
                    material.AlphaBlendMode = new BlendMode {
                        BlendOperator     = reader.ReadByte(),
                        SourceFactor      = reader.ReadByte(),
                        DestinationFactor = reader.ReadByte(),
                        LogicOperator     = reader.ReadByte(),
                    };
                }

                if (hasIndirectParam || numProjTexGenParam > 0 || hasFontShadowParam)
                {
                    Console.WriteLine($"WARN: Material ({material.Name}) with unknown sections.");
                }

                clyt.Materials.Add(material);
                reader.Stream.PopPosition();
                numMaterials--;
            }
        }
Exemple #2
0
        void ReadMaterial()
        {
            if (clyt.Materials.Count > 0)
            {
                throw new FormatException("Expecting just one mat1 section");
            }

            long baseOffset   = reader.Stream.Position - 8;
            int  numMaterials = reader.ReadInt32();

            while (numMaterials > 0)
            {
                // Read from table and jump to material
                long offset = baseOffset + reader.ReadUInt32();
                reader.Stream.PushToPosition(offset);

                var material = new Material();
                material.Name = reader.ReadString(0x14).Replace("\0", string.Empty);

                for (int i = 0; i < material.TevConstantColors.Length; i++)
                {
                    // TODO: Convert to RGBA
                    material.TevConstantColors[i] = reader.ReadUInt32();
                }

                uint flags           = reader.ReadUInt32();
                uint numTexMap       = flags & 0x3;
                uint numTexMatrix    = (flags >> 2) & 0x3;
                uint numTexCoordGen  = (flags >> 4) & 0x3;
                uint numTevStage     = (flags >> 6) & 0x7;
                uint hasAlphaCompare = (flags >> 9) & 0x01;
                uint hasBlendMode    = (flags >> 10) & 0x01;
                material.UseTextureOnly = ((flags >> 11) & 0x01) == 1;
                uint separateBlendMode  = (flags >> 12) & 0x01;
                uint hasIndirectParam   = (flags >> 13) & 0x01;
                uint numProjTexGenParam = (flags >> 14) & 0x03;
                uint hasFontShadowParam = (flags >> 16) & 0x01;

                uint texMapOffset       = 0x34;
                uint texMatrixOffset    = texMapOffset + (numTexMap * 4);
                uint texCoordGenOffset  = texMatrixOffset + (numTexMatrix * 0x14);
                uint tevStageOffset     = texCoordGenOffset + (numTexCoordGen * 4);
                uint alphaCompareOffset = tevStageOffset + (numTevStage * 0xC);
                uint blendModeOffset    = alphaCompareOffset + 0x8;

                reader.Stream.Seek(offset + texMapOffset);
                for (int i = 0; i < numTexMap; i++)
                {
                    var entry = new TextureMapEntry();
                    entry.Index = reader.ReadUInt16();

                    byte flag1 = reader.ReadByte();
                    byte flag2 = reader.ReadByte();
                    entry.WrapS     = (WrapMode)(flag1 & 0x3);
                    entry.WrapT     = (WrapMode)(flag2 & 0x3);
                    entry.MinFilter = (TextureFilter)((flag1 >> 2) & 0x3);
                    entry.MagFilter = (TextureFilter)((flag2 >> 2) & 0x3);

                    material.TexMapEntries.Add(entry);
                }

                reader.Stream.Seek(offset + texMatrixOffset);
                for (int i = 0; i < numTexMatrix; i++)
                {
                    var entry = new TextureMatrixEntry();
                    entry.Translation = new Vector2(reader.ReadSingle(), reader.ReadSingle());
                    entry.Rotation    = reader.ReadSingle();
                    entry.Scale       = new Vector2(reader.ReadSingle(), reader.ReadSingle());

                    material.TexMatrixEntries.Add(entry);
                }

                reader.Stream.Seek(offset + texCoordGenOffset);
                for (int i = 0; i < numTexCoordGen; i++)
                {
                    material.TextureCoordGen.Add(reader.ReadSingle());
                }

                // TODO: Find a bclyt with the rest of sections

                clyt.Materials.Add(material);
                reader.Stream.PopPosition();
                numMaterials--;
            }
        }