feat: Handle additional syntax (#12)
* Converts all Lighting nodes into the output * Translates Title Info and SceneInfo Info into a WorldInfo node * Translates Viewer Info into a NavigationInfo node * Captures the creaseAngle parameter * Also, this commit documents the API (such as it is) Resolves #9. Resolves #10. Reviewed-on: #12 Co-authored-by: Glen Whitney <glen@studioinfinity.org> Co-committed-by: Glen Whitney <glen@studioinfinity.org>
This commit is contained in:
parent
48925d05d9
commit
6752ab1348
3 changed files with 85 additions and 13 deletions
|
@ -74,6 +74,18 @@ function findNumbersAtTopLevel(
|
|||
function addChild(child: string | Tree, tree: Tree): void
|
||||
(tree.children ??= []).push child
|
||||
|
||||
type WorldInfoNode = {WorldInfo: (string|Tree)[]} | undefined
|
||||
function addWorldParameter(name: string, value: string, tree: Tree): void
|
||||
children := tree.children ??= []
|
||||
world .= (children.find (x) =>
|
||||
if x <? 'object'
|
||||
'WorldInfo' in x
|
||||
else false) as WorldInfoNode
|
||||
unless world
|
||||
world = WorldInfo: []
|
||||
children.push world
|
||||
world.WorldInfo.push(` ${name}`, ` ${value}`)
|
||||
|
||||
function parse(stream: Lexer, tree: Tree = {}): Tree
|
||||
held .= filtered stream // for lookahead
|
||||
|
||||
|
@ -93,7 +105,9 @@ function parse(stream: Lexer, tree: Tree = {}): Tree
|
|||
${renderList newKids} ] }\n`, tree
|
||||
'ShapeHints'
|
||||
subTree := parse stream
|
||||
if 'vertexOrdering' in subTree then tree.ccw = ['1.0']
|
||||
if 'vertexOrdering' in subTree then tree.ccw = ['true']
|
||||
if 'creaseAngle' in subTree
|
||||
tree.creaseAngle = subTree.creaseAngle
|
||||
'Coordinate3'
|
||||
tree.Coordinate = toksUntilClose stream
|
||||
'Normal'
|
||||
|
@ -124,7 +138,7 @@ function parse(stream: Lexer, tree: Tree = {}): Tree
|
|||
dims := radius: ''
|
||||
findNumbersAtTopLevel stream, dims
|
||||
addShape 'Sphere', [`radius ${dims.radius}`], tree
|
||||
/IndexedLineSet|PointSet/ // ignored
|
||||
/IndexedLineSet|PointSet/ // ignored, but why? They are in VRML97
|
||||
findNumbersAtTopLevel stream, {}
|
||||
'IndexedFaceSet'
|
||||
contents := translatedToksUntilClose stream
|
||||
|
@ -138,27 +152,62 @@ function parse(stream: Lexer, tree: Tree = {}): Tree
|
|||
if 'TextureCoordinate' in tree
|
||||
params.push "texCoord TextureCoordinate {\n",
|
||||
...tree.TextureCoordinate, " }\n"
|
||||
if 'creaseAngle' in tree
|
||||
params.push `creaseAngle ${tree.creaseAngle[0]}`
|
||||
if 'ccw' in tree
|
||||
params.push `ccw true`
|
||||
params.push ...contents
|
||||
addShape 'IndexedFaceSet', params, tree
|
||||
/Light$/
|
||||
contents := toksUntilClose stream
|
||||
addChild {[held.value]: contents}, tree
|
||||
else
|
||||
parse stream // discard the subgroup
|
||||
held = filtered stream
|
||||
{ht: 'word', hv: 'vertexOrdering', nt: 'word', nv: 'COUNTERCLOCKWISE'}
|
||||
tree.vertexOrdering = ['ccw']
|
||||
held = filtered stream
|
||||
{ht: 'word', hv: 'BackgroundColor', nt: 'word', nv: 'Info'}
|
||||
{ht: 'word', hv: 'creaseAngle', nt: 'number'}
|
||||
tree.creaseAngle = [ next.value ]
|
||||
held = filtered stream
|
||||
{ht: 'word', nt: 'word', nv: 'Info'}
|
||||
opener := filtered stream
|
||||
if opener and opener.type === 'obrace'
|
||||
contents := toksUntilClose stream
|
||||
// Find the first string token and assume it is the color
|
||||
stok := contents.find .type[0] === 'string'
|
||||
colorString := stok?.value[0]
|
||||
if colorString and typeof colorString === 'string'
|
||||
color := colorString.replace /^"|"$/g, ''
|
||||
addChild `Background {
|
||||
groundColor [ ${color} ]
|
||||
skyColor [ ${color} ]
|
||||
}\n`, tree
|
||||
switch held.value
|
||||
'BackgroundColor'
|
||||
// Find the first string token and assume it is the color
|
||||
stok := contents.find .type[0] === 'string'
|
||||
colorString := stok?.value[0]
|
||||
if colorString and typeof colorString === 'string'
|
||||
color := colorString.replace /^"|"$/g, ''
|
||||
addChild `Background {
|
||||
groundColor [ ${color} ]
|
||||
skyColor [ ${color} ]
|
||||
}\n`, tree
|
||||
'Title'
|
||||
// Find the first string token and assume it is the title
|
||||
stok := contents.find .type[0] === 'string'
|
||||
titleString := stok?.value[0]
|
||||
if titleString and typeof titleString === 'string'
|
||||
addWorldParameter 'title', titleString, tree
|
||||
'SceneInfo'
|
||||
// Filter all the strings and add them as info
|
||||
info := contents
|
||||
|> .filter .type[0] === 'string'
|
||||
|> .map .value[0]
|
||||
|> .join ' '
|
||||
addWorldParameter 'info', `[ ${info} ]`, tree
|
||||
'Viewer'
|
||||
// Filter all of the strings, and translate them into
|
||||
// current viewer names
|
||||
tr: Record<string, string> := {'"examiner"': '"EXAMINE"'}
|
||||
viewers := contents
|
||||
|> .filter .type[0] === 'string'
|
||||
|> .map .value[0] as string
|
||||
|> .map((x) => x in tr ? tr[x] : x.toUpperCase())
|
||||
|> .join ' '
|
||||
addChild `NavigationInfo { type [ ${viewers} ] }\n`, tree
|
||||
held = filtered stream
|
||||
else held = opener
|
||||
else
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue