WRL files are generated by Tool when it encounters geometry errors while importing model source files like ASS and JMS. The WRL file can then be imported back into your 3D software to identify the problematic parts of your model so they can be corrected.

Examples of errors include open edges, degenerate faces, leaky portals, and nearly coplanar faces. These errors and warnings can occur when importing level BSPs, render models, collision geometry, or running lightmaps. You should generally fix any errors you find to prevent in-game problems.

The WRL file is usually placed in the same directory of the model that Tool is importing, under data, though sometimes it can be output to the mod tools root directory.

WRL comes in two versions, 1.0 for Halo 1 and 2.0 for Halo 2+. Both versions can be imported to Blender using the Halo Asset Blender Development Toolset. WRL files aren't as important in H2+ since Tool allows geometry to be imported with errors and you can see them in Sapien.

Compatibility

Some versions of 3ds Max (at least 2010) require the 32-bit version in order to import WRL files. Blender only natively support VRMLs 2.0, not 1.0, so the Halo Asset Blender Development Toolset should be used for a consistent experience.

Format description

WRL files are technically VRML files. The following is only relevant if you plan to write a WRL parser.

Version 1

Halo 1 Tool creates WRL 1.0 files, identified by their first line #VRML 1.0 ascii. Blender cannot natively import this version, so you must use the toolset addon. The files consist of a list of Separator nodes, one for each error found by Tool. Any program which aims to parse this file format should consider whitespace to be flexible.

#VRML 1.0 ascii

# An example of an open edge error (red)
Separator {
  # The coordinates array contains all vertices which are referenced
  # by index later.
  Coordinate3 {
    point [
      # Within an array, points are separated by comma (optional trailing comma)
      3456.103516 -3708.525467 2141.230965,
      3284.476471 -3812.968445 2056.174850
    ]
  }
  # The material binding tells us how material properties are used.
  # If the binding type is PER_VERTEX, then the material properties map to the
  # coordinates array above. For PER_FACE, they map to the IndexedFaceSet.
  MaterialBinding {
    value PER_VERTEX
  }
  # The material has two sub-sections whose lengths are not guaranteed
  # to match. The diffuseColor array contains a number of float
  # triplets (RGB) equal to the number of bound elements. However, in
  # the case of PER_FACE bound materials, the transparency array has
  # a single float rather than one per diffuseColor.
  Material {
    diffuseColor [
      1.000000 0.000000 0.000000,
      1.000000 0.000000 0.000000
    ]
    # Floats can be negative and always have a 6 digit decimal part
    transparency [0.000000, 0.000000]
  }
  # An indexed line set contains 1 or more edges, each defined by a
  # pair of indexes into the coords array.
  IndexedLineSet {
    # Index arrays appear "flat", but actually use -1 as a terminator marking
    # the end of spans of indexes within. Also note that the indexes may
    # sometimes be output in a single line, or when there's many values they
    # can be output over multiple lines in which case they will also gain a
    # trailing comma before the closing "]".
    coordIndex [0,1,-1]
  }
}

# An example of nearly coplanar surfaces (red and green)
Separator {
  Coordinate3 {
    # A set of vertices which will be indexed later to form faces
    point [
      5102.994919 -2272.044373 3555.212402,
      5102.994919 -1948.299599 3734.944916,
      5130.073929 -1943.392372 3706.684875,
      5102.994919 -2272.044373 3555.212402,
      5130.073929 -1943.392372 3706.684875,
      5102.994919 -2465.299225 3447.940445,
    ]
  }
  # The number of diffuse colours will match the number of faces
  MaterialBinding {
    value PER_FACE
  }
  Material {
    # The first face will be red, and the second green
    diffuseColor [
      0.000000 1.000000 0.000000,
      1.000000 0.000000 0.000000,
    ]
    # The transparency applies to ALL faces. A value of 0 means opaque
    transparency [0.000000]
  }
  IndexedFaceSet {
    # Note how each face's indices are terminated by a -1
    coordIndex [
      0,1,2,-1,
      3,4,5,-1,
    ]
  }
}

Version 2

Halo 2+ Tool creates WRL 2.0 files, identified by their first line #VRML V2.0 utf8.

Acknowledgements

Thanks to the following individuals for their research or contributions to this topic:

  • Conscars (WRL format research)
  • stunt_man (WRL compatibility and usage notes)