feat: support Viewpoints, translating PerspectiveCamera #21
@ -13,7 +13,9 @@ VRML 1.0. Overall, it recognizes and converts
|
||||
* Title, SceneInfo, BackgroundColor, and View "Info" nodes [this node type
|
||||
was removed in VRML97].
|
||||
* All Light nodes
|
||||
* PerspectiveCamera nodes (converted into Viewpoint nodes)
|
||||
* Grouping nodes including Separator, Group, Switch, and WWWAnchor
|
||||
* Interprets a Switch named "Cameras" (by a DEF) as a list of Viewpoints
|
||||
* ShapeHints
|
||||
* Transformation nodes including Translation, Rotation, Scale, and Transform
|
||||
* All shape nodes including Cube, Cone, Cylinder, Sphere, IndexedFaceSet,
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
name: 'vrml1to97',
|
||||
version: '0.3.2',
|
||||
version: '0.4.0',
|
||||
description: 'JavaScript converter from VRML 1 to VRML97',
|
||||
scripts: {
|
||||
test: 'echo "Error: no test specified" && exit 1',
|
||||
|
@ -156,6 +156,19 @@ function parse(stream: Lexer, tree: DefTree = {}): DefTree
|
||||
continue
|
||||
currentDefinition = next.value
|
||||
held = filtered stream
|
||||
// Special case from VRML 1: DEF Cameras Switch { ... }
|
||||
// needs to be hoisted to a list of viewpoints at this level
|
||||
if currentDefinition is 'Cameras' and held?.value is 'Switch'
|
||||
held = filtered stream
|
||||
unless held?.type is 'obrace'
|
||||
console.error
|
||||
`DEF Cameras Switch followed by ${held?.value}, ignoring`
|
||||
continue
|
||||
{children, ...context} := tree
|
||||
subTree := parse stream, context
|
||||
addChild renderList(subTree.children), tree
|
||||
held = filtered stream
|
||||
continue
|
||||
if held?.type is 'word'
|
||||
clause := `DEF ${currentDefinition}`
|
||||
role .= held.value
|
||||
@ -164,16 +177,18 @@ function parse(stream: Lexer, tree: DefTree = {}): DefTree
|
||||
role = 'Child'
|
||||
matches TransformNode
|
||||
role = 'Transform'
|
||||
'ShapeHints'
|
||||
role = 'Dummy' // will fill in when we parse the ShapeHints
|
||||
'Coordinate3'
|
||||
role = 'Coordinate'
|
||||
'TextureCoordinate2'
|
||||
role = 'TextureCoordinate'
|
||||
'Texture2'
|
||||
role = 'Texture'
|
||||
/Cube|Cone|Cylinder|Sphere/
|
||||
role = 'Shape'
|
||||
'PerspectiveCamera'
|
||||
role = 'Viewpoint'
|
||||
'ShapeHints'
|
||||
role = 'Dummy' // will fill in when we parse the ShapeHints
|
||||
'Texture2'
|
||||
role = 'Texture'
|
||||
'TextureCoordinate2'
|
||||
role = 'TextureCoordinate'
|
||||
matches SetNode
|
||||
role = 'Shape'
|
||||
matches LightNode
|
||||
@ -222,7 +237,13 @@ function parse(stream: Lexer, tree: DefTree = {}): DefTree
|
||||
{children, ...context} := tree
|
||||
subTree := parse stream, context
|
||||
if newKids := subTree.children
|
||||
newChild :=
|
||||
newChild .= ''
|
||||
if held.value is 'Switch'
|
||||
newChild = "Switch {\n "
|
||||
if 'whichChoice' in subTree
|
||||
newChild += `whichChoice ${subTree.whichChoice[0]}\n `
|
||||
newChild += `choice [\n ${renderList newKids} ] }\n`
|
||||
else newChild =
|
||||
`Group { children [\n ${renderList newKids} ] }\n`
|
||||
addChild newChild, tree
|
||||
matches TransformNode
|
||||
@ -248,6 +269,14 @@ function parse(stream: Lexer, tree: DefTree = {}): DefTree
|
||||
mergeTree hints, tree
|
||||
if lastDefinition and tree._definitions
|
||||
tree._definitions[lastDefinition] = [hints]
|
||||
'PerspectiveCamera'
|
||||
contents := toksUntilClose stream
|
||||
hasDescription := contents.find (e) =>
|
||||
e.type?[0] is 'word' and e.value?[0] is 'description'
|
||||
if lastDefinition and hasDescription is undefined
|
||||
contents.push type: ['word'], value: ['description']
|
||||
contents.push type: ['word'], value: [`"${lastDefinition}"`]
|
||||
addChild {Viewpoint: contents}, tree
|
||||
'Coordinate3'
|
||||
tree.Coordinate = toksUntilClose stream
|
||||
'Normal'
|
||||
@ -314,6 +343,9 @@ function parse(stream: Lexer, tree: DefTree = {}): DefTree
|
||||
{ht: 'word', hv: 'creaseAngle', nt: 'number'}
|
||||
tree.creaseAngle = [ next.value ]
|
||||
held = filtered stream
|
||||
{ht: 'word', hv: 'whichChild'}
|
||||
tree.whichChoice = [ next.value ]
|
||||
held = filtered stream
|
||||
else
|
||||
console.error 'Ignoring unparseable token', held
|
||||
held = next // ignore unknown words
|
||||
|
Loading…
Reference in New Issue
Block a user