IBM

The IBM VRML 2.0 Compressed Binary Format

DRAFT 1 -- 08/01/96

Binary Specification


Introduction

The proposal features support for the compression of geometric data contained in the following VRML 2.0 nodes: No new nodes are proposed for the ASCII standard. Every node in the ASCII standard has a corresponding node in the binary standard. In addition to these direct-from-ASCII nodes, the proposal introduces six new binary nodes to enable geometrically-compressed representations for the following nodes.

Shape nodes:

IndexedFaceSet
--> CompressedIndexedFaceSet
IndexedLineSet
--> CompressedIndexedLineSet
PointSet
--> CompressedPointSet
Interpolator nodes:
CoordinateInterpolator
--> CompressedCoordinateInterpolator
NormalInterpolator
--> CompressedNormalInterpolator
ColorInterpolator
--> CompressedColorInterpolator
A new binary property node, the CompressedGeometricData node is also introduced. A CompressedGeometricData node is used to store compressed geometric data associated to one or more compressed nodes.

Each of the three new compressed shape nodes has a SFNode field named "compressedData" and a SFInt32 field named "component". The compressedData field determines which CompressedGeometricNode contains the compressed geometric data. The component field is used during decompression to determine which data in the CompressedGeometricData node is relevant to the compressed node. This feature permits common compressed data to be shared by multiple nodes.

The CompressedGeometricData node has an SFBinary field named "data". The SFBinary field type is the one new field type introduced by this proposal. As the name implies the SFBinary field type is designed to hold binary data.

The three compressed interpolator nodes have a SFNode field named "compressedGeometryNode" and a SFInt32 field named "record". The compressedGeometryNode field determines which Geometry node is used to provide the topological information for decompression. The record field specifies which record in the Geometry node's compressed geometric data is to be used to recover the keyValue field for the uncompressed interpolator.

The seven new nodes and the one new field type are required only for the Binary format. Specifically, they are not required for the ASCII format.

The data field of the CompressedGeometricData node contains binary data in the Compressed Geometric Data (CGD) Format. Except for the geometric detail that may be lost when geometric data is represented in a compressed form, there is no loss of information in the binary representation of the scene graph. The amount of geometric detail present in the geometric data may be controlled by the user.

When a binary file is parsed, the compressed geometry residing in the CompressedGeometricData node refered to by the compressed node may be expanded into field values for the appropriate uncompressed node. The resultant scene graph will have the same structure as the one represented by the original ASCII fromat. Alternatively, the compressed geometry residing in the CompressedGeometricData node may be represented by suitable data structures (blocks of memory) and decompressed whenever the browser needs to display the geometry.

ASCII format modifications

It is proposed that the VRML 2.0 ASCII format be altered for three existing nodes: by adding the field

   field   SFString   compressionParameters  "IBMVRML:10:9:4:10"
The compressionParameters field will address the

During the compression of an ASCII file, the compressionParameters field will provide hints to the compression algorithm. After decompression, the compressionParameters field will be set by the decompression program to contain the parameters used during compression.

For example

    compressionParameters "IBMVRML:12:9:4:10"
should be interpeted as:
IBMVRML
compression method
12
number of bits per vertex coordinate
9
number of bits per normal
4
number of bits per color
10
number of bits per texture coordinate

Binary Node Definitions

The binary format supports binary versions of the uncompressed nodes: It is not required that these nodes be compressed in the binary format. Compression can be disabled for a node by specifying "NOCOMPRESS" for the compressionParameter. If compression is disabled there will be a one-to-one relationship between ASCII nodes and fields with binary nodes and fields. Each node or field in the ascii format has a corresponding node or field in the binary format. Additionally, as mentioned above, the binary format introduces seven new nodes:
CompressedGeometricData
New node
CompressedIndexedFaceSet
Compressed version of IndexedFaceSet
CompressedIndexedLineSet
Compressed version of IndexedLineSet
CompressedPointSet
Compressed version of PointSet
CompressedCoordinateInterpolator
Compressed version of CoordinateInterpolator
CompressedNormalInterpolator
Compressed version of NormalInterpolator
CompressedColorInterpolator
Compressed version of ColorInterpolator
The binary format also introduces one new field type:
    SFBinary
The following definitions define the data content of the new binary nodes.

CompressedGeometricData

      CompressedGeometricData { 
        field SFBinary          data                    [] 
      }
    

CompressedIndexedFaceSet

      CompressedIndexedFaceSet {
        field SFNode            compressedData          NULL
        field SFInt32           component               0
        field SFString          compressionParameters   IBMVRML:10:9:4:10
        field ccw               # same as IndexedFaceSet
        field colorPerVertex    #         "
        field convex            #         "
        field creaseAngle       #         "
        field normalPerVertex   #         "
        field solid             #         "
       }
    

CompressedIndexedLineSet

      CompressedIndexedLineSet {
        field SFNode            compressedData          NULL
        field SFInt32           component               0
        field SFString          compressionParameters   IBMVRML:10:9:4:10
        field colorPerVertex    # same as IndexedLineSet
       }
    

CompressedPointSet

      CompressedPointSet {
        field SFNode            compressedData          NULL
        field SFInt32           component               0
        field SFString          compressionParameters   IBMVRML:10:9:4:10
       }
    

CompressedCoordinateInterpolator

      CompressedCoordinateInterpolator {
        field SFNode            compressedGeometryNode  NULL
        field SFInt32           record                  0
        field key                # same as CoordinateInterpolator
       }
    

CompressedNormalInterpolator

      CompressedNormalInterpolator {
        field SFNode            compressedGeometryNode  NULL
        field SFInt32           record                  0
        field key                # same as NormalInterpolator
       }
    

CompressedColorInterpolator

      CompressedColorInterpolator {
        field SFNode            compressedGeometryNode  NULL
        field SFInt32           record                  0
        field key                # same as ColorInterpolator
       }
    

Scene Graph Example

For example the uncompressed ASCII scene graph:
    Transform +- Shape +- IndexedFaceSet +- DEF C3 Coordinate3
              |        |                 +- CoordIndex
              |        |                 +- texCoord
              |        |                 +- texCoordIndex
              |        |                 +- color
              |        |                 +- colorIndex
              |        |                 +- colorPerVertex
              |        |                 +- normal
              |        |                 +- normalIndex
              |        |                 +- normalPerVertex
              |        |                 +- ccw
              |        |                 +- solid
              |        |                 +- convex
              |        |                 +- creaseAngle
              |        +- Appearance
              |
              +- Shape +- IndexedFaceSet +- USE C3
                       |                 +- CoordIndex
                       |                 +- texCoord
                       |                 +- texCoordIndex
                       |                 +- color
                       |                 +- colorIndex
                       |                 +- colorPerVertex
                       |                 +- normal
                       |                 +- normalIndex
                       |                 +- normalPerVertex
                       |                 +- ccw
                       |                 +- solid
                       |                 +- convex
                       |                 +- creaseAngle
                       +- Appearance
would be compressed into a binary scene graph something like:
    Transform +- Shape +- CompressedIndexedFaceSet +- DEF C3 CompressedGeometricData
              |        |                           |   +- SFBinary data
                       |                           +- compressionParameters
              |        |                           +- colorPerVertex
              |        |                           +- normalPerVertex
              |        |                           +- ccw
              |        |                           +- solid
              |        |                           +- convex
              |        |                           +- creaseAngle
              |        +- Appearance
              |
              +- Shape +- CompressedIndexedFaceSet +- USE C3
                       |                           +- compressionParameters
                       |                           +- colorPerVertex
                       |                           +- ccw
                       |                           +- solid
                       |                           +- convex
                       |                           +- creaseAngle
                       +- Appearance

Specification of the Binary Format


BINARY-FILE
  HEADER
  SCENEGRAPH

HEADER
  BYTE[18]
The header consists of the following sequence of ASCII bytes: "VRML V2.0 binary\r\n"
BYTE
  BIT[8]

BIT
  One bit.

SCENEGRAPH
  UNSIGNEDINT nEXTERNPROTO  // number of EXTERNPROTOs
  UNSIGNEDINT nPROTO        // number of PROTOs
  UNSIGNEDINT nNODE         // number of NODEs
  UNSIGNEDINT nROUTE        // number of ROUTEs
  EXTERNPROTO[nEXTERNPROTO]
  PROTO[nPROTO]
  NODE[nNODE]
  ROUTE[nROUTE]

UNSIGNEDINT
  BYTE[...]                 // see notes
An UNSIGNEDINT is a binary encoded unsigned integer and is serialized in a similar fashion to UTF8; if the top bit is set then additional bytes follow. For example:
  decimal     hex     encoded(hex)
        1      01       01
       16      10       10
      127      7F       7F
      128      80     8100

EXTERNPROTO
  NODETYPE                   // unique negative number
  STRING                     // prototypename
  EXTERNINTERFACEDECLARATION
  URLS
See notes regarding NODETYPE under NODETYPE.
NODETYPE
  SIGNEDINT
Note that for nodes defined in the VRML node reference NODETYPE is defined by the order of occurence in the VRML node reference. For example, Anchor=1,Apperance=2, and so forth. For nodes defined by a PROTO or EXTERNPROTO statement a negative number is assigned in the binary definition of the PROTO or EXTERNPROTO.
SIGNEDINT
  BYTE[...]            // see notes
Similar to a UNSIGNEDINT, the SIGNEDINT is a binary encoded signed integer with the one difference that the 2nd bit in the first byte is reserved to indicate the sign. For example:
  decimal     hex     encoded(hex)
        1      01       01
       -1      FF       FF
       16      10       10
       63      3F       3F
       64      40       40
      -65      BF     FF3F

STRING
  UNSIGNEDINT nUTF8    // Then length of the string
  UTF8[nUTF8]

UTF8
  BYTE[...]            // see notes
A UTF8-encoded character.
EXTERNINTERFACEDECLARATION
  UNSIGNEDINT nEifdInEv     // number of eventIn EVENT
  UNSIGNEDINT nEifdOutEv    // number of eventOut EVENT
  UNSIGNEDINT nEifFldSpc    // number of field FIELDSPEC
  UNSIGNEDINT nEifExFldSpc  // number of exposed field FIELDSPEC
  EVENT[nEifdInEv]          // eventIn 
  EVENT[nEifdOutEv]         // eventOut
  FIELDSPEC[nEifFldSpc]     // fields
  FIELDSPEC[nEifExFldSpc]   // exposed fields

URLS
  UNSIGNEDINT nUrlsStr
  STRING[nUrlsStr]

EVENT
  STRING                    // event name
  FIELDTYPE                 // event type

FIELDTYPE 
  SIGNEDINT
The value of the SIGNEDINT is calculated by ordering (starting with 1) the fields in VRML field reference (in current specification Bool=1, Color=2, ...). If the field is a single-valued field use the positive value of the ordering (SFBool=1), if the field is multiple-value field negate the value (MFBool=-1).
FIELDSPEC
  STRING                    // field name
  FIELDTYPE                 // field type

PROTO
  NODETYPE                  // unique negative number
  STRING                    // prototypename
  INTERFACEDECLARATION
  SCENEGRAPH
See notes under NODETYPE.
INTERFACEDECLARATION
  UNSIGNEDINT nIfdInEv        // number of eventIn EVENT
  UNSIGNEDINT nIfdOutEv       // number of eventOut EVENT
  UNSIGNEDINT nIfdFld         // number of field INTERFACEFIELD
  UNSIGNEDINT nIfdExFld       // number of exposed field INTERFACEFIELD
  EVENT[nIfdInEv]             // eventIn 
  EVENT[nIfdOutEv]            // eventOut
  INTERFACEFIELD[nIfdFld]     // fields
  INTERFACEFIELD[nIfdExFld]   // exposed fields

INTERFACEFIELD
  FIELDSPEC
  FIELDVALUE

NODE
  NODEFORMAT
  if(bDEF){
    STRING                  // name
    NODEID
  }
  if(bUSE)
    NODEID
  if(!bUSE){
    NODETYPE                // type of node
    NODEGUT                 // contents
    if(bSCRIPT){            // only if its a script
      SCRIPTINTERFACEDECLARATION
    }
  }

NODEFORMAT
  BIT bUse                  // a USE node?
  BIT bDef                  // a DEFed node?
  BIT bSscript              // a Script node?
  BIT                       // padding, ignored
  BIT                       // padding, ignored
  BIT                       // padding, ignored
  BIT                       // padding, ignored
  BIT                       // padding, ignored

NODEID
  UNSIGNEDINT
All named node definitions must be assigned a unique UNSIGNEDINT identifier. Node references created by a USE statement and nameless node definitions are not assigned identifiers.
NODEGUT
  UNSIGNEDINT nNgIs       // number of IS (as in 'x IS y') 
  UNSIGNEDINT nNgNf       // number of NODEFIELD
  IS[nNgIs]
  NODEFIELD[nNgNf]        // assignments of values to fields

IS                        // (x IS y)
  FIELDNUMBER             // xFieldNumber
  FIELDNUMBER             // yFieldNumber

FIELDNUMBER
  UNSIGNEDINT
The value of the UNSIGNEDINT is assigned according to context.
NODEFIELD
  FIELDNUMBER             // field number
  FIELDVALUE              // field value

FIELDVALUE                  // (fieldType is known by context)
  select fieldType
  case SFBinary
    UNSIGNEDINT nByte
    BYTE[nBye]
  case SFBool
    BIT[7]                  // not used, ignored
    BIT                     // 0=False, 1=True
  case MFBool
    UNSIGNEDINT nByte
    BIT[nByte]
    BIT[...]                // padded to byte boundary
  case SFColor
    COLOR[3]
  case MFColor
    UNSIGNEDINT nColor
    COLOR[nColor*3]
  case SFFloat
    FLOAT
  case MFFloat
    UNSIGNEDINT nFloat
    FLOAT[nFloat]
  case SFImage
    UNSIGNEDINT width     //  width
    UNSIGNEDINT height    //  height
    UNSIGNEDINT nCompon   //  number of components in the image
    BYTE[width*height*nCompon]
  case SFInt32
    UNSIGNEDINT
  case MFInt32
    UNSIGNEDINT nInt32
    UNSIGNEDINT[nInt32]
  case SFNode
    NODE
  case MFNode
    UNSIGNEDINT nNode
    NODE[nNode]
  case SFRotation
    FLOAT[4]
  case MFRotation
    UNSIGNEDINT nRot
    FLOAT[4*nRot]
  case SFString
    STRING
  case MFString
    UNSIGNEDINT nString
    STRING[nString]
  case SFTime
    DOUBLE
  case MFTime
    UNSIGNEDINT nTime
    DOUBLE[nTime]
  case SFVec2f
    FLOAT[2]
  case MFVec2f
    UNSIGNEDINT nVec2f
    FLOAT[2*nVec2f]
  case SFVec3f
    FLOAT[3]
  case MFVec3f
    UNSIGNEDINT nVec3f
    FLOAT[3*nVec3f]

COLOR
  A binary encoded 8bit unsigned integer:
  x00 maps to 0.0
  xFF maps to 1.0

FLOAT
  A Float is represented using the IEEE 32bit format

DOUBLE
  A double is represented using the IEEE 64bit format

SCRIPTINTERFACEDECLARATION
  UNSIGNEDINT nSiInEvent    // number of eventIn EVENT
  UNSIGNEDINT nSiOutEvent   // number of eventOut EVENT
  UNSIGNEDINT nSiIff        // number of INTERFACEFIELD
  if(bProto)
    UNSIGNEDINT nSiI        // number of IS fields and events
  EVENT[nInEvent]           // eventIn 
  EVENT[nOutEvent]          // eventOut
  INTERFACEFIELD[nSiIff]
  if(bPROTO)
    IS[nSiIs                // (for EventIn, EventOut, and Field)

ROUTE
  NODEID                    // from node ID
  FIELDNUMBER               // from field number
  NODEID                    // to node ID
  FIELDNUMBER               // to field number

[ IBM Research | VRML | 3DIX ]
[ RS/6000 | IBM home page | Order | Search | Contact IBM | Help | (C) | (TM) ]