pbrt = _{ whitespace? ~ (statement | comment)* ~ last_statement }
statement = { active_transform |
concat_transform |
keyword |
look_at |
medium_interface |
named_statement |
rotate |
scale |
transform |
transform_times |
translate }
named_statement = { accelerator |
area_light_source |
camera |
coord_sys_transform |
film |
integrator |
light_source |
make_named_material |
make_named_medium |
material |
named_material |
pixel_filter |
sampler |
shape |
texture }
parameter = { bool_param |
blackbody_param |
float_param |
integer_param |
point2_param |
point_param |
normal_param |
rgb_param |
spectrum_param |
string_param |
texture_param |
vector_param }
bool_param = { ("\"bool" ~ ident ~ "\"" ~ lbrack ~ string ~ rbrack) |
("\"bool" ~ ident ~ "\"" ~ string) }
blackbody_param = { ("\"blackbody" ~ ident ~ "\"" ~ lbrack ~ number ~ number+ ~ rbrack) }
float_param = { ("\"float" ~ ident ~ "\"" ~ lbrack ~ number+ ~ rbrack) |
("\"float" ~ ident ~ "\"" ~ number) }
string_param = { "\"string" ~ ident ~ "\"" ~ lbrack ~ string ~ rbrack |
"\"string" ~ ident ~ "\"" ~ string }
integer_param = { ("\"integer" ~ ident ~ "\"" ~ lbrack ~ integer+ ~ rbrack) |
("\"integer" ~ ident ~ "\"" ~ integer) }
point2_param = { "\"point2" ~ ident ~ "\"" ~ lbrack ~ number+ ~ rbrack }
point_param = { "\"point" ~ ident ~ "\"" ~ lbrack ~ number+ ~ rbrack }
vector_param = { "\"vector" ~ ident ~ "\"" ~ lbrack ~ number ~ number ~ number ~ rbrack }
normal_param = { "\"normal" ~ ident ~ "\"" ~ lbrack ~ number+ ~ rbrack }
rgb_param = { ("\"rgb" ~ ident ~ "\"" ~ lbrack ~ number ~ number ~ number ~ rbrack) |
("\"color" ~ ident ~ "\"" ~ lbrack ~ number ~ number ~ number ~ rbrack) }
// TODO: "spectrum Kd" [ 300 .3 400 .6 410 .65 415 .8 500 .2 600 .1 ]
// or
// "spectrum Kd" "filename"
spectrum_param = { "\"spectrum" ~ ident ~ "\"" ~ string }
texture_param = { "\"texture" ~ ident ~ "\"" ~ lbrack ~ string ~ rbrack |
"\"texture" ~ ident ~ "\"" ~ string }
// Translate x y z
translate = { "Translate" ~
// followed by 3 numbers:
number ~ number ~ number
}
// Rotate angle x y z
rotate = { "Rotate" ~
// followed by 4 numbers:
number ~ number ~ number ~ number
}
// Scale x y z
scale = { "Scale" ~
// followed by 3 numbers:
number ~ number ~ number
}
// Transform m00 .. m33
transform = { ("Transform" ~ lbrack ~
// followed by 16 numbers:
number ~ number ~ number ~ number ~
number ~ number ~ number ~ number ~
number ~ number ~ number ~ number ~
number ~ number ~ number ~ number ~ rbrack) |
("Transform" ~
// followed by 16 numbers:
number ~ number ~ number ~ number ~
number ~ number ~ number ~ number ~
number ~ number ~ number ~ number ~
number ~ number ~ number ~ number)
}
// TransformTimes start end
transform_times = { "TransformTimes" ~
// followed by 2 numbers:
number ~ number
}
// ActiveTransform [ StartTime | EndTime | All ]
active_transform = { ("ActiveTransform" ~ all) |
("ActiveTransform" ~ start_time) |
("ActiveTransform" ~ end_time)
}
// ConcatTransform m00 .. m33
concat_transform = { ("ConcatTransform" ~ lbrack ~
// followed by 16 numbers:
number ~ number ~ number ~ number ~
number ~ number ~ number ~ number ~
number ~ number ~ number ~ number ~
number ~ number ~ number ~ number ~ rbrack) |
("ConcatTransform" ~
// followed by 16 numbers:
number ~ number ~ number ~ number ~
number ~ number ~ number ~ number ~
number ~ number ~ number ~ number ~
number ~ number ~ number ~ number)
}
// LookAt eye_x eye_y eye_z look_x look_y look_z up_x up_y up_z
look_at = { "LookAt" ~
// followed by 9 numbers:
// eye_x eye_y eye_z
number ~ number ~ number ~
// look_x look_y look_z
number ~ number ~ number ~
// up_x up_y up_z
number ~ number ~ number
}
// MediumInterface "" "vol"
medium_interface = { "MediumInterface" ~ (empty_string | string) ~ (empty_string | string) }
// Accelerator "kdtree" "float emptybonus" 0.1
accelerator = { "Accelerator" ~ string ~ parameter* }
// Camera "perspective" "float fov" 90 ...
camera = { "Camera" ~ string ~ parameter* }
// PixelFilter "mitchell" "float xwidth" 2 "float ywidth" 2
pixel_filter = { "PixelFilter" ~ string ~ parameter* }
// Sampler "halton"
sampler = { "Sampler" ~ string ~ parameter* }
// Film "image" "string filename" "..." ...
film = { "Film" ~ string ~ parameter* }
// Integrator "path" "integer maxdepth" 5
integrator = { "Integrator" ~ string ~ parameter* }
// CoordSysTransform "camera"
coord_sys_transform = { "CoordSysTransform" ~ string }
// AreaLightSource "diffuse" "rgb L" .5 .5 .5
area_light_source = { "AreaLightSource" ~ string ~ parameter* }
// LightSource "point" "rgb I" .5 .5 .5
light_source = { "LightSource" ~ string ~ parameter* }
// Texture "mydiffuse" "spectrum" "imagemap" "string filename" "image.tga"
texture = { "Texture" ~ string ~ string ~ string ~ parameter* }
// Material "matte" "texture Kd" "mydiffuse"
material = { "Material" ~ (empty_string | string) ~ parameter* }
// MakeNamedMaterial "myplastic" "string type" "plastic" "float roughness" 0.1
make_named_material = { "MakeNamedMaterial" ~ string ~ parameter* }
// MakeNamedMedium "mymedium" "string type" "homogeneous" "rgb sigma_s" [100 100 100]
make_named_medium = { "MakeNamedMedium" ~ string ~ parameter* }
// NamedMaterial "myplastic"
named_material = { "NamedMaterial" ~ string ~ parameter* }
// Shape "sphere" "float radius" 0.25
shape = { "Shape" ~ string ~ parameter* }
// keywords
keyword = {
(attribute_begin |
attribute_end |
"CoordinateSystem" |
"Identity" |
"Include" |
object_begin |
object_end |
object_instance |
reverse_orientation |
transform_begin |
transform_end |
world_begin
)
}
all = { "All" }
attribute_begin = { "AttributeBegin" }
attribute_end = { "AttributeEnd" }
object_begin = { "ObjectBegin" ~ string }
object_end = { "ObjectEnd" }
object_instance = { "ObjectInstance" ~ string }
transform_begin = { "TransformBegin" }
transform_end = { "TransformEnd" }
end_time = { "EndTime" }
start_time = { "StartTime" }
reverse_orientation = { "ReverseOrientation" }
world_begin = { "WorldBegin" }
// IDENT a-zA-Z_a-zA-Z_0-9*
ident = { ('a'..'z' | 'A'..'Z' | "_" | '0'..'9') ~
('a'..'z' | 'A'..'Z' | " " | "_" | "-" | ":" | '0'..'9')* }
string = { ("\"" ~ ident ~ "\"") | ("\"" ~ filename ~ "\"") }
empty_string = { "\"" ~ "\"" }
filename = { ("/")? ~ // optional (can be a full path)
('a'..'z' | 'A'..'Z' | "_") ~
('a'..'z' | 'A'..'Z' | "_" | "-" | "." | "/" | '0'..'9')* }
// "" { return LBRACK; }
lbrack = { "[" }
// "" { return RBRACK; }
rbrack = { "]" }
// NUMBER -+?(0-9+|((0-9+\.0-9*)|(\.0-9+)))(eE-+?0-9+)?
number = @{
("-" | "+")? ~ // optional sign, followed by
(
(
("." ~ '0'..'9'+) // dot and digits
| // or
('0'..'9'+ ~ "." ~ '0'..'9'*) // digits, dot, and (optional digits)
)
| // or
'0'..'9'+ // just digits
) ~ ( // followed by (optional)
("e" | "E") ~ // 'e' or 'E', followed by
("-" | "+")? ~ // optional sign, followed by
'0'..'9'+ // digits
)?
}
integer = @{
("-" | "+")? ~ // optional sign, followed by
(
'1'..'9' ~ // at least one non-zero digit, followed by
'0'..'9'* // just digits
)
| // or
'0'..'9' // single digit
}
last_statement = @{ whitespace? ~ "WorldEnd" ~ (whitespace | comment)* }
whitespace = _{ (" " | "\t" | "\r" | "\n") }
comment = _{ ( "#" ~ (!("\r" | "\n") ~ any)* ~ ("\n" | "\r\n" | "\r" | eoi) ) }