Extensible 3D (X3D) encodings
Part 1: Extensible Markup Language (XML) encoding
4 Concepts
This clause describes key concepts in this part of ISO/IEC 19776. This includes how the X3D constructs defined in [I19775-1] are encoded using the Extensible Markup Language (XML) (see [XML]).
Table 4.1 lists the topics for this clause.
Table 4.1 — Topics in this clause
The following conventions are used throughout this part of ISO/IEC 19776:
Italics are used for event and field names, and are also used when new terms are introduced and equation variables are referenced.
A fixed-space
font is used for URL addresses and source code
examples. ISO/IEC 19776 Classic VRML encoding examples appear in bold,
fixed-space
font.
Node type names are appropriately capitalized (e.g., “The Billboard node is a grouping node...”). However, the concept of the node is often referred to in lower case in order to refer to the semantics of the node, not the node itself (e.g., “To rotate the billboard...”).
The form "0xhh" expresses a byte as a hexadecimal number representing the bit configuration for that byte.
With the exception of International Standards, throughout this part of ISO/IEC 19776, references to external documents are denoted using the “x.[ABCD]” notation, where "x" denotes in which clause or annex the reference is described and “[ABCD]” is an abbreviation of the reference title. References without the "x." are references to the bibliography. International Standards are referenced by their number and link to the appropriate entry in 2 Normative references.
EXAMPLE 1. 2. [ABCD] refers to a reference described in Clause 2 and [ABCD] refers to a reference described in the Bibliography. TODO: fix, distinguish [ABCD] references
The Extensible Markup Language (XML) (see [XML]) is used for a self-validating X3D encoding of Extensible 3D (X3D) Graphics. This X3D encoding provides a Web-compatible format that maximizes interoperability with other Web languages. XML supports structuring data, is similar to HTML, is readable by systems and humans, is verbose for clarity, represents a modular family of technologies, and is fundamentally interoperable with Web technologies. See [XML10] for more background information.
There is a fundamental and complete correspondence between the elements of the abstract X3D scene graph and constructs in the XML encoding. The X3D XML Encoding has full expressive power for all scene constructs defined in the X3D Architecture [I19775-1]. This section describes the design patterns that govern the correspondence.
An X3D file is structured as defined in the X3D Architecture [I19775-1].
The header is a single line of UTF-8 text identifying the file as an XML file, followed by the XML declaration that identifies the validating XML DTD, followed by X3D tags that identify the validating XML Schema, X3D profile, and (optionally) the necessary additional components of the file.
For easy identification of X3D files, every X3D file shall begin with an XML file declaration (see [XML]).
<?xml version="1.0" encoding="UTF-8"?>
The identifier "UTF-8" indicates a clear text character encoding that allows for international characters to be displayed in X3D using the UTF-8 encoding defined in [ISO/IEC 10646-1].
The XML header is immediately followed by an XML DOCTYPE statement which provides both PUBLIC and SYSTEM literals for the X3D XML Document Type Definition (DTD) (see [XML]).
The X3D DOCTYPE declaration is as follows:
EXAMPLE 1 XML Document Type Definition (DTD or DOCTYPE) validation syntax for an X3D model.
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 4.0//EN" "https://www.web3d.org/specifications/x3d-4.0.dtd">
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.3//EN" "http://www.web3d.org/specifications/x3d-3.3.dtd">
In addition As an alternative to DTD validation, XML Schema validation can be performed through identification of XML Schema and X3D namespaces within the root X3D tags as defined in [XML_SCHEMA] [XML_NAMESPACES] .
EXAMPLE 2 1 XML Schema validation syntax for an X3D model.
<X3D profile='Immersive' version='4.0'
xmlns:xsd='https://www.w3.org/2001/XMLSchema-instance'
xsd:noNamespaceSchemaLocation='https://www.web3d.org/specifications/x3d-4.0.xsd'>
<X3D profile='Immersive' version='3.3'
xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance'
xsd:noNamespaceSchemaLocation='http://www.web3d.org/specifications/x3d-3.3.xsd'>
A DOCTYPE or schema declaration is optional. The reference DTD and location is specified in this document. To allow for extensible tag sets (supersets of the base specification), authors may point to a document definition other than the ones listed in this specification. However, the alternate definition shall specify an equivalent document to the base X3D DTD/Schema (i.e., the tag instances shall look exactly the same regardless of the source DTD schema). Authors shall use the X3D DOCTYPE and/or X3D Schema extension mechanisms to add validation capability for new nodes and fields.
Next comes the required X3D document root tag that specifies version and profile information with optional schema validation. Within the X3D document root tag is the optional header section, and the required scene body.
EXAMPLE 3 2 XML syntax for a complete X3D model.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 4.0//EN" "https://www.web3d.org/specifications/x3d-4.0.dtd">
<X3D version='4.0' version='3.3' profile='Immersive'>
<head>
<component name='Geospatial' level='1'/>
<component name='NURBS' level='2'/>
<meta name='description' content='X3D scene header and prototype syntax examples. '/>
<meta name='title' content='X3dHeaderPrototypeSyntaxExamples.x3d'/>
<meta name='identifier'
content='https://web3d.org/x3d/content/examples/Basic/development/X3dHeaderPrototypeSyntaxExamples.x3d'/>
</head>
<Scene>
<!-- Scene graph nodes are added here -->
</Scene>
</X3D>
This example header indicates that the content is XML encoded,
matches X3D version 4.0, 3.3, follows the
Immersive Profile, and explicitly lists additional expected components. The
X3D header may also contain further semantic information, using meta tags for
name='metadataTerm'
and content='value'
pairs.
Note that the third meta tag should not break in the middle of the string.
This clause describes the syntax of XML-encoded, human-readable X3D files. The syntax of X3D in terms of the XML encoding are presented in this part of ISO/IEC 19776. The semantics of X3D are as defined in [I19775-1]. Rules for parsing and handling XML-encoded documents are defined in [XML].
Two formal grammar descriptions of the XML syntax for X3D may be found in Annex A X3D XML Document Type Definition (DTD) and Annex B X3D XML Schema. These grammars are directly implementable by XML parsers.
In the XML encoding, the character sequences <!--
and
-->
delimit a comment.
EXAMPLE XML comment syntax.
<!-- This is an X3D comment. -->
The only exceptions to this description of XML comments are within
XML CDATA sections, which are ignored during XML parsing and typically only used for embedded script code.
Comment exceptions also
occur within double-quoted SFString and MFString fields, where the
comment characters are escaped
(using <
for <
and >
for >
)
and are defined to be part of the string.
Attribute values may be delimited by paired single-quote ('
) or double-quote ("
) characters.
Neither authors nor parsers can guarantee which
type types
of paired delimiting characters
might be encountered when processing an XML file, is encountered
since
XML processors are allowed to independently choose either form. These rules are
described in [XML] and
[XML_INFOSET]
.
which take precedence over all rules in this clause.
XML elements (e.g., (i.e., X3D nodes) may not appear within attribute values.
Space characters, Spaces, tabs, linefeeds, and carriage-returns are separator characters wherever they appear outside of XML attribute values. Separator characters are collectively termed whitespace. Commas are not ignorable whitespace when mixed between XML elements or element and attribute values.
Within X3D attribute values, the rules are slightly different. Commas, spaces, tabs, linefeeds, and carriage-returns are separator characters wherever they appear outside of XML attribute values. Separator characters and comments are collectively termed whitespace.
Field, event, PROTO, EXTERNPROTO, and node names shall not contain control characters (0x0-0x1f, 0x7f), space (0x20), double or single quotes (0x22: ", 0x27: '), sharp (0x23: #), comma (0x2c: ,), period (0x2e: .), brackets (0x5b, 0x5d: []), backslash (0x5c: \) or braces (0x7b, 0x7d: {}). Further, their first character shall not be a digit (0x30-0x39), plus (0x2b: +), or minus (0x2d: -) character. Otherwise, names may contain any ISO 10646 character encoded using UTF-8. X3D is case-sensitive; "Sphere" is different from "sphere" and "BEGIN" is different from "begin."
In order to maintain interoperable conversion capabilities translatability between the various file encodings and programming-language bindings different X3D encodings of X3D scenes, the following reserved keywords shall not be used for field, event, Protytype or node names:
After the required XML header and <X3D> document-root tag, an X3D file may contain any combination of the following:
head
element which can contain component,
unit, and metadata information
(as described 4.3.1 XML encoding);
then
X3D nodes are expressed as XML elements (i.e., tagged names).
Simple non-node X3D fields are expressed as XML attributes in
the form of name="value"
pairs.
Nodes which serve as fields to other X3D nodes are expressed as contained XML elements, i.e. additional tagged names. Each includes an implicit (default) or explicitly defined containerField value.
A node statement consists of the type-name for the node element followed by the allowed simple-field attributes. A node instance can be given a label using the attribute DEF followed by an equals sign and the quoted name of the node.
Each tag begins and ends with angle brackets < and >, respectively. A node's body is enclosed by a pair of matching open and closing tags, where a closing tag has a slash / prepended to the element name.
EXAMPLE 1 The following XML declarations illustrate illustrates the use of node and field syntax:
<Group DEF='ExampleChildElement'>
<Shape>
<Box/>
<Appearance>
<Material diffuseColor='0.6 0.4 0.2'/>
</Appearance>
</Shape>
</Group>
Alternatively, if no further elements are contained as child nodes, a
singleton
single tag may omit the
closing element tag by ending the single element with />
characters.
EXAMPLE 2 A pair of XML singleton elements.
<Viewpoint DEF='ExampleSingleElement'
description='Hello syntax'/>
<NavigationInfo type='"EXAMINE" "ANY"'/>
A node element contains zero or more field attributes, as appropriate for each node type.
When nested inside a ProtoDeclare ProtoBody, a node's content can optionally begin with a single IS
statement,
which in turn contains one or more connect
statements.
A node then contains zero or more child nodes, ROUTE statements, ProtoDeclare statements or ExternProtoDeclare statements.
These contained nodes and statements are allowed as appropriate for each node type, and can typically appear in any order.
Whitespace shall separate
the name of the node and attribute="value"
pairs, but is not required before or after
the tags that enclose the node's body.
XML-based scene validation for proper parent-child relationships among nodes can be performed using using either the X3D XML Document Type Definition (DTD) or X3D Schema. The DTD and Schema also define default values for attribute fields, matching the abstract specification. See 6 Encoding of nodes for the specification of the XML encoding of each node type.
A declared node with accompanying DEF identification can be copied by reference through a USE reference. Both DEF and USE node types shall be exactly the same.
A USE attribute indicates that a node is a reference copy of a DEF node with the same ID.
DEF
is assigned XML type ID
, and
USE
is assigned XML type IDREF
, respectively.
The same name-construction conventions regarding legal character combinations apply.
Each DEF (ID) value in a scene shall be unique. Non-unique node DEF names in the body of ProtoDeclare definitions will cause validation errors when checked by the X3D DTD or Schema. This is a constraint from limitation of XML that requires each XML DTD and Schema to have a single namespace for ID types.
Nodes being reused via a USE="someDEFname"
attribute can include no other attributes except containerField
and class
.
Modified values for other fields in a USE node are not allowed, since explicit and implicit field definitions found in the
original DEF node declaration take precedence and remain unchanged by the USE node.
EXAMPLE Reusing the ExampleChildElement node declared in Example 5 as a USE node: Continuing the previous example statements:
<Transform DEF='ExampleWithChildUSEnode' DEF='ExampleUSE'
rotation='0 1 0 0.78'
translation='0 2.5 0'>
<Group USE='ExampleChildElement' containerField='children' USE='ExampleChildElement'/>
</Transform>
Nodes containing a USE="someName"
attribute can include no other attributes except containerField
and class
.
Default values for other fields shall be ignored since field definitions in the
original DEF node declaration have precedence.
Each node type defines the names and types of the fields that each node of that type contains. In general, nearly all field-node relationships are unambiguous due to the well-defined parent-child node relationships in X3D.
In order to achieve a compact tagset in the XML encoding for X3D,
the name of the parent node's field field typically containing each node is accounted for
by the containerField attribute. For example, Sensor nodes are typically
contained by the children
field of Grouping nodes, hence each
Sensor node has containerField='children'
as the default value.
Ordinarily the containerField value can be omitted. The default containerField value for a given node may be overridden when necessary to indicate a different relationship with a given node's parent.
EXAMPLE
Again reusing the ExampleChildElement node declared in Example 5 as a USE node,
this time without including the default containerField='children'
attribute:
<Collision>
<Shape containerField='proxy'>
<Sphere/>
</Shape>
<Group USE='ExampleChildElement'/>
</Collision>
The class
attribute is reserved for use with XML Cascading Style Sheets
(see [W3C-CSS-Snapshot]). [CSS]).
TODO discuss purpose of cascading stylesheets, X3D Architecture Annex L HTML Guidelines
A Prototype declaration consists of the ProtoDeclare
keyword, followed in order by the
prototype name attribute, optional prototype interface field declarations
contained within a ProtoInterface
, and required prototype body definition
contained within a ProtoBody
.
Prototype field statements consist of the field
keyword, followed in any order by the
attribute values for
field name
, field type
and field accessType
(having value inputOnly
, outputOnly
, initializeOnly
or inputOutput
).
EXAMPLE 1 A prototype declaration example (without and with field declarations, respectively) follow:
<ProtoDeclare name='NewWorldInfoNode'>
<ProtoBody>
<WorldInfo DEF='ExamplePrototypeBody' title='Hello New World Intro'/>
</ProtoBody>
</ProtoDeclare>
<ProtoDeclare name='EmissiveMaterial'>
<ProtoInterface>
<field name='onlyColor'
type='SFColor'
accessType='inputOutput'/>
</ProtoInterface>
<ProtoBody>
<!-- Override default diffuseColor value 0.8 0.8 0.8 -->
<Material diffuseColor='0 0 0'>
<!-- Connect emissiveColor field of current node to onlyColor field of parent ProtoDeclare. -->
<IS>
<connect nodeField='emissiveColor' protoField='onlyColor'/>
</IS>
</Material>
</ProtoBody>
</ProtoDeclare>
A field statement also contains the default value of the field when the accessType is either initializeOnly or inputOutput. Simple values are contained in the value attribute (e.g., value='true'). If the default value of an SFString or MFString field is empty, the default value may be omitted. Node (or node array) values are contained as child nodes within the field declaration.
EXAMPLE 2 The <Group DEF='DefaultNodeValue'/> in EXAMPLE 2 below provides a default initialization for the children field in the ProtoDeclare body.
EXAMPLE 2 X3D prototype definition using XML ProtoDeclare syntax.
<ProtoDeclare name='ShiftGroupUp2m'>
<ProtoInterface>
<field name='children'
type='MFNode'
accessType='inputOutput'>
<Group DEF='DefaultNodeValue' bboxSize='2 2 2'/>
</field>
</ProtoInterface>
<ProtoBody>
<Transform translation='0 2 0'>
<Group>
<IS>
<connect nodeField='children'
protoField='children'/>
</IS>
</Group>
</Transform>
</ProtoBody>
</ProtoDeclare>
The same field name may be used independently by multiple node prototypes.
See 5 Encoding of fields for the specification of the XML encoding of each X3D field type.
The body of a node statement that is inside a prototype definition may
optionally contain a single <IS>
statement, which in turn contains one or more
<connect>
statements. Each <connect>
statement
consists of a nodeField attribute with the name of a field from the parent node's interface,
followed by a protoField attribute with the name of a field from the ancestor ProtoDeclare
.
When defined in a scene, any contained <IS>
element shall be
the first child element within a node definition, with two exceptions.
Script, ComposedShader, PackagedShader, and ShaderProgram nodes include field
definitions before IS/connect. ProtoInstance definitions include
fieldValue initializations before IS/connect.
The type
and accessType
of each field
shall match exactly.
These nodeField and protoField names may be overloaded; i.e., these two names
may be identical since each is part of a different namespace.
See the Prototype declaration specified in 4.3.7 Prototype and field declaration syntax for example use of IS/connect constructs.
ISO/IEC 19775-1 (see 4.4.4 Prototype semantics) specifies [I19775-1] for details on external prototype statements.
TODO: provide an example.
An ExternProtoDeclare statement consists of the ExternProtoDeclare element,
a name
attribute for the referenced Prototype, and a url of one or more
addresses referring to the scene defining this Prototype.
Zero or more contained field
definitions
then follow to provide the interface for the prototype.
Contained field statements consist of the field
keyword, followed in any order by the
attribute values for
field name
, field type
and field accessType
(inputOnly
, outputOnly
, initializeOnly
and inputOutput
).
url
values are
"quote delimited"
local filenames and/or remote addresses.
Each filename or address should have a pound #
symbol appended,
followed by the case-sensitive literal name of the externally defined Prototype node.
(This url syntax is similar to HTML bookmarks and X3D Anchor viewpoint links.)
EXAMPLE An external prototype declaration follows:
<ExternProtoDeclare
name='ViewPositionOrientation'
nodeType='Viewpoint'
url='"ViewPositionOrientationPrototype.x3d#ViewPositionOrientation"
"https://www.myorg.org/examples/ViewPositionOrientationPrototype.x3d#ViewPositionOrientation"
"ViewPositionOrientationPrototype.wrl#ViewPositionOrientation"
"https://www.myorg.org/examples/ViewPositionOrientationPrototype.wrl#ViewPositionOrientation"' >
<field name='enabled'
type='Boolean'
accessType='inputOutput'/>
</ExternProtoDeclare>
See 4.4.5 External prototype semantics in [I19775-1] for details on external prototype statements.
The ProtoInstance
element is used to create instances of nodes, which shall be
defined previously in the scene using either ProtoDeclare
or ExternProtoDeclare
statements.
ProtoInstance
can contain zero or more fieldValue
elements
which are used to provide initial values for fields defined in the corresponding
predecessor ProtoDeclare
or ExternProtoDeclare
statement.
These fieldValue
initializations are only used for field definitions with
accesstype
of initializeOnly
or inputOutput
and
override
any default values defined in the corresponding
ProtoDeclare
.
EXAMPLE 1 ProtoInstance fieldValue initialization
<Transform translation='0 -2.5 0'>
<Shape>
<Appearance>
<ProtoInstance name='EmissiveMaterial'>
<fieldValue name='onlyColor'
value='0.2 0.6 0.6'/>
</ProtoInstance>
</Appearance>
<Text string='"Prototype syntax" "examples"'>
<FontStyle justify='"MIDDLE" "MIDDLE"'/>
</Text>
</Shape>
</Transform>
<ProtoInstance DEF='MyVPO' name='ViewPositionOrientation'>
<fieldValue name='enabled' value='true'/>
</ProtoInstance>
ProtoInstance definitions always require a valid name, even when defining a USE node.
EXAMPLE 2 ProtoInstance USE node
<ProtoInstance USE='MyVPO' name='ViewPositionOrientation'/>
A ROUTE statement consists of a ROUTE element followed by attributes
fromNode
, fromField
, toNode
and toField
.
The fromNode
and toNode
attributes are of XML type IDREF
,
meaning that corresponding DEF values shall be found in the preceding nodes.
The following semantic restrictions apply:
ROUTE
elements are not scene-graph nodesProtoDeclare
form a separate namespace.
It is an error to ROUTE
into (or out of) a ProtoDeclare
body.
EXAMPLE The following illustrates ROUTE statement syntax:
<TimeSensor DEF='Clock' cycleInterval='4' loop='true'/>
<OrientationInterpolator
DEF='Spinner'
key='0 0.5 1'
keyValue='0 1 0 0,0 1 0 3.1416, 0 1 0 6.2832'/>
<ROUTE fromNode='Clock' fromField='fraction'
toNode='Spinner' toField='set_fraction'/>
<ROUTE fromNode='Spinner' fromField='value_changed'
toNode='TransformExampleUSE' toField='rotation'/>
The following XML syntax applies to the IMPORT/EXPORT functionality of X3D.
An IMPORT statement consists of an IMPORT element followed by attributes
inlineDEF
,
importedDEF
,
exportedDEF
, and (optionally) AS
.
An EXPORT statement consists of an EXPORT element followed by attributes
localDEF
and (optionally) AS
.
EXAMPLE 1 2 The following depicts the XML encoding of an EXPORT statement within the inlined InlineExport.x3d model:
<!-- file InlineExport.x3d -->
<Transform DEF='T1'> <!-- contained 3D content --> </Transform>
<!-- Hint: EXPORT statement follows node of interest, since localDEF field is similar to USE with type IDREF -->
<EXPORT localDEF='T1' AS='RootTransform'/>
EXAMPLE 2 1 The following depicts the XML encoding of an IMPORT statement within a parent scene that corresponds to a separate Inline model:
<!-- file InlineImport.x3d -->
<Inline DEF='MyInlineModel' url='"InlineExport.x3d"' DEF='I1' url='"someUrl.x3d"'/>
<IMPORT
inlineDEF='MyInlineModel' inlineDEF='I1'
importedDEF='RootTransform' exportedDEF='RootTransform'
AS='MyInlineRootTransform' AS='I1Root'/>
<OrientationInterpolator DEF='MySpinner' key='0 0.3333 0.6667 1' keyValue='0 1 0 0, 0 1 0 2.094395, 0 1 0 4.18879, 0 1 0 0'/>
<ROUTE
fromNode='MySpinner' fromField='value_changed'
toNode='MyInlineRootTransform' toNode='I1Root' toField='set_rotation'/>
Code for scripts should not be placed so as to be parsed by XML parsers. Therefore, such code should be encapsulated to avoid such parsing. The preferred method to encapsulate source code in a Script node is to wrap it in a child CDATA construct following the <field/> and <IS><connect/></IS> definitions. The CDATA construct (see [XML]) ensures that all contained characters are treated literally without further escaping or modification.
If both a url field and a CDATA clause are encountered, the url field is processed first. Thus, the CDATA construct can also be considered equivalent to one additional value appended to the url MFString array. This ordering allows an online script code url to take priority over fallback default script code in the CDATA construct. This ordering also allows run-time updates if a viewer is connected to the network, if so desired by the originating author.
EXAMPLE The following example demonstrates the use of a CDATA construct within a Script node:
<Script directOutput='true'>
<field name='ROOT' type='SFNode' accessType='initializeOnly'>
<Transform USE='ROOT'/>
</field>
<![CDATA[
javascript:
function R ()
{
return Math.random();
}
function initialize()
{
for (i=0; i < 10; i++)
{
rand1 = 100*R();
rand2 = 100*R();
rand3 = 20*R();
rand4 = 40*R();
rand5 = 20*R();
string =
'Transform {' +
' translation ' + rand1 + ' 0 ' + rand2 +
' children [' +
' Shape {' +
' appearance Appearance {' +
' material Material {' +
' diffuseColor ' + R() + ' ' + R() + ' ' + R() +
' }' +
' }' +
' geometry Box {' +
' size ' + rand3 + ' ' + rand4 + ' ' + rand5 +
' }' +
' }' +
' ]' +
'}';
newNode = Browser.createVrmlFromString(string);
ROOT.children[i] = newNode[0];
}
}
]]>
</Script>
XML-encoded X3D files shall use a file extension of either “.x3d” or “.xml”. the file extension “.x3d”. The MIME-type associated with that XML-encoded X3D file is “model/x3d+xml”.
X3D-encoded X3D files that have been “gzipped” shall use a file extension of either “.x3dz” or “.x3d.gz”. The MIME type is “model/x3d+xml”. The content-encoding value is “gzip”.
The concept of MIME types is defined in [RFC2077 MIME].
(TODO: description of EXI file extension and MIME )The X3D XML DTD is useful for file validation and quality assurance (QA). It is defined in Annex A X3D XML Document Type Definition (DTD).
The X3D XML schema is useful for file validation and quality assurance (QA). It is defined in Annex B X3D XML Schema.
X3D XML Schematron is useful for file validation and quality assurance (QA). It is defined in Annex C X3D XML Schematron.