XML3D Specification

Unofficial Draft 15 June 2020

Editors:Kristian SonsChristian SchlinkmannAuthors:Felix Klein, Intel Visual Computing InstituteKristian Sons, DFKIChristian Schlinkmann, DFKI

This document is licensed under a Creative Commons Attribution 3.0 License.


Abstract

This document defines the 5th revision of XML3D, an extension to HTML5 for describing interactive 3D scenes.

Status of This Document

This document is merely a public working draft of a potential specification. It has no official standing of any kind and does not represent the support or consensus of any standards organisation.

1. Introduction

1.1 Motivation

The idea of adding virtual 3D worlds to the web has a long history: In 1994, Dave Ragget proposed a platform independent 3D scene description based on web technologies as “mechanisms for people to share VR models on a global basis”. Ragget also proposed to describe the structure of the virtual world on a high abstraction level based on the experiences of SGML and HTML. In the same year, Pesce et al. proposed extending “HTML to describe both geometry and space”.

However, the developers of the resulting VRML standard decided against designing VRML as an extension to HTML. As a result, Web3D never took off until Vladimir Vukićević prototyped an OpenGL-based API for the HTML <canvas> element in 2006. This idea finally led to [WebGL].

Although WebGL is a great technology and paved the way for accelerated 3D graphics in the browser, it also comes with some disadvantages that are addressed by XML3D: First, it is only loosely coupled with other W3C technologies such as HTML, CSS, DOM scripting and events. As a consequence, web developers need to learn new concepts and WebGL-based libraries can not interoperate with HTML and DOM libraries such as jQuery. Secondly, WebGL is tied to OpenGL and does not take other algorithms and APIs into account. For instance, the definition of pipeline shaders is too specific and too low-level to use for ray tracing or global-illumination algorithms.

Thus, XML3D picks up the idea of a platform independent 3D scene description on a higher abstraction level on the basis of HTML (and yes, XML3D is a stupid name for that). At the same time, it takes the features of modern graphics APIs into account and exposes data processing and shading capabilities to the user, which can be mapped to the GPU pipeline. Despite these capabilities it can still be rendered with arbitrary rendering algorithms.

We do not expect that browser vendors will implement XML3D natively in the near future. The main motivation of this specification is to enable people to share their 3D assets including 3D models, materials and animations and to easily create stunning 3D web applications. Therefore, XML3D is accompanied with a reference application, a polyfill that uses WebGL and JavaScript to emulate native XML3D support. As a result, XML3D is fully usable today and various applications already exist.

However, having said that, we expect that a native implementation of XML3D would come with a series of benefits: Browsers could render scenes with advanced rendering algorithms or render the scene or parts of the scene as a service in the cloud. The higher abstraction level gives implementations opportunities to optimize performance and to provide advanced debugging facilities. A native renderer can also reason about the scene’s content and changes and – as a result – driving VR applications would be much easier.

1.2 About XML3D

This specification defines the features and syntax of XML3D.

XML3D is a language for describing interactive 3D scenes. Although the name may suggest otherwise, XML3D is not an XML language. Instead it is designed as an extension to [HTML5]. Consequently, XML3D defines an abstract language and APIs for interacting with the 3D scene. Similar to HTML5, the concrete syntax of XML3D can be either the [HTML5] syntax or the [XML] syntax.

XML3D reuses concepts from HTML5: [DOM] scripting and [UIEvents] allow easy creation of interactive 3D scenes. [CSS2] can be used to define styling properties for XML3D elements such as transformations or visibility. Hence, XML3D is tightly integrated into the W3C technology stack.

On the other hand, XML3D introduces some novel concepts. XML3D introduces a generic data model to define arbitrarily named and typed parameters. XML3D has a dataflow graph concept in order to describe data processing within the HTML document. Finally, it supports programmable materials based on JavaScript. These concepts are essential to gain a higher flexibility compared to previous declarative 3D scene descriptions (e.g. VRML or X3D).

XML3D is platform independent, i.e. an XML3D scene description can be rendered using arbitrary rendering algorithms. Thus, XML3D can not only be rendered with various flavours of GPU rasterization (forward rendering, deferred rendering, etc), but also with ray tracing and rendering algorithms taking global illumination into account (e.g. Monte Carlo path tracing). Similar to HTML, XML3D describes what should be rendered rather than how it should be rendered.

XML3D is a lean low-level 3D scene description. Convenience functionality found in other approaches can be implemented on top of XML3D, for instance using scripting and concepts such as [custom-elements].

1.3 Compatibility with Other Standards Efforts

XML3D leverages and integrates with other W3C specifications and standards efforts. By leveraging and conforming to other standards, XML3D becomes more powerful and makes it easier for users to learn how to incorporate XML3D into their Web sites.

  • XML3D is an extension to [HTML5].
  • XML3D reuses [HTML5] elements, e.g. the <img> element to define texture data.
  • XML3D content can be styled with [CSS2], i.e. XML3D supports all relevant style properties.
  • XML3D defines [DOM] interfaces for scripting. All XML3D elements derive from the HTMLElement DOM interface.
  • XML3D leverages [UIEvents] as its event system and supports all relevant events available in HTML. Additionally, it supports all relevant event attributes.
  • XML3D adopts the <defs> element from [SVG].

XML3D uses [URI]s, in particular URNs for identifiying predefined models and URLs for identifing resources in the same or in external documents.

2. Concepts

2.1 Generic data model

HTML elements can be parametrized using HTML attributes or CSS properties. In graphics we need, however, the possibility to define sets of arbitrarily named and typed parameters. Additionally, these parameters may be very long, for instance the positions of a mesh. Hence, we introduce a generic data model for XML3D, which is used consistently throughout XML3D’s abstract model.

XML3D’s generic data model provides means to share and compose data between data consumers such as the mesh elementlight elementview element, and material element. It is also the basis for the dataflow graph concept and for programmable materials with shade.js, which both require arbritraily typed and named parameters.All data elements output a table of named entries. This table is composed

NOTETo not spoil the user experience, large parameter sets (e.g. mesh data) should never be defined inside the web page. Instead, this kind of data should be defined in external resources which are loaded asynchronously, e.g. in a JSON file or, more efficiently, using a container in Blast format.

2.1.1 Mark-up

The value elements can be used to define data table entries directly in mark-up. This is useful for all parameters that need to be modified during runtime using the DOM API. Value elements can be used to construct a reusable data source using the data element, or to parametrize a consumer element, e.g. a mesh element, directly.EXAMPLE 1

<data id="parameter-set">     <!-- generic data container -->
    <float3 name="parameter-1">1.0 0.0 0.0</float3>
    <float name="parameter-2">0.5</float>
</data>

<material id="material1" model="...">     <!-- parameterized consumer -->
    <float3 name="parameter-1">1.0 0.0 0.0</float3>
    <float name="parameter-2">0.5</float>
</material>

2.1.2 Sequences

The generic data model allows arbitrarily long sequences of data to be defined using the key attribute on value elements. This is useful, for example, to define the base data for mesh animations to be driven by Xflow compute operators.EXAMPLE 2

<data id="keyFrameData">
  <float3 name="position" key="0" >-5 0 5 ... </float3>
  <float3 name="normal" key="0" >0 -1 0 ... </float3>

  <float3 name="position" key="0.1" >-2.886751 2.113249 2.886751 ... </float3>
  <float3 name="normal" key="0.1">-0.554395 -0.620718 0.554395 ... </float3>

  <float3 name="position" key="0.2">-1.341089 4.649148 1.341089 ... </float3>
  <float3 name="normal" key="0.2">-0.696886 0.169412 0.696886 ... </float3>

  <float3 name="position" key="0.3" >-6.158403 1.408833 6.158403 ... </float3>
  <float3 name="normal" key="0.3">-0.141341 -0.979819 0.141341 ... </float3>

  ...
</data>

The above sequence of data represents the keyframes of a mesh animation. Typically a compute operator would then be used to interpolate between keyframes, or to otherwise map the sequences of data to a definite set of position and normal data to be rendered.

2.1.3 External resources

For external data resources, a mapping to a data table needs to be defined which is identified via the internet media type [rfc2045] of the resource. XML3D comes with mappings for external XML3D files, and JSON files in XML3D format. In xml3d.js, additional mappings can be provide via a plug-in mechanism.NOTEA STL file consists of vertex positions and face normals. A mapping could define that the vertex positions are mapped to an entry named position and to per-vertex normals (requires processing) named normal, both of type float3. Then a mesh element can reference STL files directly:

        <mesh src="printable-teapot.stl"></mesh>
        

Note that defining this mapping is possible in xml3d.js via a plug-in. A plug-in for STL files is available here.

2.1.4 Data compositing

Data can be shared and composed from multiple internal and external sources. A set of overriding rules handles cases, where entries with the same name and sequence key exits.

  1. A subsequent value element overrides previous ones.
  2. Local value elements override referenced data sources.
  3. Entries in the output of a referenced data table override entries of a previously referenced data table.
  4. The output of a referenced data table gets evaluated with the same set of overriding rules before it is taken into account.

The overriding rules can be exploited to specialize more general data sources.EXAMPLE 3

<data id="specularTerm">
  <float3 name="specularColor">0.1 0.2 0.3</float3>
  <float name="ambientIntensity">0.1</float>
  <float name="shininess">0.2</float>
  <float name="shininess">0.6</float> <!-- shininess is 0.6 according to rule 1 -->
</data>

<data id="diffuseTerm">
  <float3 name="diffuseColor">0.1 0.2 0.3</float3>
  <float name="ambientIntensity">0.9</float>
</data>

<material id="composedMaterial"> <!-- Composing a material from multiple sources -->
  <data src="path/to/external/resource.xml#textureData"></data>
  <data src="#specularTerm"></data>  <!-- shininess is 0.6 according to rule 4 -->
  <data src="#diffuseTerm"></data>   <!-- ambientIntensity is 0.9 according to rule 3 -->

</material>

<material id="specializedMaterial">
  <data src="#specularTerm"></data>  <!-- Reuse data from #specularTerm -->
  <float name="shininess">0.4</float> <!-- shininess is 0.4 according to rule 2 -->
</material>

2.1.5 Filters

The generic data model defines three filters that may be applied to data through the filter attribute on the data element and the dataflow element.

        filter="keep|remove(field1 [, field2...])"
        filter="rename( { newFieldName : field [, newFieldName2 : field2...] } )"
      

A filter does not change the data itself but rather influences how that data is made available to other elements. For example, using a remove filter does not actually remove the data from the element, it simply hides it from parent elements.

An data element may only have one filter, if multiple filters are needed they can be applied with nested data elements.EXAMPLE 4

<data filter="keep(A,D)">
  <float name="A" >0</float>
  <float name="B" >1</float> <!-- will be removed -->
  <float name="C" >1</float> <!-- will be removed -->
  <float name="D" >1</float>
</data>

<data filter="remove(D)">
  <float name="A" >0</float>
  <float name="B" >1</float>
  <float name="C" >1</float>
  <float name="D" >1</float> <!-- will be removed -->
</data>

<data filter="rename( {A2 : A, B2 : B} )">
  <float name="A" >0</float> <!-- will be renamed into A2 -->
  <float name="B" >1</float> <!-- will be renamed into B2 -->
  <float name="C" >1</float>
  <float name="D" >1</float>
</data>

<data filter="keep( {A2 : A, B2 : B} )">
  <float name="A" >0</float> <!-- will be renamed into A2 -->
  <float name="B" >1</float> <!-- will be renamed into B2 -->
  <float name="C" >1</float> <!-- will be removed -->
  <float name="D" >1</float> <!-- will be removed -->
</data>

<data filter="rename( {A1 : A, A2 : A, A3: A} )">
  <float name="A" >0</float> <!-- will be provided under the names A1, A2 and A3 -->
</data>

2.2 Dataflow graph (Xflow)

XML3D comes with a lean set of scene elements, in particular if compared to other scene descriptions. To describe dynamic effects in the scene XML3D provides a dataflow graph approach (Xflow), that allows arranging data processing operations as a graph of operations. This way, it is possible to describe complex dynamic data processing from basic blocks.

Xflow is powerful enough to describe all common dynamic effects usually implemented in fixed-function entities including skinning, morphing, augmented reality functionality, etc. The basic principle of Xflow is a small addition to the general data model: It allows attaching an operator to a data element using the compute attribute. A data element with such a compute operator attached first composes the data table as usual. This data tabe is then used as the input of the compute operator. The output of the compute operator (i.e. the result) is merged with original data table. In this merge, entries from the result table override entries with the same name from the input table.

2.2.1 The compute operator

Compute operators can be used to change or create data inside an Xflow graph. They operate like functions, receiving a set of input arguments, doing some work and then outputting the result. On a data element an operator may be invoked through the compute attribute using the following syntax:

         compute="(output1 [,output2...]) = xflow.[operatorName]([argument1, ...])"
        

In a dataflow element one or more compute operators can be invoked inside a compute block using the compute element.

The fields listed as outputs will be added to the list of data that this data element provides. The arguments must be available to the data element that invokes the operator, either as value elements or provided by a child data element. Compute operators can be invoked in sequence by nesting data elements:EXAMPLE 5

<data compute="position = xflow.add(position, offset2)">
  <data compute="position = xflow.add(position, offset1)">
    <float3 name="position">...</float3>
    <float3 name="offset1">...</float3>
  </data>
  <float3 name="offset2">...</float3>
</data>

XML3D includes several compute operators by default (a complete list may be found here) but also provides an interface to declare custom compute operators. These can be saved in their own JavaScript files and served alongside xml3d.js. Before being used a custom operator must be registered with Xflow by calling Xflow.registerOperator with the following syntax:EXAMPLE 6

Xflow.registerOperator("xflow.myOperatorName", {
  outputs: [ {type: 'float3', name: 'outputName', customAlloc=true },
             ...
  ],

  params:  [ {type: 'int', source: 'inputName1', optional=true },
             {type: 'float3', source: 'inputName2', array=true },
             ...
  ],

  alloc: function(sizes [, inputName1, ...]) {
     // Only necessary if one or more outputs have the flag 'customAlloc=true'
     sizes['outputName'] = inputName2.length;
  },

  evaluate: function(outputName, inputName1, inputName2, info) {
     ...
  }
});

NOTEAs long as a custom operator appears after the xml3d.js script in the document flow the Xflow.registerOperator function can (and should) be called immediately. This is typical behavior for a JavaScript plugin architecture and ensures the operators have been registered before XML3D initializes the scene (during the document.onload event).

In essence the declaration of the compute operator must contain at least a list of input and output fields, including types, and an evaluate function that is called by Xflow during data processing. Input fields may be marked as optional, otherwise they will generate an error if missing.

Output fields may be allocated with a custom size, indicated with the customAlloc flag. When this flag is present Xflow will call the alloc function, which should declare the sizes of the data arrays that Xflow needs to create for these fields. If a field is not marked with customAlloc then Xflow will attempt to choose the right size based on the inputs to the compute operator.

Fields marked with the array flag will be provided to the evaluate function as is and will exclude them from the normal length-matching checks that Xflow performs on input arguments. This can be used, for example, to pass an array of data with 100 elements while the other input fields all contain thousands of elements. Normally this would generate an error as Xflow would not be able to properly iterate through the data.

The evaluate function will always be called with the list of output fields first, then the input fields, then an info object supplied by Xflow. The info object contains information about how the data can be iterated and offers a place to store data during processing:

          info = {
            iterFlag: [true|false,...], // Is the input at this position an array that should be iterated over or a single element?
            iterateCount: number,       // The number of elements in the input data to iterate over, ie. (input array length) / (tuple size)
            customData: {}              // A field to hold custom data during and between operator executions
          }
        

NOTEFields marked with the array flag will always have an iterFlag value of false

The following is an example operator that uses the info object to iterate over a set of positions, adding a constant offset and returning the result as a new array of positions:EXAMPLE 7

Xflow.registerOperator("xflow.addOffset", {
  outputs: [ {type: 'float3', name: 'result' }
  ],

  params:  [ {type: 'float3', source: 'position' },
             {type: 'float3', source: 'offset', array=true }
  ],

  evaluate: function(result, position, offset, info) {
     // In this example 'offset' is an array with 3 values (a single float3)
     // 'position' is an array containing thousands of values

     for (var i=0; i < info.iterateCount; i++) {
        result[i*3] = position[ info.iterFlag[0] ? i*3 : 0 ] + offset[0];
        result[i*3+1] = position[ info.iterFlag[0] ? i*3+1 : 1 ] + offset[1];
        result[i*3+1] = position[ info.iterFlag[0] ? i*3+2 : 2 ] + offset[2];
     }
  }
}

3. Style

Since XML3D extends HTML, all [CSS2] properties also apply to XML3D elements. However, only the semantic of a few of them make sense for the 3D scene description. In the following we list the relevant style properties that influence the rendering of the scene.NOTEOther properties may affect XML3D elements in the future. Good candidates include the visible and pointer-events properties.

3.1 The display property

‘display’

Value:  inline | block | list-item | inline-block | table | inline-table | table-row-group | table-header-group | table-footer-group | table-row | table-column-group | table-column | table-cell | table-caption | none | inherit
Initial:  inherit
Applies to:  Scene elements

The meanings of the values of this property for XML3D elements:noneThis value causes an element to not contribute to the rendering, i.e. geometry elements are not rendered, light elements do not emit light into the scene. Also, geometry elements do not generate bounding boxes (empty boxes) nor contribute to their parent’s bounding box. Descendant elements do not display and do not contribute to the parents’ bounding boxes either.<other values>All other values do not affect the rendering of the element.A ‘display’ value of none will hide all descendant elements regardless of their local properties, as it does in HTML. Here are some examples for the ‘display’ property:EXAMPLE 8

mesh.hidden { display: none } /* do not display meshes with hidden class */
xml3d > * > * > * > * model { display: none; } /* Hide all models deeper than the fifth hierarchy level */

Modifying the display property with jQuery:EXAMPLE 9

$("#myMesh").hide();
$(".walls").toggle();

NOTEBe careful when assigning display: none to the xml3d element itself (or a parent of it). In HTML, elements with display: none have a width and height of 0 and this may cause XML3D to be initialized improperly.

3.2 The transform property

‘transform’

Values:  translateX | translateY | translateZ | translate3d | rotateX | rotateY | rotateZ | rotate3d | scaleX | scaleY | scaleZ | scale3d | matrix3d
Initial:  identity matrix
Applies to:  Transformable elements

[CSS3-transforms] can be used to specify 3D transformations for any transformable element. The transform property may hold any number and combination of values, which will be combined from left to right. Transformations also apply to all descendant scene elements, building a transformation hierarchy.NOTESome transform functions (eg. translate3d) require a unit of measurement to be valid. Because browsers do not yet support units that make sense for a 3D scene these values should be given in ‘px’. For example, translate3d(10px, 5px, 0px). Internally these transformations will of course be in the units that the scene uses.NOTESome browsers silently ignore invalid CSS transforms. If a CSS transform is not behaving as expected double check to ensure the formatting and syntax are valid.

3.3 The z-index property

‘z-index’

Value:  auto | <integer>
Initial:  auto
Applies to:  Scene elements

The meanings of the values of this property for XML3D elements:autoThis is the default value and causes the element to be rendered in the same z-layer (stacking context) as its parent element. If no other z-index values appear in the scene this means all elements will be rendered in a single z-layer according to their distance from the camera.<other values>Any value other than ‘0’ will create a new stacking context, similar to the behavior of z-index for normal HTML elements.

During rendering objects will first be sorted into bins according to the stacking contexts present in the scene. Then the bins will be rendered from lowest z-index to highest, with the objects in each bin sorted according to their distance from the camera. The depth buffer will be cleared between each bin.

This has the effect of rendering objects with a higher z-index on top of those with a lower z-index regardless of their spatial orientation in the scene.

Note that the same stacking context rules apply for XML3D elements as for HTML elements. This means an element’s z-index is always relative to the closest parent element having a z-index value other than ‘auto’.Here are some examples for the ‘z-index’ property:EXAMPLE 10

<mesh src="example.xml" style="z-index: 5"></mesh>
<mesh src="example.xml" style="z-index: 10"></mesh> <!-- Will always be drawn above the other two meshes -->
<mesh src="example.xml" style="z-index: -5"></mesh> <!-- Will always be drawn below the other two meshes -->

In the example below the mesh with the z-index value of 500 will be drawn below the other meshes. This is because both groups create their own stacking contexts, and the second group’s z-index is lower than that of the first.EXAMPLE 11

<group style="z-index: 1">
    <mesh src="example.xml" style="z-index: 10"></mesh> <!-- Will always be drawn above the second mesh -->
    <mesh src="example.xml"></mesh>
</group>
<group style="z-index: -1">
    <mesh src="example.xml" style="z-index: 500"></mesh> <!-- Will be drawn *below* the other meshes -->
</group>

4. The elements of XML3D

4.1 Kinds of elements

4.1.1 Transformable elements

assetmeshgroupmeshmodellightview

Transformable elements are those that are able to be transformed, either through CSS3 transforms or the transform element. Not all transformable elements can be nested but when they are they build a transformation hierarchy, with the transformation matrix of each node being defined as its own local transformation matrix multiplied with the transformation matrix of its parent element.

A third possibility for defining a transformation is to reference a data element through the transform attribute instead of a transform element. This data element may either contain a single float4x4 element with name transform or use a compute operator to generate the transformation matrix.NOTEIn cases where both a CSS transform and a transform attribute are given the CSS transform will take precedence.

The following example shows four different ways of defining the same transformation on a group element.EXAMPLE 12

<!-- Using a CSS3 transform -->
<group style="transform: translate3d(0px, 0px, 10px)"></group>

<!-- Using a transform element -->
<transform id="myTransformElement" translation="0 0 10"></transform>
<group transform="#myTransformElement"></group>

<!-- Giving the transformation matrix directly -->
<data id="myDataTransform">
  <float4x4 name="transform">1 0 0 0 0 1 0 0 0 0 1 10 0 0 0 1</float4x4>
</data>
<group transform="#myDataTransform"></group>

<!-- Computing the transformation matrix with an Xflow operator -->
<data id="myComputeTransform" compute="transform = xflow.createTransform(translation)">
  <float3 name="translation">0 0 10</float3>
</data>
<group transform="#myComputeTransform"></group>

4.1.2 Data elements

assetdatadatadataflowmeshmaterialmodellight

Data elements are the non-leaf nodes of an Xflow graph. They may contain any combination of data elements and value elements. They may also reference other data elements through the src attribute using a standard HTML URI.

The ultimate function of a graph of data elements is to provide data to a “sink”. Some data sinks in XML3D include the mesh element, the material element and the projection attribute of the view element.

The ability to reference data elements makes it possible to share a common set of data between many different sinks. This saves memory and increases performance, as the data is also shared internally whenever possible. For example, a set of vertex positions may be shared between many instances of the same mesh using a different set of face indices each time. Internally these meshes will also share a common WebGL vertex position buffer:EXAMPLE 13

<data id="shared_positions">
  <float3 name="position"> 1.0 0.0 0.0 0.5 1.0 1.0 ... </float3>
</data>
<mesh>
  <data src="#shared_positions"></data>
  <int name="index"> 0 1 2 3 4 5 ... </int>
</mesh>
<mesh>
  <data src="#shared_positions"></data>
  <int name="index"> 3 4 5 0 1 2 ... </int>
</mesh>

If two data elements containing fields with identical names are present in an XFlow data graph then the outermost value will replace any value nested deeper within the graph. In this example the value of the color field will be 1.0 0.0 0.0 when referencing #my-data:EXAMPLE 14

<data id="my-data">
    <float3 name="color">1.0 0.0 0.0</float3> <!-- Overrides the nested color -->
    <data>
        <float3 name="color">1.0 1.0 1.0</float3>
    </data>
</data>

4.1.3 Value elements

float, float2, float3, float4, float4x4int, int4booltexture

Value elements are the leaf nodes of an Xflow graph. They may not be nested and may not contain any non-text child elements. Data should be provided as a text node containing a space-separated list of values. The tag name determines how this data is interpreted:EXAMPLE 15

<bool>1 0 0</bool>     // an array of three boolean values
<float3>1 0 0</float3> // a single three-dimensional floating point vector

The name attribute of a value element acts as an ID for the data contained in this element. It may be referenced in XFlow operators or in material shaders.

If two value elements with the same name are present inside a data element then the value appearing later in the DOM will be used. In this example the value of the color field will be 1.0 1.0 1.0 when referencing #my-data:EXAMPLE 16

<data id="my-data">
    <float3 name="color">1.0 0.0 0.0</float3>
    <float3 name="color">1.0 1.0 1.0</float3> <!-- Overrides the previous color -->
</data>

4.1.4 Pickable elements

meshmodel

Pickable elements are the drawable geometries of a scene. These elements can trigger mouse events like most visible HTML elements do, we call this picking. The list of available mouse event listeners is described in the Events section.

Mouse events will also bubble up through the scene hierarchy, which allows mouse event listeners to also be placed on the group element and the xml3d element. Listeners on these elements can only be triggered by a pickable element (model or mesh) in the element’s subtree.

When the user interacts with an object on the canvas (eg. clicks on it) the relevant MouseEvent will be generated on the mesh element or model element and then bubbled up the scene hierarchy. This will continue until the event reaches the xml3d element, or until event.stopPropagation() is called.

In the following example, when clicking on the object in the scene corresponding to this mesh element both listeners will be triggered in the appropriate order:EXAMPLE 17

<group onmousedown="myMouseDownListener(event)">
    <group>
        <mesh onmouseup="myMouseUpListener(event)" type="triangles"></mesh>
    </group>
</group>

NOTEObject visibility may affect whether or not mouse event listeners are triggered. See the Style section on visibility for more information.

4.2 The root element

4.2.1 The xml3d element

The xml3d element is the root element of an XML3D scene. It will create a canvas element at this position in the DOM to display the rendered scene. CSS styles and event listeners from the XML3D element are also applied to the canvas allowing for mouse interaction with the XML3D scene.

A page may have more than one XML3D element, in this case multiple canvases with their own WebGL contexts will be created. It is also possible to share date elements between scenes in which case XML3D will automatically create the necessary WebGL buffers for each context.

Because XML3D uses HTML ids to reference elements it is important to avoid duplicate ids. For example, a duplicate id for a data element that appears in two different XML3D scenes on the same page may lead to undefined behavior.

The view attribute, if present, must contain a selector that returns a view element as first matching element using querySelector on the xml3d element. The selection mechanism is described in the Selectors API [selectors-api2]. If the attribute is not present, or if the selector does not return a valid view element, the selector view is used instead, returning the first view in the scene. If no view is available, the system must append a view element as first child of the xml3d element.

The background color of the 3D canvas may be set through CSS using the background-color property on the xml3d element.

interface XML3DXml3dElement : HTMLElement {
                    attribute unsigned long width;
                    attribute unsigned long height;
    readonly        attribute boolean       complete;
                    attribute DOMString     view;
                    attribute Function      onframedrawn;
                    attribute Function      onload;
    HTMLElement? getElementByPoint (unsigned long x, unsigned long y, optional Vec3 hitPoint, optional Vec3 hitNormal);
    HTMLElement? getElementByRay (Ray ray, optional Vec3 hitPoint, optional Vec3 hitNormal);
    Box          getLocalBoundingBox ();
    Box          getWorldBoundingBox ();
    Ray          generateRay (unsigned long x, unsigned long y);
};
4.2.1.1 Attributes

complete of type boolean, readonlyReturns true if all resources of the root element have been completely downloaded and rendered; otherwise, returns false.height of type unsigned longVertical dimensiononframedrawn of type FunctionEvent listener to be executed whenever a new frame has been drawn. Is passed a FrameDrawn event.onload of type FunctionEvent listener to be executed when the xml3d element has finished loading. This event is fired once after initial loading of the scene is complete, including all external resources such as textures or external models. It will not be fired again if subsequent changes to the scene cause more resources to be loaded. When adding a listener for this event through JavaScript it may be necessary to check the status of the complete attribute beforehand, as the load event will not be resent if it was already dispatched before the listener was registered.NOTEThis event may be preceeded by one or more FrameDrawn events as XML3D continues to redraw the scene even as external resources are being loaded.view of type DOMStringThe view IDL attribute must reflect the respective content attribute of the same name.width of type unsigned longHorizontal dimension

4.2.1.2 Methods

generateRayUses WebGL unProject to generate a new ray from the given x,y window coordinates.

ParameterTypeNullableOptionalDescription
xunsigned longThe x coordinate relative to the top left of the browser window
yunsigned longThe y coordinate relative to the top left of the browser window

Return type: RaygetElementByPointReturns the element at the point with window coordinates x,y if there is a scene element; otherwise, returns null.

ParameterTypeNullableOptionalDescription
xunsigned longThe x coordinate relative to the top left of the browser window
yunsigned longThe y coordinate relative to the top left of the browser window
hitPointVec3If provided this vector will be filled with the position of the hit point in world space.
hitNormalVec3If provided this vector will be filled with the normal of the hit point in world space.

Return type: HTMLElement, nullablegetElementByRayReturns the first element that intersects with the ray if the ray intersects with a scene element; otherwise, returns null. Unlike getElementByPoint this function is not dependent on the currently active view. This makes it useful for, for example, finding the surface normal of an object at a particular point regardless of whether or not that object is currently visible to the active camera.

ParameterTypeNullableOptionalDescription
rayRay
hitPointVec3If provided this vector will be filled with the position of the hit point in world space.
hitNormalVec3If provided this vector will be filled with the normal of the hit point in world space.

Return type: HTMLElement, nullablegetLocalBoundingBoxReturns the bounding box of the scene. Because the XML3D element is the root element the bounding box will be in world space by definition.No parameters.Return type: BoxgetWorldBoundingBoxReturns the bounding box of the scene in world space.No parameters.Return type: Box

4.3 Scene elements

4.3.1 The group element

Categories:Transformable element

The group element is a non-leaf node in an XML3D scene tree. They can be used to build transformation hierarchies and to group renderable objects together. Groups can be nested, but because they are not Xflow elements they may not hold any data elements and cannot be referenced by other group elements. This means that unlike data elements, groups build a tree structure rather than a graph. Each group may only have a single parent.

Group elements inherit properties such as transformations, visibility and materials from their parent group.EXAMPLE 18

<group style="display: none;" material="#blueMaterial">
    <group style="display: block;">
        <!-- This mesh will not be visible but will inherit #blueMaterial -->
        <mesh type="triangles"></mesh>
    </group>
</group>
interface XML3DGroupElement : HTMLElement {
                    attribute DOMString transform;
                    attribute DOMString material;
    Mat4 getWorldMatrix ();
    Mat4 getLocalMatrix ();
    Box  getLocalBoundingBox ();
    Box  getWorldBoundingBox ();
};
4.3.1.1 Attributes

material of type DOMStringAccepts a URI fragment referencing a material element. Material is inherited from the parent group if this attribute is not present.transform of type DOMStringAccepts a URI fragment referencing a transform element. Alternatively a transformation may be defined with CSS through the style attribute.

4.3.1.2 Methods

getLocalBoundingBoxReturns the bounding box of this group in its local transformation space. This is calculated as the smallest volume containing the bounding boxes of all child elements.No parameters.Return type: BoxgetLocalMatrixReturns the local transformation matrix of this group element (does not include parent transformations).No parameters.Return type: Mat4getWorldBoundingBoxReturns the bounding box of this group in world space. This is calculated as the smallest volume containing the bounding boxes of all child elements.No parameters.Return type: BoxgetWorldMatrixReturns the transformation matrix of this group element in world space (includes parent transformations).No parameters.Return type: Mat4

4.3.2 The view element

Categories:Data elementTransformable element

The view element defines a viewport into the scene. The view (or camera) model that defines the projection of the scene to the XML3D canvas is defined by the model attribute. The view uses the generic data model to define the parameters of the referenced view model (aka intrinsic camera parameters). The coordinate system of the view element defines the coordinate system for the view (aka extrinsic camera parameters).

The view model used by the view is defined by the view model attribute. If the model attribute is present, it must contain a valid non-empty URN referencing one of the predefined view models. If the URN is empty or references an unknown view model, or if the model attribute is not present, the perspective view model is used.NOTECurrently, XML3D supports predefined view models only. However, similar to materials, we envisage programmable view models for future versions of XML3D.

This example illustrates the use of a view based on the predefined perspective view model using its default parameters:EXAMPLE 19

<view></view>

It defines a perspective frustum that conforms to the right-handed rules and points along the negative z-axis. In the following example, the default direction is altered using CSS Transformations. Additionally, the perspective frustum has a different vertical field-of-view:EXAMPLE 20

<view style="transform: rotate3d(0, 1, 0, 180deg);">
  <float name="fovVertical">0.5</float>
</view>

This example illustrates the use of a projective view model using a custom projection matrix:EXAMPLE 21

<view model="urn:xml3d:view:projective">
  <float4x4 name="projectionMatrix">1.4485281705856323 0 0 0 0 2.4142134189605713 0 0 0 0 -9.523809432983398 -1 0 0 -94.18809509277344 0</float4x4>
</view>

NOTEXML3D does not provide camera navigation through the scene by e.g. binding mouse events to changes to the active view element. Instead, this is left to the application (or some navigation library), because the navigation is part of the interaction with the scene and is typically very application-specific.

interface XML3DViewElement : HTMLElement {
                    attribute DOMString model;
    Mat4 getWorldMatrix ();
    Mat4 getLocalMatrix ();
    Mat4 getViewMatrix ();
    Mat4 getProjectionMatrix ();
};
4.3.2.1 Attributes

model of type DOMStringThe model IDL attribute must reflect the model content attribute.

4.3.2.2 Methods

getLocalMatrixReturns the local transformation matrix of this view element (does not include parent transformations).No parameters.Return type: Mat4getProjectionMatrixReturns the projection matrix for the frustum defined by this view.No parameters.Return type: Mat4getViewMatrixReturns the view matrix of the camera (the matrix used to transform from world to view space).No parameters.Return type: Mat4getWorldMatrixReturns the transformation matrix of this view element in world space.No parameters.Return type: Mat4

4.3.3 The light element

Categories:Data elementTransformable element

The light element defines a light source in the scene that emits light based on the light model defined by the model attribute. The light uses the generic data model to define the parameters of the referenced light model. The coordinate system of the light element defines the base coordinate system for the light. However, the final position and direction of the light source can altered by specific parameters of the light model.

A light affects all geometry elements within the same scene, i.e. with the same xml3d element as ancestor.

The light model used by the light is defined by the model attribute. If the model attribute is present, it must contain a valid non-empty URN referencing one of the predefined light models. If the URN is empty or references an unknown light model, or if the model attribute is not present, the directional light model is used.NOTECurrently, XML3D supports predefined light models only. However, similar to materials, we envisage programmable light models for future versions of XML3D.

This example illustrates the use of a single light source based on the predefined directional light model using its default parameters:EXAMPLE 22

<light></light>

Since no direction for the light source is specified for the light source, the default direction 0 0 -1 (along the negative z axis) is transformed by the global coordinate system of the light element.

This example illustrates the use of a single light source based on the predefined point light model:EXAMPLE 23

<light model="urn:xml3d:light:point">
  <float3 name="intensity">0.8 0.8 1</float3>
</light>
interface XML3DLightElement : XML3DDataElement {
                    attribute DOMString model;
    Mat4 getWorldMatrix ();
    Mat4 getLocalMatrix ();
};
4.3.3.1 Attributes

model of type DOMStringThe model IDL attribute must reflect the model content attribute.

4.3.3.2 Methods

getLocalMatrixReturns the local transformation matrix of this light element (does not include parent transformations).No parameters.Return type: Mat4getWorldMatrixReturns the transformation matrix of this light element in world space.No parameters.Return type: Mat4

4.3.4 The mesh element

Categories:Data elementPickable elementTransformable element

The mesh element represents a single renderable object in the scene. To be drawn correctly a mesh must either inherit a material from a parent element or assign its own through the material attribute. The type attribute determines how the mesh data is interpreted to be drawn and must be one of the predefined primitive types.NOTEA mesh can only be assigned a single material. Models that contain multiple materials will have to be broken down into separate meshes.

The simplest way to define a mesh is to include its data directly in the mesh element:EXAMPLE 24

<mesh type="triangles" material="#myMaterial">
    <int name="index">0 1 2 ... </int>
    <float3 name="position">1.0 0.0 0.0 ... </float3>
    <float3 name="normal">0.0 1.0 0.0 ... </float3>
</mesh>

However it’s usually a good idea to reference this data instead, either in the same document or in an external document as shown below:EXAMPLE 25

<!-- myDataElement is the id of a data element containing the mesh data -->
<mesh src="myMesh.xml#myDataElement" type="triangles" material="#myMaterial"></mesh>

Each entry in the mesh data is passed on to the material shader in the form of a vertex attribute. A mesh must always supply at least a position entry, any others are optional but may be required by a material in order to be rendered properly (eg. normal in conjunction with the predefined phong material).

As with any data element, a mesh may override certain entries or supply its own. This applies even to material entries:EXAMPLE 26

<!-- This mesh will be rendered with a blue diffuseColor even though the material specifies a red one -->
<mesh src="myMesh.xml#myDataElement" type="triangles" material="#myRedMaterial">
    <float3 name="diffuseColor">0.0 0.0 1.0</float3>
</mesh>

The mesh type can also be set using the generic attribute system, setting the mesh type to derivedEXAMPLE 27

<!-- The mesh data will be interpreted as lines -->
<mesh src="teapot.json" type="derived">
    <string name="type">lines</string>
</mesh>

Different ways of assigning transformations to meshes are described in the transformable elements section.

interface XML3DMeshElement : HTMLElement {
    readonly        attribute boolean   complete;
                    attribute DOMString type;
                    attribute DOMString src;
                    attribute DOMString material;
                    attribute DOMString transform;
    XML3DDataResult getResult (Array filter);
    Array           getOutputNames ();
    Mat4            getWorldMatrix ();
    Mat4            getLocalMatrix ();
    Box             getLocalBoundingBox ();
    Box             getWorldBoundingBox ();
};
4.3.4.1 Attributes

complete of type boolean, readonlyReturns true if all external resources required by this mesh have been loaded, false otherwise.material of type DOMStringURI reference to a material element.src of type DOMStringURI reference to another data element containing the data for this mesh. Can be a reference to an external document.transform of type DOMStringURI reference to a transform element.type of type DOMStringThe primitive type that this mesh uses. Supported values are trianglestristripspointslineslinestrips and derived.

4.3.4.2 Methods

getLocalBoundingBoxReturns the bounding box of this mesh in object space, without any transformations applied.No parameters.Return type: BoxgetLocalMatrixReturns the local transformation matrix of this mesh element (does not include parent transformations).No parameters.Return type: Mat4getOutputNamesReturns the names of the data fields available to this mesh node.No parameters.Return type: ArraygetResultReturns a XML3DDataResult object containing the data for the fields requested by the given filter, eg. ["position", "index", "normal"]. This is useful for accessing the mesh data directly through JavaScript.

ParameterTypeNullableOptionalDescription
filterArray

Return type: XML3DDataResultgetWorldBoundingBoxReturns the bounding box of this mesh in world space.No parameters.Return type: BoxgetWorldMatrixReturns the transformation matrix of this mesh element in world space (includes parent transformations).No parameters.Return type: Mat4

4.3.5 The model element

Categories:Data elementPickable elementTransformable element

The model element is used to instantiate an asset. This is useful for rendering complex objects with many individual meshes or materials. Not only is it easier to insert a single model element into the DOM, it’s also much more efficient.

When referencing an external file the URI must contain the id of the asset element to be instantiated:EXAMPLE 28

<model src="myExternalAsset.xml#myAsset"></model>

A model may override data inside the Asset by specifying the assetmesh element or assetdata element that should be overwritten. For example, to change the material of a mesh inside the Asset named “hat” we would define our model tag as follows:EXAMPLE 29

<model src="myExternalAsset.xml#myAsset">
   <assetmesh name="hat" material="#aNewMaterialDefinedLocally"></assetmesh>
</model>

NOTEMaterials inside the asset will always override those assigned to the model. To assign a material from outside the asset either remove all inner materials entirely or override each assetmesh individually as shown above.This behavior is especially useful in driving animations inside the instantiated asset. Each instance of the model element can have its own animation state, even if all reference the same asset. Typically this is done by exposing the animation key through its own assetdata, which is then overwritten in the model:EXAMPLE 30

<!-- Assuming "myAsset" contains an assetdata element with name "animation" -->
<model src="myExternalAsset.xml#myAsset">
   <assetdata name="animation">
    <float id="animation_key" name="key">1.0</float>
  </assetdata>
</model>

By changing the value of the animation_key through JavaScript we can now control the model’s animation state.

interface XML3DModelElement : HTMLElement {
                    attribute DOMString src;
                    attribute DOMString material;
                    attribute DOMString transform;
    Mat4 getWorldMatrix ();
    Mat4 getLocalMatrix ();
    Box  getLocalBoundingBox ();
    Box  getWorldBoundingBox ();
};
4.3.5.1 Attributes

material of type DOMStringURI reference to a material element. This material will only be used for objects that do not define their own material inside the asset.src of type DOMStringURI reference to an asset element that this model should instantiate.transform of type DOMStringURI reference to a transform element.

4.3.5.2 Methods

getLocalBoundingBoxReturns the bounding box of this model without any parent transformations applied.No parameters.Return type: BoxgetLocalMatrixReturns the local transformation matrix of this model element (does not include parent transformations).No parameters.Return type: Mat4getWorldBoundingBoxReturns the bounding box of this model in world space, including parent transformations.No parameters.Return type: BoxgetWorldMatrixReturns the transformation matrix of this model in world space, including parent transformations.No parameters.Return type: Mat4

4.4 Definition Areas

4.4.1 The defs element

The defs element is simply an organizational tool to separate the scene tree from elements that are not explicitly part of the scene, but may be referenced by elements that are. These implicit elements include transformmaterialdata and dataflow. Note that any of these elements may appear inside the scene tree as well, it’s just good practice to keep them in the defs section whenever possible.Ideally the only elements that should appear outside the defs section are groupmeshmodelview and light. Note that these elements will be ignored if they are inside the defs section, since it is not considered part of the scene tree. data elements usually belong in the defs section but may also be part of the scene tree if contained by a mesh element.EXAMPLE 31

<xml3d>
  <defs>
     <transform id="myTransform" rotation="0 1 0 0.75">
     <data id="myMeshData" >
        <float3 name="position">1.0 0.0 0.0 ...</float3>
     </data>
  </defs>

  <group transform="#myTransform">
     <mesh src="#myMeshData" type="triangles"></mesh>
  </group>
</xml3d>

4.5 Property elements

4.5.1 The material element

Categories:Data element

A material describes the surface shading of an object. Materials are defined using the material element and then referenced by the material property on a given scene element to indicate that the given element shall be shaded using the referenced material. Multiple scene elements can share a material. The material uses the generic data model to define the parameters of the referenced material model. Note that graphics elements can override the parameters defined in the material element. Hence, the parameters in the material element can be considered default values.

The material model used by the material is defined by the material model attribute. The model attribute must be present, and must contain a valid non-empty URL referencing either a predefined material model or a scripted material model, e.g. using shade.js or a custom shader.

Here is a simple example for a material based on the predefined phong material model:EXAMPLE 32

<material model="urn:xml3d:material:phong">
  <float3 name="diffuseColor">0 0 1</float3>
  <texture name="diffuseTexture">
    <img src="../stone.jpg"/>
  </texture>
</material>
interface XML3DMaterialElement : XML3DDataElement {
                    attribute DOMString model;
};
4.5.1.1 Attributes

model of type DOMStringThe model IDL attribute must reflect the model content attribute.

4.5.2 The transform element

In addition to CSS3 transformations applied through the style attribute, the transform element provides another way to define transformations for transformable elements. The various transformation components are combined into a transformation matrix which is then applied to the element or elements referencing this transform element.

Transform elements are generally placed into the defs section of a scene, however it’s possible to define them anywhere inside the xml3d element. No matter where a transform element is defined it must be referenced by its id from the transform attribute of a transformable element to be used. A single transform element can be referenced by multiple other elements.

interface XML3DTransformElement : HTMLElement {
                    attribute AxisAngle scaleorientation;
                    attribute AxisAngle rotation;
                    attribute Vec3      translation;
                    attribute Vec3      scale;
                    attribute Vec3      center;
};
4.5.2.1 Attributes

center of type Vec3The center point of this transformation.rotation of type AxisAngleThe rotation component of this transformation. In axis-angle form [x,y,z,a] with the angle expressed in radians.scale of type Vec3The scale component of this transformation. Note: non-uniform scaling and negative values are allowed.scaleorientation of type AxisAngleThe orientation on which to apply the scaling factor supplied by the IDL attribute scale. In axis-angle form [x,y,z,a] with the angle expressed in radians.translation of type Vec3The translation component of this transformation.

4.6 Assets

The XML3D asset format is designed to encompass everything needed to define a complex model consisting of one or more meshes and materials. Conceptually an asset is designed to be static and self-enclosed. When referenced from a model element an asset behaves as a single object in the scene, even though it may be composed of many different meshes. Interaction through mouse event listeners, for example, can only be done on the model level and not on the level of individual meshes comprising the asset.

As with other Xflow elements most parts of the asset (eg. materials, mesh data, transformations) can be overridden inside the model element. However it’s important to note that adding or removing overrides for assets has a very high performance penalty. Best practice is to define all the necessary overrides during construction of the model element and then stick to changing the values of those overrides, which carries no performance penalty. See the XML3D Wiki for more information on how to override asset data.

It’s important to note that unlike a group and mesh hierarchy, assets are always flattened. An asset always consists of an asset element with a list of assetmesh elements as children, which cannot be nested. Asset elements themselves, on the other hand, can be nested.

4.6.1 The asset element

The asset element defines an asset that can be instantiated through a model element or extended by another asset. The asset element also defines a scope for the name and includes attributes of any child assetdata and assetmesh elements.

Asset elements may be nested but their id must be unique within the document.

interface XML3DAssetElement : HTMLElement {
                    attribute DOMString src;
};
4.6.1.1 Attributes

src of type DOMStringA URI to another asset that this one should extend.

4.6.2 The assetdata element

Categories:Data element

Similar to the data element an assetdata element is used to define and share generic data within an asset. Unlike data elements, assetdata elements may not be nested and are named by and referenced through a name attribute rather than an id. An assetdata element may contain normal data elements as children.

Assetdata names must be unique within an asset element.

interface XML3DAssetdataElement : HTMLElement {
                    attribute DOMString name;
                    attribute DOMString includes;
};
4.6.2.1 Attributes

includes of type DOMStringA space separated list of names corresponding to other assetdata elements that this one should extend.name of type DOMStringThe name of this assetdata element. The name is scoped to the surrounding asset element and may not be duplicated within this scope.

4.6.3 The assetmesh element

Categories:Data elementTransformable element

An assetmesh element represents a single drawable mesh in the asset and works similar to the mesh element. Unlike the mesh element assetmeshes are identified by their name attribute, which may not be duplicated within the same asset element.

As with the mesh element a transformation may be supplied either through the transform attribute or through a CSS3 transform.EXAMPLE 33

<assetmesh name="exampleMesh" style="transform: translate3d(0px, 0px, 10px)" type="triangles" material="#exampleMaterial">
  <data src="#myMeshData"></data>
  <assetdata src="#someMoreMeshData"></assetdata>
</assetmesh>
interface XML3DAssetmeshElement : HTMLElement {
                    attribute DOMString name;
                    attribute DOMString includes;
                    attribute DOMString type;
                    attribute DOMString material;
                    attribute DOMString transform;
};
4.6.3.1 Attributes

includes of type DOMStringA space separated list of names corresponding to other assetmesh or assetdata elements that this one should extend.material of type DOMStringURI reference to a material element.name of type DOMStringThe name of this assetmesh element. The name is scoped to the surrounding asset element and may not be duplicated within this scope.transform of type DOMStringURI reference to a transform element.type of type DOMStringThe primitive type of this assetmesh. Supported values are trianglestristripspointslineslinestrips, and derived

4.7 Data and dataflow elements

4.7.1 The data element

Categories:Data element

data element is a non-leaf node in an Xflow graph. They act primarily as containers for data but may also modify that data through compute operators and filters. When data elements are nested the data from all child elements is merged, in this sense the parent data element acts as a data aggregator. In the case of two data fields with the same name the data element further down the list in the DOM will have priority. For example:EXAMPLE 34

<data> <!-- At this level "color" will be "0.0 1.0 0.0" -->
  <data>
    <float3 name="color">1.0 0.0 0.0</float3>
  </data>
  <data>
    <float3 name="color">0.0 1.0 0.0</float3>
  </data>
</data>

Data elements may also reference other data elements. This can be used to share a common dataset between objects, overwriting certain fields on a per-object basis as required. See the data elements section for an example.

One important use for data elements is to dynamically change or generate data, for example to drive an animation or generate a ground mesh from a height map. This can be accomplished with a combination of compute operators and data overrides. The following is an example of a simple compute operator that will add the provided offset to all vertex positions of a mesh:EXAMPLE 35

<mesh>
   <data compute="position = xflow.add(position, offset)">
     <float3 name="offset">0.5 0.5 0.5 ... </float3>
     <data id="originalData">
        <float3 name="position">1.0 0.0 0.0 ... </float3>
     </data>
   </data>
</mesh>

When using a compute operator with a data element all input arguments must be available to the data element that invokes the operator. In this example the “position” field of the mesh will contain the offset position data, while the data element with id originalData will contain the original positions. If this data element were referenced from another mesh it would also return the original positions:EXAMPLE 36

<mesh>
    <!-- "positions" contains the original data 1.0 0.0 0.0 ... -->
   <data src="#originalData"></data>
</mesh>

Xflow is designed as a reactive framework, meaning operators will only be recomputed if input data has changed and a sink element has requested the output data (eg. during a draw call in a subsequent frame).

interface XML3DDataElement : HTMLElement {
    readonly        attribute boolean   complete;
                    attribute DOMString compute;
                    attribute DOMString filter;
                    attribute DOMString src;
    XML3DDataResult getResult (Array filter);
    Array           getOutputNames ();
};
4.7.1.1 Attributes

complete of type boolean, readonlyReturns true if all external resources required by this data have been loaded, false otherwise.compute of type DOMStringA Javascript-like statement that can invoke an Xflow compute operator on a set of input data. See the compute operator section for more information.filter of type DOMStringMay contain a filter (keeprename or remove) to adjust the data that is provided by this data element. See the Wiki page How to use Xflow for more information.src of type DOMStringAccepts an HTML ID reference to another data element. The other element’s data will be included as an implicit first child of this data node. Note that in cases of duplicate data any child data or value elements will override the data found in the src node.

4.7.1.2 Methods

getOutputNamesReturns the names of the data fields provided by this data element.No parameters.Return type: ArraygetResultReturns a XML3DDataResult object containing the data for the fields requested by the given filter, eg. ["position", "index", "normal"]. This is useful for accessing the data directly through JavaScript.

ParameterTypeNullableOptionalDescription
filterArray

Return type: XML3DDataResult

4.7.2 The dataflow element

Categories:Data element

The dataflow element can be thought of as a template for a compute operation consisting of one or more Xflow operators executed in sequence. This template can be defined once and then reused many times in the scene, applying the operations to a different set of input data each time. Consider the following dataflow example which computes skeletal animation for a mesh:EXAMPLE 37

<dataflow id="skinning" out="position, normal, boneXform">
  <float3 param="true" name="position" ></float3>
  <float3 param="true" name="normal" ></float3>
  <int4   param="true" name="boneIdx" ></int4>
  <float4 param="true" name="boneWeight" ></float4>

  <int    param="true" name="boneParent" ></int>
  <float3 param="true" name="bindTranslation" ></float3>
  <float4 param="true" name="bindRotation" ></float4>

  <float3 param="true" name="translation" ></float3>
  <float4 param="true" name="rotation" ></float4>

  <float  param="true" name="key" >0</float>
  <compute>
    bindPose = xflow.createTransformInv({translation: bindTranslation, rotation: bindRotation});
    bindPose = xflow.forwardKinematicsInv(boneParent, bindPose);

    rot = xflow.slerpSeq(rotation, key);
    trans = xflow.lerpSeq(translation, key);
    pose = xflow.createTransform({translation: trans, rotation: rot});
    pose = xflow.forwardKinematics(boneParent, pose);

    boneXform = xflow.mul(bindPose, pose);

    normal = xflow.skinDirection(normal, boneIdx, boneWeight, boneXform);
    position = xflow.skinPosition(position, boneIdx, boneWeight, boneXform);
  </compute>
</dataflow>

By defining the param attribute of the various value elements we instruct Xflow to expect them as inputs provided by any element that references this dataflow. The compute element is only found inside dataflows and can be used to define a sequence of Xflow operators that should be applied to the input data. The list of operators will be computed from top to bottom and any new data fields they create (ie. bindPose in this example) can be used as input for operators further down the list.

To apply this dataflow to a set of data another data element may reference it in its own compute block or attribute:EXAMPLE 38

<data compute="position, normal = dataflow['#skinning']">
  <!-- We assume this file contains all the input data that the 'skinning' dataflow expects -->
  <data src="myMeshData.xml"></data>
  <float id="myAnimationKey" name="key">1.0<float>
</data>

Conceptually this data element will ‘call’ the dataflow element with the input ‘arguments’ from the file myMeshData.xml and then assign the output of the dataflow to the position and normal fields, effectively overriding the ones found in myMeshData.xml. Note the URI fragment inside the dataflow[] construct. This may also reference an external document containing the dataflow.

By declaring the key value separately we can control the animation state of this model. Note also that the key is declared after the reference to myMeshData.xml to ensure that it overrides the key value found in the xml file.

interface XML3DDataflowElement : HTMLElement {
                    attribute DOMString out;
    readonly        attribute boolean   complete;
    XML3DDataResult getResult (Array filter);
    Array           getOutputNames ();
};
4.7.2.1 Attributes

complete of type boolean, readonlyReturns true if all external resources required by this dataflow have been loaded, false otherwise.out of type DOMStringA comma-separated list of fields that this dataflow provides as output. If this attribute is not present then all computed fields will be provided as output.

4.7.2.2 Methods

getOutputNamesReturns the names of the data fields provided by this data element.No parameters.Return type: ArraygetResultReturns a XML3DDataResult object containing the data for the fields requested by the given filter, eg. ["position", "index", "normal"]. This is useful for accessing the data directly through JavaScript.

ParameterTypeNullableOptionalDescription
filterArray

Return type: XML3DDataResult

4.7.3 The floatfloat2float3float4, and float4x4 elements

Categories:Value element

The float* elements hold a space separated list of floating point values. The tag name determines how this data is interpreted, ie. a float2 element will interpret the data as an array of 2D vectors while a float4x4 element will interpret it as an array of 4×4 matrices.

interface XML3DFloatValueElement : HTMLElement {
                    attribute DOMString name;
                    attribute boolean   param;
                    attribute float     key;
    void setScriptValue (Float32Array value);
};
4.7.3.1 Attributes

key of type floatA keyframe value to assist in defining animated values. A script may, for example, interpolate the data between successive keys.name of type DOMStringThe name of the value element. A good name should be a semantic description of the data that this element holds.param of type booleanMarks this value as one to be supplied by a different data element. Value elements with the param attribute are the only value elements that may be empty, all others must contain data. See the dataflow element for example usage.

4.7.3.2 Methods

setScriptValueA high performance setter to set the data of this value element directly through JavaScript.

ParameterTypeNullableOptionalDescription
valueFloat32Array

Return type: void

4.7.4 The int and int4 elements

Categories:Value element

The int* elements hold a space separated list of integer values. The tag name determines how this data is interpreted, ie. an int4 element will interpret the data as an array of 4-component integer vectors.

interface XML3DIntValueElement : HTMLElement {
                    attribute DOMString name;
                    attribute boolean   param;
                    attribute float     key;
    void setScriptValue (Int16Array value);
};
4.7.4.1 Attributes

key of type floatA keyframe value to assist in defining animated values. A script may, for example, interpolate the data between successive keys.name of type DOMStringThe name of the value element. A good name should be a semantic description of the data that this element holds.param of type booleanMarks this value as one to be supplied by a different data element. Value elements with the param attribute are the only value elements that may be empty, all others must contain data. See the dataflow element for example usage.

4.7.4.2 Methods

setScriptValueA high performance setter to set the data of this value element directly through JavaScript.

ParameterTypeNullableOptionalDescription
valueInt16Array

Return type: void

4.7.5 The bool element

Categories:Value element

The bool element holds a space separated list of boolean values. The values may be given in string form (true/false) or as integers (1/0).

interface XML3DBoolValueElement : HTMLElement {
                    attribute DOMString name;
                    attribute boolean   param;
                    attribute float     key;
    void setScriptValue (Int16Array value);
};
4.7.5.1 Attributes

key of type floatA keyframe value to assist in defining animated values. A script may, for example, interpolate the data between successive keys.name of type DOMStringThe name of the value element. A good name should be a semantic description of the data that this element holds.param of type booleanMarks this value as one to be supplied by a different data element. Value elements with the param attribute are the only value elements that may be empty, all others must contain data. See the dataflow element for example usage.

4.7.5.2 Methods

setScriptValueA high performance setter to set the data of this value element directly through JavaScript.

ParameterTypeNullableOptionalDescription
valueInt16Array

Return type: void

4.7.6 The string element

Categories:Value element

The string element holds a comma separated list of string values.

Currently the following string attributes may be supplied by including a string element with the matching name:

Below is an example using a custom Xflow operator to change the type attribute of a mesh element:EXAMPLE 39

<!-- The custom xflow operator will output a string field named 'type' -->
<data id="meshTypeCompute" compute="type = xflow.selectString(selector, value1, value2)">
    <string name="value1">triangles</string>
    <string name="value2">lines</string>
    <int name="selector">2</int>
</data>

<!-- In this case type will evaluate to 'lines' -->
<mesh src="#meshdata" type="derived">
  <data src="#meshTypeCompute"></data>
</mesh>
interface XML3DStringValueElement : HTMLElement {
                    attribute DOMString name;
                    attribute boolean   param;
                    attribute float     key;
    void setScriptValue (Array value);
};
4.7.6.1 Attributes

key of type floatA keyframe value to assist in defining animated values. A script may, for example, interpolate the data between successive keys.name of type DOMStringThe name of the value element. A good name should be a semantic description of the data that this element holds.param of type booleanMarks this value as one to be supplied by a different data element. Value elements with the param attribute are the only value elements that may be empty, all others must contain data. See the dataflow element for example usage.

4.7.6.2 Methods

setScriptValueA high performance setter to set the data of this value element directly through JavaScript.

ParameterTypeNullableOptionalDescription
valueArray

Return type: void

4.7.7 The texture element

Categories:Value elementContent model:One or more imgvideo, or canvas elementsThe texture element represents a texture that can be used as parameter for materials or as input for generic dataflow processing. The image data of the texture is defined by its children. The texture element’s attributes determine how samples are derived from the image.NOTE

Texture sampling attributes configure fixed-function sampling methods on the graphics hardware. Thus these attributes qualify as CSS properties. We have abstained from using CSS properties because we currently cannot define custom CSS properties.The wrap attribute controls the texture access if the provided texture coordinates are outside range [0;1]. The wrap attribute is a combined enumerated attribute. A valid wrap value is a string that matches the wrap production of the following form:

        wrap := <wrap-mode> <wrap-mode>?
        wrap-mode := repeat | clamp
      

If two wrap-mode values are given, then the first value defines the wrap mode for s coordinates and the second for t coordinates. Otherwise the wrap mode is applied in all directions. The wrap-mode values correspond to CLAMP_TO_EDGE and REPEAT in OpenGL.
The filter attribute controls the filtering of the texture, i.e. which texture pixel access function is used. The wrap attribute is a combined enumerated attribute. A valid filter value is a string that matches the filter production of the following form:

        filter := (<min-filter-mode> <mag-filter-mode>) | <mag-filter-mode>
        min-filter-mode := nearest | linear | nearest-mipmap-nearest | nearest-mipmap-linear | linear-mipmap-nearest | linear-mipmap-linear
        mag-filter-mode := nearest | linear
      

If only the mag-filter-mode is given, the specified function is used for both, minifying and magnification. Otherwise, the min-filter-mode is used for minifying and the mag-filter-mode is used for magnification. The functions specified by the filter modes correspond to those in OpenGL (NEAREST, LINEAR, NEAREST_MIPMAP_NEAREST, NEAREST_MIPMAP_LINEAR, LINEAR_MIPMAP_NEAREST, and LINEAR_MIPMAP_LINEAR). The default filter mode is “linear-mipmap-linear linear”.NOTE

xml3d.js will automatically resize textures to the nearest power-of-two dimensions when the texture wrap mode is set to “repeat” or filtermin is set to anything other than “nearest” or “linear”. See WebGL limitations for more information.Here is an example of using the wrap and filter attributes to configure the sampling of a texture:EXAMPLE 40

<texture name="diffuseTexture" wrap="repeat clamp" filter="nearest linear">
  <img src="../stone.jpg"/>
</texture>

The type attribute is an enumerated attribute with four states with three explicit keywords:The 1D keyword, which maps to the 1D stateThe 1D state means the children elements define a 1D texture each.The 2D keyword, which maps to the 2D stateThe 2D state means the children elements defines a 2D texture.The 3D keyword, which maps to the 3D stateThe 3D state means the children elements defines a 3D texture.The auto stateThe type of the texture is determined by the system based on the texture’s children elements.

The type attribute’s missing value default is the auto state.

interface XML3DTextureElement : HTMLElement {
                    attribute DOMString wrap;
                    attribute DOMString filter;
                    attribute DOMString name;
                    attribute boolean   param;
                    attribute DOMString type;
};
4.7.7.1 Attributes

filter of type DOMStringThe filter IDL attribute must reflect the respective content attribute of the same name.name of type DOMStringRequired. The name of the texture as defined by the material shader.param of type booleanIf this element appears inside a DataFlow element the param attribute will mark it as a parameter to be supplied by the Data element referencing the DataFlow.type of type DOMStringThe type IDL attribute must reflect the content attribute of the same name, limited to only known values.wrap of type DOMStringThe wrap IDL attribute must reflect the respective content attribute of the same name.

5. Predefined models

5.1 Predefined primitive types

5.1.1 Triangle

Attribute name: triangles

WebGL primitive: TRIANGLEParameters:

NameTypeDescription
indexintA list of indicies to build triangles out of.

The triangle primitive type renders faces out of sets of 3 vertices. Triangles may be constructed with or without an array of indices. If no indices are provided XML3D will construct the triangles from the array of vertex positions: the first 3 will create the first triangle, the next 3 the second and so on.EXAMPLE 41

<mesh type="triangles">
  <int name="index">0 1 2 1 3 2 ... </int>
  <float3 name="position">-1 -1 1  1 -1 1  -1 1 1  1 1 1 ... </float3>
</mesh>

5.1.2 Tristrip

Attribute name: tristrips

WebGL primitive: TRIANGLE_STRIPParameters:

NameTypeDescription
indexintA list of indicies to build tristrips out of.
vertexCountintThe number of vertices or indices to use for each tristrip segment.

The tristrip primitive type creates triangles from a list of vertex positions and (optionally) a list of segments and/or indices. Each segment begins by building a triangle out of 3 vertex positions. Each subsequent triangle in the segment is then created from the last two vertex positions and the next one in the list. Note that this creates a sequence of connected triangles.

Segments can be used to create disconnected sets of triangles by providing a list of integers with the name vertexCount. Each number in the list specifies the number of vertex positions to use for that segment. XML3D will then work through the list of vertex positions sequentially building a tristrip for each segment.EXAMPLE 42

<mesh type="tristrips">
  <int name="vertexCount">4 4 4 4 4 4</int>
  <float3 name="position">-1 -1 1  1 -1 1  -1 1 1  1 1 1 ... </float3>
</mesh>

Note that because the first triangle in a segment requires 3 vertex positions to define, a segment with vertex count 4 will create two triangles, while vertex count 5 will create 3 and so on.

5.1.3 Line

Attribute name: lines

WebGL primitive: LINESParameters:

NameTypeDescription
indexintA list of indicies to build lines out of.

Lines are drawn from pairs of vertex positions and (optionally) a list of indices.

5.1.4 Linestrip

Attribute name: linestrips

WebGL primitive: LINE_STRIPParameters:

NameTypeDescription
indexintA list of indicies to build linestrips out of.
vertexCountintThe number of vertices or indices to use for each linestrip segment.

A linestrip is drawn from a list of vertex positions and (optionally) a list of segments and/or indices. For each segment a line is drawn between the first vertex and the second, then the second and the third and so on. This creates a continuous line.EXAMPLE 43

<mesh type="linestrips">
  <int name="vertexCount">4 2</int>
  <int name="index">0 1 2 3 1 3</int>
  <float3 name="position">-1 -1 1  1 -1 1  -1 1 1  1 1 1 ... </float3>
</mesh>

The above example will create two line segments, the first using vertices 0, 1, 2, 3 and the second using vertices 1 and 3.

5.1.5 Point

Attribute name: points

WebGL primitive: POINT

Points are drawn from a list of vertex positions, which each position being drawn as a single point.NOTECurrently to change the size of the drawn points, or to draw them as textured sprites, it is necessary to define a custom material shader.

5.1.6 Derived

Attribute name: derived

The special primitive type derived delegates the evaluation of the primitive type to the generic data model. The requested parameter has the name type. The contained value needs to match one of the primitive types above.EXAMPLE 44

<mesh type="derived">
  <string name="type">triangles</string>
  ...
</mesh>

5.2 Predefined material models

5.2.1 Matte

URN: urn:xml3d:material:matteParameters:

NameTypeDefaultDescription
diffuseColorfloat31 1 1The objects RGB color
useVertexColorboolfalseif true, the vertex attribute ‘color’ is used to color the object.

Simple material that does not apply any lighting but shades the object with a single uniform color defined by the diffuseColor parameter or by the vertex attribute color, if useVertexColor is set to ”true”.

5.2.2 Diffuse

URN: urn:xml3d:material:diffuseParameters:

NameTypeDefaultDescription
diffuseColorfloat31 1 1The object’s RGB diffuse color component.
diffuseTexturetextureundefinedTexture to read the diffuse color component and opacity (alpha) from. Accessed based on texcoord per-vertex attribute. If diffuseTexture is defined, the rgb channel of the diffuseTexture gets multiplied with the current diffuseColor and the the alpha channel gets multiples with the current opacity.
emissiveColorfloat30 0 0The object’s RGB emissive color component.
emissiveTexturetextureundefinedTexture to read the emissive color component from. Accessed based on texcoord per-vertex attribute. If emissiveTexture is defined, the emissiveColor gets multiplied with the color accessed from the texture.
ambientIntensityfloat0The amount of the ‘diffuseColor’ to be added to the shading without considering lighting.
opacityfloat1The opacity of the object, with 1 being opaque and 0 being fully transparent.
useVertexColorboolfalseSetting useVertexColor to ‘true’, the vertex attribute color will be multiplied to the diffuse color component (before the diffuseTexture gets applied).

The diffuse material model describes a diffuse surfaces that reflects light equally in all directions. Additionally, the surface has an optional emissive and ambient component. This is the logic of the diffuse material model in JavaScript/shade.js pseudo code:

        function shade(env) {
          var diffuseColor = env.diffuseColor || new Vec3(1, 1, 1);
          var emissiveColor = env.emissiveColor || new Vec3(0);
          var opacity = Math.max(1, env.opacity);

          if (env.useVertexColor && env.color) {
            diffuseColor *= new Vec3(env.color);
          }

          if (env.diffuseTexture && env.diffuseTexture.sample2D) {
             var texDiffuse = env.diffuseTexture.sample2D(env.texcoord);
             diffuseColor *= texDiffuse.rgb();
             opacity *= texDiffuse.a();
          }

          if (env.emissiveTexture && env.emissiveTexture.sample2D) {
             var texEmissive = env.emissiveTexture.sample2D(env.texcoord);
             emissiveColor *= texEmissive.rgb();
          }

          return Shade.diffuse(diffuseColor, env.normal)
                      .transparent(1.0 - opacity)
                      .emissive(emissiveColor);
        }
      

5.2.3 Phong

URN: urn:xml3d:material:phongParameters:

NameTypeDefaultDescription
diffuseColorfloat31 1 1The object’s RGB diffuse color component.
diffuseTexturetextureundefinedTexture to read the diffuse color component and opacity (alpha) from. Accessed based on texcoord per-vertex attribute. If diffuseTexture is defined, the rgb channel of the diffuseTexture gets multiplied with the current diffuseColor and the the alpha channel gets multiples with the current opacity.
specularColorfloat30 0 0The object’s RGB specular color component.
specularTexturetextureundefinedTexture to read the specular color component from. Accessed based on texcoord per-vertex attribute. If specularTexture is defined, the specularColor gets multiplied with the rgb-color accessed from the texture.
shininessfloat0.5A scalar for the object’s specular exponent, to be multiplied by 128 (e.g. a value of 0.5 will give a specular exponent of 64)
emissiveColorfloat30 0 0The object’s RGB emissive color component.
emissiveTexturetextureundefinedTexture to read the emissive color component from. Accessed based on texcoord per-vertex attribute. If emissiveTexture is defined, the emissiveColor gets multiplied with the rgb-color accessed from the texture.
ambientIntensityfloat0The amount of the ‘diffuseColor’ to be added to the shading without considering lighting.
opacityfloat1The opacity of the object, with 1 being opaque and 0 being fully transparent.
useVertexColorboolfalseSetting useVertexColor to ‘true’, the vertex attribute ‘color’ will be multiplied to the diffuse color component.

The phong material model extends the diffuse material model by the specular term from the Phong reflection model. The additional parameters are specularColor, specularTexture and shininess. This is the logic of the phong material model in JavaScript/shade.js pseudo code:

        function shade(env) {
          var diffuseColor = env.diffuseColor || new Vec3(1, 1, 1);
          var specularColor = env.specularColor || new Vec3(0, 0, 0);
          var emissiveColor = env.emissiveColor || new Vec3(0);
          var opacity = Math.max(1, env.opacity);
          var shininess = env.shininess != undefined ? env.shininess : 0.5;

          if (env.useVertexColor && env.color) {
            diffuseColor *= new Vec3(env.color);
          }

          if (env.diffuseTexture && env.diffuseTexture.sample2D) {
             var texDiffuse = env.diffuseTexture.sample2D(env.texcoord);
             diffuseColor *= texDiffuse.rgb();
             opacity *= texDiffuse.a();
          }

          if (env.specularTexture && env.specularTexture.sample2D) {
             var texSpecular = env.specularTexture.sample2D(env.texcoord);
             diffuseColor *= texSpecular.rgb();
          }

          if (env.emissiveTexture && env.emissiveTexture.sample2D) {
             var texEmissive = env.emissiveTexture.sample2D(env.texcoord);
             emissiveColor *= texEmissive.rgb();
          }


          return Shade.diffuse(diffuseColor, env.normal)
                      .phong(specularColor, env.normal, shininess)
                      .transparent(1.0 - opacity)
                      .emissive(emissiveColor);
        }
      

5.3 Predefined light models

5.3.1 Point Lights

URN: urn:xml3d:light:pointParameters:

NameTypeDefaultDescription
positionfloat30 0 0The position of the point light in object space
attenuationfloat30 0 1The attenuation of the point light given as its constant, linear, e.g quadratic component.
intensityfloat31 1 1The RGB intensity of the point light.

Point light sources emit light from a single point in space with a uniform distribution in all directions, i.e. omnidirectional. The position of the point light is defined by its position attribute and affected by the transformation of the light element that defines the occurrence of the point light. The orientation of the light element is not influencing the light.

5.3.2 Directional Lights

URN: urn:xml3d:light:directionalParameters:

NameTypeDefaultDescription
directionfloat30 0 -1The direction of the light in object space.
intensityfloat31 1 1The RGB intensity of the point light.

Directional light sources, also known as distant light sources, emit light along parallel rays from an infinite distance away. The direction the light sources emits from is defined by its direction attribute and affected by the transformation of the light element that defines the occurrence of the distant light. The position of the light element is not taken into account.

5.3.3 Spot Lights

URN: urn:xml3d:light:spotParameters:

NameTypeDefaultDescription
positionfloat30 0 0The position of the point light in object space
directionfloat30 0 -1The direction of the light in object space.
intensityfloat31 1 1The RGB intensity of the directional light.
attenuationfloat30 0 1The attenuation of the point light given as its constant, linear, e.g quadratic component.
cutoffAnglefloatMath.PI/4Spot angle in radians. Controls the size of the outer cone of a spot light, i.e. the circular area a spot light covers.
softnessfloat0Softness of the spot light in the range [0;1].

Spot light source are a variation of point lights: Instead of emitting light omnidirectional, they emit light from their position in a cone of direction. The cutoffAngle attribute defines the size of the cone. Objects outside the cone defined by the cutoffAngle are not lit by the light source. The softness attribute defines the percentage of the cone in which the illumination ramps down from full to no illumination, i.e. a softness of 0 specifies a hard transition between full to no illumination and a softness of 1.0 a linear transition along the radius of the cone.

5.4 Predefined view models

This section describes the currently available predefined view models.

5.4.1 Perspective

URN: urn:xml3d:view:perspectiveParameters:

NameTypeDefaultDescription
fovVerticalfloatMath.PI / 4The vertical field of view of the view frustum in radians
fovHorizontalfloatThe horizontal field of view of the view frustum in radians
nearfloatThe distance of the near clipping plane (unitless)
farfloatThe distance of the far clipping plane (unitless)

The perspective view model defines a perspective view frustum based on the near and far planes and on a vertical or horizontal opening angle. A small field of view roughly corresponds to a telephoto lens; a large field of view roughly corresponds to a wide-angle lens. If fovHorizontal is given, the frustum is defined using this horizontal angle, otherwise fovVertical is used. If the far or the near clipping place is not defined, the system will try to compute a useful value automatically based on the scene’s dimension.

5.4.2 Projective

URN: urn:xml3d:view:projectiveParameters:

NameTypeDefaultDescription
projectionMatrixfloat4x4The frustum described as projection matrix

The projective view model defines a projective view frustum based on a projection matrix. This view model is typically used, if the intrisic camera parameters are computed, e.g. from a webcam image using computer vision algorithms.

6. Custom materials

XML3D provides an interface to define custom materials in addition to the predefined material models. Such materials must first be registered with XML3D:EXAMPLE 45

XML3D.materials.register("my-material", { ...material definition... });

and may then be referenced through the model attribute of a material element:EXAMPLE 46

<material model="urn:xml3d:materials:my-material"></material>

The material definition must provide vertex and fragment shader code in the form of a string as well as definitions and default values for all uniform and sampler variables:EXAMPLE 47

XML3D.materials.register("my-material", {
    vertex : "...vertex shader code...",
    fragment : "...fragment shader code...",

    //All uniform variables that appear in either shader block, with default values
    uniforms : {
        exampleFloat : 0.5,
        exampleVec3  : [1, 1, 1]
    },

    //All textures that appear in either shader block
    samplers : {
        exampleTexture : null
    },

    //All vertex attributes that appear in the vertex shader
    attributes : {
        position : {required : true},
        normal : null //Synonymous with {required : false}
        exampleVertexAttribute : {required : false},
    },

    //Optional function to mark this material as requiring alpha blending
    hasTransparency : function(params) {
        return params.opacity && params.opacity.getValue()[0] < 1;
    },

    //Optional function to add compiler directives to shaders based on scene parameters (eg. the number of lights)
    addDirectives : function(directives, lights, params) {
        directives.push("HAS_EXAMPLETEXTURE " + ('exampleTexture' in params ? "1" : "0"));
    }
});

As with the predefined material models the generic data model can be used to set material parameters like uniform variables and textures for custom materials:EXAMPLE 48

<material model="urn:xml3d:material:my-material">
    <float3 name="exampleVec3">0 1 0</float3>
    <texture name="exampleTexture">
        <img src="textures/my-example-texture.png"/>
    </texture>
</material>

Custom materials may also be defined through shade.js which is generally easier to use and is able to generate cross platform materials that may be used outside of XML3D as well.NOTEBe careful with materials that modify the vertex positions of a mesh. These objects will not be pickable and may have incorrect bounding boxes, which can lead to incorrect clipping planes and frustum culling in the camera. If your material falls into this category you should always provide a reasonable bounding box for the object manually:EXAMPLE 49

<mesh src="myMesh.xml" material="#my-material">
    <float3 name="boundingBox">-10 -10 -10 5 5 5</float3> <!-- min max points of the bounding box -->
</mesh>

7. Global options

XML3D provides a set of global options through the XML3D.options interface. These options are shared between all XML3D elements on a page.

interface options {
    string getValue (string key);
    void   setValue (string key, string value);
    Array  getKeys ();
    void   addObserver (string key, function observer);
    void   removeObserver (function observer);
    void   resetValue (string key);
    void   setOptionsFromQuery ();
};

7.1 Methods

addObserverAdds a change observer to the option with the given key. Supports the ‘*’ wildcard to observe all options.

ParameterTypeNullableOptionalDescription
keystring
observerfunction

Return type: voidgetKeysReturns an array of all available option keys.No parameters.Return type: ArraygetValueReturns the current value of the option with the matching key.

ParameterTypeNullableOptionalDescription
keystring

Return type: stringremoveObserverRemoves the given change observer from all keys.

ParameterTypeNullableOptionalDescription
observerfunction

Return type: voidresetValueResets the value of the option with the matching key to the default value.

ParameterTypeNullableOptionalDescription
keystring

Return type: voidsetOptionsFromQueryParses the page URL for option keys and values in the standard query form. Done once automatically on page load.No parameters.Return type: voidsetValueSet the option with the given key to the given value.

ParameterTypeNullableOptionalDescription
keystring
valuestring

Return type: void

Currently the following options are available in xml3d.js, the default is shown in bold:

KeyValuesDescription
loglevelall, debug, info, warning, error, exceptionControls the level of logging to the console.
resource-crossorigin-attributeanonymous, use-credentialsThis value will be assigned to the crossOrigin field of requested resources such as img or video.
renderer-facecullingback, front, both, noneControls which faces are culled during rendering. Corresponds to WebGL’s cullFace function.
renderer-frontfacecw, ccwControls the winding order of polygon faces during rendering. Corresponds to WebGL’s frontFace function.
renderer-frustum-cullingtrue, falseToggles view frustum culling during rendering.
renderer-mousemove-pickingtrue, falseEnable object picking for mousemove events. Ex: The XML3D standard camera disables mousemove picking between the mousedown and mouseup events of a camera rotation.
renderer-movement-aware-click-handlertrue, falseWhen true, disregard click events where the mouse has moved between the mousedown and mouseup events.
renderer-continuoustrue, falseToggle continuous rendering. If false a frame will only be drawn if XML3D detects a scene change that requires it.
renderer-ssaotrue, falseToggle screen space ambient occlusion. Note: This is an experimental feature!

NOTEThese options can also be set through URL queries by appending xml3d-, like so: ?xml3d-loglevel=debug

8. Content-Types

XML3D specifies the following content-types for external resources:

        JSON mesh file     model/vnd.xml3d.mesh+json

        XML mesh file      model/vnd.xml3d.mesh+xml

        XML asset file     model/vnd.xml3d.model+xml
    

The response should include a Content-Type header with the same content-type or the appropriate standard type application/jsonapplication/xml or application/octet-stream.NOTEA response with no Content-Type header at all will not be handled and will generate an error message.

9. Datatypes

XML3D provides a range of math types based on the glMatrix library. In general the functions they provide are immutable, with the exception of the Box and Ray types.

9.1 Vec2

A two component vector object.

[ Constructor,
 Constructor (float x, float y),
 Constructor (Float32Array other),
 Constructor (Vec2 other)]
interface Vec2 {
                    attribute Float32Array data;
                    attribute float        x;
                    attribute float        y;
    static Vec2 fromDOMString (DOMString str);
    DOMString   toDOMString (Vec2 vec);
    Vec2        add (Vec2 other);
    Vec2        clone ();
    float       dist (Vec2 other);
    Vec2        divide (Vec2 other);
    float       dot (Vec2 other);
    float       length ();
    Vec2        lerp (Vec2 other, float weight);
    Vec2        max (Vec2 other);
    Vec2        min (Vec2 other);
    Vec2        mul (Vec2 other);
    Vec2        mul (Mat2 other);
    Vec2        mul (Mat3 other);
    Vec2        mul (Mat4 other);
    Vec2        negate ();
    Vec2        normalize ();
    static Vec2 random (optional float scale);
    Vec2        scale (float scale);
    Vec2        sub (Vec2 other);
    static Vec2 wrap (Float32Array data);
};

9.1.1 Constructors

Vec2Creates a new identity Vec2 [0,0]No parameters.Vec2Creates a new Vec2 from the given values.

ParameterTypeNullableOptionalDescription
xfloat
yfloat

Vec2Creates a new Vec2 which is a copy of the values in the passed array.

ParameterTypeNullableOptionalDescription
otherFloat32Array

Vec2Creates a new Vec2 which is a copy of the given Vec2.

ParameterTypeNullableOptionalDescription
otherVec2

9.1.2 Attributes

data of type Float32ArrayThe underlying typed array that this Vec2 wraps.x of type floatProvides mutable access to the first component of this vector.y of type floatProvides mutable access to the second component of this vector.

9.1.3 Methods

addReturns the component wise addition of the two vectors as a new Vec2.

ParameterTypeNullableOptionalDescription
otherVec2

Return type: Vec2cloneReturns a new copy of this Vec2.No parameters.Return type: Vec2distThe distance between this and the given vector.

ParameterTypeNullableOptionalDescription
otherVec2

Return type: floatdivideReturns the component wise division of the two vectors as a new Vec2.

ParameterTypeNullableOptionalDescription
otherVec2

Return type: Vec2dotThe dot product of this and the given vector.

ParameterTypeNullableOptionalDescription
otherVec2

Return type: floatfromDOMString, staticCreates a new Vec2 object from the space-separated string representation as used in XML3D element attributes.

ParameterTypeNullableOptionalDescription
strDOMString

Return type: Vec2lengthReturns the length of this vector.No parameters.Return type: floatlerpReturns a linear interpolation between the two vectors as a new Vec2.

ParameterTypeNullableOptionalDescription
otherVec2
weightfloatInterpolation amount between the two vectors, range of [0,1].

Return type: Vec2maxReturns a new Vec2 that contains the component wise maximum of the two vectors.

ParameterTypeNullableOptionalDescription
otherVec2

Return type: Vec2minReturns a new Vec2 that contains the component wise minimum of the two vectors.

ParameterTypeNullableOptionalDescription
otherVec2

Return type: Vec2mulReturns the component wise multiplication of the two vectors as a new Vec2.

ParameterTypeNullableOptionalDescription
otherVec2

Return type: Vec2mulReturns the transformation of this vector with the given 2×2 matrix as a new Vec2.

ParameterTypeNullableOptionalDescription
otherMat2

Return type: Vec2mulReturns the transformation of this vector with the given 3×3 matrix as a new Vec2. The third vector component is implicitly ‘1’.

ParameterTypeNullableOptionalDescription
otherMat3

Return type: Vec2mulReturns the transformation of this vector with the given 4×4 matrix as a new Vec2. The third vector component is implicitly ‘0’, the fourth ‘1’.

ParameterTypeNullableOptionalDescription
otherMat4

Return type: Vec2negateReturns the component wise negation of this vector as a new Vec2.No parameters.Return type: Vec2normalizeReturns the normalized representation of this vector as a new Vec2.No parameters.Return type: Vec2random, staticGenerates a random vector with the given scale, or a unit vector if omitted.

ParameterTypeNullableOptionalDescription
scalefloat

Return type: Vec2scaleReturns the scaled vector as a new Vec2.

ParameterTypeNullableOptionalDescription
scalefloat

Return type: Vec2subReturns the component wise subtraction of the two vectors as a new Vec2.

ParameterTypeNullableOptionalDescription
otherVec2

Return type: Vec2toDOMStringConverts a Vec2 into the space-seperated string representation used in XML3D element attributes.

ParameterTypeNullableOptionalDescription
vecVec2

Return type: DOMStringwrap, staticReturns a new Vec2 wrapper around the given Float32Array. Note: Changes to the returned Vec2 will also change the data in the array!

ParameterTypeNullableOptionalDescription
dataFloat32Array

Return type: Vec2

9.2 Vec3

A three component vector object.

[ Constructor,
 Constructor (float x, float y, float z),
 Constructor (Float32Array other),
 Constructor (Vec3 other)]
interface Vec3 {
                    attribute Float32Array data;
                    attribute float        x;
                    attribute float        y;
                    attribute float        z;
    static Vec3 fromDOMString (DOMString str);
    DOMString   toDOMString (Vec3 vec);
    Vec3        add (Vec3 other);
    Vec3        clone ();
    Vec3        cross (Vec3 other);
    float       dist (Vec3 other);
    Vec3        divide (Vec3 other);
    float       dot (Vec3 other);
    float       length ();
    Vec3        lerp (Vec3 other, float weight);
    Vec3        max (Vec3 other);
    Vec3        min (Vec3 other);
    Vec3        mul (Vec3 other);
    Vec3        mul (Mat3 other);
    Vec3        mul (Mat4 other);
    Vec3        mul (Quat q);
    Vec3        negate ();
    Vec3        normalize ();
    static Vec3 random (optional float scale);
    Vec3        reciprocal ();
    Vec3        scale (float scale);
    Vec3        sub (Vec3 other);
    Vec3        transformDirection (Mat4 mat);
    static Vec3 wrap (Float32Array data);
};

9.2.1 Constructors

Vec3Creates a new identity Vec3 [0,0,0]No parameters.Vec3Creates a new Vec3 from the given values.

ParameterTypeNullableOptionalDescription
xfloat
yfloat
zfloat

Vec3Creates a new Vec3 which is a copy of the values in the passed array.

ParameterTypeNullableOptionalDescription
otherFloat32Array

Vec3Creates a new Vec3 which is a copy of the given Vec3.

ParameterTypeNullableOptionalDescription
otherVec3

9.2.2 Attributes

data of type Float32ArrayThe underlying typed array that this Vec3 wraps.x of type floatProvides mutable access to the first component of this vector.y of type floatProvides mutable access to the second component of this vector.z of type floatProvides mutable access to the third component of this vector.

9.2.3 Methods

addReturns the component wise addition of the two vectors as a new Vec3.

ParameterTypeNullableOptionalDescription
otherVec3

Return type: Vec3cloneReturns a new copy of this Vec3.No parameters.Return type: Vec3crossReturns the cross product of this and the other vector as a new Vec3.

ParameterTypeNullableOptionalDescription
otherVec3

Return type: Vec3distThe distance between this and the given vector.

ParameterTypeNullableOptionalDescription
otherVec3

Return type: floatdivideReturns the component wise division of the two vectors as a new Vec3.

ParameterTypeNullableOptionalDescription
otherVec3

Return type: Vec3dotThe dot product of this and the given vector.

ParameterTypeNullableOptionalDescription
otherVec3

Return type: floatfromDOMString, staticCreates a new Vec3 object from the space-separated string representation as used in XML3D element attributes.

ParameterTypeNullableOptionalDescription
strDOMString

Return type: Vec3lengthReturns the length of this vector.No parameters.Return type: floatlerpReturns a linear interpolation between the two vectors as a new Vec3.

ParameterTypeNullableOptionalDescription
otherVec3
weightfloatInterpolation amount between the two vectors, range of [0,1].

Return type: Vec3maxReturns a new Vec3 that contains the component wise maximum of the two vectors.

ParameterTypeNullableOptionalDescription
otherVec3

Return type: Vec3minReturns a new Vec3 that contains the component wise minimum of the two vectors.

ParameterTypeNullableOptionalDescription
otherVec3

Return type: Vec3mulReturns the component wise multiplication of the two vectors as a new Vec3.

ParameterTypeNullableOptionalDescription
otherVec3

Return type: Vec3mulReturns the transformation of this vector with the given 3×3 matrix as a new Vec3.

ParameterTypeNullableOptionalDescription
otherMat3

Return type: Vec3mulReturns the transformation of this vector with the given 4×4 matrix as a new Vec3. The fourth vector component is implicitly ‘1’

ParameterTypeNullableOptionalDescription
otherMat4

Return type: Vec3mulReturns the transformation of this vector with the given quaternion as a new Vec3.

ParameterTypeNullableOptionalDescription
qQuat

Return type: Vec3negateReturns the component wise negation of this vector as a new Vec3.No parameters.Return type: Vec3normalizeReturns the normalized representation of this vector as a new Vec3.No parameters.Return type: Vec3random, staticGenerates a random vector with the given scale, or a unit vector if omitted.

ParameterTypeNullableOptionalDescription
scalefloat

Return type: Vec3reciprocalReturns the component wise reciprocal of this vector as a new Vec3.No parameters.Return type: Vec3scaleReturns the scaled vector as a new Vec3.

ParameterTypeNullableOptionalDescription
scalefloat

Return type: Vec3subReturns the component wise subtraction of the two vectors as a new Vec3.

ParameterTypeNullableOptionalDescription
otherVec3

Return type: Vec3toDOMStringConverts a Vec3 into the space-seperated string representation used in XML3D element attributes.

ParameterTypeNullableOptionalDescription
vecVec3

Return type: DOMStringtransformDirectionReturns the transformation of this vector with the given 4×4 matrix as a new Vec3. The fourth vector component is implicitly ‘0’

ParameterTypeNullableOptionalDescription
matMat4

Return type: Vec3wrap, staticReturns a new Vec3 wrapper around the given Float32Array. Note: Changes to the returned Vec3 will also change the data in the array!

ParameterTypeNullableOptionalDescription
dataFloat32Array

Return type: Vec3

9.3 Vec4

A four component vector object.

[ Constructor,
 Constructor (float x, float y, float z, float w),
 Constructor (Float32Array other),
 Constructor (Vec4 other)]
interface Vec4 {
                    attribute Float32Array data;
                    attribute float        x;
                    attribute float        y;
                    attribute float        z;
                    attribute float        w;
    static Vec4 fromDOMString (DOMString str);
    DOMString   toDOMString (Vec4 vec);
    Vec4        add (Vec4 other);
    Vec4        clone ();
    float       dist (Vec4 other);
    Vec4        divide (Vec4 other);
    float       dot (Vec4 other);
    float       length ();
    Vec4        lerp (Vec4 other, float weight);
    Vec4        max (Vec4 other);
    Vec4        min (Vec4 other);
    Vec4        mul (Vec4 other);
    Vec4        mul (Mat4 other);
    Vec4        negate ();
    Vec4        normalize ();
    static Vec4 random (optional float scale);
    Vec4        scale (float scale);
    Vec4        sub (Vec4 other);
    Vec4        transformQuat (Quat q);
    static Vec4 wrap (Float32Array data);
};

9.3.1 Constructors

Vec4Creates a new identity Vec4 [0,0,0,0]No parameters.Vec4Creates a new Vec4 from the given values.

ParameterTypeNullableOptionalDescription
xfloat
yfloat
zfloat
wfloat

Vec4Creates a new Vec4 which is a copy of the values in the passed array.

ParameterTypeNullableOptionalDescription
otherFloat32Array

Vec4Creates a new Vec4 which is a copy of the given Vec4.

ParameterTypeNullableOptionalDescription
otherVec4

9.3.2 Attributes

data of type Float32ArrayThe underlying typed array that this Vec4 wraps.w of type floatProvides mutable access to the fourth component of this vector.x of type floatProvides mutable access to the first component of this vector.y of type floatProvides mutable access to the second component of this vector.z of type floatProvides mutable access to the third component of this vector.

9.3.3 Methods

addReturns the component wise addition of the two vectors as a new Vec4.

ParameterTypeNullableOptionalDescription
otherVec4

Return type: Vec4cloneReturns a new copy of this Vec4.No parameters.Return type: Vec4distThe distance between this and the given vector.

ParameterTypeNullableOptionalDescription
otherVec4

Return type: floatdivideReturns the component wise division of the two vectors as a new Vec4.

ParameterTypeNullableOptionalDescription
otherVec4

Return type: Vec4dotThe dot product of this and the given vector.

ParameterTypeNullableOptionalDescription
otherVec4

Return type: floatfromDOMString, staticCreates a new Vec4 object from the space-separated string representation as used in XML3D element attributes.

ParameterTypeNullableOptionalDescription
strDOMString

Return type: Vec4lengthReturns the length of this vector.No parameters.Return type: floatlerpReturns a linear interpolation between the two vectors as a new Vec4.

ParameterTypeNullableOptionalDescription
otherVec4
weightfloatInterpolation amount between the two vectors, range of [0,1].

Return type: Vec4maxReturns a new Vec4 that contains the component wise maximum of the two vectors.

ParameterTypeNullableOptionalDescription
otherVec4

Return type: Vec4minReturns a new Vec4 that contains the component wise minimum of the two vectors.

ParameterTypeNullableOptionalDescription
otherVec4

Return type: Vec4mulReturns the component wise multiplication of the two vectors as a new Vec4.

ParameterTypeNullableOptionalDescription
otherVec4

Return type: Vec4mulReturns the transformation of this vector with the given 4×4 matrix as a new Vec4.

ParameterTypeNullableOptionalDescription
otherMat4

Return type: Vec4negateReturns the component wise negation of this vector as a new Vec4.No parameters.Return type: Vec4normalizeReturns the normalized representation of this vector as a new Vec4.No parameters.Return type: Vec4random, staticGenerates a random vector with the given scale, or a unit vector if omitted.

ParameterTypeNullableOptionalDescription
scalefloat

Return type: Vec4scaleReturns the scaled vector as a new Vec4.

ParameterTypeNullableOptionalDescription
scalefloat

Return type: Vec4subReturns the component wise subtraction of the two vectors as a new Vec4.

ParameterTypeNullableOptionalDescription
otherVec4

Return type: Vec4toDOMStringConverts a Vec4 into the space-seperated string representation used in XML3D element attributes.

ParameterTypeNullableOptionalDescription
vecVec4

Return type: DOMStringtransformQuatReturns the transformation of this vector with the given quaternion as a new Vec4.

ParameterTypeNullableOptionalDescription
qQuat

Return type: Vec4wrap, staticReturns a new Vec4 wrapper around the given Float32Array. Note: Changes to the returned Vec4 will also change the data in the array!

ParameterTypeNullableOptionalDescription
dataFloat32Array

Return type: Vec4

9.4 AxisAngle

An axis-angle representation of a rotation with the angle in radians. This type is used for all XML3D interface methods and element attributes that expect a rotation. When working with rotations mathematically it’s best to first convert the AxisAngle representation to a Quat and convert back to AxisAngle when passing the result back to an XML3D interface.

[ Constructor,
 Constructor (float x, float y, float z, float angle),
 Constructor (Float32Array other),
 Constructor (AxisAngle other)]
interface AxisAngle {
                    attribute Float32Array data;
                    attribute Vec3         axis;
                    attribute float        angle;
    static AxisAngle fromDOMString (DOMString str);
    DOMString        toDOMString (AxisAngle vec);
    AxisAngle        clone ();
    static AxisAngle fromQuat (Quat q);
    Quat             toQuat ();
    static AxisAngle wrap (Float32Array data);
};

9.4.1 Constructors

AxisAngleCreates a new identity AxisAngle [0,0,1,0]No parameters.AxisAngleCreates a new AxisAngle from the given values.

ParameterTypeNullableOptionalDescription
xfloat
yfloat
zfloat
anglefloat

AxisAngleCreates a new AxisAngle which is a copy of the values in the passed array.

ParameterTypeNullableOptionalDescription
otherFloat32Array

AxisAngleCreates a new AxisAngle which is a copy of the given AxisAngle.

ParameterTypeNullableOptionalDescription
otherAxisAngle

9.4.2 Attributes

angle of type floatProvides mutable access to the angle component. The angle should always be in radians.axis of type Vec3Provides mutable access to the axis vector.data of type Float32ArrayThe underlying typed array that this AxisAngle wraps in the form [x, y, z, angle]

9.4.3 Methods

cloneReturns a new copy of this AxisAngle.No parameters.Return type: AxisAnglefromDOMString, staticCreates a new AxisAngle object from the space-separated string representation as used in XML3D element attributes.

ParameterTypeNullableOptionalDescription
strDOMString

Return type: AxisAnglefromQuat, staticCreates a new axis-angle representation of the given quaternion’s rotation.

ParameterTypeNullableOptionalDescription
qQuat

Return type: AxisAngletoDOMStringConverts a AxisAngle into the space-seperated string representation used in XML3D element attributes.

ParameterTypeNullableOptionalDescription
vecAxisAngle

Return type: DOMStringtoQuatCreates a new quaternion representation of this AxisAngle’s rotation.No parameters.Return type: Quatwrap, staticReturns a new AxisAngle wrapper around the given Float32Array. Note: Changes to the returned AxisAngle will also change the data in the array!

ParameterTypeNullableOptionalDescription
dataFloat32Array

Return type: AxisAngle

9.5 Quat

Quat represents a rotation as a quaternion of the form [x, y, z, w]. The provided functions and accessors do not automatically normalize the quaternion unless otherwise stated.

[ Constructor,
 Constructor (float x, float y, float z, float w),
 Constructor (Float32Array other),
 Constructor (Quat other)]
interface Quat {
                    attribute Float32Array data;
                    attribute float        x;
                    attribute float        y;
                    attribute float        z;
                    attribute float        w;
    static Quat fromDOMString (DOMString str);
    DOMString   toDOMString (Quat vec);
    Quat        add (Quat other);
    Quat        clone ();
    Quat        calculateW ();
    Quat        conjugate ();
    float       dot (Quat other);
    Quat        invert ();
    float       length ();
    Quat        lerp (Quat other, float weight);
    Quat        mul (Quat other);
    Quat        normalize ();
    Quat        rotateX (float angleInRadians);
    Quat        rotateY (float angleInRadians);
    Quat        rotateZ (float angleInRadians);
    Quat        scale (float scale);
    static Quat fromAxisAngle (AxisAngle a);
    static Quat fromBasis (Vec3 x, Vec3 y, Vec3 z);
    static Quat fromMat3 (Mat3 mat);
    static Quat fromRotationTo (Vec3 from, Vec3 to);
    Quat        slerp (Quat other, float weight);
    static Quat wrap (Float32Array data);
};

9.5.1 Constructors

QuatCreates a new identity Quat [0,0,0,1]No parameters.QuatCreates a new Quat from the given values.

ParameterTypeNullableOptionalDescription
xfloat
yfloat
zfloat
wfloat

QuatCreates a new Quat which is a copy of the values in the passed array.

ParameterTypeNullableOptionalDescription
otherFloat32Array

QuatCreates a new Quat which is a copy of the given Quat.

ParameterTypeNullableOptionalDescription
otherQuat

9.5.2 Attributes

data of type Float32ArrayThe underlying typed array that this Quat wraps.w of type floatProvides mutable access to the fourth component of this quaternion.x of type floatProvides mutable access to the first component of this quaternion.y of type floatProvides mutable access to the second component of this quaternion.z of type floatProvides mutable access to the third component of this quaternion.

9.5.3 Methods

addReturns the addition of the two quaternions as a new Quat.

ParameterTypeNullableOptionalDescription
otherQuat

Return type: QuatcalculateWReturns a new Quat with the w component calculated from the x,y,z components of this quaternion. Any existing w component will be ignored.No parameters.Return type: QuatcloneReturns a new copy of this Quat.No parameters.Return type: QuatconjugateReturns the conjugate of this quaternion as a new Quat. Note: This method should only be used on normalized quaternions!No parameters.Return type: QuatdotReturns the dot product of the two quaternions.

ParameterTypeNullableOptionalDescription
otherQuat

Return type: floatfromAxisAngle, staticGenerates a normalized quaternion representation of the given AxisAngle.

ParameterTypeNullableOptionalDescription
aAxisAngle

Return type: QuatfromBasis, staticGenerates a normalized quaternion from the given basis vectors, defined as the rotation between the coordinate space defined by these vectors and the standard space.

ParameterTypeNullableOptionalDescription
xVec3
yVec3
zVec3

Return type: QuatfromDOMString, staticCreates a new Quat object from a space-separated string representation.

ParameterTypeNullableOptionalDescription
strDOMString

Return type: QuatfromMat3, staticGenerates a normalized quaternion from the given rotation matrix.

ParameterTypeNullableOptionalDescription
matMat3

Return type: QuatfromRotationTo, staticGenerates a normalized quaternion representing the shortest rotation from one vector to another.

ParameterTypeNullableOptionalDescription
fromVec3
toVec3

Return type: QuatinvertReturns the inverse of this quaternion as a new Quat. This is slower than Quat.conjugate but also works on non-normalized quaternions.No parameters.Return type: QuatlengthReturns the magnitude of this quaternion.No parameters.Return type: floatlerpReturns a linear interpolation between the two quaternions as a new Quat.

ParameterTypeNullableOptionalDescription
otherQuat
weightfloatInterpolation amount between the two quaternions, range of [0,1].

Return type: QuatmulReturns the component wise multiplication of the two quaternions as a new Quat.

ParameterTypeNullableOptionalDescription
otherQuat

Return type: QuatnormalizeReturns the normalized representation of this quaternion as a new Quat.No parameters.Return type: QuatrotateXReturns a new quaternion representing this one rotated around the X axis by the given angle.

ParameterTypeNullableOptionalDescription
angleInRadiansfloat

Return type: QuatrotateYReturns a new quaternion representing this one rotated around the Y axis by the given angle.

ParameterTypeNullableOptionalDescription
angleInRadiansfloat

Return type: QuatrotateZReturns a new quaternion representing this one rotated around the Z axis by the given angle.

ParameterTypeNullableOptionalDescription
angleInRadiansfloat

Return type: QuatscaleReturns the scaled quaternion as a new Quat. This is identical to Vec4.scale.

ParameterTypeNullableOptionalDescription
scalefloat

Return type: QuatslerpReturns a spherical linear interpolation between the two quaternions as a new Quat.

ParameterTypeNullableOptionalDescription
otherQuat
weightfloatInterpolation amount between the two quaternions, range of [0,1].

Return type: QuattoDOMStringConverts a Quat into a space-seperated string representation.

ParameterTypeNullableOptionalDescription
vecQuat

Return type: DOMStringwrap, staticReturns a new Quat wrapper around the given Float32Array. Note: Changes to the returned Quat will also change the data in the array!

ParameterTypeNullableOptionalDescription
dataFloat32Array

Return type: Quat

9.6 Mat2

A 2×2 matrix object.

[ Constructor,
 Constructor (Float32Array other),
 Constructor (Mat2 other)]
interface Mat2 {
                    attribute Float32Array data;
                    attribute float        m11;
                    attribute float        m12;
                    attribute float        m21;
                    attribute float        m22;
    Mat2        adjoint ();
    Mat2        clone ();
    float       determinant ();
    Mat2        invert ();
    Mat2        mul (Mat2 other);
    Mat2        rotate (float angleInRadians);
    Mat2        scale (Vec2 scale);
    Mat2        transpose ();
    static Mat2 wrap (Float32Array data);
};

9.6.1 Constructors

Mat2Creates a new identity Mat2.No parameters.Mat2Creates a new Mat2 which is a copy of the values in the passed array.

ParameterTypeNullableOptionalDescription
otherFloat32Array

Mat2Creates a new Mat2 which is a copy of the given Mat2.

ParameterTypeNullableOptionalDescription
otherMat2

9.6.2 Attributes

data of type Float32ArrayThe underlying typed array that this Mat2 wraps.m11 of type floatProvides mutable access to the first column of the first row of this matrix.m12 of type floatProvides mutable access to the second column of the first row of this matrix.m21 of type floatProvides mutable access to the first column of the second row of this matrix.m22 of type floatProvides mutable access to the second column of the second row of this matrix.

9.6.3 Methods

adjointComputes the adjugate of this matrix as a new Mat2.No parameters.Return type: Mat2cloneReturns a new copy of this Mat2.No parameters.Return type: Mat2determinantComputes the determinant of this matrix.No parameters.Return type: floatinvertReturns the inverse of this matrix as a new Mat2. If this matrix is not invertible null will be returned.No parameters.Return type: Mat2mulReturns the multiplication of this matrix with the other as a new Mat2.

ParameterTypeNullableOptionalDescription
otherMat2

Return type: Mat2rotateReturns the rotation of this matrix by the given angle in radians as a new Mat2.

ParameterTypeNullableOptionalDescription
angleInRadiansfloat

Return type: Mat2scaleReturns the scaled matrix as a new Mat2.

ParameterTypeNullableOptionalDescription
scaleVec2

Return type: Mat2transposeReturns the transpose of this matrix as a new Mat2.No parameters.Return type: Mat2wrap, staticReturns a new Mat2 wrapper around the given Float32Array. Note: Changes to the returned Mat2 will also change the data in the array!

ParameterTypeNullableOptionalDescription
dataFloat32Array

Return type: Mat2

9.7 Mat3

A 3×3 matrix object.

[ Constructor,
 Constructor (Float32Array other),
 Constructor (Mat3 other)]
interface Mat3 {
                    attribute Float32Array data;
                    attribute float        m11;
                    attribute float        m12;
                    attribute float        m13;
                    attribute float        m21;
                    attribute float        m22;
                    attribute float        m23;
                    attribute float        m31;
                    attribute float        m32;
                    attribute float        m33;
    Mat3        adjoint ();
    Mat3        clone ();
    float       determinant ();
    static Mat3 fromMat4 (Mat4 mat);
    static Mat3 fromQuat (Quat q);
    static Mat3 normalFromMat4 (Mat4 mat);
    Mat3        invert ();
    Mat3        mul (Mat3 other);
    Mat3        rotate (float angleInRadians);
    Mat3        scale (Vec3 scale);
    Mat3        translate (Vec3 translation);
    Mat3        transpose ();
    static Mat3 wrap (Float32Array data);
};

9.7.1 Constructors

Mat3Creates a new identity Mat3.No parameters.Mat3Creates a new Mat3 which is a copy of the values in the passed array.

ParameterTypeNullableOptionalDescription
otherFloat32Array

Mat3Creates a new Mat3 which is a copy of the given Mat3.

ParameterTypeNullableOptionalDescription
otherMat3

9.7.2 Attributes

data of type Float32ArrayThe underlying typed array that this Mat3 wraps.m11 of type floatProvides mutable access to the first column of the first row of this matrix.m12 of type floatProvides mutable access to the second column of the first row of this matrix.m13 of type floatProvides mutable access to the third column of the first row of this matrix.m21 of type floatProvides mutable access to the first column of the second row of this matrix.m22 of type floatProvides mutable access to the second column of the second row of this matrix.m23 of type floatProvides mutable access to the third column of the second row of this matrix.m31 of type floatProvides mutable access to the first column of the third row of this matrix.m32 of type floatProvides mutable access to the second column of the third row of this matrix.m33 of type floatProvides mutable access to the third column of the third row of this matrix.

9.7.3 Methods

adjointComputes the adjugate of this matrix as a new Mat3.No parameters.Return type: Mat3cloneReturns a new copy of this Mat3.No parameters.Return type: Mat3determinantComputes the determinant of this matrix.No parameters.Return type: floatfromMat4, staticCreates a new Mat3 from the upper-left values of the given 4×4 matrix.

ParameterTypeNullableOptionalDescription
matMat4

Return type: Mat3fromQuat, staticCreates a new 3×3 rotation matrix from the given quaternion.

ParameterTypeNullableOptionalDescription
qQuat

Return type: Mat3invertReturns the inverse of this matrix as a new Mat3. If this matrix is not invertible null will be returned.No parameters.Return type: Mat3mulReturns the multiplication of this matrix with the other as a new Mat3.

ParameterTypeNullableOptionalDescription
otherMat3

Return type: Mat3normalFromMat4, staticCreates a 3×3 normal matrix (transpose inverse) from the given 4×4 matrix.

ParameterTypeNullableOptionalDescription
matMat4

Return type: Mat3rotateReturns the rotation of this matrix by the given angle in radians as a new Mat3.

ParameterTypeNullableOptionalDescription
angleInRadiansfloat

Return type: Mat3scaleReturns the scaled matrix as a new Mat3.

ParameterTypeNullableOptionalDescription
scaleVec3

Return type: Mat3translateReturns the translated matrix as a new Mat3.

ParameterTypeNullableOptionalDescription
translationVec3

Return type: Mat3transposeReturns the transpose of this matrix as a new Mat3.No parameters.Return type: Mat3wrap, staticReturns a new Mat3 wrapper around the given Float32Array. Note: Changes to the returned Mat3 will also change the data in the array!

ParameterTypeNullableOptionalDescription
dataFloat32Array

Return type: Mat3

9.8 Mat4

A 4×4 matrix object.

[ Constructor,
 Constructor (Float32Array other),
 Constructor (Mat4 other)]
interface Mat4 {
                    attribute Float32Array data;
                    attribute float        m11;
                    attribute float        m12;
                    attribute float        m13;
                    attribute float        m14;
                    attribute float        m21;
                    attribute float        m22;
                    attribute float        m23;
                    attribute float        m24;
                    attribute float        m31;
                    attribute float        m32;
                    attribute float        m33;
                    attribute float        m34;
                    attribute float        m41;
                    attribute float        m42;
                    attribute float        m43;
                    attribute float        m44;
    Mat4        adjoint ();
    Mat4        clone ();
    float       determinant ();
    static Mat4 frustum (float left, float right, float bottom, float top, float near, float far);
    Mat4        invert ();
    static Mat4 lookAt (Vec3 eye, Vec3 center, Vec3 up);
    Mat4        mul (Mat4 other);
    static Mat4 ortho (float left, float right, float bottom, float top, float near, float far);
    static Mat4 perspective (float left, float right, float bottom, float top, float near, float far);
    Mat4        rotate (float angleInRadians, Vec3 axis);
    Mat4        rotateX (float angleInRadians);
    Mat4        rotateY (float angleInRadians);
    Mat4        rotateZ (float angleInRadians);
    Mat4        scale (Vec3 scale);
    Mat4        translate (Vec3 translation);
    Mat4        transpose ();
    static Mat4 fromQuat (Quat q);
    static Mat4 fromRotationTranslation (Quat rotation, Vec3 translation);
    static Mat4 wrap (Float32Array data);
};

9.8.1 Constructors

Mat4Creates a new identity Mat4.No parameters.Mat4Creates a new Mat4 which is a copy of the values in the passed array.

ParameterTypeNullableOptionalDescription
otherFloat32Array

Mat4Creates a new Mat4 which is a copy of the given Mat4.

ParameterTypeNullableOptionalDescription
otherMat4

9.8.2 Attributes

data of type Float32ArrayThe underlying typed array that this Mat4 wraps.m11 of type floatProvides mutable access to the first column of the first row of this matrix.m12 of type floatProvides mutable access to the second column of the first row of this matrix.m13 of type floatProvides mutable access to the third column of the first row of this matrix.m14 of type floatProvides mutable access to the fourth column of the first row of this matrix.m21 of type floatProvides mutable access to the first column of the second row of this matrix.m22 of type floatProvides mutable access to the second column of the second row of this matrix.m23 of type floatProvides mutable access to the third column of the second row of this matrix.m24 of type floatProvides mutable access to the fourth column of the second row of this matrix.m31 of type floatProvides mutable access to the first column of the third row of this matrix.m32 of type floatProvides mutable access to the second column of the third row of this matrix.m33 of type floatProvides mutable access to the third column of the third row of this matrix.m34 of type floatProvides mutable access to the fourth column of the third row of this matrix.m41 of type floatProvides mutable access to the first column of the fourth row of this matrix.m42 of type floatProvides mutable access to the second column of the fourth row of this matrix.m43 of type floatProvides mutable access to the third column of the fourth row of this matrix.m44 of type floatProvides mutable access to the fourth column of the fourth row of this matrix.

9.8.3 Methods

adjointComputes the adjugate of this matrix as a new Mat4.No parameters.Return type: Mat4cloneReturns a new copy of this Mat4.No parameters.Return type: Mat4determinantComputes the determinant of this matrix.No parameters.Return type: floatfromQuat, staticGenerates a 4×4 rotation matrix from the given quaternion.

ParameterTypeNullableOptionalDescription
qQuat

Return type: Mat4fromRotationTranslation, staticGenerates a matrix representing the given rotation and translation. This is much faster than setting the transformations individually.

ParameterTypeNullableOptionalDescription
rotationQuat
translationVec3

Return type: Mat4frustum, staticGenerates a frustum matrix with the given bounds.

ParameterTypeNullableOptionalDescription
leftfloat
rightfloat
bottomfloat
topfloat
nearfloat
farfloat

Return type: Mat4invertReturns the inverse of this matrix as a new Mat4. If this matrix is not invertible null will be returned.No parameters.Return type: Mat4lookAt, staticGenerates a look-at matrix with the given eye position, focal point and up axis.

ParameterTypeNullableOptionalDescription
eyeVec3
centerVec3
upVec3

Return type: Mat4mulReturns the multiplication of this matrix with the other as a new Mat4.

ParameterTypeNullableOptionalDescription
otherMat4

Return type: Mat4ortho, staticGenerates an orthogonal projection matrix with the given bounds.

ParameterTypeNullableOptionalDescription
leftfloat
rightfloat
bottomfloat
topfloat
nearfloat
farfloat

Return type: Mat4perspective, staticGenerates a perspective projection matrix with the given bounds.

ParameterTypeNullableOptionalDescription
leftfloat
rightfloat
bottomfloat
topfloat
nearfloat
farfloat

Return type: Mat4rotateReturns the rotation of this matrix by the given angle around the given axis as a new Mat4.

ParameterTypeNullableOptionalDescription
angleInRadiansfloat
axisVec3

Return type: Mat4rotateXReturns the rotation of this matrix by the given angle around the X axis as a new Mat4.

ParameterTypeNullableOptionalDescription
angleInRadiansfloat

Return type: Mat4rotateYReturns the rotation of this matrix by the given angle around the Y axis as a new Mat4.

ParameterTypeNullableOptionalDescription
angleInRadiansfloat

Return type: Mat4rotateZReturns the rotation of this matrix by the given angle around the Z axis as a new Mat4.

ParameterTypeNullableOptionalDescription
angleInRadiansfloat

Return type: Mat4scaleReturns the scaled matrix as a new Mat4.

ParameterTypeNullableOptionalDescription
scaleVec3

Return type: Mat4translateReturns the translated matrix as a new Mat4.

ParameterTypeNullableOptionalDescription
translationVec3

Return type: Mat4transposeReturns the transpose of this matrix as a new Mat4.No parameters.Return type: Mat4wrap, staticReturns a new Mat4 wrapper around the given Float32Array. Note: Changes to the returned Mat4 will also change the data in the array!

ParameterTypeNullableOptionalDescription
dataFloat32Array

Return type: Mat4

9.9 Box

The Box type represents a bounding box with a stored minimum and maximum point. Unlike the math types the methods of the Box object are mutable and, when applicable, return the same instance of the Box.

[ Constructor,
 Constructor (Box other)]
interface Box {
                    attribute Float32Array data;
                    attribute Vec3         min;
                    attribute Vec3         max;
    Box       clone ();
    Box       copy (Box other);
    Box       copyMin (Box other);
    Box       copyMax (Box other);
    Box       extend (Box other);
    Box       setEmpty ();
    boolean   isEmpty ();
    Vec3      center ();
    Vec3      size ();
    Vec3      extent ();
    Box       transformAxisAligned (Mat4 mat);
    Box       transform (Mat4 mat);
    float     longestSide ();
    boolean   intersects (Ray r, optional Object opt);
    boolean   contains (Vec3 point);
    DOMString toString ();
};

9.9.1 Constructors

BoxCreates a new empty Box with min set to MAX_VALUE and max set to MIN_VALUE.No parameters.BoxCreates a new Box which is a copy of the given Box.

ParameterTypeNullableOptionalDescription
otherBox

9.9.2 Attributes

data of type Float32ArrayThe underlying typed array that this Box wraps.max of type Vec3Mutable accessor to the maximum point of this bounding box.min of type Vec3Mutable accessor to the minimum point of this bounding box.

9.9.3 Methods

centerReturns the center of this box as a new Vec3.No parameters.Return type: Vec3cloneReturns a new clone of this bounding box.No parameters.Return type: BoxcontainsReturns true if the given point is inside the box.

ParameterTypeNullableOptionalDescription
pointVec3

Return type: booleancopyCopies the minimum and maximum points from the other bounding box into this one.

ParameterTypeNullableOptionalDescription
otherBox

Return type: BoxcopyMaxCopies only the maximum point from the given Box.

ParameterTypeNullableOptionalDescription
otherBox

Return type: BoxcopyMinCopies only the minimum point from the given Box.

ParameterTypeNullableOptionalDescription
otherBox

Return type: BoxextendExpands this box to also enclose the given box. This method respects axis alignment if both boxes are axis aligned.

ParameterTypeNullableOptionalDescription
otherBox

Return type: BoxextentReturns the extent of this box as a new Vec3, defined as half of its size.No parameters.Return type: Vec3intersectsReturns true if the given ray intersects this box.

ParameterTypeNullableOptionalDescription
rRay
optObjectIf opt.dist exists then the distance to the intersection point will be written into this field. If the ray does not intersect then this field will hold Infinity

Return type: booleanisEmptyReturns true if the box is empty. Empty is defined as any box whose minimum point is greater than its maximum.No parameters.Return type: booleanlongestSideReturns the length of the longest side of this box.No parameters.Return type: floatsetEmptyResets this box to the empty state.No parameters.Return type: BoxsizeReturns the size of this box as a new Vec3.No parameters.Return type: Vec3toStringA human readable string representation of this box.No parameters.Return type: DOMStringtransformTransforms this box with the given transformation matrix. This method does not enforce axis alignment./dd>

ParameterTypeNullableOptionalDescription
matMat4

Return type: BoxtransformAxisAlignedTransforms this box with the given transformation matrix. This box will remain axis-aligned.

ParameterTypeNullableOptionalDescription
matMat4

Return type: Box

9.10 Ray

The Ray type represents a ray with an origin and a direction. Unlike the math types Rays are mutable and methods will return the same instance, if applicable.

[ Constructor,
 Constructor (Ray other)]
interface Ray {
                    attribute Float32Array data;
                    attribute Vec3         origin;
                    attribute Vec3         direction;
    Ray       clone ();
    Ray       copy (Ray other);
    Ray       copyOrigin (Ray other);
    Ray       copyMax (Ray other);
    Box       setFromOriginDirection (Vec3 origin, Vec3 direction);
    boolean   intersects (Box box, optional Object opt);
    DOMString toString ();
};

9.10.1 Constructors

RayCreates a new Ray with origin [0,0,0] and direction [0,0,-1]No parameters.RayCreates a new Ray which is a copy of the given Ray.

ParameterTypeNullableOptionalDescription
otherRay

9.10.2 Attributes

data of type Float32ArrayThe underlying typed array that this Ray wraps.direction of type Vec3Mutable accessor to the direction of this ray. Assignments should always be normalized.origin of type Vec3Mutable accessor to the origin point of this ray.

9.10.3 Methods

cloneReturns a new clone of this ray.No parameters.Return type: RaycopyCopies the origin and direction from the other ray into this one.

ParameterTypeNullableOptionalDescription
otherRay

Return type: RaycopyMaxCopies only the direction from the given Ray.

ParameterTypeNullableOptionalDescription
otherRay

Return type: RaycopyOriginCopies only the origin from the given Ray.

ParameterTypeNullableOptionalDescription
otherRay

Return type: RayintersectsReturns true if this ray intersects the given box.

ParameterTypeNullableOptionalDescription
boxBox
optObjectIf opt.dist exists then the distance to the intersection point will be written into this field. If the ray does not intersect then this field will hold Infinity

Return type: booleansetFromOriginDirectionSets the origin and direction of this ray to the given values.

ParameterTypeNullableOptionalDescription
originVec3
directionVec3

Return type: BoxtoStringA human readable string representation of this ray.No parameters.Return type: DOMString

10. Events

10.1 Mouse and Keyboard Events

The following event listeners are available on all pickable elements as well as the group element and the xml3d element:

  • onclick
  • ondblclick
  • onmousedown
  • onmouseup
  • onmouseover
  • onmousemove
  • onmouseout
  • onkeypress
  • onkeydown
  • onkeyup

The event received by these listeners is a standard HTML5 MouseEvent or KeyboardEvent respectively. As in normal HTML, event listeners may be added to the element through an appropriate on[eventName] attribute or through JavaScript using element.addEventListener(...).NOTEListeners registered through an attribute must use the following format: "myListenerFunction(event)"

10.2 FrameDrawn

interface FrameDrawn : CustomEvent {
                    attribute float detail.timeStart;
                    attribute float detail.timeEnd;
                    attribute float detail.renderTimeInMilliseconds;
                    attribute int   detail.count.objects;
                    attribute int   detail.count.primitives;
};

10.2.1 Attributes

detail.count.objects of type intThe total number of distinct meshes drawn in this frame after applying frustum culling (if enabled).detail.count.primitives of type intThe total number of primitives drawn in this frame after applying frustum culling (if enabled).detail.renderTimeInMilliseconds of type floatThe total time taken to render this frame. Includes time spent updating the scene state and any XFlow data processing.detail.timeEnd of type floatThe system time at the end of the frame draw.detail.timeStart of type floatThe system time at the beginning of the frame draw.ReSpec

A. References

A.1 Informative references

[CSS2]Bert Bos; Tantek Çelik; Ian Hickson; Håkon Wium Lie et al. W3C. Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification. 7 June 2011. W3C Recommendation. URL: https://web.archive.org/web/20200612205034/https://www.w3.org/TR/CSS2/[CSS3-transforms]Simon Fraser; Dean Jackson; Theresa O’Connor; Dirk Schulze. W3C. CSS Transforms Module Level 1. 14 February 2019. W3C Candidate Recommendation. URL: https://web.archive.org/web/20200612205034/https://www.w3.org/TR/css-transforms-1/[DOM]Anne van Kesteren. WHATWG. DOM Standard. Living Standard. URL: https://web.archive.org/web/20200612205034/https://dom.spec.whatwg.org/[HTML5]Ian Hickson; Robin Berjon; Steve Faulkner; Travis Leithead; Erika Doyle Navara; Theresa O’Connor; Silvia Pfeiffer. W3C. HTML5. 27 March 2018. W3C Recommendation. URL: https://web.archive.org/web/20200612205034/https://www.w3.org/TR/html5/[SVG]Jon Ferraiolo. W3C. Scalable Vector Graphics (SVG) 1.0 Specification. 4 September 2001. W3C Recommendation. URL: https://web.archive.org/web/20200612205034/https://www.w3.org/TR/SVG/[UIEvents]Gary Kacmarcik; Travis Leithead; Doug Schepers. W3C. UI Events. 30 May 2019. W3C Working Draft. URL: https://web.archive.org/web/20200612205034/https://www.w3.org/TR/uievents/[URI]T. Berners-Lee; R. Fielding; L. Masinter. IETF. Uniform Resource Identifier (URI): Generic Syntax. January 2005. Internet Standard. URL: https://web.archive.org/web/20200612205034/https://tools.ietf.org/html/rfc3986[WebGL]Dean Jackson; Jeff Gilbert. Khronos. WebGL 2.0 Specification. 12 August 2017. URL: https://web.archive.org/web/20200612205034/https://www.khronos.org/registry/webgl/specs/latest/2.0/[XML]Tim Bray; Jean Paoli; Michael Sperberg-McQueen; Eve Maler; François Yergeau et al. W3C. Extensible Markup Language (XML) 1.0 (Fifth Edition). 26 November 2008. W3C Recommendation. URL: https://web.archive.org/web/20200612205034/https://www.w3.org/TR/xml/[custom-elements]Domenic Denicola. W3C. Custom Elements. 3 May 2018. W3C Note. URL: https://web.archive.org/web/20200612205034/https://www.w3.org/TR/custom-elements/[rfc2045]N. Freed; N. Borenstein. IETF. Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies. November 1996. Draft Standard. URL: https://web.archive.org/web/20200612205034/https://tools.ietf.org/html/rfc2045[selectors-api2]Lachlan Hunt. W3C. Selectors API Level 2. 17 October 2013. W3C Note. URL: https://web.archive.org/web/20200612205034/https://www.w3.org/TR/selectors-api2/

Leave a Reply

Your email address will not be published. Required fields are marked *