.mtl filesvar mtl_src = """
# Green material with low reflections
newmtl GreenMaterial
Ns 96.078431
Ka 0.000000 0.000000 0.000000
Kd 0.027186 0.180434 0.012088
Ks 0.500000 0.500000 0.500000
Ni 1.000000
d 1.000000
illum 2
"""
var parser = new MtlFileParser(mtl_src)
var name_to_mtls = parser.parse
assert name_to_mtls.keys.join == "GreenMaterial"gamnit :: MtlFileParser :: defaultinit
gamnit $ MtlFileParser :: SELF
Type of this instance, automatically specialized in every classcore :: Object :: class_factory
Implementation used byget_class to create the specific class.
			parser_base :: StringProcessor :: current_location
Gives the current location in thesrc
			gamnit :: MtlFileParser :: defaultinit
core :: Object :: defaultinit
parser_base :: StringProcessor :: hot_location
Returns the current location as aLocation object
			parser_base :: StringProcessor :: ignore_until
Reads characters until patterns is found
			parser_base :: StringProcessor :: ignore_until_whitespace
Ignores any printable character until a whitespace is encounteredparser_base :: StringProcessor :: ignore_until_whitespace_or_comment
Advancepos until a whitespace or # is encountered
			parser_base :: StringProcessor :: ignore_whitespaces
Advances insrc until a non-whitespace character is encountered
			core :: Object :: is_same_instance
Return true ifself and other are the same instance (i.e. same identity).
			core :: Object :: is_same_serialized
Isself the same as other in a serialization context?
			core :: Object :: is_same_type
Return true ifself and other have the same dynamic type.
			parser_base :: StringProcessor :: line_offset
Offset in the current lineparser_base :: StringProcessor :: line_start
Position at which current line startedparser_base :: StringProcessor :: line_start=
Position at which current line startedcore :: Object :: output_class_name
Display class name on stdout (debug only).parser_base :: StringProcessor :: read_number
Read a token and parse it as aFloat
			parser_base :: StringProcessor :: read_token
Read a single token after skipping preceding whitespacesparser_base :: StringProcessor :: read_until_eol_or_comment
Advancepos until the next end of line or a #
			parser_base :: StringProcessor :: read_vec3
Read 2 or 3 numbers and return them as aVec3
			parser_base :: StringProcessor :: read_vec4
Read 3 or 4 numbers and return them as aVec4
			parser_base :: StringProcessor :: skip_eol
Advancepos to skip the next end of line
			parser_base :: StringProcessor
Basic facilities for common parser operations on String sources
# Parser of `.mtl` files
#
# ~~~
# var mtl_src = """
# # Green material with low reflections
# newmtl GreenMaterial
# Ns 96.078431
# Ka 0.000000 0.000000 0.000000
# Kd 0.027186 0.180434 0.012088
# Ks 0.500000 0.500000 0.500000
# Ni 1.000000
# d 1.000000
# illum 2
# """
#
# var parser = new MtlFileParser(mtl_src)
# var name_to_mtls = parser.parse
# assert name_to_mtls.keys.join == "GreenMaterial"
# ~~~
class MtlFileParser
	super StringProcessor
	# Read and parse source and return all materials organized by their names
	fun parse: Map[String, MtlDef]
	do
		var mat_lib = new Map[String, MtlDef]
		var material: nullable MtlDef = null
		while not eof do
			var token = read_token
			if token == "newmtl" then
				var name = read_until_eol_or_comment
				material = new MtlDef(name)
				mat_lib[name] = material
			else if material != null then
				if token == "Ka" then
					material.ambient = read_vec3
				else if token == "Kd" then
					material.diffuse = read_vec3
				else if token == "Ks" then
					material.specular = read_vec3
				else if token == "d" then
					material.dissolved = read_number
				else if token == "Tr" then
					material.dissolved = 1.0 - read_number
				else if token == "illum" then
					material.illumination_model = read_number.to_i
				else if token == "map_Ka" then
					material.map_ambient = read_until_eol_or_comment
				else if token == "map_Kd" then
					material.map_diffuse = read_until_eol_or_comment
				else if token == "map_Bump" then
					material.map_bump = read_until_eol_or_comment
				else if token == "map_Ks" then
					material.map_specular = read_until_eol_or_comment
				else if token == "map_Ns" then
					material.map_exponent = read_until_eol_or_comment
				# TODO other line type headers
				else if token == "Ns" then
				else if token == "Ni" then
				else if token == "sharpness" then
				else if token == "bump" then
				end
			end
			skip_eol
		end
		return mat_lib
	end
end
					lib/gamnit/model_parsers/mtl.nit:20,1--90,3