Extensible 3D (X3D)
Part 3: Compressed binary encoding
5 Encoding of fields
Table 5.1 lists the topics in this clause.
This clause specifies the syntax of field data type values.
Field values follow the syntax for fields defined in 5 Encoding of Fields of ISO/IEC 19776-1. These field values are then encoded using Fast Infoset rules as defined in ISO/IEC 24824-1. Specific rules for each field type follow. In general, SFNode and MFNode are encoded using Element rules as specified in 7.3.1 of ISO/IEC 24824-1. Other field types are encoded using the Attribute rules specified in 7.4 of ISO/IEC 24824-1.
Each field specifies what method it has used to write its values. This allows the Compressed binary encoding to use type-specific knowledge to further compress a field. Encoders are expected to pick the right methods to meet the users expectations for parsing speed versus file size.
The usage of encoding algorithms not specified in this part of ISO/IEC 19776 or in ISO/IEC 24824-1 is invalid. A conformant implementation need only support these algorithms to parse a Compressed binary encoded file.
All field values shall end on a byte boundary.
By default all field values are written in String form. ISO/IEC 24824-1 allows the specification of encoders to write values in a compact binary form. This subclause defines the encoders available for compressing X3D content. Only encoders defined in this clause or in ISO/IEC 24824-1 may be used for compressing X3D content. All X3D encoders defined in this document provide a unique URI to be used in the Encoding Algorithms table of the document serialization as required by ISO/IEC 24824-1. If an encoder is used, this URI shall be added to the Encoding Algorithm Table described in 8.3 of ISO/IEC 24824-1.
Fast Infoset defines a set of native encoders to help speed parsing and decrease file size for commonly used constructs. When possible, these encoders are used for handling X3D field types. This subclause specifies the encoders used along with a brief description of their function. See ISO/IEC 24824-1 for a detailed discussion of each encoder, including the exact definition of what is written to a stream.
All encoders defined by ISO/IEC 24824-1 are lossless.
zlib compression is used for several encoders. zlib works by detecting common patterns in a stream and outputing short-hand tags for these patterns.
Implementations should reuse or reimplement the zlib library specified in 2.[RFC1950].
This encoder takes an array of float values and encodes them as a quantized form of the single-precision floating point numbers specified in IEC 60559. A custom value is selected for the exponent, mantissa and sign bits typically used to encode floats. The bias of 127 is still used. These values are written to the stream first before the data. The exponent is encoded using three bits, giving a range of 1-8. Zero exponent bits cannot be used. The number of mantissa bits is encoded using five bits. One bit is used for the sign bit. When a number uses zero sign bits, it is assumed to be positive. The remaining bits are used for data. Data follows the float description using the extra seven bits of the second byte for storage. Extra bits needed to byte align the data array are padded with bits of value 0.
The number of floats written can be determined by:
NumFloats = floor((numBytes × 8 - 9) / (exponent + mantissa + sign));
The "9" in the above formula represents the number of header bits.
This technique is a lossy encoder.
The URI for identifying this encoder is:
"encoder://web3d.org/QuantizedFloatArrayEncoder"
EXAMPLE
value to encode: "0.42 -1 0.1972"
parameters: exponent = 4 bits, mantissa = 4 bits, sign = 1 bitsresultant bits:
byte Octet(s) Description 1 100 00100 Exponent(4) written in 3 bits, Mantissa(4) 5 bits 2 1 0110101 Sign(0) 1 bit. Start of 0.42 3 10 100000 End of 0.42, start of -1 4 000 01011 End of -1, start of 0.1972 5 0010 0000 End of 0.1972, 4 bits of padding
This encoder uses the zlib library (see 2.[RFC1950]) to find patterns in float values.
The array of floats is sent to the zlib library unmodified.
This technique is a lossless encoder.
The URI for identifying this encoder is:
"encoder://web3d.org/zlibFloatArrayEncoder"
This encoder takes an array of float values and encodes them as a quantized form of the single precision floating point numbers defined in IEC 60559. A custom value is selected for the exponent, mantissa and sign bits typically used to encode floats. The bias of 127 is still used. These values are written to the stream first before the data. The number of exponent bits is encoded using three bits, giving a range of 1-8, zero exponent bits cannot be used. The number of mantissa bits is encoded using five bits. One bit is used for the sign bit. When a number uses zero sign bits, it is assumed to be positive. The seven remaining bits are padded with '0000000' (padding) are appended to the bit stream.
The number of float values in the field is appended to the stream using four bytes. The float values themselves are then encoded using the zlib library (see 2.[RFC1950]) and appended to the stream.
This technique is a lossy encoder.
The URI for identifying this encoder is:
"encoder://web3d.org/QuantizedzlibFloatArrayEncoder"
This encoder takes an array of double values and encodes them as a quantized form of the double precision floating point numbers defined in IEC 60559. A custom value is selected for the exponent, mantissa and sign bits typically used to encode floats. The bias of 1023 is still used. These values are written to the stream first before the data. The number of exponent bits is encoded using four bits, giving a range of 0-15. The number of mantissa bits is encoded using six bits. One bit is used for the sign bit. When a number uses zero sign bits it is assumed to be positive. The remaining bits are used for data. Data follows the float description using the extra seven bits of the second byte for storage. Extra bits needed to byte align the data are padded with bits of value 0.
The number of doubles written can be determined by:
NumDoubles = floor((numBytes × 8 - 11) / (exponent + mantissa + sign));
The "11" in the above formula represents the number of header bits.
This technique is a lossy encoder.
The URI for identifying this encoder is:
"encoder://web3d.org/QuantizedDoubleArrayEncoder"
This encoder use the zlib algorithm to find patterns in double values (see 2.[RFC1950]).
This technique is a lossless encoder.
The URI for identifying this encoder is:
"encoder://web3d.org/zlibDoubleArrayEncoder"
This encoder takes an array of double values and encodes them as a quantized form of the double precision floating point numbers defined in IEC 60559. A custom value is selected for the exponent, mantissa and sign bits typically used to encode floats. The bias of 1023 is still used. These values are written to the stream first before the data. The number of exponent bits is encoded using four bits, giving a range of 0-15. The number of mantissa bits is encoded using six bits. One bit is used for the sign bit. When a number uses zero sign bits, it is assumed to be positive. The remaining bits are used for data. Data follows the float description using the extra seven bits of the second byte for storage. Extra bits needed to byte align the data are padded with bits of value 0.
These values are then encoded using the zlib library (see 2.[RFC1950]).
This technique is a lossy encoder.
The URI for identifying this encoder is:
"encoder://web3d.org/QuantizedzlibDoubleArrayEncoder"
This encoder takes an array of integer values and encodes them in the least number of bits required to express the range of integers encoded. This is accomplished by determining the range of the integers present. All values are then shifted to a positive value (called shift). Each integer is written using the number of bits required to encode the range of integer values present.
The shift value can be determined by:
shift = -minValue; // sets minimum value in range of integers to zero
The number of bits (numBits) used to represent each integer is determined by:
numBits = ceiling(log2(maxValue - minValue));
The number of integers written can be determined by:
length / numBits per Integer
The numBits value is written out as an 8-bit byte immediately followed by the shift value as a 32-bit integer.
Unused bits following the last value of the integer array are set to 0 to restore the overall encoded length to a byte boundary.
This technique is a lossless encoder.
The URI for identifying this encoder is:
"encoder://web3d.org/RangeIntArrayEncoder"
This encoder takes an array of integer values, calculates delta values and then encodes them using the zlib library (see 2.[RFC1950]). Span is how many values to skip between deltas. The range for Span is 0-255. The first Span values are the original values, the rest are deltas.
EXAMPLE The following array: 0,1,2,-1,3,4,5,-1,6,9,8,-1 with a span of 4 generates the following deltas: 0,1,2,-1,3,3,3,0,3,5,3,0.
The span is written using eight bits. The number of integer values of the field is appended to the stream using four bytes. The array of deltas is then compressed using the zlib library and appended to the stream.
This technique is a lossless encoder.
The URI for identifying this encoder is:
"encoder://web3d.org/DeltazlibIntArrayEncoder"
SFBool and MFBool values are encoded using the "boolean" algorithm as defined in 10.7 of ISO/IEC 24824-1.
The SFColor field specifies one RGB (red-green-blue) colour triple. MFColor specifies zero or more RGB triples.
EXAMPLE
<ColorNode color='"1 0 0", "0 1 0", "0 0 1"'/>
is an MFColor field, color, containing the three primary colours red, green, and blue.
SFColor and MFColor fields can be encoded using lossy and lossless techniques.
Values can be losslessly encoded using these encoders:
Values can be lossy encoded using these encoders:
The SFColorRGBA field specifies one RGBA (red-green-blue-alpha) colour 4-tuple. MFColorRGBA specifies zero or more RGBA 4-tuples.
EXAMPLE
<ColorRGBANode color='"1 0 0 0.5", "0 1 0 0.5", "0 0 1 0.5"'/>
is an MFColorRGBA field, color, containing the three partially transparent primary colours red, green, blue.
SFColorRGBA and MFColorRGBA fields can be encoded using lossy and lossless techniques.
Values can be losslessly encoded using these encoders:
Values can be lossy encoded using these encoders:
The SFDouble field specifies one double-precision floating point number. MFDouble specifies zero or more double-precision floating point numbers.
EXAMPLE
<NurbsCurve knot="1000.123456789, 200.123456789, 300.123456789"/>
is an MFDouble field, knot, containing three double-precision floating point values.
SFDouble and MFDouble fields can be encoded using lossy and lossless techniques.
Values can be losslessly encoded using these encoders:
Values can be lossy encoded using these encoders:
The SFFloat field specifies one single-precision floating point number. MFFloat specifies zero or more single-precision floating point numbers.
EXAMPLE
<ElevationGrid creaseAngle="0.785"/>
is an SFFloat field, creaseAngle, containing a single floating point value.
SFFloat and MFFloat fields can be encoded using lossy and lossless techniques.
Values can be losslessly encoded using these encoders:
Values can be lossy encoded using these encoders:
The SFImage field specifies a single uncompressed two-dimensional pixel image. The MFImage field specifies zero or more SFImage fields. SFImage fields are encoded as three integers representing the width, height and number of components in the image, followed by width × height hexadecimal or integer values representing the pixels in the image, separated by whitespace.
SFImage values can be losslessly encoded using these encoders:The SFInt32 field specifies one 32-bit integer. The MFInt32 field specifies zero or more 32-bit integers. SFInt32 and MFInt32 fields are encoded as an integer in decimal or hexadecimal (beginning with '0x') format.
EXAMPLE
<IndexedLineSet coordIndex="0 1 -1"> <Coordinate point="1 2 3, 3 2 1"/> </IndexedLineSet>
The IndexedLineSet in this example contains an MFInt32 field, coordIndex, containing three integer values.
SFInt32 fields shall be encoded using the encoder specified in 5.2.6 Integer encoder.
MFInt32 fields can only be encoded using lossless techniques.
MFInt32 values can be losslessly encoded using any of these encoders:
The SFMatrix3d field specifies a 3×3 matrix containing nine double-precision floating point numbers. An MFMatrix3d field specifies zero or more SFMatrix3d fields.
EXAMPLE
<field name="two identities"
type="MFMatrix3d"
value='"1 0 0 0 1 0 0 0 1" "1 0 0 0 1 0 0 0 1"'/>
SFMatrix3d and MFMatrix3d fields can be encoded using lossy and lossless techniques.
Values can be losslessly encoded using these encoders:
Values can be lossy encoded using these encoders:
The SFMatrix3f field specifies a 3×3 matrix containing nine single-precision floating point numbers. An MFMatrix3f field specifies zero or more SFMatrix3f fields.
EXAMPLE
<field name="two identities"
type="MFMatrix3f"
value='"1 0 0 0 1 0 0 0 1" "1 0 0 0 1 0 0 0 1"'/>
SFMatrix3f and MFMatrix3f fields can be encoded using lossy and lossless techniques.
Values can be losslessly encoded using these encoders:
Values can be lossy encoded using these encoders:
The SFMatrix4d field specifies a 4×4 matrix containing sixteen double-precision floating point numbers. An MFMatrix4d field specifies zero or more SFMatrix4d fields.
EXAMPLE
<field name="two identities"
type="MFMatrix4d"
value='"1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1" "1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1"'/>
SFMatrix4d and MFMatrix4d fields can be encoded using lossy and lossless techniques.
Values can be losslessly encoded using these encoders:
Values can be lossy encoded using these encoders:
The SFMatrix4f field specifies a 4×4 matrix containing sixteen single-precision floating point numbers. An MFMatrix4f field specifies zero or more SFMatrix4f fields.
EXAMPLE
<field name="two identities"
type="MFMatrix4f"
value='"1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1" "1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1"'/>
SFMatrix4f and MFMatrix4f fields can be encoded using lossy and lossless techniques.
Values can be losslessly encoded using these encoders:
Values can be lossy encoded using these encoders:
The SFNode field specifies a single X3D node. The MFNode field specifies an array of zero or more nodes.
EXAMPLE 1 The following illustrates initialization of a user-defined prototype field, named PositioningNodes, having type MFNode:
<fieldValue name="PositioningNodes"> <Transform USE="someTransformInstance"/> <GeoLocation DEF="defaultGeoLocationInstance"/> <ESPDUTransform USE="someEspduTransformInstance"/> </fieldValue>
Nodes are handled by the generic Fast Infoset rules for dealing with Elements as specified in 7.3 of ISO/IEC 24824-1. No special encoders are defined.
The SFRotation field specifies one arbitrary rotation. The MFRotation field specifies zero or more arbitrary rotations.
EXAMPLE An SFRotation containing a π/4 radians rotation of a Box about the Y axis is:
<Transform rotation='"0.0 1.0 0.0 0.785"'>
<Shape>
<Box/>
</Shape>
</Transform>
SFRotation and MFRotation fields can be encoded using lossy and lossless techniques.
Values can be losslessly encoded using these encoders:
Values can be lossy encoded using these encoders:
The SFString and MFString fields contain strings formatted with the UTF-8 universal character set (see ISO/IEC 10646). SFString specifies a single string encoded as a sequence of UTF-8 octets enclosed in double-quote characters (e.g., "string"). The MFString specifies zero or more SFStrings enclosed in single-quote characters (e.g., '"string1" "string2"').
NOTE The construct
"string3"
is not a valid instance of an MFString. Such an MFString is properly specified as
'"string3"'
EXAMPLE 1 A node with an MFString:
<NavigationInfo type='"WALK" "ANY"' />
Any characters (including linefeeds and ‘#’) may appear within the quotation marks. Special characters as defined by XML (e.g., single-quote and double-quote characters) are specified using the XML character entity encodings (see 2.[XML]).
EXAMPLE 2 Two instances of the double-quote character are contained in the following SFString field string:
<Text string='"He said, "Immel did it!""' />
SFString values are encoded directly as a string as specified in ISO/IEC 24824-1. No encoders are used.
MFString values are encoded directly as a string using the canonical form for MFStrings. No encoders are used.
The SFTime field specifies a single time value. The MFTime field specifies zero or more time values.
EXAMPLE
<TimeSensor cycleInterval="5.0"/>
is an SFTime field, cycleInterval, representing a time of 5.0 seconds for the interval of the TimeSensor node.
SFTime and MFTime fields shall be encoded using the encoder specified in 5.2.4 Double encoder.
Lossy encoders are not allowed due to the sensitive nature of time values to the simulation model.
The SFVec2d field specifies a two-dimensional (2D) double-precision vector. An MFVec2d field specifies zero or more 2D double-precision vectors.
EXAMPLE
<field name="corners"
type="MFVec2d"
value='"42.89978899 666.000123", "84.97778978 933.70941"'/>
SFVec2d and MFVec2d fields can be encoded using lossy and lossless techniques.
Values can be losslessly encoded using these encoders:
Values can be lossy encoded using these encoders:
The SFVec2f field specifies a two-dimensional (2D) single-precision vector. An MFVec2f field specifies zero or more 2D single-precision vectors.
EXAMPLE
<TextureCoordinate point='"0.25 0.25", "0.8 0.8"'/>
SFVec2f and MFVec2f fields can be encoded using lossy and lossless techniques.
Values can be losslessly encoded using these encoders:
Values can be lossy encoded using these encoders:
The SFVec3d field specifies a three-dimensional (3D) double-precision vector. An MFVec3d field specifies zero or more 3D double-precision vectors.
EXAMPLE
<GeoOrigin geoCoords='"1000.123456789 100.123456789 100.123456789"'/>
is an SFVec3d field, geoCoords, defining a high-precision vector value.
SFVec3d and MFVec3d fields can be encoded using lossy and lossless techniques.
Values can be losslessly encoded using these encoders:
Values can be lossy encoded using these encoders:
The SFVec3f field specifies a three-dimensional (3D) single-precision vector. An MFVec3f field specifies zero or more 3D single-precision vectors.
EXAMPLE
<Coordinate point='"1 2.24 3.4", "3 2 1", "4.5 1.2 5.745"'/>
is an SFVec3f field, point, defining three 3D vectors.
SFVec3f and MFVec3f fields can be encoded using lossy and lossless techniques.
Values can be losslessly encoded using these encoders:
Values can be lossy encoded using these encoders:
The SFVec4d field specifies a four-dimensional (4D) double-precision vector. An MFVec4d field specifies zero or more 4D double-precision vectors.
EXAMPLE
<MyCoordinate point='"1 0.75 0.5 0", "0.35 0.6 0.35 1.0", "0.125 0.875 0.375 0.625"'/>
is an SFVec4d field, point, defining three 4D vectors.
SFVec4d and MFVec4d fields can be encoded using lossy and lossless techniques.
Values can be losslessly encoded using these encoders:
Values can be lossy encoded using these encoders:
The SFVec4f field specifies a four-dimensional (4D) single-precision vector. An MFVec4f field specifies zero or more 4D single precision vectors.
EXAMPLE
<TextureCoordinate point='"1.0 0.75 0.5, 0", "0.35 0.6 0.35, 1.0", "0.125 0.875 0.375 0.625"'/>
is an SFVec4f field, point, defining three 4D vectors.
SFVec4f and MFVec4f fields can be encoded using lossy and lossless techniques.
Values can be losslessly encoded using these encoders:
Values can be lossy encoded using these encoders: