fix: Transformation nodes must create new scope
In VRML 1, transformations like translations and rotations accumulate within a scope as they are encountered, and one can even have multiple translations with shapes interleaved between them. This accumulation is not possible in VRML97. Therefore, it's necessary to insert new scopes in the translated file every time a new transformation is encountered. This commit makes sure that happens.
This commit is contained in:
parent
a6a6e60894
commit
b6c5c6d0a5
@ -1,6 +1,6 @@
|
||||
{
|
||||
name: 'vrml1to97',
|
||||
version: '0.3.1',
|
||||
version: '0.3.2',
|
||||
description: 'JavaScript converter from VRML 1 to VRML97',
|
||||
scripts: {
|
||||
test: 'echo "Error: no test specified" && exit 1',
|
||||
|
@ -91,6 +91,7 @@ function addWorldParameter(name: string, value: string, tree: Tree): void
|
||||
matches := (str: string, pat: RegExp) => pat.test(str)
|
||||
operator matches
|
||||
GroupNode := /(?:Transform)?Separator|Group|Switch|WWWAnchor/
|
||||
TransformNode := /^(?:Rotation|Scale|Transform|Translation)$/
|
||||
SetNode := /IndexedFaceSet|IndexedLineSet|PointSet/
|
||||
LightNode := /Light$/
|
||||
|
||||
@ -161,6 +162,8 @@ function parse(stream: Lexer, tree: DefTree = {}): DefTree
|
||||
switch role
|
||||
matches GroupNode
|
||||
role = 'Child'
|
||||
matches TransformNode
|
||||
role = 'Transform'
|
||||
'ShapeHints'
|
||||
role = 'Dummy' // will fill in when we parse the ShapeHints
|
||||
'Coordinate3'
|
||||
@ -193,6 +196,19 @@ function parse(stream: Lexer, tree: DefTree = {}): DefTree
|
||||
addChild clause, tree
|
||||
'Shape'
|
||||
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
|
||||
else
|
||||
@ -203,20 +219,24 @@ function parse(stream: Lexer, tree: DefTree = {}): DefTree
|
||||
{ht: 'word', nt: 'obrace'}
|
||||
switch held.value
|
||||
matches GroupNode
|
||||
parent :=
|
||||
held.value.endsWith('Separator') ? 'Transform' : 'Group'
|
||||
{children, Translation, Rotation, ...context} := tree
|
||||
{children, ...context} := tree
|
||||
subTree := parse stream, context
|
||||
if newKids := subTree.children
|
||||
newChild .= `${parent} {\n `
|
||||
if 'Rotation' in subTree
|
||||
newChild += renderList subTree.Rotation
|
||||
newChild += "\n "
|
||||
if 'Translation' in subTree
|
||||
newChild += renderList subTree.Translation
|
||||
newChild += "\n "
|
||||
newChild += `children [\n ${renderList newKids} ] }\n`
|
||||
newChild :=
|
||||
`Group { children [\n ${renderList newKids} ] }\n`
|
||||
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'
|
||||
subTree := parse stream
|
||||
hints: Tree := {}
|
||||
@ -228,10 +248,6 @@ function parse(stream: Lexer, tree: DefTree = {}): DefTree
|
||||
mergeTree hints, tree
|
||||
if lastDefinition and tree._definitions
|
||||
tree._definitions[lastDefinition] = [hints]
|
||||
'Rotation'
|
||||
tree.Rotation = toksUntilClose stream
|
||||
'Translation'
|
||||
tree.Translation = toksUntilClose stream
|
||||
'Coordinate3'
|
||||
tree.Coordinate = toksUntilClose stream
|
||||
'Normal'
|
||||
|
Loading…
Reference in New Issue
Block a user