fix: Transformation nodes must create new scope #20

Merged
glen merged 2 commits from apply_transform into main 2024-02-14 08:10:01 +00:00
2 changed files with 32 additions and 16 deletions
Showing only changes of commit b6c5c6d0a5 - Show all commits

View File

@ -1,6 +1,6 @@
{ {
name: 'vrml1to97', name: 'vrml1to97',
version: '0.3.1', version: '0.3.2',
description: 'JavaScript converter from VRML 1 to VRML97', description: 'JavaScript converter from VRML 1 to VRML97',
scripts: { scripts: {
test: 'echo "Error: no test specified" && exit 1', test: 'echo "Error: no test specified" && exit 1',

View File

@ -91,6 +91,7 @@ function addWorldParameter(name: string, value: string, tree: Tree): void
matches := (str: string, pat: RegExp) => pat.test(str) matches := (str: string, pat: RegExp) => pat.test(str)
operator matches operator matches
GroupNode := /(?:Transform)?Separator|Group|Switch|WWWAnchor/ GroupNode := /(?:Transform)?Separator|Group|Switch|WWWAnchor/
TransformNode := /^(?:Rotation|Scale|Transform|Translation)$/
SetNode := /IndexedFaceSet|IndexedLineSet|PointSet/ SetNode := /IndexedFaceSet|IndexedLineSet|PointSet/
LightNode := /Light$/ LightNode := /Light$/
@ -161,6 +162,8 @@ function parse(stream: Lexer, tree: DefTree = {}): DefTree
switch role switch role
matches GroupNode matches GroupNode
role = 'Child' role = 'Child'
matches TransformNode
role = 'Transform'
'ShapeHints' 'ShapeHints'
role = 'Dummy' // will fill in when we parse the ShapeHints role = 'Dummy' // will fill in when we parse the ShapeHints
'Coordinate3' 'Coordinate3'
@ -193,6 +196,19 @@ function parse(stream: Lexer, tree: DefTree = {}): DefTree
addChild clause, tree addChild clause, tree
'Shape' 'Shape'
addShape clause, [], tree addShape clause, [], tree
'Transform'
// VRML97 doesn't allow just the transform part of
// a Transform to be USEd (the whole node must be), so
// we have to recreate the transform. FIXME: dedupe code
content := known[next.value][1..]
{children, ...context} := tree
restOfTree := parse stream, context
if remainingKids := restOfTree.children
newChild := `Transform {\n ${renderList content}\n `
+ `children [\n ${renderList remainingKids}`
+ "] }\n"
addChild newChild, tree
return tree
{} {}
mergeTree role, tree mergeTree role, tree
else else
@ -203,20 +219,24 @@ function parse(stream: Lexer, tree: DefTree = {}): DefTree
{ht: 'word', nt: 'obrace'} {ht: 'word', nt: 'obrace'}
switch held.value switch held.value
matches GroupNode matches GroupNode
parent := {children, ...context} := tree
held.value.endsWith('Separator') ? 'Transform' : 'Group'
{children, Translation, Rotation, ...context} := tree
subTree := parse stream, context subTree := parse stream, context
if newKids := subTree.children if newKids := subTree.children
newChild .= `${parent} {\n ` newChild :=
if 'Rotation' in subTree `Group { children [\n ${renderList newKids} ] }\n`
newChild += renderList subTree.Rotation
newChild += "\n "
if 'Translation' in subTree
newChild += renderList subTree.Translation
newChild += "\n "
newChild += `children [\n ${renderList newKids} ] }\n`
addChild newChild, tree addChild newChild, tree
matches TransformNode
content := toksUntilClose stream
if (lastDefinition
and tree._definitions?[lastDefinition][0] is 'Transform')
tree._definitions[lastDefinition].push ...content
{children, ...context} := tree
restOfTree := parse stream, context
if remainingKids := restOfTree.children
newChild := `Transform {\n ${renderList content}\n `
+ `children [\n ${renderList remainingKids} ] }\n`
addChild newChild, tree
return tree // used the rest of the tree, so done
'ShapeHints' 'ShapeHints'
subTree := parse stream subTree := parse stream
hints: Tree := {} hints: Tree := {}
@ -228,10 +248,6 @@ function parse(stream: Lexer, tree: DefTree = {}): DefTree
mergeTree hints, tree mergeTree hints, tree
if lastDefinition and tree._definitions if lastDefinition and tree._definitions
tree._definitions[lastDefinition] = [hints] tree._definitions[lastDefinition] = [hints]
'Rotation'
tree.Rotation = toksUntilClose stream
'Translation'
tree.Translation = toksUntilClose stream
'Coordinate3' 'Coordinate3'
tree.Coordinate = toksUntilClose stream tree.Coordinate = toksUntilClose stream
'Normal' 'Normal'