The build-time converter
Open the live demo · Read the source · View on GitHub
flutter3d_build is a command line tool, not something this application
runs: it depends on hooks and code_assets to be a Flutter build
hook, and pulling a build tool into a showcase app would ship it inside
every application that depends on this engine. This page shows what the
tool does by running its two steps, decode then write, by hand.
Step 1: A model, the way the tool would find one #
dart run flutter3d_build:convert model.obj reads a file by its
extension and hands it to the matching decoder: glTF, GLB, OBJ or STL in,
.f3d out. This page's own source is a small OBJ, so nothing here is
made up beyond not being a file on disk.
// `dart run flutter3d_build:convert model.obj` reads a model by its file
// extension. This page hands the same source text straight to the same
// decoder the real tool would pick.
static const String _sourceObj = '''
v 0 1 0
v 1 -1 1
v -1 -1 1
v 0 -1 -1.4
f 1 2 3
f 1 3 4
f 1 4 2
f 2 4 3
''';
Step 2: Decode it, then write it #
This is the whole of what the real tool does to one file: read it with
the ordinary decoder, then hand the decoded document to F3dWriter. The
command line version does this for every recognised model under a
directory, and writes each result beside its source rather than holding
it in memory.
// The converter's own two steps, run here by hand: decode the source
// with the format's ordinary reader, then write it to `.f3d` with
// `F3dWriter`. `dart run flutter3d_build:convert` does exactly this,
// for every model under a directory at once, and writes the result
// beside the source rather than holding it in memory.
final sourceBytes = utf8.encode(_sourceObj);
_sourceBytes = sourceBytes.length;
_decoded = await ObjLoader().load(sourceBytes);
final converted = F3dWriter(_decoded).write();
_convertedBytes = converted.length;
Note. The real tool also has a build hook,
dart run flutter3d_build:init, which wires this conversion into a project's ownflutter buildso a project never has to run the command by hand again.--texturescompresses images on the way through:bc,etc2, oruniversalfor one file the upload transcodes on every device.
Step 3: Compare the sizes #
Even a four-vertex tetrahedron is smaller as .f3d than as text, because
.f3d stores exactly the bytes a GPU wants and nothing has to be parsed
back out of them.
String _report() =>
'source (.obj) bytes: $_sourceBytes\n'
'converted (.f3d) bytes: $_convertedBytes\n\n'
'The real command line tool:\n'
'dart run flutter3d_build:convert model.obj -o model.f3d\n\n'
'and, once per project, the build hook that runs it automatically:\n'
'dart run flutter3d_build:init';
Step 4: Check the claim #
The source has to actually decode, and the converter has to actually write something.
if (_decoded.surfaces.isEmpty) {
throw StateError('the source did not decode to a surface');
}
if (_convertedBytes == 0) {
throw StateError('the converter wrote nothing');
}
if (frame.drawCalls < 1) {
throw StateError('the tetrahedron was not drawn');
}