Post

Building an X3D World

Building an X3D World

X3D File Structure

X3D files contain:

  • The file header
  • Comments - notes to yourself
  • Nodes - nuggets of scene information
  • Fields - node attributes you can change
  • Values - attribute values
  • Routes - connections between fields
  • more …

A Sample X3D File

XML Encoding

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 4.1/EN" "https://www.web3d.org/specifications/x3d-4.1.dtd">
<X3D profile='Interchange' version='4.1' xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='https://www.web3d.org/specifications/x3d-4.1.xsd'>
  <Scene>
  <!-- A Cylinder -->
  <Shape>
    <Appearance>
      <Material/>
    <Appearance>
    <Cylinder
        height='2'
        radius='1.5'/>
    </Shape>
  </Scene>
</X3D>

Classic VRML Encoding

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#X3D V4.1 utf8

PROFILE Interchange

# A Cylinder
Shape {
  appearance Appearance {
    material Material { }
  }
  geometry Cylinder {
    height 2
    radius 1.5
  }
}

Example

Cylinder

Understanding the Header

#X3D V4.1 utf8

  • #X3D: File contains X3D text
  • V4.1 : Text conforms to version 4.1 syntax
  • utf8 : Text uses UTF8 character set

Understanding UTF8

  • utf8 is an international character set standard
  • utf8 stands for:
    • UCS (Universal Character Set) Transformation Format, 8-bit
    • Can encodes up to 2,164,864 characters for many languages
    • ASCII is a subset

Understanding Profiles and Components

  • PROFILE Interchange: File uses nodes from the Interchange profile
  • Nodes are grouped into components
  • Components are grouped into profiles
  • Browsers can load components on demand to reduce initial load times and improve performance by only fetching what is necessary when it’s needed
  • Additionally add as many COMPONENT statements you need

XML Encoding

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 4.1/EN" "https://www.web3d.org/specifications/x3d-4.1.dtd">
<X3D profile='Interchange' version='4.1' xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='https://www.web3d.org/specifications/x3d-4.1.xsd'>
  <head>
    <component name='CubeMapTexturing' level='3'/>
    <component name='Scripting' level='1'/>
  </head>
  <Scene>
    ...
  </Scene>
</X3D>

Classic VRML Encoding

1
2
3
4
PROFILE Interchange

COMPONENT CubeMapTexturing : 3
COMPONENT Scripting : 1

What profiles and components are there:

Head Statements

There are a few other head statements, but always add a PROFILE statement. If there is no profile declared, profile Full is assumed and all components will be loaded, but this is probably not always desired.

There are three head statements:

  1. COMPONENT statements
  2. UNIT statements
  3. META statements

Order of head statements is important!

XML Encoding

  • head - can contain component, unit, and meta statements
  • Scene - contains the scene content, such as nodes, routes, imports, and exports
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 4.1/EN" "https://www.web3d.org/specifications/x3d-4.1.dtd">
<X3D profile='Interchange' version='4.1' xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='https://www.web3d.org/specifications/x3d-4.1.xsd'>
  <head>
    <!-- zero or more component, unit, meta statements in arbitrary order -->
    <component name='CubeMapTexturing' level='3'/>
    <component name='Scripting' level='1'/>
    <unit category='angle' name='degree' conversionFactor='0.017453292519943295'/>
    <unit category='length' name='millimetre' conversionFactor='0.001'/>
    <meta name='created' content='Thu, 08 May 2025 14:11:46 GMT'/>
    <meta name='modified' content='Thu, 08 May 2025 14:19:44 GMT'/>
  </head>
  <Scene>
    <!-- zero or more proto, node, route, import, export statements in arbitrary order -->
    ...
  </Scene>
</X3D>

Classic VRML Encoding

Order of Statements

  1. Header statement (#X3D V4.1 utf8)
  2. PROFILE statement (required)
  3. COMPONENT statements (optional)
  4. UNIT statements (optional)
  5. META statements (optional)
  6. Node statements (e.g., WorldInfo, Shape, etc.)
  7. IMPORT and EXPORT statements (optional)
  8. ROUTE statements (optional)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#X3D V4.1 utf8

# exactly one profile statement
PROFILE Interchange

# zero or more component statements
COMPONENT Scripting : 1
COMPONENT CubeMapTexturing : 3

# zero or more unit statements
UNIT angle degree 0.017453292519943295
UNIT length millimetre 0.001

# zero or more meta statements
META "created" "Thu, 08 May 2025 14:11:46 GMT"
META "modified" "Thu, 08 May 2025 14:12:13 GMT"

# zero or more proto, node, route, import, export statements
# in arbitrary order
...

Using Comments

XML Encoding

1
<!-- A comment -->
  • Comments start with <!-- and must end with -->.

Classic VRML Encoding

1
2
3
4
5
# A comment

#/* A
  * multi-line
  * comment */#
  • Comments start with a number-sign # and extend to the end of the line.
  • Mult-line comments start with #/* and must end with */#.

Using Nodes

XML Encoding

1
<Cylinder/>

Classic VRML Encoding

1
2
Cylinder {
}
  • Nodes describe shapes, lights, sounds, etc.
  • Every node has:
    • A node type (Shape, Cylinder, etc.)
    • A pair of curly-braces
    • Zero or more fields inside the curly-braces

Using Node Type Names

Node type names are case sensitive:

  • Each word starts with an upper-case character
  • The rest of the word is lower-case

Some examples:

Appearance, Cylinder, Material, Shape

Using Fields and Values

XML Encoding

1
2
3
<Cylinder
    height='2'
    radius='1.5'/>

Classic VRML Encoding

1
2
3
4
Cylinder {
  height 2
  radius 1.5
}
  • Fields describe node attributes

Every field has:

  • A field name (height, radius, etc.)
  • A data type (float, integer, etc.)
  • A default value
  • Different node types have different fields
  • Fields are optional
    • A default value is used if a field is not given
  • Fields can be listed in any order
    • The order doesn’t affect the node

Placing Nodes

Every node has a »containerField« attribute with a default value, which is different for each node type. You can change the value if needed.

1
2
3
4
5
6
7
8
<Collision>
  <Shape containerField='proxy'>
    <Box/>
  </Shape>
  <Transform>
    <!-- ... -->
  </Transform>
</Collision>

Summary

  • The file header gives the version and encoding
  • Nodes describe scene content
  • Fields and values specify node attributes
  • containerField attribute can be changed.
  • Everything is case sensitive
This post is licensed under CC BY 4.0 by the author.