VRML -> X3D
Introducing
X3D
X3D XML Syntax Overview (2)
The Actual Transcoding
Now, a quick study of the existing VRML97 definitions and syntax, before developing the XML encoding.
Basic Syntax
VRML97 Spec Node Description:
Shape {
exposedField SFNode appearance NULL
exposedField SFNode geometry NULL
}
X3D Spec Node Description:
Shape : X3DShapeNode {
SFNode [in,out] appearance NULL [X3DAppearanceNode]
SFNode [in,out] geometry NULL [X3DGeometryNode]
SFVec3f [] bboxCenter 0 0 0 (-∞,∞)
SFVec3f [] bboxSize -1 -1 -1 (0,∞)|[-1 -1 -1]
}
For Example:
Appearance : X3DAppearanceNode {
SFNode [in,out] material NULL [X3DMaterialNode]
SFNode [in,out] texture NULL [X3DTextureNode]
SFNode [in,out] textureTransform NULL [X3DTextureTransformNode]
}
Material : X3DMaterialNode {
SFFloat [in,out] ambientIntensity 0.2 [0,1]
SFColor [in,out] diffuseColor 0.8 0.8 0.8 [0,1]
SFColor [in,out] emissiveColor 0 0 0 [0,1]
SFFloat [in,out] shininess 0.2 [0,1]
SFColor [in,out] specularColor 0 0 0 [0,1]
SFFloat [in,out] transparency 0 [0,1]
}
[0,1] applies to each numeric component of the value.
Example: SFColor is a float triplet, RGB, each float 0 to 1.
This use of fields and nodes could be described
in a venacular as:
"Everything is a strongly typed field and a
field can be a node with fields."
The Shape node has two fields, appearance and geometry, which are used to create rendered objects in the world. The appearance field contains an Appearance node that specifies the visual attributes (e.g., material and texture) to be applied to the geometry. The geometry field contains a geometry node. The specified geometry node is rendered with the specified appearance nodes appled.
Basic Syntax
appearance texture nodes
Texturing :
ImageTexture MovieTexture
PixelTexture MultiTexture
ImageTexture : X3DTextureNode {
MFUrl [in,out] url [] [urn]
SFBool [] repeatS TRUE [TRUE|FALSE]
SFBool [] repeatT TRUE [TRUE|FALSE]
}
TextureTransform : X3DTextureTransformNode {
SFVec2f [in,out] center 0 0 (-∞,∞)
SFFloat [in,out] rotation 0 (-∞,∞)
SFVec2f [in,out] scale 1 1 (-∞,∞)
SFVec2f [in,out] translation 0 0 (-∞,∞)
}
Texture can contain ImageTexture, MovieTexture, PixelTexture nodes.
Default texture mapping.
Basic Syntax
geometry
field [in,out] SFNode geometry NULL Box Cone Cylinder ElevationGrid Extrusion IndexedFaceSet IndexedLineSet PointSet Sphere Text Geometry nodes created from PROTOs or EXTERNPROTOs Humanoid Parameteric Volumetric Hypermetric Wavelet-based Surface Primitives HyperMultiMetric Plus new stuff ...
There is not now or was ever a node named geometry. It is a container field for one of the geometry nodes: Box, Cone, Cylinder, ElevationGrid, Extrusion, IndexedFaceSet, IndexedLineSet and all.
Basic IndexedFaceSet
IndexedFaceSet : X3DGeometryNode {
MFInt32 [in] set_colorIndex
MFInt32 [in] set_coordIndex
MFInt32 [in] set_normalIndex
MFInt32 [in] set_texCoordIndex
SFNode [in,out] color NULL
SFNode [in,out] coord NULL
SFNode [in,out] normal NULL
SFNode [in,out] texCoord NULL
SFBool [] ccw TRUE
MFInt32 [] colorIndex [coordIndex]
SFBool [] colorPerVertex TRUE
SFBool [] convex TRUE
MFInt32 [] coordIndex [x y z]
SFFloat [] creaseAngle 0
MFInt32 [] normalIndex [coordIndex]
SFBool [] normalPerVertex TRUE
SFBool [] solid TRUE
MFInt32 [] texCoordIndex [coordIndex]
}
Coordinate : X3DCoordinateNode {
MFVec3f [in,out] point [] (-∞,∞);
}
Example:
geometry IndexedFaceSet {
coord Coordinate {
point [ 3 0 -3, -3 0 -3, -3 0 3, 3 0 3, 0 6 0 ]
}
coordIndex [ 0 4 3 -1 # face A, right
1 4 0 -1 # face B, back
2 4 1 -1 # face C, left
3 4 2 -1 # face D, front
0 3 2 1 ] # face E, bottom
}
Each face of the IndexedFaceSet shall have:
- at least three non-coincident vertices,
- vertices that define a planar polygon,
- vertices that define a non-self-intersecting polygon.
Otherwise, results are undefined.
Color : X3DColorNode {
MFColor [in,out] color [] [0,1]
}
Normal : X3DNormalNode {
MFVec3f [in,out] vector [] (-∞,∞)
}
TextureCoordinate : X3DTextureCoordinateNode {
MFVec2f [in,out] point [] (-∞,∞)
}
Here is the IndexedfaceSet IDL.
It shows that the Color, Coordinate, Normal, TextureCoordinate
are nodes.
If color, normal, texCoord points, or colorIndex, texCoordIndex, or normalIndex
are NULL, then coord point or coordIndex is used.
In this notation the coordIndex Integers are lists of vertex numbers comprising the polygon, with -1 being the signal that the polygon is complete. The coord Coordinate point Vector3Floats are actually defined groups of three floats which are interpreted as the x, y, and z coordinate of the vertex, automatically numbered 0 thru howevermany by order in the field. In this example the shape has 4 vertices with vertex 0 at 3,0,-3 and connected to vertex 4 and 3 and 1.
Basic Syntax
A VRML97 Result
Shape {
appearance Appearance {
material Material {
ambientIntensity 0.2
diffuseColor 0.8 0.8 0.8
emissiveColor 0 0 0
shininess 0.2
specularColor 0 0 0
transparency 0
}
texture ImageTexture {
url ["somePic.jpeg"]
repeatS TRUE
repeatT TRUE
}
textureTransform TextureTransform {
center 0 0
rotation 0
scale 1 1
translation 0 0
}
}
geometry IndexedFaceSet {
ccw TRUE
convex TRUE
solid TRUE
creaseAngle 0
coord Coordinate {point[ x y z, ... ] }
coordIndex [ v1 v2 v3 ... -1, ... ]
color Color {color [r g b, ... ] }
colorIndex [ v1 v2 v3 ... -1, ...]
colorPerVertex TRUE
texCoord TextureCoordinate {point [ x y z, ... ]}
texCoordIndex [ v1 v2 v3 ... -1, ...]
normalPerVertex TRUE
normal Normal {vector[x y z, ... ] }
normalIndex [ v1 v2 v3 ... -1, ... ]
}
}
The coord Coordinate point gives the x,y,z for each vertex.
The coordIndex identifies the vertices in the polygon by
order in coord Coordinate point,
then closing the polygon with -1.
So, can XML handle this?
How about adopting the simplist possible rule and see how it works?
"If a field is a node, then it becomes an element.
If the node has fields, each field becomes an attribute,
unless the field is a node, in which case
it becomes an element which may have fields,
which become attributes."
Basic XML Syntax
Elements contain Content and Attributes
The Basic Content Tagset:
<tagname attr1='string' >
... content ...
</tagname >
attribute is name and value pair: name='value'
The Empty Element:
<tagname attr2="string' />
Elements can be Content:
<tag1>
<tag2 />
<tag3>
<tag4 />
</tag3>
</tag1>
XML Namespaces:
tagname = namespace:tagname
attrname = namespace:attrname
value space - lexical space - facets
The tagset for a basic element consists of a start tag and an end tag.
Everything between the start and end tags is called content.
Content can be another set of tags.
If the element does not contain content, only attributes,
the
begin and end tags can be combined as shown in this example of an empty
element.
Elements can be content: Here the element called tag1 contains
the empty element called tag2, along with the element called tag3,
which in turn contains the element called tag4.
The tagname and attrname (atribute name) actually consist of two
parts, an XML namespace, and the tagname. The XML namespace is defined by the
XML schema and is a slightly different concept than the typical use
of the term in programmng because it allows definiton of the structure of the
subject element. And an amazing thing about it is that some item way down
in the middle of a structure can obtain its identity from a completely
different environment than any other items in the structure.
X3D XML Shape
X3D Spec IDL:
Shape : X3DShapeNode {
SFNode [in,out] appearance NULL [X3DAppearanceNode]
SFNode [in,out] geometry NULL [X3DGeometryNode]
SFVec3f [] bboxCenter 0 0 0 (-∞,∞)
SFVec3f [] bboxSize -1 -1 -1 (0,∞)|[-1 -1 -1]
}
X3D XML Encoding:
<Shape >
...
</Shape >
<Shape >
appearance
geometry
</Shape >
So that is what it begins to look like. We have a Shape element
and place to add appearance and geometry.
Now let's look at the X3D XML Schema for more detail.
X3D XML Shape Schema
<xsd:element name="Shape"> <xsd:element ref="Appearance"/> <xsd:element ref="IndexedFaceSet" /> </xsd:element>
Yes, that is a bit too simple, we really need:
<xsd:element name="Shape">
<xsd:attribute name="DEF" type="IDREF"/>
<xsd:element ref="Appearance"/>
<xsd:group ref="GeometryContentModel"/>
</xsd:element>
<xsd:group name="GeometryContentModel">
<xsd:choice>
<xsd:element ref="IndexedFaceSet"/>
<xsd:element ref="IndexedLineSet"/>
<xsd:element ref="PointSet"/>
...
<xsd:element ref="Nurbs"/>
</xsd:choice>
</xsd:group>
XML Schema Definition of Group:
<group name = NodeName>
Content: ((all | choice | sequence))
</group>
Shape, GeometryContentModel, Appearance
X3D XML IndexedFaceSet Schema
And the Schema looks like:
<xsd:element name="IndexedFaceSet">
<xsd:attribute name="DEF" type="IDREF"/>
<xsd:attribute name="ccw" type="SFBool" default="true" />
<xsd:attribute name="convex" type="SFBool"default="true" />
<xsd:attribute name="solid" type="SFBool" default="true" />
<xsd:attribute name="creaseAngle" type="SFFloat" default="0" />
<xsd:element name="Coordinate">
<xsd:attribute name="point" type="MFVector3f"/>
</xsd:element>
<xsd:attribute name="coordIndex" type="SFInt"/>
<xsd:element name="ColorNode">
<xsd:attribute name="color" type="MFColor"/>
</xsd:element>
<xsd:attribute name="colorIndex" type="MFInt"/>
<xsd:attribute name="colorPerVertex" type="SFBool" default="true" />
<xsd:element name="Normal">
<xsd:attribute name="vector" type="MFVect3f"/>
</xsd:element>
<xsd:attribute name="normalIndex" type="MFInt"/>
<xsd:attribute name="normalPerVertex" type="SFBool" default="true" />
<xsd:element name="TextureCoordinate">
<xsd:attribute name="point" type="MFVect2f"/>
</xsd:element>
<xsd:attribute name="texCoordIndex" type="MFInt"/>
</xsd:element>
Gives us:
<IndexedFaceSet
ccw='SFBool'
convex='SFBool'
solid='SFBool'
creaseAngle='SFFloat'
coordIndex='MFInt'
colorIndex='MFInt'
colorPerVertex='SFBool'
normalIndex='MFInt'
normalPerVertex='SFBool'
texCoordIndex='MFInt' >
<Coordinate point='MFVector3f' />
<ColorNode color='MFColor' />
<Normal vector='MFVect3f' />
<TextureCoordinate point='MFVect2f' />
</IndexedFaceSet>
element name="IndexedFaceSet"
* coordIndex used if colorIndex or normalIndex is NULL.
* default texCoordIndex provided if NULL.
web3d x3d syntax
Welcome to a discussion of the XMLization and DOMification of VRML.