fromFlatbuffer static method
Deserialize a model from Flutter Scene's compact model format.
If you're using Flutter Scene's offline importer tool, consider using fromAsset to load the model directly from the asset bundle instead.
Implementation
static Future<Node> fromFlatbuffer(ByteData byteData) async {
ImportedScene importedScene = ImportedScene.fromFlatbuffer(byteData);
fb.Scene fbScene = importedScene.flatbuffer;
debugPrint('Unpacking Scene (nodes: ${fbScene.nodes?.length}, '
'textures: ${fbScene.textures?.length})');
// Unpack textures.
List<gpu.Texture> textures = [];
for (fb.Texture fbTexture in fbScene.textures ?? []) {
if (fbTexture.embeddedImage == null) {
if (fbTexture.uri == null) {
debugPrint(
'Texture ${textures.length} has no embedded image or URI. A white placeholder will be used instead.');
textures.add(Material.getWhitePlaceholderTexture());
continue;
}
try {
// If the texture has a URI, try to load it from the asset bundle.
textures.add(await gpuTextureFromAsset(fbTexture.uri!));
continue;
} catch (e) {
debugPrint('Failed to load texture from asset URI: ${fbTexture.uri}. '
'A white placeholder will be used instead. (Error: $e)');
textures.add(Material.getWhitePlaceholderTexture());
continue;
}
}
fb.EmbeddedImage image = fbTexture.embeddedImage!;
gpu.Texture? texture = gpu.gpuContext.createTexture(
gpu.StorageMode.hostVisible, image.width, image.height);
if (texture == null) {
throw Exception('Failed to allocate texture');
}
Uint8List textureData = image.bytes! as Uint8List;
if (!texture.overwrite(ByteData.sublistView(textureData))) {
throw Exception('Failed to overwrite texture data');
}
textures.add(texture);
}
Node result = Node(
name: 'root',
localTransform: fbScene.transform?.toMatrix4() ?? Matrix4.identity());
if (fbScene.nodes == null || fbScene.children == null) {
return result; // The scene is empty. ¯\_(ツ)_/¯
}
// Initialize nodes for unpacking the entire scene.
List<Node> sceneNodes = [];
for (fb.Node _ in fbScene.nodes ?? []) {
sceneNodes.add(Node());
}
// Connect children to the root node.
for (int childIndex in fbScene.children ?? []) {
if (childIndex < 0 || childIndex >= sceneNodes.length) {
throw Exception('Scene child index out of range.');
}
result.add(sceneNodes[childIndex]);
}
// Unpack each node.
for (int nodeIndex = 0; nodeIndex < sceneNodes.length; nodeIndex++) {
sceneNodes[nodeIndex]._unpackFromFlatbuffer(
fbScene.nodes![nodeIndex], sceneNodes, textures);
}
// Unpack animations.
if (fbScene.animations != null) {
for (fb.Animation fbAnimation in fbScene.animations!) {
result._animations
.add(Animation.fromFlatbuffer(fbAnimation, sceneNodes));
}
}
return result;
}