Class GltfLoader

java.lang.Object
limn.render3d.gltf.GltfLoader

public final class GltfLoader extends Object
Loads a glTF 2.0 asset into a neutral GltfModel: no AWT, no GPU. Handles both .gltf (JSON, with base64 data: buffers) and .glb (binary container). Reads the node hierarchy, mesh primitives (POSITION/NORMAL/TEXCOORD_0 + indices), metallic-roughness materials and encoded texture images. Buffers and images must be embedded, as data: URIs or the GLB binary chunk: a reference to an external file is refused. Skinning and animation are not read; nodes are placed by their static transforms. Images are kept encoded here; decoding them is the separate, off-thread-able step GltfModel.decodeTextures().

Every entry point reads and parses on the thread that calls it. The ...Async ones put that on the Ui worker pool and deliver on the UI thread, which is what an application loading a model behind a live window wants; the synchronous ones stay for setup code and tests.

  • Method Details

    • load

      public static GltfModel load(Path file)
      Reads file whole and parses it (.gltf or .glb), on the calling thread. This is the toolkit's largest blocking read: the file, a JSON parse of the document, a base64 decode of every embedded buffer, and a de-interleaving copy per accessor add up to hundreds of milliseconds for an ordinary model. That is a dropped second on the UI thread. loadAsync(Path) is the same work on the worker pool.
    • fromResource

      public static GltfModel fromResource(String resource)
      Reads a classpath resource whole and parses it (.gltf or .glb), on the calling thread: the shape for a model shipped inside the application jar. See load(Path) for the cost and fromResourceAsync(java.lang.String) for the same work on the worker pool.
      Parameters:
      resource - an absolute resource path, e.g. "/app/models/robot.glb"
      Throws:
      IllegalStateException - if no such resource exists
    • load

      public static GltfModel load(byte[] data)
      Parses a model already in memory, on the calling thread. It is still a JSON parse, a base64 decode of every embedded buffer and a copy per accessor, so see load(Path) for the cost and loadAsync(byte[]) for the same work on the worker pool.
      Throws:
      IllegalArgumentException - if the document is malformed, including one that declares more elements or bytes than the buffer behind them holds, which is refused before the array for them is allocated, so a small file cannot ask for an enormous heap
    • loadAsync

      public static Work<GltfModel> loadAsync(Path file)
      Reads and parses file on the Ui worker pool, delivering the model to onSuccess on the UI thread: the asynchronous form of load(Path).
      
       loading = GltfLoader.loadAsync(file)
                           .onProgress(bar::setValue)
                           .onSuccess(model -> show(model))
                           .deliverIf(view::isShowing)
                           .start();
       

      Returned unstarted: register handlers, then call start(). Nothing is read until then, and a job cancelled while it runs stops between meshes rather than parsing the rest. No disposer is registered and none is needed: a GltfModel is plain arrays, so an undelivered one is collected like any other object.

      Progress runs 0 to 1 across the read, the JSON parse, the buffers and the meshes, weighted by where the time actually goes rather than by member count, so it is monotonic but not linear in time.

      The model it produces is CPU data only. Turning it into something drawable still costs a texture decode and a GPU upload; see GltfModel.decodeTexturesAsync() for the half of that which also belongs here.

      Throws:
      IllegalStateException - if no backend is running (there is no worker pool to use)
    • loadAsync

      public static Work<GltfModel> loadAsync(byte[] data)
      Parses bytes already in memory on the Ui worker pool, delivering the model on the UI thread: the asynchronous form of load(byte[]). Returned unstarted, cancellable and reporting progress exactly as loadAsync(Path) does, minus the read.

      The array is read by the worker thread and must not be modified until the job finishes.

      Throws:
      IllegalStateException - if no backend is running (there is no worker pool to use)
    • fromResourceAsync

      public static Work<GltfModel> fromResourceAsync(String resource)
      Reads and parses a classpath resource on the Ui worker pool, delivering the model on the UI thread: the asynchronous form of fromResource(String), and what an application shipping models in its jar should call. Returned unstarted, cancellable and reporting progress exactly as loadAsync(Path) does.
      Parameters:
      resource - an absolute resource path, e.g. "/app/models/robot.glb"
      Throws:
      IllegalStateException - if no backend is running (there is no worker pool to use)