import 'dart:async'; import 'package:flutter/services.dart'; typedef FilamentAsset = int; abstract class FilamentController { late int textureId; Future initialize(int width, int height); Future resize(int width, int height); Future setBackgroundImage(String path); Future loadSkybox(String skyboxPath); Future removeSkybox(); Future loadIbl(String path); Future removeIbl(); Future loadGlb(String path); Future loadGltf(String path, String relativeResourcePath); Future panStart(double x, double y); Future panUpdate(double x, double y); Future panEnd(); Future rotateStart(double x, double y); Future rotateUpdate(double x, double y); Future rotateEnd(); Future applyWeights(FilamentAsset asset, List weights); Future> getTargetNames(FilamentAsset asset, String meshName); Future> getAnimationNames(FilamentAsset asset); Future removeAsset(FilamentAsset asset); Future clearAssets(); Future playAnimation(FilamentAsset asset, int index, {bool loop = false}); Future playAnimations(FilamentAsset asset, List indices, {bool loop = false}); Future stopAnimation(FilamentAsset asset); Future setCamera(FilamentAsset asset, String name); Future setTexture(FilamentAsset asset, String assetPath, { int renderableIndex=0}); Future transformToUnitCube(FilamentAsset asset); Future setPosition(FilamentAsset asset, double x, double y, double z); Future setRotation(FilamentAsset asset, double rads, double x, double y, double z); /// /// Set the weights of all morph targets in the mesh to the specified weights at successive frames (where each frame requires a duration of [frameLengthInMs]. /// Accepts a list of doubles representing a sequence of "frames", stacked end-to-end. /// Each frame is [numWeights] in length, where each entry is the weight to be applied to the morph target located at that index in the mesh primitive at that frame. /// In other words, weights is a contiguous sequence of floats of size W*F, where W is the number of weights and F is the number of frames /// Future animate(FilamentAsset asset, List data, int numWeights, int numFrames, double frameLengthInMs); Future zoom(double z); } class PolyvoxFilamentController extends FilamentController { late MethodChannel _channel = MethodChannel("app.polyvox.filament/event"); PolyvoxFilamentController() { _channel.setMethodCallHandler((call) async { print("Received Filament method channel call : ${call.method}"); throw Exception("Unknown method channel invocation ${call.method}"); }); } Future initialize(int width, int height) async { textureId = await _channel.invokeMethod("initialize", [width, height]); } Future resize(int width, int height) async { await _channel.invokeMethod("resize", [width, height]); } @override Future setBackgroundImage(String path) async { await _channel.invokeMethod("setBackgroundImage", path); } @override Future loadSkybox(String skyboxPath) async { await _channel.invokeMethod("loadSkybox", skyboxPath); } @override Future loadIbl(String lightingPath) async { await _channel.invokeMethod("loadIbl", lightingPath); } @override Future removeSkybox() async { await _channel.invokeMethod("removeSkybox"); } @override Future removeIbl() async { await _channel.invokeMethod("removeIbl"); } Future loadGlb(String path) async { print("Loading GLB at $path "); var asset = await _channel.invokeMethod("loadGlb", path); print("Got asset : $asset "); return asset as FilamentAsset; } Future loadGltf(String path, String relativeResourcePath) async { print( "Loading GLTF at $path with relative resource path $relativeResourcePath"); var asset = await _channel.invokeMethod("loadGltf", [path, relativeResourcePath]); return asset as FilamentAsset; } Future panStart(double x, double y) async { await _channel.invokeMethod("panStart", [x.toInt(), y.toInt()]); } Future panUpdate(double x, double y) async { await _channel.invokeMethod("panUpdate", [x.toInt(), y.toInt()]); } Future panEnd() async { await _channel.invokeMethod("panEnd"); } Future rotateStart(double x, double y) async { await _channel.invokeMethod("rotateStart", [x.toInt(), y.toInt()]); } Future rotateUpdate(double x, double y) async { await _channel.invokeMethod("rotateUpdate", [x.toInt(), y.toInt()]); } Future rotateEnd() async { await _channel.invokeMethod("rotateEnd"); } Future applyWeights(FilamentAsset asset, List weights) async { await _channel.invokeMethod("applyWeights", [asset, weights]); } Future> getTargetNames(FilamentAsset asset, String meshName) async { var result = (await _channel.invokeMethod("getTargetNames", [asset, meshName])) .cast(); return result; } Future> getAnimationNames(FilamentAsset asset) async { var result = (await _channel.invokeMethod("getAnimationNames", asset)).cast(); return result; } Future animate(FilamentAsset asset, List weights, int numWeights, int numFrames, double frameLengthInMs) async { await _channel.invokeMethod( "animateWeights", [asset, weights, numWeights, numFrames, frameLengthInMs]); } Future removeAsset(FilamentAsset asset) async { await _channel.invokeMethod("removeAsset", asset); } Future clearAssets() async { await _channel.invokeMethod("clearAssets"); } Future zoom(double z) async { await _channel.invokeMethod("zoom", z); } Future playAnimation(FilamentAsset asset, int index, {bool loop = false}) async { await _channel.invokeMethod("playAnimation", [asset, index, loop]); } Future playAnimations(FilamentAsset asset, List indices, {bool loop = false}) async { return Future.wait(indices.map((index) { return _channel.invokeMethod("playAnimation", [asset, index, loop]); })); } Future stopAnimation(FilamentAsset asset) async { await _channel.invokeMethod("stopAnimation"); } Future setCamera(FilamentAsset asset, String name) async { await _channel.invokeMethod("setCamera", [asset, name]); } Future setTexture(FilamentAsset asset, String assetPath, { int renderableIndex=0}) async { await _channel.invokeMethod("setTexture", [asset, assetPath, renderableIndex]); } Future transformToUnitCube(FilamentAsset asset) async { await _channel.invokeMethod("transformToUnitCube", asset); } Future setPosition(FilamentAsset asset, double x, double y, double z) async { await _channel.invokeMethod("setPosition", [asset, x, y, z]); } Future setRotation(FilamentAsset asset, double rads, double x, double y, double z) async { await _channel.invokeMethod("setRotation", [asset, rads, x, y, z]); } }