Models can be saved to X3D or STL now (soon to glTF too), new engine API to register custom model formats that can be loaded/saved, proper handling of duplicate node names in glTF on conversion to X3D

Posted on

Cathedral minecraft model, by Patrix, from

We’re working on a big release of our tools soon! For this week, we have some new inter-connected developments:

  1. First of all, I want our tools to be able to output various model formats, not only X3D. My goal is to be able to write glTF files, with as much features as possible. Thus utilizing glTF as both excellent input (right now!) but also output format (soon!) across our tooling.

    While the glTF output is not ready yet, this week I’ve done a big first step. I added a new trivial output format STL (common file format used in 3D printing) and made our tools capable of this alternative output format.

    This means:

    • The implementation of SaveNode procedure in the engine is now nice and flexible, supporting multiple possible model output formats.

    • Castle Model Viewer has a simpler “Save As” dialog that allows to choose any output format, in particular STL.

    • Castle Model Converter allows and recommends to specify a 2nd parameter, the output filename. The extension of the output determines it’s type. This is usually simpler than outputting to stdout. (But if you still want to output to stdout, you can influence output format using new --stdout-url).

    • Our online model converter can also output STL now.

    • Some old and no longer useful things were removed or deprecated. We removed --force-x3d option from Castle Model Converter (it’s no longer necessary, the output type already indicates when VRML->X3D upgrade is necessary). We deprecated --write-* options of Castle Model Viewer (better use now Castle Model Converter for command-line tasks). We deprecated --encoding, as output type (extension) determines already if it’s X3D classic or XML encoding.

  2. Connected to above: we have great new engine API to register custom model formats. Use RegisterModelFormat and TModelFormat to register format that can be saved/loaded to X3D node. 100% of existing formats were remade to use the new system, resulting in simpler code of the engine too.

    The formats you register this way, can be loaded using LoadNode or TCastleSceneCore.Load and saved using SaveNode.

    Here’s an example how to register Wavefront OBJ reader. Use it as a template — but don’t register exactly this format, as we already handle Wavefront OBJ in the engine 🙂 Remember to associate also extensions with MIME type by extending global UriMimeExtensions dictionary.

    function LoadWavefrontOBJ(const Stream: TStream; const BaseUrl: String): TX3DRootNode;
      ModelFormat: TModelFormat;
      ModelFormat := TModelFormat.Create;
      ModelFormat.OnLoad := {$ifdef FPC}@{$endif} LoadWavefrontOBJ;
      ModelFormat.FileFilterName := 'Wavefront (*.obj)';
  3. Finally, we also changed our strategy to deal with name duplicates on input (like non-unique names in glTF content). We now rename non-unique node names on input (like glTF) to be unique on output (to guarantee to make valid X3D from valid input glTF).

    The result is that valid glTF on input (which means: with possible non-unique names for glTF stuff) should always result in valid X3D on output (which means: X3D node names have to be unique).

    See docs: glTF files may have non-unique names, but we advise to generate them to be unique; eventually we’ll force them unique at loading. See also more details in the What to do with node names when importing e.g. glTF? document.

    And see demo of glTF including in X3D: avocado_and_exports. Here the Castle Model Viewer allows to work with the glTF file, despite glTF having duplicate names.

Start the discussion at Castle Game Engine Forum