private void Parse( string _block ) { m_states.m_unknownStates.Clear(); m_parms.m_unknownParms.Clear(); m_options.m_unknownOptions.Clear(); m_unknownVariables.Clear(); m_forbiddenParms.Clear(); m_isUsingVegetationParms = false; m_isUsingCloudParms = false; m_isUsingWaterParms = false; Parser P = new Parser( _block ); while ( P.OK ) { string token = P.ReadString(); if ( token == null ) break; // Done! if ( token.StartsWith( "//" ) ) { RecordSingleLineCommentVariable( token, P ); continue; } if ( token.StartsWith( "/*" ) ) { RecordCommentVariable( token, P ); continue; } if ( token.EndsWith( "{" ) ) { // Handle problematic parms without space before their values token = token.Substring( 0, token.Length-1 ); P.m_Index--; } P.SkipSpaces(); switch ( token.ToLower() ) { case "version": P.SkipSpaces(); m_version = P.ReadInteger(); break; case "state": m_states.Parse( P.ReadBlock() ); break; case "parms": m_parms.Parse( P.ReadBlock() ); break; case "options": ParseOptions( P.ReadBlock() ); break; // Programs case "mainprogram": m_programs.SetMainProgram( P.ReadString() ); break; case "zprepassprogram": m_programs.m_ZPrepass = P.ReadString(); break; case "shadowprogram": m_programs.m_shadow = P.ReadString(); break; // Textures // Layer 0 case "diffusemap": Layer0.m_diffuse = new Layer.Texture( P.ReadToEOL() ); break; case "bumpmap": Layer0.m_normal = new Layer.Texture( P.ReadToEOL() ); break; case "glossmap": Layer0.m_gloss = new Layer.Texture( P.ReadToEOL() ); break; case "metallicmap": Layer0.m_metal = new Layer.Texture( P.ReadToEOL() ); break; case "specularmap": Layer0.m_specular = new Layer.Texture( P.ReadToEOL() ); break; case "heightmap": m_height = new Layer.Texture( P.ReadToEOL() ); break; case "lightmap": m_lightMap = new Layer.Texture( P.ReadToEOL() ); break; case "occlusionmap": Layer0.m_AO = new Layer.Texture( P.ReadToEOL() ); break; case "translucencymap": Layer0.m_translucency = new Layer.Texture( P.ReadToEOL() ); break; case "emissivemap": Layer0.m_emissive = new Layer.Texture( P.ReadToEOL() ); break; case "layer0_maskmap": Layer0.m_mask = new Layer.Texture( P.ReadToEOL() ); break; case "layer0_scalebias": Layer0.ParseScaleBias( P ); break; case "layer0_maskscalebias":Layer0.ParseMaskScaleBias( P ); break; case "layer0_colorconstant":Layer0.m_colorConstant = P.ReadFloat4(); break; // Layer 1 case "layer1_diffusemap": Layer1.m_diffuse = new Layer.Texture( P.ReadToEOL() ); break; case "layer1_bumpmap": Layer1.m_normal = new Layer.Texture( P.ReadToEOL() ); break; case "layer1_glossmap": Layer1.m_gloss = new Layer.Texture( P.ReadToEOL() ); break; case "layer1_specularmap": Layer1.m_specular = new Layer.Texture( P.ReadToEOL() ); break; case "layer1_metallicmap": Layer1.m_metal = new Layer.Texture( P.ReadToEOL() ); break; case "layer1_maskmap": Layer1.m_mask = new Layer.Texture( P.ReadToEOL() ); break; case "layer1_emissivemap": throw new Exception( "Shouldn't be allowed!" );//P.SkipSpaces(); Layer1.m_emissive = new Layer.Texture( P.ReadToEOL() ); break; case "layer1_scalebias": Layer1.ParseScaleBias( P ); break; case "layer1_maskscalebias":Layer1.ParseMaskScaleBias( P ); break; case "layer1_colorconstant":Layer1.m_colorConstant = P.ReadFloat4(); break; // Layer 2 case "layer2_diffusemap": Layer2.m_diffuse = new Layer.Texture( P.ReadToEOL() ); break; case "layer2_bumpmap": Layer2.m_normal = new Layer.Texture( P.ReadToEOL() ); break; case "layer2_glossmap": Layer2.m_gloss = new Layer.Texture( P.ReadToEOL() ); break; case "layer2_specularmap": Layer2.m_specular = new Layer.Texture( P.ReadToEOL() ); break; case "layer2_metallicmap": Layer2.m_metal = new Layer.Texture( P.ReadToEOL() ); break; case "layer2_emissivemap": throw new Exception( "Shouldn't be allowed!" );//P.SkipSpaces(); Layer2.m_emissive = new Layer.Texture( P.ReadToEOL() ); break; case "layer2_maskmap": Layer2.m_mask = new Layer.Texture( P.ReadToEOL() ); break; case "layer2_scalebias": Layer2.ParseScaleBias( P ); break; case "layer2_maskscalebias":Layer2.ParseMaskScaleBias( P ); break; case "layer2_colorconstant":Layer2.m_colorConstant = P.ReadFloat4(); break; // Main variables case "m_physicsmaterial": m_physicsMaterial = P.ReadToEOL(); break; case "wardroughness": float4 roughness = P.ReadFloat4(); m_glossMinMax.x = roughness.x; m_glossMinMax.y = roughness.y; break; case "metallicminmax": float4 metal = P.ReadFloat4(); m_metallicMinMax.x = metal.x; m_metallicMinMax.y = metal.y; break; default: if ( CheckSafeTokens( token ) ) RecordUnknownVariable( token, P ); else RecordForbiddenVariable( token, P ); break; } } }
private void ParseOptions( string _options ) { try { Parser P = new Parser( _options ); while ( P.OK ) { string token = P.ReadString(); if ( token == null ) break; // Done! if ( token.StartsWith( "//" ) ) { RecordSingleLineCommentOption( token, P ); continue; } if ( token.StartsWith( "/*" ) ) { RecordCommentOption( token, P ); continue; } P.SkipSpaces(); if ( !P.IsNumeric() ) continue; // Ill-formed option? int value = P.ReadInteger(); switch ( token.ToLower() ) { case "glossindiffusealpha": m_options.m_glossInDiffuseAlpha = value != 0; break; case "alphatest": m_options.m_isAlphaTest = value != 0; break; case "ismasking": m_options.m_isMasking = value != 0; break; case "hasbumpmap": m_options.m_hasNormal = value != 0; break; case "hasspecularmap": m_options.m_hasSpecular = value != 0; break; case "hasocclusionmap": m_options.m_hasOcclusionMap = value != 0; break; case "hasglossmap": m_options.m_hasGloss = value != 0; break; case "hasmetallicmap": m_options.m_hasMetal = value != 0; break; case "hasemissivemap": m_options.m_hasEmissive = value != 0; break; case "translucency/enable": m_options.m_translucencyEnabled = value != 0; break; case "translucencyusevertexcolor": m_options.m_translucencyUseVertexColor = value != 0; break; case "extralayer": switch ( value ) { case 0: Layer0.m_mask = null; m_options.m_extraLayers = 0; break; case 1: Layer1.m_mask = null; m_options.m_extraLayers = 1; break; case 2: Layer2.m_mask = null; m_options.m_extraLayers = 2; break; default: throw new Exception( "Unsupported amount of extra layers!" ); } break; // LAYER 0 case "use_layer0_colorconstant": Layer0.m_useColorConstant = value != 0; break; case "layer0_uvset": switch ( value ) { case 0: Layer0.m_UVSet = Layer.UV_SET.UV0; break; case 1: Layer0.m_UVSet = Layer.UV_SET.UV1; break; default: throw new Exception( "Unsupported UV set!" ); } break; case "layer0_mask_uvset": switch ( value ) { case 0: Layer0.m_maskUVSet = Layer.UV_SET.UV0; break; case 1: Layer0.m_maskUVSet = Layer.UV_SET.UV1; break; default: throw new Exception( "Unsupported UV set!" ); } break; case "layer0_maskmode": switch ( value ) { case 0: Layer0.m_maskingMode = Layer.MASKING_MODE.VERTEX_COLOR; break; case 1: Layer0.m_maskingMode = Layer.MASKING_MODE.MASK_MAP; break; case 2: Layer0.m_maskingMode = Layer.MASKING_MODE.MASK_MAP_AND_VERTEX_COLOR; break; default: throw new Exception( "Unsupported UV set!" ); } break; // LAYER 1 case "use_layer1_colorconstant": Layer1.m_useColorConstant = value != 0; break; case "layer1_uvset": switch ( value ) { case 0: Layer1.m_UVSet = Layer.UV_SET.UV0; break; case 1: Layer1.m_UVSet = Layer.UV_SET.UV1; break; default: throw new Exception( "Unsupported UV set!" ); } break; case "layer1_mask_uvset": switch ( value ) { case 0: Layer1.m_maskUVSet = Layer.UV_SET.UV0; break; case 1: Layer1.m_maskUVSet = Layer.UV_SET.UV1; break; default: throw new Exception( "Unsupported UV set!" ); } break; case "layer1_maskmode": switch ( value ) { case 0: Layer1.m_maskingMode = Layer.MASKING_MODE.VERTEX_COLOR; break; case 1: Layer1.m_maskingMode = Layer.MASKING_MODE.MASK_MAP; break; case 2: Layer1.m_maskingMode = Layer.MASKING_MODE.MASK_MAP_AND_VERTEX_COLOR; break; default: throw new Exception( "Unsupported UV set!" ); } break; case "layer1_diffusereuselayer": switch ( value ) { case 0: Layer1.m_diffuseReUse = Layer.REUSE_MODE.DONT_REUSE; break; case 1: Layer1.m_diffuseReUse = Layer.REUSE_MODE.REUSE_LAYER0; break; default: throw new Exception( "Unsupported re-use mode!" ); } break; case "layer1_bumpreuselayer": switch ( value ) { case 0: Layer1.m_normalReUse = Layer.REUSE_MODE.DONT_REUSE; break; case 1: Layer1.m_normalReUse = Layer.REUSE_MODE.REUSE_LAYER0; break; default: throw new Exception( "Unsupported re-use mode!" ); } break; case "layer1_glossreuselayer": switch ( value ) { case 0: Layer1.m_glossReUse = Layer.REUSE_MODE.DONT_REUSE; break; case 1: Layer1.m_glossReUse = Layer.REUSE_MODE.REUSE_LAYER0; break; default: throw new Exception( "Unsupported re-use mode!" ); } break; case "layer1_specularreuselayer": switch ( value ) { case 0: Layer1.m_specularReUse = Layer.REUSE_MODE.DONT_REUSE; break; case 1: Layer1.m_specularReUse = Layer.REUSE_MODE.REUSE_LAYER0; break; default: throw new Exception( "Unsupported re-use mode!" ); } break; case "layer1_metallicreuselayer": switch ( value ) { case 0: Layer1.m_metalReUse = Layer.REUSE_MODE.DONT_REUSE; break; case 1: Layer1.m_metalReUse = Layer.REUSE_MODE.REUSE_LAYER0; break; default: throw new Exception( "Unsupported re-use mode!" ); } break; case "layer1_maskreuselayer": switch ( value ) { case 0: Layer1.m_maskReUse = Layer.REUSE_MODE.DONT_REUSE; break; case 1: Layer1.m_maskReUse = Layer.REUSE_MODE.REUSE_LAYER0; break; default: throw new Exception( "Unsupported re-use mode!" ); } break; // LAYER 2 case "use_layer2_colorconstant": Layer2.m_useColorConstant = value != 0; break; case "layer2_uvset": switch ( value ) { case 0: Layer2.m_UVSet = Layer.UV_SET.UV0; break; case 1: Layer2.m_UVSet = Layer.UV_SET.UV1; break; default: throw new Exception( "Unsupported UV set!" ); } break; case "layer2_mask_uvset": switch ( value ) { case 0: Layer2.m_maskUVSet = Layer.UV_SET.UV0; break; case 1: Layer2.m_maskUVSet = Layer.UV_SET.UV1; break; default: throw new Exception( "Unsupported UV set!" ); } break; case "layer2_maskmode": switch ( value ) { case 0: Layer2.m_maskingMode = Layer.MASKING_MODE.VERTEX_COLOR; break; case 1: Layer2.m_maskingMode = Layer.MASKING_MODE.MASK_MAP; break; case 2: Layer2.m_maskingMode = Layer.MASKING_MODE.MASK_MAP_AND_VERTEX_COLOR; break; default: throw new Exception( "Unsupported UV set!" ); } break; case "layer2_diffusereuselayer": switch ( value ) { case 0: Layer2.m_diffuseReUse = Layer.REUSE_MODE.DONT_REUSE; break; case 1: Layer2.m_diffuseReUse = Layer.REUSE_MODE.REUSE_LAYER0; break; case 2: Layer2.m_diffuseReUse = Layer.REUSE_MODE.REUSE_LAYER1; break; default: throw new Exception( "Unsupported re-use mode!" ); } break; case "layer2_bumpreuselayer": switch ( value ) { case 0: Layer2.m_normalReUse = Layer.REUSE_MODE.DONT_REUSE; break; case 1: Layer2.m_normalReUse = Layer.REUSE_MODE.REUSE_LAYER0; break; case 2: Layer2.m_normalReUse = Layer.REUSE_MODE.REUSE_LAYER1; break; default: throw new Exception( "Unsupported re-use mode!" ); } break; case "layer2_glossreuselayer": switch ( value ) { case 0: Layer2.m_glossReUse = Layer.REUSE_MODE.DONT_REUSE; break; case 1: Layer2.m_glossReUse = Layer.REUSE_MODE.REUSE_LAYER0; break; case 2: Layer2.m_glossReUse = Layer.REUSE_MODE.REUSE_LAYER1; break; default: throw new Exception( "Unsupported re-use mode!" ); } break; case "layer2_specularreuselayer": switch ( value ) { case 0: Layer2.m_specularReUse = Layer.REUSE_MODE.DONT_REUSE; break; case 1: Layer2.m_specularReUse = Layer.REUSE_MODE.REUSE_LAYER0; break; case 2: Layer2.m_specularReUse = Layer.REUSE_MODE.REUSE_LAYER1; break; default: throw new Exception( "Unsupported re-use mode!" ); } break; case "layer2_metallicreuselayer": switch ( value ) { case 0: Layer2.m_metalReUse = Layer.REUSE_MODE.DONT_REUSE; break; case 1: Layer2.m_metalReUse = Layer.REUSE_MODE.REUSE_LAYER0; break; case 2: Layer2.m_metalReUse = Layer.REUSE_MODE.REUSE_LAYER1; break; default: throw new Exception( "Unsupported re-use mode!" ); } break; case "layer2_maskreuselayer": switch ( value ) { case 0: Layer2.m_maskReUse = Layer.REUSE_MODE.DONT_REUSE; break; case 1: Layer2.m_maskReUse = Layer.REUSE_MODE.REUSE_LAYER0; break; case 2: Layer2.m_maskReUse = Layer.REUSE_MODE.REUSE_LAYER1; break; default: throw new Exception( "Unsupported re-use mode!" ); } break; default: CheckSafeOptionsTokens( token, value ); RecordUnknownOption( token, value, P ); break; } } } catch ( Exception _e ) { throw new Exception( "Failed parsing options block!", _e ); } }