public void ReadXML(XmlNode node)
            {
                MTD = node.Attributes["mtd"].InnerText.ToLower();


                AcceptableVertexBufferDeclarations.Clear();

                var vertBufferDeclarations = node.SelectNodes("acceptable_vertex_buffer_declarations/vertex_buffer_declaration");

                foreach (XmlNode vbnode in vertBufferDeclarations)
                {
                    var vb = new VertexBufferDeclaration();
                    vb.ReadXML(vbnode);
                    AcceptableVertexBufferDeclarations.Add(vb);
                }


                TextureChannels.Clear();

                var texChannelNodes = node.SelectNodes("texture_channel_list/texture_channel");

                foreach (XmlNode tcn in texChannelNodes)
                {
                    var texChannelSemanticIndex = tcn.SafeGetInt32Attribute("index");

                    string semanticAttribute  = tcn.SafeGetAttribute("semantic");
                    var    texChannelSemantic = (TextureChannelSemantic)Enum.Parse(typeof(TextureChannelSemantic), semanticAttribute);

                    // Try to figure out at runtime.
                    if (texChannelSemantic == TextureChannelSemantic.Unknown)
                    {
                        texChannelSemantic = GetTexChannelTypeFromName(tcn.InnerText).Semantic;
                    }

                    // See if runtime check passed.
                    if (texChannelSemantic == TextureChannelSemantic.Unknown)
                    {
                        throw new Exception($"Semantic of texture channel '{tcn.InnerText}' not defined.");
                    }

                    var chanTypeKey = new FlverTextureChannelType()
                    {
                        Semantic = texChannelSemantic,
                        Index    = texChannelSemanticIndex,
                    };


                    if (!TextureChannels.ContainsKey(chanTypeKey))
                    {
                        TextureChannels.Add(chanTypeKey, tcn.InnerText);
                    }
                    //ErrorTODO else print warning maybe
                }


                GXItems.Clear();

                var gxItemNodes = node.SelectNodes("gx_item_list/gx_item");

                foreach (XmlNode gin in gxItemNodes)
                {
                    var g = new GXItemDef();
                    g.ReadXML(gin);
                    GXItems.Add(g);
                }
            }
 public string GetTexChannelName(string mtd, FlverTextureChannelType channelType)
 {
     //ERRORTODO you know the drill
     return(MaterialDefs[mtd].TextureChannels[channelType]);
 }
            public static FlverTextureChannelType GetTexChannelTypeFromName(string name)
            {
                FlverTextureChannelType t = new FlverTextureChannelType();

                t.Semantic = TextureChannelSemantic.Unknown;

                bool Check(params string[] check)
                {
                    foreach (var s in check)
                    {
                        if (name.Contains(s))
                        {
                            return(true);
                        }
                    }

                    return(false);
                }

                if (Check("Diffuse", "Albedo"))
                {
                    t.Semantic = TextureChannelSemantic.Diffuse;
                }

                else if (Check("Specular", "Reflectance"))
                {
                    t.Semantic = TextureChannelSemantic.Specular;
                }

                else if (Check("Shininess"))
                {
                    t.Semantic = TextureChannelSemantic.Shininess;
                }

                // Check before normals because this contains "Bumpmap"
                else if (Check("DetailBumpmap", "DetailBumpMap", "DetailNormal"))
                {
                    t.Semantic = TextureChannelSemantic.DetailNormals;
                }
                else if (Check("AdditionalBumpmapTexture"))
                {
                    t.Semantic = TextureChannelSemantic.AdditionalNormals;
                }
                // Check before normals because this contains "Bumpmap"
                else if (Check("BreakBumpmap", "DamageNormal", "DamagedNormalTexture"))
                {
                    t.Semantic = TextureChannelSemantic.EquipmentBrokenNormals;
                }
                else if (Check("NormalMap", "Bumpmap"))
                {
                    t.Semantic = TextureChannelSemantic.Normals;
                }

                else if (Check("EmissiveMask"))
                {
                    t.Semantic = TextureChannelSemantic.Emissive;
                }
                else if (Check("Emissive"))
                {
                    t.Semantic = TextureChannelSemantic.Emissive;
                }

                else if (Check("BlendMask", "Blendmask", "BlendMap"))
                {
                    //TODO: Double check if "Blendmask" is used
                    t.Semantic = TextureChannelSemantic.Blendmask;
                }

                else if (Check("Vector"))
                {
                    t.Semantic = TextureChannelSemantic.Vector;
                }

                else if (Check("_MaskTexture"))
                {
                    t.Semantic = TextureChannelSemantic.Mask;
                }

                else if (Check("BlendEdge"))
                {
                    t.Semantic = TextureChannelSemantic.BlendEdge;
                }

                else if (Check("BloodMask"))
                {
                    t.Semantic = TextureChannelSemantic.BloodMask;
                }

                else if (Check("Displacement"))
                {
                    t.Semantic = TextureChannelSemantic.Displacement;
                }

                else if (Check("ScatteringMask", "SSSMask", "g_Subsurf"))
                {
                    t.Semantic = TextureChannelSemantic.ScatteringMask;
                }

                else if (Check("HighLight", "Highlight"))
                {
                    t.Semantic = TextureChannelSemantic.Highlight;
                }

                else if (Check("OpacityTexture"))
                {
                    t.Semantic = TextureChannelSemantic.Opacity;
                }

                else if (Check("_MetallicMap"))
                {
                    t.Semantic = TextureChannelSemantic.Metallic;
                }

                else if (Check("_Mask1Map"))
                {
                    t.Semantic = TextureChannelSemantic.SDTMask1;
                }

                else if (Check("_Mask3Map"))
                {
                    t.Semantic = TextureChannelSemantic.SDTMask3;
                }

                else if (Check("_Ripple"))
                {
                    t.Semantic = TextureChannelSemantic.SDTRipple;
                }

                else if (Check("_AmbientOcculusionMap")) // Typo everywhere it's found in SDT
                {
                    t.Semantic = TextureChannelSemantic.AmbientOcclusion;
                }

                else if (Check("_Star")) // Typo everywhere it's found in SDT
                {
                    t.Semantic = TextureChannelSemantic.SDTStar;
                }

                else if (Check("FlowMap", "_FlowTexture"))
                {
                    t.Semantic = TextureChannelSemantic.Flow;
                }

                else if (Check("_アルファマップ")) // Lit. "ALPHA MAP"
                // Going to guess alpha map is opacity
                {
                    t.Semantic = TextureChannelSemantic.Opacity;
                }

                else if (Check("HeightMap", "g_SnowHeightTexture", "g_Height"))
                {
                    t.Semantic = TextureChannelSemantic.Height;
                }

                else if (Check("_Foam1"))
                {
                    t.Semantic = TextureChannelSemantic.SDTFoam1;
                }

                else if (Check("_BurningMap"))
                {
                    t.Semantic = TextureChannelSemantic.DS3Burning;
                }

                else if (Check("_DOLTexture1", "g_Lightmap"))
                {
                    t.Semantic = TextureChannelSemantic.Lightmap1;
                    if (name.EndsWith("_DOLTexture1"))
                    {
                        t.Index = 0;
                    }
                }

                else if (Check("_DOLTexture2"))
                {
                    t.Semantic = TextureChannelSemantic.Lightmap2;
                    if (name.EndsWith("_DOLTexture2"))
                    {
                        t.Index = 0;
                    }
                }

                else if (Check("GITexture"))
                {
                    t.Semantic = TextureChannelSemantic.GlobalIllumination;
                }

                //if (t.Semantic == TextureChannelSemantic.Unknown)
                //    throw new NotImplementedException($"Texture channel type '{name}' not recognized.");

                if (char.IsDigit(name[name.Length - 1]))
                {
                    t.Index = int.Parse(name.Substring(name.Length - 1));
                }

                return(t);
            }